rs6000: Optimise SImode cstore on 64-bit
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob26b0962ae7d4c62a85121f17538497f3faa8cd1b
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2015 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 [HI 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 ; Definitions for load to 32-bit fpr register
432 (define_mode_attr f32_lr  [(SF "f")               (SD "wz")])
433 (define_mode_attr f32_lr2 [(SF "wb")              (SD "wn")])
434 (define_mode_attr f32_lm  [(SF "m")               (SD "Z")])
435 (define_mode_attr f32_lm2 [(SF "o")               (SD "wn")])
436 (define_mode_attr f32_li  [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
437 (define_mode_attr f32_li2 [(SF "lxssp %0,%1")     (SD "lfiwzx %0,%y1")])
438 (define_mode_attr f32_lv  [(SF "lxsspx %x0,%y1")  (SD "lxsiwzx %x0,%y1")])
440 ; Definitions for store from 32-bit fpr register
441 (define_mode_attr f32_sr  [(SF "f")                (SD "wx")])
442 (define_mode_attr f32_sr2 [(SF "wb")               (SD "wn")])
443 (define_mode_attr f32_sm  [(SF "m")                (SD "Z")])
444 (define_mode_attr f32_sm2 [(SF "o")                (SD "wn")])
445 (define_mode_attr f32_si  [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
446 (define_mode_attr f32_si2 [(SF "stxssp %1,%0")     (SD "stfiwx %1,%y0")])
447 (define_mode_attr f32_sv  [(SF "stxsspx %x1,%y0")  (SD "stxsiwzx %x1,%y0")])
449 ; Definitions for 32-bit fpr direct move
450 ; At present, the decimal modes are not allowed in the traditional altivec
451 ; registers, so restrict the constraints to just the traditional FPRs.
452 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
454 ; Definitions for 32-bit VSX
455 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
457 ; Definitions for 32-bit use of altivec registers
458 (define_mode_attr f32_av  [(SF "wu") (SD "wn")])
460 ; Definitions for 64-bit VSX
461 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
463 ; Definitions for 64-bit direct move
464 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
466 ; Definitions for 64-bit use of altivec registers
467 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
469 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
470 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
472 ; These modes do not fit in integer registers in 32-bit mode.
473 ; but on e500v2, the gpr are 64 bit registers
474 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
476 ; Iterator for reciprocal estimate instructions
477 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
479 ; Iterator for just SF/DF
480 (define_mode_iterator SFDF [SF DF])
482 ; Iterator for 128-bit floating point that uses the IBM double-double format
483 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
484                               (TF "FLOAT128_IBM_P (TFmode)")])
486 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
487 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
488                                (TF "FLOAT128_IEEE_P (TFmode)")])
490 ; Iterator for 128-bit floating point
491 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128")
492                                 (IF "TARGET_FLOAT128")
493                                 (TF "TARGET_LONG_DOUBLE_128")])
495 ; SF/DF suffix for traditional floating instructions
496 (define_mode_attr Ftrad         [(SF "s") (DF "")])
498 ; SF/DF suffix for VSX instructions
499 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
501 ; SF/DF constraint for arithmetic on traditional floating point registers
502 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
504 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
505 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
506 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
507 ; format.
508 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
510 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
511 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
512 ; instructions added in ISA 2.07 (power8)
513 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
515 ; SF/DF constraint for arithmetic on altivec registers
516 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
518 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
519 (define_mode_attr Fs            [(SF "s")  (DF "d")])
521 ; FRE/FRES support
522 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
523 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
525 ; Conditional returns.
526 (define_code_iterator any_return [return simple_return])
527 (define_code_attr return_pred [(return "direct_return ()")
528                                (simple_return "1")])
529 (define_code_attr return_str [(return "") (simple_return "simple_")])
531 ; Logical operators.
532 (define_code_iterator iorxor [ior xor])
534 ; Signed/unsigned variants of ops.
535 (define_code_iterator any_extend        [sign_extend zero_extend])
536 (define_code_iterator any_fix           [fix unsigned_fix])
537 (define_code_iterator any_float         [float unsigned_float])
539 (define_code_attr u  [(sign_extend      "")
540                       (zero_extend      "u")])
542 (define_code_attr su [(sign_extend      "s")
543                       (zero_extend      "u")
544                       (fix              "s")
545                       (unsigned_fix     "s")
546                       (float            "s")
547                       (unsigned_float   "u")])
549 (define_code_attr az [(sign_extend      "a")
550                       (zero_extend      "z")
551                       (fix              "a")
552                       (unsigned_fix     "z")
553                       (float            "a")
554                       (unsigned_float   "z")])
556 (define_code_attr uns [(fix             "")
557                        (unsigned_fix    "uns")
558                        (float           "")
559                        (unsigned_float  "uns")])
561 ; Various instructions that come in SI and DI forms.
562 ; A generic w/d attribute, for things like cmpw/cmpd.
563 (define_mode_attr wd [(QI    "b")
564                       (HI    "h")
565                       (SI    "w")
566                       (DI    "d")
567                       (V16QI "b")
568                       (V8HI  "h")
569                       (V4SI  "w")
570                       (V2DI  "d")])
572 ;; How many bits in this mode?
573 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
575 ; DImode bits
576 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
578 ;; ISEL/ISEL64 target selection
579 (define_mode_attr sel [(SI "") (DI "64")])
581 ;; Bitmask for shift instructions
582 (define_mode_attr hH [(SI "h") (DI "H")])
584 ;; A mode twice the size of the given mode
585 (define_mode_attr dmode [(SI "di") (DI "ti")])
586 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
588 ;; Suffix for reload patterns
589 (define_mode_attr ptrsize [(SI "32bit")
590                            (DI "64bit")])
592 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
593                             (DI "TARGET_64BIT")])
595 (define_mode_attr mptrsize [(SI "si")
596                             (DI "di")])
598 (define_mode_attr ptrload [(SI "lwz")
599                            (DI "ld")])
601 (define_mode_attr ptrm [(SI "m")
602                         (DI "Y")])
604 (define_mode_attr rreg [(SF   "f")
605                         (DF   "ws")
606                         (TF   "f")
607                         (TD   "f")
608                         (V4SF "wf")
609                         (V2DF "wd")])
611 (define_mode_attr rreg2 [(SF   "f")
612                          (DF   "d")])
614 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
615                                  (DF "TARGET_FCFID")])
617 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
618                                 (DF "TARGET_E500_DOUBLE")])
620 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
621                                 (DF "TARGET_DOUBLE_FLOAT")])
623 ;; Mode iterator for logical operations on 128-bit types
624 (define_mode_iterator BOOL_128          [TI
625                                          PTI
626                                          (V16QI "TARGET_ALTIVEC")
627                                          (V8HI  "TARGET_ALTIVEC")
628                                          (V4SI  "TARGET_ALTIVEC")
629                                          (V4SF  "TARGET_ALTIVEC")
630                                          (V2DI  "TARGET_ALTIVEC")
631                                          (V2DF  "TARGET_ALTIVEC")
632                                          (V1TI  "TARGET_ALTIVEC")])
634 ;; For the GPRs we use 3 constraints for register outputs, two that are the
635 ;; same as the output register, and a third where the output register is an
636 ;; early clobber, so we don't have to deal with register overlaps.  For the
637 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
638 ;; either.
640 ;; Mode attribute for boolean operation register constraints for output
641 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
642                                          (PTI   "&r,r,r")
643                                          (V16QI "wa,v,&?r,?r,?r")
644                                          (V8HI  "wa,v,&?r,?r,?r")
645                                          (V4SI  "wa,v,&?r,?r,?r")
646                                          (V4SF  "wa,v,&?r,?r,?r")
647                                          (V2DI  "wa,v,&?r,?r,?r")
648                                          (V2DF  "wa,v,&?r,?r,?r")
649                                          (V1TI  "wa,v,&?r,?r,?r")])
651 ;; Mode attribute for boolean operation register constraints for operand1
652 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
653                                          (PTI   "r,0,r")
654                                          (V16QI "wa,v,r,0,r")
655                                          (V8HI  "wa,v,r,0,r")
656                                          (V4SI  "wa,v,r,0,r")
657                                          (V4SF  "wa,v,r,0,r")
658                                          (V2DI  "wa,v,r,0,r")
659                                          (V2DF  "wa,v,r,0,r")
660                                          (V1TI  "wa,v,r,0,r")])
662 ;; Mode attribute for boolean operation register constraints for operand2
663 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
664                                          (PTI   "r,r,0")
665                                          (V16QI "wa,v,r,r,0")
666                                          (V8HI  "wa,v,r,r,0")
667                                          (V4SI  "wa,v,r,r,0")
668                                          (V4SF  "wa,v,r,r,0")
669                                          (V2DI  "wa,v,r,r,0")
670                                          (V2DF  "wa,v,r,r,0")
671                                          (V1TI  "wa,v,r,r,0")])
673 ;; Mode attribute for boolean operation register constraints for operand1
674 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
675 ;; is used for operand1 or operand2
676 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
677                                          (PTI   "r,0,0")
678                                          (V16QI "wa,v,r,0,0")
679                                          (V8HI  "wa,v,r,0,0")
680                                          (V4SI  "wa,v,r,0,0")
681                                          (V4SF  "wa,v,r,0,0")
682                                          (V2DI  "wa,v,r,0,0")
683                                          (V2DF  "wa,v,r,0,0")
684                                          (V1TI  "wa,v,r,0,0")])
686 ;; Reload iterator for creating the function to allocate a base register to
687 ;; supplement addressing modes.
688 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
689                               SF SD SI DF DD DI TI PTI KF IF TF])
692 ;; Start with fixed-point load and store insns.  Here we put only the more
693 ;; complex forms.  Basic data transfer is done later.
695 (define_insn "zero_extendqi<mode>2"
696   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
697         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
698   ""
699   "@
700    lbz%U1%X1 %0,%1
701    rlwinm %0,%1,0,0xff"
702   [(set_attr "type" "load,shift")])
704 (define_insn_and_split "*zero_extendqi<mode>2_dot"
705   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
706         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
707                     (const_int 0)))
708    (clobber (match_scratch:EXTQI 0 "=r,r"))]
709   "rs6000_gen_cell_microcode"
710   "@
711    andi. %0,%1,0xff
712    #"
713   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
714   [(set (match_dup 0)
715         (zero_extend:EXTQI (match_dup 1)))
716    (set (match_dup 2)
717         (compare:CC (match_dup 0)
718                     (const_int 0)))]
719   ""
720   [(set_attr "type" "logical")
721    (set_attr "dot" "yes")
722    (set_attr "length" "4,8")])
724 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
725   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
726         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
727                     (const_int 0)))
728    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
729         (zero_extend:EXTQI (match_dup 1)))]
730   "rs6000_gen_cell_microcode"
731   "@
732    andi. %0,%1,0xff
733    #"
734   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
735   [(set (match_dup 0)
736         (zero_extend:EXTQI (match_dup 1)))
737    (set (match_dup 2)
738         (compare:CC (match_dup 0)
739                     (const_int 0)))]
740   ""
741   [(set_attr "type" "logical")
742    (set_attr "dot" "yes")
743    (set_attr "length" "4,8")])
746 (define_insn "zero_extendhi<mode>2"
747   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
748         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
749   ""
750   "@
751    lhz%U1%X1 %0,%1
752    rlwinm %0,%1,0,0xffff"
753   [(set_attr "type" "load,shift")])
755 (define_insn_and_split "*zero_extendhi<mode>2_dot"
756   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
757         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
758                     (const_int 0)))
759    (clobber (match_scratch:EXTHI 0 "=r,r"))]
760   "rs6000_gen_cell_microcode"
761   "@
762    andi. %0,%1,0xffff
763    #"
764   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
765   [(set (match_dup 0)
766         (zero_extend:EXTHI (match_dup 1)))
767    (set (match_dup 2)
768         (compare:CC (match_dup 0)
769                     (const_int 0)))]
770   ""
771   [(set_attr "type" "logical")
772    (set_attr "dot" "yes")
773    (set_attr "length" "4,8")])
775 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
776   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
777         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
778                     (const_int 0)))
779    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
780         (zero_extend:EXTHI (match_dup 1)))]
781   "rs6000_gen_cell_microcode"
782   "@
783    andi. %0,%1,0xffff
784    #"
785   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
786   [(set (match_dup 0)
787         (zero_extend:EXTHI (match_dup 1)))
788    (set (match_dup 2)
789         (compare:CC (match_dup 0)
790                     (const_int 0)))]
791   ""
792   [(set_attr "type" "logical")
793    (set_attr "dot" "yes")
794    (set_attr "length" "4,8")])
797 (define_insn "zero_extendsi<mode>2"
798   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
799         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
800   ""
801   "@
802    lwz%U1%X1 %0,%1
803    rldicl %0,%1,0,32
804    mtvsrwz %x0,%1
805    lfiwzx %0,%y1
806    lxsiwzx %x0,%y1"
807   [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
809 (define_insn_and_split "*zero_extendsi<mode>2_dot"
810   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
811         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
812                     (const_int 0)))
813    (clobber (match_scratch:EXTSI 0 "=r,r"))]
814   "rs6000_gen_cell_microcode"
815   "@
816    rldicl. %0,%1,0,32
817    #"
818   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
819   [(set (match_dup 0)
820         (zero_extend:DI (match_dup 1)))
821    (set (match_dup 2)
822         (compare:CC (match_dup 0)
823                     (const_int 0)))]
824   ""
825   [(set_attr "type" "shift")
826    (set_attr "dot" "yes")
827    (set_attr "length" "4,8")])
829 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
830   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
831         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
832                     (const_int 0)))
833    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
834         (zero_extend:EXTSI (match_dup 1)))]
835   "rs6000_gen_cell_microcode"
836   "@
837    rldicl. %0,%1,0,32
838    #"
839   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
840   [(set (match_dup 0)
841         (zero_extend:EXTSI (match_dup 1)))
842    (set (match_dup 2)
843         (compare:CC (match_dup 0)
844                     (const_int 0)))]
845   ""
846   [(set_attr "type" "shift")
847    (set_attr "dot" "yes")
848    (set_attr "length" "4,8")])
851 (define_insn "extendqi<mode>2"
852   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
853         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
854   ""
855   "extsb %0,%1"
856   [(set_attr "type" "exts")])
858 (define_insn_and_split "*extendqi<mode>2_dot"
859   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
860         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
861                     (const_int 0)))
862    (clobber (match_scratch:EXTQI 0 "=r,r"))]
863   "rs6000_gen_cell_microcode"
864   "@
865    extsb. %0,%1
866    #"
867   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
868   [(set (match_dup 0)
869         (sign_extend:EXTQI (match_dup 1)))
870    (set (match_dup 2)
871         (compare:CC (match_dup 0)
872                     (const_int 0)))]
873   ""
874   [(set_attr "type" "exts")
875    (set_attr "dot" "yes")
876    (set_attr "length" "4,8")])
878 (define_insn_and_split "*extendqi<mode>2_dot2"
879   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
880         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
881                     (const_int 0)))
882    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
883         (sign_extend:EXTQI (match_dup 1)))]
884   "rs6000_gen_cell_microcode"
885   "@
886    extsb. %0,%1
887    #"
888   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
889   [(set (match_dup 0)
890         (sign_extend:EXTQI (match_dup 1)))
891    (set (match_dup 2)
892         (compare:CC (match_dup 0)
893                     (const_int 0)))]
894   ""
895   [(set_attr "type" "exts")
896    (set_attr "dot" "yes")
897    (set_attr "length" "4,8")])
900 (define_expand "extendhi<mode>2"
901   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
902         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
903   ""
904   "")
906 (define_insn "*extendhi<mode>2"
907   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
908         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
909   "rs6000_gen_cell_microcode"
910   "@
911    lha%U1%X1 %0,%1
912    extsh %0,%1"
913   [(set_attr "type" "load,exts")
914    (set_attr "sign_extend" "yes")])
916 (define_insn "*extendhi<mode>2_noload"
917   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
918         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
919   "!rs6000_gen_cell_microcode"
920   "extsh %0,%1"
921   [(set_attr "type" "exts")])
923 (define_insn_and_split "*extendhi<mode>2_dot"
924   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
925         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
926                     (const_int 0)))
927    (clobber (match_scratch:EXTHI 0 "=r,r"))]
928   "rs6000_gen_cell_microcode"
929   "@
930    extsh. %0,%1
931    #"
932   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
933   [(set (match_dup 0)
934         (sign_extend:EXTHI (match_dup 1)))
935    (set (match_dup 2)
936         (compare:CC (match_dup 0)
937                     (const_int 0)))]
938   ""
939   [(set_attr "type" "exts")
940    (set_attr "dot" "yes")
941    (set_attr "length" "4,8")])
943 (define_insn_and_split "*extendhi<mode>2_dot2"
944   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
945         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
946                     (const_int 0)))
947    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
948         (sign_extend:EXTHI (match_dup 1)))]
949   "rs6000_gen_cell_microcode"
950   "@
951    extsh. %0,%1
952    #"
953   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
954   [(set (match_dup 0)
955         (sign_extend:EXTHI (match_dup 1)))
956    (set (match_dup 2)
957         (compare:CC (match_dup 0)
958                     (const_int 0)))]
959   ""
960   [(set_attr "type" "exts")
961    (set_attr "dot" "yes")
962    (set_attr "length" "4,8")])
965 (define_insn "extendsi<mode>2"
966   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
967         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
968   ""
969   "@
970    lwa%U1%X1 %0,%1
971    extsw %0,%1
972    mtvsrwa %x0,%1
973    lfiwax %0,%y1
974    lxsiwax %x0,%y1"
975   [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
976    (set_attr "sign_extend" "yes")])
978 (define_insn_and_split "*extendsi<mode>2_dot"
979   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
980         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
981                     (const_int 0)))
982    (clobber (match_scratch:EXTSI 0 "=r,r"))]
983   "rs6000_gen_cell_microcode"
984   "@
985    extsw. %0,%1
986    #"
987   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
988   [(set (match_dup 0)
989         (sign_extend:EXTSI (match_dup 1)))
990    (set (match_dup 2)
991         (compare:CC (match_dup 0)
992                     (const_int 0)))]
993   ""
994   [(set_attr "type" "exts")
995    (set_attr "dot" "yes")
996    (set_attr "length" "4,8")])
998 (define_insn_and_split "*extendsi<mode>2_dot2"
999   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1000         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1001                     (const_int 0)))
1002    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1003         (sign_extend:EXTSI (match_dup 1)))]
1004   "rs6000_gen_cell_microcode"
1005   "@
1006    extsw. %0,%1
1007    #"
1008   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1009   [(set (match_dup 0)
1010         (sign_extend:EXTSI (match_dup 1)))
1011    (set (match_dup 2)
1012         (compare:CC (match_dup 0)
1013                     (const_int 0)))]
1014   ""
1015   [(set_attr "type" "exts")
1016    (set_attr "dot" "yes")
1017    (set_attr "length" "4,8")])
1019 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1021 (define_insn "*macchwc"
1022   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1023         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1024                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1025                                        (const_int 16))
1026                                       (sign_extend:SI
1027                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1028                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1029                     (const_int 0)))
1030    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1031         (plus:SI (mult:SI (ashiftrt:SI
1032                            (match_dup 2)
1033                            (const_int 16))
1034                           (sign_extend:SI
1035                            (match_dup 1)))
1036                  (match_dup 4)))]
1037   "TARGET_MULHW"
1038   "macchw. %0,%1,%2"
1039   [(set_attr "type" "halfmul")])
1041 (define_insn "*macchw"
1042   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1043         (plus:SI (mult:SI (ashiftrt:SI
1044                            (match_operand:SI 2 "gpc_reg_operand" "r")
1045                            (const_int 16))
1046                           (sign_extend:SI
1047                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1048                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1049   "TARGET_MULHW"
1050   "macchw %0,%1,%2"
1051   [(set_attr "type" "halfmul")])
1053 (define_insn "*macchwuc"
1054   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1055         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1056                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1057                                        (const_int 16))
1058                                       (zero_extend:SI
1059                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1060                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1061                     (const_int 0)))
1062    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1063         (plus:SI (mult:SI (lshiftrt:SI
1064                            (match_dup 2)
1065                            (const_int 16))
1066                           (zero_extend:SI
1067                            (match_dup 1)))
1068                  (match_dup 4)))]
1069   "TARGET_MULHW"
1070   "macchwu. %0,%1,%2"
1071   [(set_attr "type" "halfmul")])
1073 (define_insn "*macchwu"
1074   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1075         (plus:SI (mult:SI (lshiftrt:SI
1076                            (match_operand:SI 2 "gpc_reg_operand" "r")
1077                            (const_int 16))
1078                           (zero_extend:SI
1079                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1080                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1081   "TARGET_MULHW"
1082   "macchwu %0,%1,%2"
1083   [(set_attr "type" "halfmul")])
1085 (define_insn "*machhwc"
1086   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1087         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1088                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1089                                        (const_int 16))
1090                                       (ashiftrt:SI
1091                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1092                                        (const_int 16)))
1093                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1094                     (const_int 0)))
1095    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1096         (plus:SI (mult:SI (ashiftrt:SI
1097                            (match_dup 1)
1098                            (const_int 16))
1099                           (ashiftrt:SI
1100                            (match_dup 2)
1101                            (const_int 16)))
1102                  (match_dup 4)))]
1103   "TARGET_MULHW"
1104   "machhw. %0,%1,%2"
1105   [(set_attr "type" "halfmul")])
1107 (define_insn "*machhw"
1108   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1109         (plus:SI (mult:SI (ashiftrt:SI
1110                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1111                            (const_int 16))
1112                           (ashiftrt:SI
1113                            (match_operand:SI 2 "gpc_reg_operand" "r")
1114                            (const_int 16)))
1115                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1116   "TARGET_MULHW"
1117   "machhw %0,%1,%2"
1118   [(set_attr "type" "halfmul")])
1120 (define_insn "*machhwuc"
1121   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1122         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1123                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1124                                        (const_int 16))
1125                                       (lshiftrt:SI
1126                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1127                                        (const_int 16)))
1128                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1129                     (const_int 0)))
1130    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1131         (plus:SI (mult:SI (lshiftrt:SI
1132                            (match_dup 1)
1133                            (const_int 16))
1134                           (lshiftrt:SI
1135                            (match_dup 2)
1136                            (const_int 16)))
1137                  (match_dup 4)))]
1138   "TARGET_MULHW"
1139   "machhwu. %0,%1,%2"
1140   [(set_attr "type" "halfmul")])
1142 (define_insn "*machhwu"
1143   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1144         (plus:SI (mult:SI (lshiftrt:SI
1145                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1146                            (const_int 16))
1147                           (lshiftrt:SI
1148                            (match_operand:SI 2 "gpc_reg_operand" "r")
1149                            (const_int 16)))
1150                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1151   "TARGET_MULHW"
1152   "machhwu %0,%1,%2"
1153   [(set_attr "type" "halfmul")])
1155 (define_insn "*maclhwc"
1156   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1157         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1158                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1159                                       (sign_extend:SI
1160                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1161                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1162                     (const_int 0)))
1163    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1164         (plus:SI (mult:SI (sign_extend:SI
1165                            (match_dup 1))
1166                           (sign_extend:SI
1167                            (match_dup 2)))
1168                  (match_dup 4)))]
1169   "TARGET_MULHW"
1170   "maclhw. %0,%1,%2"
1171   [(set_attr "type" "halfmul")])
1173 (define_insn "*maclhw"
1174   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1175         (plus:SI (mult:SI (sign_extend:SI
1176                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1177                           (sign_extend:SI
1178                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1179                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1180   "TARGET_MULHW"
1181   "maclhw %0,%1,%2"
1182   [(set_attr "type" "halfmul")])
1184 (define_insn "*maclhwuc"
1185   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1186         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1187                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1188                                       (zero_extend:SI
1189                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1190                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1191                     (const_int 0)))
1192    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1193         (plus:SI (mult:SI (zero_extend:SI
1194                            (match_dup 1))
1195                           (zero_extend:SI
1196                            (match_dup 2)))
1197                  (match_dup 4)))]
1198   "TARGET_MULHW"
1199   "maclhwu. %0,%1,%2"
1200   [(set_attr "type" "halfmul")])
1202 (define_insn "*maclhwu"
1203   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1204         (plus:SI (mult:SI (zero_extend:SI
1205                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1206                           (zero_extend:SI
1207                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1208                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1209   "TARGET_MULHW"
1210   "maclhwu %0,%1,%2"
1211   [(set_attr "type" "halfmul")])
1213 (define_insn "*nmacchwc"
1214   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1215         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1216                               (mult:SI (ashiftrt:SI
1217                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1218                                         (const_int 16))
1219                                        (sign_extend:SI
1220                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1221                     (const_int 0)))
1222    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1223         (minus:SI (match_dup 4)
1224                   (mult:SI (ashiftrt:SI
1225                             (match_dup 2)
1226                             (const_int 16))
1227                            (sign_extend:SI
1228                             (match_dup 1)))))]
1229   "TARGET_MULHW"
1230   "nmacchw. %0,%1,%2"
1231   [(set_attr "type" "halfmul")])
1233 (define_insn "*nmacchw"
1234   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1235         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1236                   (mult:SI (ashiftrt:SI
1237                             (match_operand:SI 2 "gpc_reg_operand" "r")
1238                             (const_int 16))
1239                            (sign_extend:SI
1240                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1241   "TARGET_MULHW"
1242   "nmacchw %0,%1,%2"
1243   [(set_attr "type" "halfmul")])
1245 (define_insn "*nmachhwc"
1246   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1247         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1248                               (mult:SI (ashiftrt:SI
1249                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1250                                         (const_int 16))
1251                                        (ashiftrt:SI
1252                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1253                                         (const_int 16))))
1254                     (const_int 0)))
1255    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1256         (minus:SI (match_dup 4)
1257                   (mult:SI (ashiftrt:SI
1258                             (match_dup 1)
1259                             (const_int 16))
1260                            (ashiftrt:SI
1261                             (match_dup 2)
1262                             (const_int 16)))))]
1263   "TARGET_MULHW"
1264   "nmachhw. %0,%1,%2"
1265   [(set_attr "type" "halfmul")])
1267 (define_insn "*nmachhw"
1268   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1269         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1270                   (mult:SI (ashiftrt:SI
1271                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1272                             (const_int 16))
1273                            (ashiftrt:SI
1274                             (match_operand:SI 2 "gpc_reg_operand" "r")
1275                             (const_int 16)))))]
1276   "TARGET_MULHW"
1277   "nmachhw %0,%1,%2"
1278   [(set_attr "type" "halfmul")])
1280 (define_insn "*nmaclhwc"
1281   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1282         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1283                               (mult:SI (sign_extend:SI
1284                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1285                                        (sign_extend:SI
1286                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1287                     (const_int 0)))
1288    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1289         (minus:SI (match_dup 4)
1290                   (mult:SI (sign_extend:SI
1291                             (match_dup 1))
1292                            (sign_extend:SI
1293                             (match_dup 2)))))]
1294   "TARGET_MULHW"
1295   "nmaclhw. %0,%1,%2"
1296   [(set_attr "type" "halfmul")])
1298 (define_insn "*nmaclhw"
1299   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1300         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1301                   (mult:SI (sign_extend:SI
1302                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1303                            (sign_extend:SI
1304                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1305   "TARGET_MULHW"
1306   "nmaclhw %0,%1,%2"
1307   [(set_attr "type" "halfmul")])
1309 (define_insn "*mulchwc"
1310   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1311         (compare:CC (mult:SI (ashiftrt:SI
1312                               (match_operand:SI 2 "gpc_reg_operand" "r")
1313                               (const_int 16))
1314                              (sign_extend:SI
1315                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1316                     (const_int 0)))
1317    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1318         (mult:SI (ashiftrt:SI
1319                   (match_dup 2)
1320                   (const_int 16))
1321                  (sign_extend:SI
1322                   (match_dup 1))))]
1323   "TARGET_MULHW"
1324   "mulchw. %0,%1,%2"
1325   [(set_attr "type" "halfmul")])
1327 (define_insn "*mulchw"
1328   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1329         (mult:SI (ashiftrt:SI
1330                   (match_operand:SI 2 "gpc_reg_operand" "r")
1331                   (const_int 16))
1332                  (sign_extend:SI
1333                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1334   "TARGET_MULHW"
1335   "mulchw %0,%1,%2"
1336   [(set_attr "type" "halfmul")])
1338 (define_insn "*mulchwuc"
1339   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1340         (compare:CC (mult:SI (lshiftrt:SI
1341                               (match_operand:SI 2 "gpc_reg_operand" "r")
1342                               (const_int 16))
1343                              (zero_extend:SI
1344                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1345                     (const_int 0)))
1346    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1347         (mult:SI (lshiftrt:SI
1348                   (match_dup 2)
1349                   (const_int 16))
1350                  (zero_extend:SI
1351                   (match_dup 1))))]
1352   "TARGET_MULHW"
1353   "mulchwu. %0,%1,%2"
1354   [(set_attr "type" "halfmul")])
1356 (define_insn "*mulchwu"
1357   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1358         (mult:SI (lshiftrt:SI
1359                   (match_operand:SI 2 "gpc_reg_operand" "r")
1360                   (const_int 16))
1361                  (zero_extend:SI
1362                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1363   "TARGET_MULHW"
1364   "mulchwu %0,%1,%2"
1365   [(set_attr "type" "halfmul")])
1367 (define_insn "*mulhhwc"
1368   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1369         (compare:CC (mult:SI (ashiftrt:SI
1370                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1371                               (const_int 16))
1372                              (ashiftrt:SI
1373                               (match_operand:SI 2 "gpc_reg_operand" "r")
1374                               (const_int 16)))
1375                     (const_int 0)))
1376    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1377         (mult:SI (ashiftrt:SI
1378                   (match_dup 1)
1379                   (const_int 16))
1380                  (ashiftrt:SI
1381                   (match_dup 2)
1382                   (const_int 16))))]
1383   "TARGET_MULHW"
1384   "mulhhw. %0,%1,%2"
1385   [(set_attr "type" "halfmul")])
1387 (define_insn "*mulhhw"
1388   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1389         (mult:SI (ashiftrt:SI
1390                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1391                   (const_int 16))
1392                  (ashiftrt:SI
1393                   (match_operand:SI 2 "gpc_reg_operand" "r")
1394                   (const_int 16))))]
1395   "TARGET_MULHW"
1396   "mulhhw %0,%1,%2"
1397   [(set_attr "type" "halfmul")])
1399 (define_insn "*mulhhwuc"
1400   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1401         (compare:CC (mult:SI (lshiftrt:SI
1402                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1403                               (const_int 16))
1404                              (lshiftrt:SI
1405                               (match_operand:SI 2 "gpc_reg_operand" "r")
1406                               (const_int 16)))
1407                     (const_int 0)))
1408    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1409         (mult:SI (lshiftrt:SI
1410                   (match_dup 1)
1411                   (const_int 16))
1412                  (lshiftrt:SI
1413                   (match_dup 2)
1414                   (const_int 16))))]
1415   "TARGET_MULHW"
1416   "mulhhwu. %0,%1,%2"
1417   [(set_attr "type" "halfmul")])
1419 (define_insn "*mulhhwu"
1420   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1421         (mult:SI (lshiftrt:SI
1422                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1423                   (const_int 16))
1424                  (lshiftrt:SI
1425                   (match_operand:SI 2 "gpc_reg_operand" "r")
1426                   (const_int 16))))]
1427   "TARGET_MULHW"
1428   "mulhhwu %0,%1,%2"
1429   [(set_attr "type" "halfmul")])
1431 (define_insn "*mullhwc"
1432   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1433         (compare:CC (mult:SI (sign_extend:SI
1434                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1435                              (sign_extend:SI
1436                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1437                     (const_int 0)))
1438    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1439         (mult:SI (sign_extend:SI
1440                   (match_dup 1))
1441                  (sign_extend:SI
1442                   (match_dup 2))))]
1443   "TARGET_MULHW"
1444   "mullhw. %0,%1,%2"
1445   [(set_attr "type" "halfmul")])
1447 (define_insn "*mullhw"
1448   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1449         (mult:SI (sign_extend:SI
1450                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1451                  (sign_extend:SI
1452                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1453   "TARGET_MULHW"
1454   "mullhw %0,%1,%2"
1455   [(set_attr "type" "halfmul")])
1457 (define_insn "*mullhwuc"
1458   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1459         (compare:CC (mult:SI (zero_extend:SI
1460                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1461                              (zero_extend:SI
1462                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1463                     (const_int 0)))
1464    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1465         (mult:SI (zero_extend:SI
1466                   (match_dup 1))
1467                  (zero_extend:SI
1468                   (match_dup 2))))]
1469   "TARGET_MULHW"
1470   "mullhwu. %0,%1,%2"
1471   [(set_attr "type" "halfmul")])
1473 (define_insn "*mullhwu"
1474   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1475         (mult:SI (zero_extend:SI
1476                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1477                  (zero_extend:SI
1478                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1479   "TARGET_MULHW"
1480   "mullhwu %0,%1,%2"
1481   [(set_attr "type" "halfmul")])
1483 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1484 (define_insn "dlmzb"
1485   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1486         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1487                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1488                    UNSPEC_DLMZB_CR))
1489    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1490         (unspec:SI [(match_dup 1)
1491                     (match_dup 2)]
1492                    UNSPEC_DLMZB))]
1493   "TARGET_DLMZB"
1494   "dlmzb. %0,%1,%2")
1496 (define_expand "strlensi"
1497   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1498         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1499                     (match_operand:QI 2 "const_int_operand" "")
1500                     (match_operand 3 "const_int_operand" "")]
1501                    UNSPEC_DLMZB_STRLEN))
1502    (clobber (match_scratch:CC 4 "=x"))]
1503   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1505   rtx result = operands[0];
1506   rtx src = operands[1];
1507   rtx search_char = operands[2];
1508   rtx align = operands[3];
1509   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1510   rtx loop_label, end_label, mem, cr0, cond;
1511   if (search_char != const0_rtx
1512       || GET_CODE (align) != CONST_INT
1513       || INTVAL (align) < 8)
1514         FAIL;
1515   word1 = gen_reg_rtx (SImode);
1516   word2 = gen_reg_rtx (SImode);
1517   scratch_dlmzb = gen_reg_rtx (SImode);
1518   scratch_string = gen_reg_rtx (Pmode);
1519   loop_label = gen_label_rtx ();
1520   end_label = gen_label_rtx ();
1521   addr = force_reg (Pmode, XEXP (src, 0));
1522   emit_move_insn (scratch_string, addr);
1523   emit_label (loop_label);
1524   mem = change_address (src, SImode, scratch_string);
1525   emit_move_insn (word1, mem);
1526   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1527   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1528   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1529   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1530   emit_jump_insn (gen_rtx_SET (pc_rtx,
1531                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1532                                                      cond,
1533                                                      gen_rtx_LABEL_REF
1534                                                        (VOIDmode,
1535                                                         end_label),
1536                                                      pc_rtx)));
1537   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1538   emit_jump_insn (gen_rtx_SET (pc_rtx,
1539                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1540   emit_barrier ();
1541   emit_label (end_label);
1542   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1543   emit_insn (gen_subsi3 (result, scratch_string, addr));
1544   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1545   DONE;
1548 ;; Fixed-point arithmetic insns.
1550 (define_expand "add<mode>3"
1551   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1552         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1553                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1554   ""
1556   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1557     {
1558       rtx lo0 = gen_lowpart (SImode, operands[0]);
1559       rtx lo1 = gen_lowpart (SImode, operands[1]);
1560       rtx lo2 = gen_lowpart (SImode, operands[2]);
1561       rtx hi0 = gen_highpart (SImode, operands[0]);
1562       rtx hi1 = gen_highpart (SImode, operands[1]);
1563       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1565       if (!reg_or_short_operand (lo2, SImode))
1566         lo2 = force_reg (SImode, lo2);
1567       if (!adde_operand (hi2, SImode))
1568         hi2 = force_reg (SImode, hi2);
1570       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1571       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1572       DONE;
1573     }
1575   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1576     {
1577       rtx tmp = ((!can_create_pseudo_p ()
1578                   || rtx_equal_p (operands[0], operands[1]))
1579                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1581       HOST_WIDE_INT val = INTVAL (operands[2]);
1582       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1583       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1585       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1586         FAIL;
1588       /* The ordering here is important for the prolog expander.
1589          When space is allocated from the stack, adding 'low' first may
1590          produce a temporary deallocation (which would be bad).  */
1591       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1592       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1593       DONE;
1594     }
1597 (define_insn "*add<mode>3"
1598   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1599         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1600                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1601   ""
1602   "@
1603    add %0,%1,%2
1604    addi %0,%1,%2
1605    addis %0,%1,%v2"
1606   [(set_attr "type" "add")])
1608 (define_insn "addsi3_high"
1609   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1610         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1611                  (high:SI (match_operand 2 "" ""))))]
1612   "TARGET_MACHO && !TARGET_64BIT"
1613   "addis %0,%1,ha16(%2)"
1614   [(set_attr "type" "add")])
1616 (define_insn_and_split "*add<mode>3_dot"
1617   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1618         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1619                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1620                     (const_int 0)))
1621    (clobber (match_scratch:GPR 0 "=r,r"))]
1622   "<MODE>mode == Pmode"
1623   "@
1624    add. %0,%1,%2
1625    #"
1626   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1627   [(set (match_dup 0)
1628         (plus:GPR (match_dup 1)
1629                  (match_dup 2)))
1630    (set (match_dup 3)
1631         (compare:CC (match_dup 0)
1632                     (const_int 0)))]
1633   ""
1634   [(set_attr "type" "add")
1635    (set_attr "dot" "yes")
1636    (set_attr "length" "4,8")])
1638 (define_insn_and_split "*add<mode>3_dot2"
1639   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1640         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1641                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1642                     (const_int 0)))
1643    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1644         (plus:GPR (match_dup 1)
1645                   (match_dup 2)))]
1646   "<MODE>mode == Pmode"
1647   "@
1648    add. %0,%1,%2
1649    #"
1650   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1651   [(set (match_dup 0)
1652         (plus:GPR (match_dup 1)
1653                   (match_dup 2)))
1654    (set (match_dup 3)
1655         (compare:CC (match_dup 0)
1656                     (const_int 0)))]
1657   ""
1658   [(set_attr "type" "add")
1659    (set_attr "dot" "yes")
1660    (set_attr "length" "4,8")])
1662 (define_insn_and_split "*add<mode>3_imm_dot"
1663   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1664         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1665                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1666                     (const_int 0)))
1667    (clobber (match_scratch:GPR 0 "=r,r"))
1668    (clobber (reg:GPR CA_REGNO))]
1669   "<MODE>mode == Pmode"
1670   "@
1671    addic. %0,%1,%2
1672    #"
1673   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1674   [(set (match_dup 0)
1675         (plus:GPR (match_dup 1)
1676                   (match_dup 2)))
1677    (set (match_dup 3)
1678         (compare:CC (match_dup 0)
1679                     (const_int 0)))]
1680   ""
1681   [(set_attr "type" "add")
1682    (set_attr "dot" "yes")
1683    (set_attr "length" "4,8")])
1685 (define_insn_and_split "*add<mode>3_imm_dot2"
1686   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1687         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1688                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1689                     (const_int 0)))
1690    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1691         (plus:GPR (match_dup 1)
1692                   (match_dup 2)))
1693    (clobber (reg:GPR CA_REGNO))]
1694   "<MODE>mode == Pmode"
1695   "@
1696    addic. %0,%1,%2
1697    #"
1698   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1699   [(set (match_dup 0)
1700         (plus:GPR (match_dup 1)
1701                   (match_dup 2)))
1702    (set (match_dup 3)
1703         (compare:CC (match_dup 0)
1704                     (const_int 0)))]
1705   ""
1706   [(set_attr "type" "add")
1707    (set_attr "dot" "yes")
1708    (set_attr "length" "4,8")])
1710 ;; Split an add that we can't do in one insn into two insns, each of which
1711 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1712 ;; add should be last in case the result gets used in an address.
1714 (define_split
1715   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1716         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1717                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1718   ""
1719   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1720    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1722   HOST_WIDE_INT val = INTVAL (operands[2]);
1723   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1724   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1726   operands[4] = GEN_INT (low);
1727   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1728     operands[3] = GEN_INT (rest);
1729   else if (can_create_pseudo_p ())
1730     {
1731       operands[3] = gen_reg_rtx (DImode);
1732       emit_move_insn (operands[3], operands[2]);
1733       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1734       DONE;
1735     }
1736   else
1737     FAIL;
1741 (define_insn "add<mode>3_carry"
1742   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1743         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1744                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1745    (set (reg:P CA_REGNO)
1746         (ltu:P (plus:P (match_dup 1)
1747                        (match_dup 2))
1748                (match_dup 1)))]
1749   ""
1750   "add%I2c %0,%1,%2"
1751   [(set_attr "type" "add")])
1753 (define_insn "*add<mode>3_imm_carry_pos"
1754   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1755         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1756                 (match_operand:P 2 "short_cint_operand" "n")))
1757    (set (reg:P CA_REGNO)
1758         (geu:P (match_dup 1)
1759                (match_operand:P 3 "const_int_operand" "n")))]
1760   "INTVAL (operands[2]) > 0
1761    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1762   "addic %0,%1,%2"
1763   [(set_attr "type" "add")])
1765 (define_insn "*add<mode>3_imm_carry_0"
1766   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1767         (match_operand:P 1 "gpc_reg_operand" "r"))
1768    (set (reg:P CA_REGNO)
1769         (const_int 0))]
1770   ""
1771   "addic %0,%1,0"
1772   [(set_attr "type" "add")])
1774 (define_insn "*add<mode>3_imm_carry_m1"
1775   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1776         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1777                 (const_int -1)))
1778    (set (reg:P CA_REGNO)
1779         (ne:P (match_dup 1)
1780               (const_int 0)))]
1781   ""
1782   "addic %0,%1,-1"
1783   [(set_attr "type" "add")])
1785 (define_insn "*add<mode>3_imm_carry_neg"
1786   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1787         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1788                 (match_operand:P 2 "short_cint_operand" "n")))
1789    (set (reg:P CA_REGNO)
1790         (gtu:P (match_dup 1)
1791                (match_operand:P 3 "const_int_operand" "n")))]
1792   "INTVAL (operands[2]) < 0
1793    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1794   "addic %0,%1,%2"
1795   [(set_attr "type" "add")])
1798 (define_expand "add<mode>3_carry_in"
1799   [(parallel [
1800      (set (match_operand:GPR 0 "gpc_reg_operand")
1801           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1802                               (match_operand:GPR 2 "adde_operand"))
1803                     (reg:GPR CA_REGNO)))
1804      (clobber (reg:GPR CA_REGNO))])]
1805   ""
1807   if (operands[2] == const0_rtx)
1808     {
1809       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1810       DONE;
1811     }
1812   if (operands[2] == constm1_rtx)
1813     {
1814       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1815       DONE;
1816     }
1819 (define_insn "*add<mode>3_carry_in_internal"
1820   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1821         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1822                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1823                   (reg:GPR CA_REGNO)))
1824    (clobber (reg:GPR CA_REGNO))]
1825   ""
1826   "adde %0,%1,%2"
1827   [(set_attr "type" "add")])
1829 (define_insn "add<mode>3_carry_in_0"
1830   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1831         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1832                   (reg:GPR CA_REGNO)))
1833    (clobber (reg:GPR CA_REGNO))]
1834   ""
1835   "addze %0,%1"
1836   [(set_attr "type" "add")])
1838 (define_insn "add<mode>3_carry_in_m1"
1839   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1840         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1841                             (reg:GPR CA_REGNO))
1842                   (const_int -1)))
1843    (clobber (reg:GPR CA_REGNO))]
1844   ""
1845   "addme %0,%1"
1846   [(set_attr "type" "add")])
1849 (define_expand "one_cmpl<mode>2"
1850   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1851         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1852   ""
1854   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1855     {
1856       rs6000_split_logical (operands, NOT, false, false, false);
1857       DONE;
1858     }
1861 (define_insn "*one_cmpl<mode>2"
1862   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1863         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1864   ""
1865   "not %0,%1")
1867 (define_insn_and_split "*one_cmpl<mode>2_dot"
1868   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1869         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1870                     (const_int 0)))
1871    (clobber (match_scratch:GPR 0 "=r,r"))]
1872   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1873   "@
1874    not. %0,%1
1875    #"
1876   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1877   [(set (match_dup 0)
1878         (not:GPR (match_dup 1)))
1879    (set (match_dup 2)
1880         (compare:CC (match_dup 0)
1881                     (const_int 0)))]
1882   ""
1883   [(set_attr "type" "logical")
1884    (set_attr "dot" "yes")
1885    (set_attr "length" "4,8")])
1887 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1888   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1889         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1890                     (const_int 0)))
1891    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1892         (not:GPR (match_dup 1)))]
1893   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1894   "@
1895    not. %0,%1
1896    #"
1897   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1898   [(set (match_dup 0)
1899         (not:GPR (match_dup 1)))
1900    (set (match_dup 2)
1901         (compare:CC (match_dup 0)
1902                     (const_int 0)))]
1903   ""
1904   [(set_attr "type" "logical")
1905    (set_attr "dot" "yes")
1906    (set_attr "length" "4,8")])
1909 (define_expand "sub<mode>3"
1910   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1911         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1912                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1913   ""
1915   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1916     {
1917       rtx lo0 = gen_lowpart (SImode, operands[0]);
1918       rtx lo1 = gen_lowpart (SImode, operands[1]);
1919       rtx lo2 = gen_lowpart (SImode, operands[2]);
1920       rtx hi0 = gen_highpart (SImode, operands[0]);
1921       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1922       rtx hi2 = gen_highpart (SImode, operands[2]);
1924       if (!reg_or_short_operand (lo1, SImode))
1925         lo1 = force_reg (SImode, lo1);
1926       if (!adde_operand (hi1, SImode))
1927         hi1 = force_reg (SImode, hi1);
1929       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1930       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1931       DONE;
1932     }
1934   if (short_cint_operand (operands[1], <MODE>mode))
1935     {
1936       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1937       DONE;
1938     }
1941 (define_insn "*subf<mode>3"
1942   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1943         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1944                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1945   ""
1946   "subf %0,%1,%2"
1947   [(set_attr "type" "add")])
1949 (define_insn_and_split "*subf<mode>3_dot"
1950   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1951         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1952                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1953                     (const_int 0)))
1954    (clobber (match_scratch:GPR 0 "=r,r"))]
1955   "<MODE>mode == Pmode"
1956   "@
1957    subf. %0,%1,%2
1958    #"
1959   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1960   [(set (match_dup 0)
1961         (minus:GPR (match_dup 2)
1962                    (match_dup 1)))
1963    (set (match_dup 3)
1964         (compare:CC (match_dup 0)
1965                     (const_int 0)))]
1966   ""
1967   [(set_attr "type" "add")
1968    (set_attr "dot" "yes")
1969    (set_attr "length" "4,8")])
1971 (define_insn_and_split "*subf<mode>3_dot2"
1972   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1973         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1974                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1975                     (const_int 0)))
1976    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1977         (minus:GPR (match_dup 2)
1978                    (match_dup 1)))]
1979   "<MODE>mode == Pmode"
1980   "@
1981    subf. %0,%1,%2
1982    #"
1983   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1984   [(set (match_dup 0)
1985         (minus:GPR (match_dup 2)
1986                    (match_dup 1)))
1987    (set (match_dup 3)
1988         (compare:CC (match_dup 0)
1989                     (const_int 0)))]
1990   ""
1991   [(set_attr "type" "add")
1992    (set_attr "dot" "yes")
1993    (set_attr "length" "4,8")])
1995 (define_insn "subf<mode>3_imm"
1996   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1997         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
1998                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
1999    (clobber (reg:GPR CA_REGNO))]
2000   ""
2001   "subfic %0,%1,%2"
2002   [(set_attr "type" "add")])
2005 (define_insn "subf<mode>3_carry"
2006   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2007         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2008                  (match_operand:P 1 "gpc_reg_operand" "r")))
2009    (set (reg:P CA_REGNO)
2010         (leu:P (match_dup 1)
2011                (match_dup 2)))]
2012   ""
2013   "subf%I2c %0,%1,%2"
2014   [(set_attr "type" "add")])
2016 (define_insn "*subf<mode>3_imm_carry_0"
2017   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2018         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2019    (set (reg:P CA_REGNO)
2020         (eq:P (match_dup 1)
2021               (const_int 0)))]
2022   ""
2023   "subfic %0,%1,0"
2024   [(set_attr "type" "add")])
2026 (define_insn "*subf<mode>3_imm_carry_m1"
2027   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2028         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2029    (set (reg:P CA_REGNO)
2030         (const_int 1))]
2031   ""
2032   "subfic %0,%1,-1"
2033   [(set_attr "type" "add")])
2036 (define_expand "subf<mode>3_carry_in"
2037   [(parallel [
2038      (set (match_operand:GPR 0 "gpc_reg_operand")
2039           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2040                               (reg:GPR CA_REGNO))
2041                     (match_operand:GPR 2 "adde_operand")))
2042      (clobber (reg:GPR CA_REGNO))])]
2043   ""
2045   if (operands[2] == const0_rtx)
2046     {
2047       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2048       DONE;
2049     }
2050   if (operands[2] == constm1_rtx)
2051     {
2052       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2053       DONE;
2054     }
2057 (define_insn "*subf<mode>3_carry_in_internal"
2058   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2059         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2060                             (reg:GPR CA_REGNO))
2061                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2062    (clobber (reg:GPR CA_REGNO))]
2063   ""
2064   "subfe %0,%1,%2"
2065   [(set_attr "type" "add")])
2067 (define_insn "subf<mode>3_carry_in_0"
2068   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2069         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2070                   (reg:GPR CA_REGNO)))
2071    (clobber (reg:GPR CA_REGNO))]
2072   ""
2073   "subfze %0,%1"
2074   [(set_attr "type" "add")])
2076 (define_insn "subf<mode>3_carry_in_m1"
2077   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2078         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2079                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2080                   (const_int -2)))
2081    (clobber (reg:GPR CA_REGNO))]
2082   ""
2083   "subfme %0,%1"
2084   [(set_attr "type" "add")])
2086 (define_insn "subf<mode>3_carry_in_xx"
2087   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2088         (plus:GPR (reg:GPR CA_REGNO)
2089                   (const_int -1)))
2090    (clobber (reg:GPR CA_REGNO))]
2091   ""
2092   "subfe %0,%0,%0"
2093   [(set_attr "type" "add")])
2096 (define_insn "neg<mode>2"
2097   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2098         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2099   ""
2100   "neg %0,%1"
2101   [(set_attr "type" "add")])
2103 (define_insn_and_split "*neg<mode>2_dot"
2104   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2105         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2106                     (const_int 0)))
2107    (clobber (match_scratch:GPR 0 "=r,r"))]
2108   "<MODE>mode == Pmode"
2109   "@
2110    neg. %0,%1
2111    #"
2112   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2113   [(set (match_dup 0)
2114         (neg:GPR (match_dup 1)))
2115    (set (match_dup 2)
2116         (compare:CC (match_dup 0)
2117                     (const_int 0)))]
2118   ""
2119   [(set_attr "type" "add")
2120    (set_attr "dot" "yes")
2121    (set_attr "length" "4,8")])
2123 (define_insn_and_split "*neg<mode>2_dot2"
2124   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2125         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2126                     (const_int 0)))
2127    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2128         (neg:GPR (match_dup 1)))]
2129   "<MODE>mode == Pmode"
2130   "@
2131    neg. %0,%1
2132    #"
2133   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2134   [(set (match_dup 0)
2135         (neg:GPR (match_dup 1)))
2136    (set (match_dup 2)
2137         (compare:CC (match_dup 0)
2138                     (const_int 0)))]
2139   ""
2140   [(set_attr "type" "add")
2141    (set_attr "dot" "yes")
2142    (set_attr "length" "4,8")])
2145 (define_insn "clz<mode>2"
2146   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2147         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2148   ""
2149   "cntlz<wd> %0,%1"
2150   [(set_attr "type" "cntlz")])
2152 (define_expand "ctz<mode>2"
2153   [(set (match_dup 2)
2154         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2155    (set (match_dup 3)
2156         (and:GPR (match_dup 1)
2157                  (match_dup 2)))
2158    (set (match_dup 4)
2159         (clz:GPR (match_dup 3)))
2160    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2161                    (minus:GPR (match_dup 5)
2162                               (match_dup 4)))
2163               (clobber (reg:GPR CA_REGNO))])]
2164   ""
2166   if (TARGET_CTZ)
2167     {
2168       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2169       DONE;
2170     }
2172   operands[2] = gen_reg_rtx (<MODE>mode);
2173   operands[3] = gen_reg_rtx (<MODE>mode);
2174   operands[4] = gen_reg_rtx (<MODE>mode);
2175   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2178 (define_insn "ctz<mode>2_hw"
2179   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2180         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2181   "TARGET_CTZ"
2182   "cnttz<wd> %0,%1"
2183   [(set_attr "type" "cntlz")])
2185 (define_expand "ffs<mode>2"
2186   [(set (match_dup 2)
2187         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2188    (set (match_dup 3)
2189         (and:GPR (match_dup 1)
2190                  (match_dup 2)))
2191    (set (match_dup 4)
2192         (clz:GPR (match_dup 3)))
2193    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2194                    (minus:GPR (match_dup 5)
2195                               (match_dup 4)))
2196               (clobber (reg:GPR CA_REGNO))])]
2197   ""
2199   operands[2] = gen_reg_rtx (<MODE>mode);
2200   operands[3] = gen_reg_rtx (<MODE>mode);
2201   operands[4] = gen_reg_rtx (<MODE>mode);
2202   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2206 (define_expand "popcount<mode>2"
2207   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2208         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2209   "TARGET_POPCNTB || TARGET_POPCNTD"
2211   rs6000_emit_popcount (operands[0], operands[1]);
2212   DONE;
2215 (define_insn "popcntb<mode>2"
2216   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2217         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2218                     UNSPEC_POPCNTB))]
2219   "TARGET_POPCNTB"
2220   "popcntb %0,%1"
2221   [(set_attr "type" "popcnt")])
2223 (define_insn "popcntd<mode>2"
2224   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2225         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2226   "TARGET_POPCNTD"
2227   "popcnt<wd> %0,%1"
2228   [(set_attr "type" "popcnt")])
2231 (define_expand "parity<mode>2"
2232   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2233         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2234   "TARGET_POPCNTB"
2236   rs6000_emit_parity (operands[0], operands[1]);
2237   DONE;
2240 (define_insn "parity<mode>2_cmpb"
2241   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2242         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2243   "TARGET_CMPB && TARGET_POPCNTB"
2244   "prty<wd> %0,%1"
2245   [(set_attr "type" "popcnt")])
2248 ;; Since the hardware zeros the upper part of the register, save generating the
2249 ;; AND immediate if we are converting to unsigned
2250 (define_insn "*bswaphi2_extenddi"
2251   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2252         (zero_extend:DI
2253          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2254   "TARGET_POWERPC64"
2255   "lhbrx %0,%y1"
2256   [(set_attr "length" "4")
2257    (set_attr "type" "load")])
2259 (define_insn "*bswaphi2_extendsi"
2260   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2261         (zero_extend:SI
2262          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2263   ""
2264   "lhbrx %0,%y1"
2265   [(set_attr "length" "4")
2266    (set_attr "type" "load")])
2268 (define_expand "bswaphi2"
2269   [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2270                    (bswap:HI
2271                     (match_operand:HI 1 "reg_or_mem_operand" "")))
2272               (clobber (match_scratch:SI 2 ""))])]
2273   ""
2275   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2276     operands[1] = force_reg (HImode, operands[1]);
2279 (define_insn "bswaphi2_internal"
2280   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2281         (bswap:HI
2282          (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2283    (clobber (match_scratch:SI 2 "=X,X,&r"))]
2284   ""
2285   "@
2286    lhbrx %0,%y1
2287    sthbrx %1,%y0
2288    #"
2289   [(set_attr "length" "4,4,12")
2290    (set_attr "type" "load,store,*")])
2292 (define_split
2293   [(set (match_operand:HI 0 "gpc_reg_operand" "")
2294         (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2295    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2296   "reload_completed"
2297   [(set (match_dup 3)
2298         (and:SI (lshiftrt:SI (match_dup 4)
2299                              (const_int 8))
2300                 (const_int 255)))
2301    (set (match_dup 2)
2302         (and:SI (ashift:SI (match_dup 4)
2303                            (const_int 8))
2304                 (const_int 65280)))             ;; 0xff00
2305    (set (match_dup 3)
2306         (ior:SI (match_dup 3)
2307                 (match_dup 2)))]
2308   "
2310   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2311   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2314 (define_insn "*bswapsi2_extenddi"
2315   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2316         (zero_extend:DI
2317          (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2318   "TARGET_POWERPC64"
2319   "lwbrx %0,%y1"
2320   [(set_attr "length" "4")
2321    (set_attr "type" "load")])
2323 (define_expand "bswapsi2"
2324   [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2325         (bswap:SI
2326          (match_operand:SI 1 "reg_or_mem_operand" "")))]
2327   ""
2329   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2330     operands[1] = force_reg (SImode, operands[1]);
2333 (define_insn "*bswapsi2_internal"
2334   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2335         (bswap:SI
2336          (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2337   ""
2338   "@
2339    lwbrx %0,%y1
2340    stwbrx %1,%y0
2341    #"
2342   [(set_attr "length" "4,4,12")
2343    (set_attr "type" "load,store,*")])
2345 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2346 ;; zero_extract insns do not change for -mlittle.
2347 (define_split
2348   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2349         (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2350   "reload_completed"
2351   [(set (match_dup 0)                                   ; DABC
2352         (rotate:SI (match_dup 1)
2353                    (const_int 24)))
2354    (set (match_dup 0)                                   ; DCBC
2355         (ior:SI (and:SI (ashift:SI (match_dup 1)
2356                                    (const_int 8))
2357                         (const_int 16711680))
2358                 (and:SI (match_dup 0)
2359                         (const_int -16711681))))
2360    (set (match_dup 0)                                   ; DCBA
2361         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2362                                      (const_int 24))
2363                         (const_int 255))
2364                 (and:SI (match_dup 0)
2365                         (const_int -256))))
2367   ]
2368   "")
2370 (define_expand "bswapdi2"
2371   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2372                    (bswap:DI
2373                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2374               (clobber (match_scratch:DI 2 ""))
2375               (clobber (match_scratch:DI 3 ""))])]
2376   ""
2378   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2379     operands[1] = force_reg (DImode, operands[1]);
2381   if (!TARGET_POWERPC64)
2382     {
2383       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2384          that uses 64-bit registers needs the same scratch registers as 64-bit
2385          mode.  */
2386       emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2387       DONE;
2388     }
2391 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2392 (define_insn "*bswapdi2_ldbrx"
2393   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2394         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2395    (clobber (match_scratch:DI 2 "=X,X,&r"))
2396    (clobber (match_scratch:DI 3 "=X,X,&r"))]
2397   "TARGET_POWERPC64 && TARGET_LDBRX
2398    && (REG_P (operands[0]) || REG_P (operands[1]))"
2399   "@
2400    ldbrx %0,%y1
2401    stdbrx %1,%y0
2402    #"
2403   [(set_attr "length" "4,4,36")
2404    (set_attr "type" "load,store,*")])
2406 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2407 (define_insn "*bswapdi2_64bit"
2408   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2409         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2410    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2411    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2412   "TARGET_POWERPC64 && !TARGET_LDBRX
2413    && (REG_P (operands[0]) || REG_P (operands[1]))
2414    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2415    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2416   "#"
2417   [(set_attr "length" "16,12,36")])
2419 (define_split
2420   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2421         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2422    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2423    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2424   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2425   [(const_int 0)]
2426   "
2428   rtx dest   = operands[0];
2429   rtx src    = operands[1];
2430   rtx op2    = operands[2];
2431   rtx op3    = operands[3];
2432   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2433                                     BYTES_BIG_ENDIAN ? 4 : 0);
2434   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2435                                      BYTES_BIG_ENDIAN ? 4 : 0);
2436   rtx addr1;
2437   rtx addr2;
2438   rtx word1;
2439   rtx word2;
2441   addr1 = XEXP (src, 0);
2442   if (GET_CODE (addr1) == PLUS)
2443     {
2444       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2445       if (TARGET_AVOID_XFORM)
2446         {
2447           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2448           addr2 = op2;
2449         }
2450       else
2451         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2452     }
2453   else if (TARGET_AVOID_XFORM)
2454     {
2455       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2456       addr2 = op2;
2457     }
2458   else
2459     {
2460       emit_move_insn (op2, GEN_INT (4));
2461       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2462     }
2464   word1 = change_address (src, SImode, addr1);
2465   word2 = change_address (src, SImode, addr2);
2467   if (BYTES_BIG_ENDIAN)
2468     {
2469       emit_insn (gen_bswapsi2 (op3_32, word2));
2470       emit_insn (gen_bswapsi2 (dest_32, word1));
2471     }
2472   else
2473     {
2474       emit_insn (gen_bswapsi2 (op3_32, word1));
2475       emit_insn (gen_bswapsi2 (dest_32, word2));
2476     }
2478   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2479   emit_insn (gen_iordi3 (dest, dest, op3));
2480   DONE;
2483 (define_split
2484   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2485         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2486    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2487    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2488   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2489   [(const_int 0)]
2490   "
2492   rtx dest   = operands[0];
2493   rtx src    = operands[1];
2494   rtx op2    = operands[2];
2495   rtx op3    = operands[3];
2496   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2497                                     BYTES_BIG_ENDIAN ? 4 : 0);
2498   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2499                                     BYTES_BIG_ENDIAN ? 4 : 0);
2500   rtx addr1;
2501   rtx addr2;
2502   rtx word1;
2503   rtx word2;
2505   addr1 = XEXP (dest, 0);
2506   if (GET_CODE (addr1) == PLUS)
2507     {
2508       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2509       if (TARGET_AVOID_XFORM)
2510         {
2511           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2512           addr2 = op2;
2513         }
2514       else
2515         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2516     }
2517   else if (TARGET_AVOID_XFORM)
2518     {
2519       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2520       addr2 = op2;
2521     }
2522   else
2523     {
2524       emit_move_insn (op2, GEN_INT (4));
2525       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2526     }
2528   word1 = change_address (dest, SImode, addr1);
2529   word2 = change_address (dest, SImode, addr2);
2531   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2533   if (BYTES_BIG_ENDIAN)
2534     {
2535       emit_insn (gen_bswapsi2 (word1, src_si));
2536       emit_insn (gen_bswapsi2 (word2, op3_si));
2537     }
2538   else
2539     {
2540       emit_insn (gen_bswapsi2 (word2, src_si));
2541       emit_insn (gen_bswapsi2 (word1, op3_si));
2542     }
2543   DONE;
2546 (define_split
2547   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2548         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2549    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2550    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2551   "TARGET_POWERPC64 && reload_completed"
2552   [(const_int 0)]
2553   "
2555   rtx dest    = operands[0];
2556   rtx src     = operands[1];
2557   rtx op2     = operands[2];
2558   rtx op3     = operands[3];
2559   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2560   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2561   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2562   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2563   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2565   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2566   emit_insn (gen_bswapsi2 (dest_si, src_si));
2567   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2568   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2569   emit_insn (gen_iordi3 (dest, dest, op3));
2570   DONE;
2573 (define_insn "bswapdi2_32bit"
2574   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2575         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2576    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2577   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2578   "#"
2579   [(set_attr "length" "16,12,36")])
2581 (define_split
2582   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2583         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2584    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2585   "!TARGET_POWERPC64 && reload_completed"
2586   [(const_int 0)]
2587   "
2589   rtx dest  = operands[0];
2590   rtx src   = operands[1];
2591   rtx op2   = operands[2];
2592   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2593   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2594   rtx addr1;
2595   rtx addr2;
2596   rtx word1;
2597   rtx word2;
2599   addr1 = XEXP (src, 0);
2600   if (GET_CODE (addr1) == PLUS)
2601     {
2602       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2603       if (TARGET_AVOID_XFORM
2604           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2605         {
2606           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2607           addr2 = op2;
2608         }
2609       else
2610         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2611     }
2612   else if (TARGET_AVOID_XFORM
2613            || REGNO (addr1) == REGNO (dest2))
2614     {
2615       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2616       addr2 = op2;
2617     }
2618   else
2619     {
2620       emit_move_insn (op2, GEN_INT (4));
2621       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2622     }
2624   word1 = change_address (src, SImode, addr1);
2625   word2 = change_address (src, SImode, addr2);
2627   emit_insn (gen_bswapsi2 (dest2, word1));
2628   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2629      thus allowing us to omit an early clobber on the output.  */
2630   emit_insn (gen_bswapsi2 (dest1, word2));
2631   DONE;
2634 (define_split
2635   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2636         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2637    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2638   "!TARGET_POWERPC64 && reload_completed"
2639   [(const_int 0)]
2640   "
2642   rtx dest = operands[0];
2643   rtx src  = operands[1];
2644   rtx op2  = operands[2];
2645   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2646   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2647   rtx addr1;
2648   rtx addr2;
2649   rtx word1;
2650   rtx word2;
2652   addr1 = XEXP (dest, 0);
2653   if (GET_CODE (addr1) == PLUS)
2654     {
2655       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2656       if (TARGET_AVOID_XFORM)
2657         {
2658           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2659           addr2 = op2;
2660         }
2661       else
2662         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2663     }
2664   else if (TARGET_AVOID_XFORM)
2665     {
2666       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2667       addr2 = op2;
2668     }
2669   else
2670     {
2671       emit_move_insn (op2, GEN_INT (4));
2672       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2673     }
2675   word1 = change_address (dest, SImode, addr1);
2676   word2 = change_address (dest, SImode, addr2);
2678   emit_insn (gen_bswapsi2 (word2, src1));
2679   emit_insn (gen_bswapsi2 (word1, src2));
2680   DONE;
2683 (define_split
2684   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2685         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2686    (clobber (match_operand:SI 2 "" ""))]
2687   "!TARGET_POWERPC64 && reload_completed"
2688   [(const_int 0)]
2689   "
2691   rtx dest  = operands[0];
2692   rtx src   = operands[1];
2693   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2694   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2695   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2696   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2698   emit_insn (gen_bswapsi2 (dest1, src2));
2699   emit_insn (gen_bswapsi2 (dest2, src1));
2700   DONE;
2704 (define_insn "mul<mode>3"
2705   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2706         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2707                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2708   ""
2709   "@
2710    mull<wd> %0,%1,%2
2711    mulli %0,%1,%2"
2712    [(set_attr "type" "mul")
2713     (set (attr "size")
2714       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2715                 (const_string "8")
2716              (match_operand:GPR 2 "short_cint_operand" "")
2717                 (const_string "16")]
2718         (const_string "<bits>")))])
2720 (define_insn_and_split "*mul<mode>3_dot"
2721   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2722         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2723                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2724                     (const_int 0)))
2725    (clobber (match_scratch:GPR 0 "=r,r"))]
2726   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2727   "@
2728    mull<wd>. %0,%1,%2
2729    #"
2730   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2731   [(set (match_dup 0)
2732         (mult:GPR (match_dup 1)
2733                   (match_dup 2)))
2734    (set (match_dup 3)
2735         (compare:CC (match_dup 0)
2736                     (const_int 0)))]
2737   ""
2738   [(set_attr "type" "mul")
2739    (set_attr "size" "<bits>")
2740    (set_attr "dot" "yes")
2741    (set_attr "length" "4,8")])
2743 (define_insn_and_split "*mul<mode>3_dot2"
2744   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2745         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2746                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2747                     (const_int 0)))
2748    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2749         (mult:GPR (match_dup 1)
2750                   (match_dup 2)))]
2751   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2752   "@
2753    mull<wd>. %0,%1,%2
2754    #"
2755   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2756   [(set (match_dup 0)
2757         (mult:GPR (match_dup 1)
2758                   (match_dup 2)))
2759    (set (match_dup 3)
2760         (compare:CC (match_dup 0)
2761                     (const_int 0)))]
2762   ""
2763   [(set_attr "type" "mul")
2764    (set_attr "size" "<bits>")
2765    (set_attr "dot" "yes")
2766    (set_attr "length" "4,8")])
2769 (define_expand "<su>mul<mode>3_highpart"
2770   [(set (match_operand:GPR 0 "gpc_reg_operand")
2771         (subreg:GPR
2772           (mult:<DMODE> (any_extend:<DMODE>
2773                           (match_operand:GPR 1 "gpc_reg_operand"))
2774                         (any_extend:<DMODE>
2775                           (match_operand:GPR 2 "gpc_reg_operand")))
2776          0))]
2777   ""
2779   if (<MODE>mode == SImode && TARGET_POWERPC64)
2780     {
2781       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2782                                              operands[2]));
2783       DONE;
2784     }
2786   if (!WORDS_BIG_ENDIAN)
2787     {
2788       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2789                                                  operands[2]));
2790       DONE;
2791     }
2794 (define_insn "*<su>mul<mode>3_highpart"
2795   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2796         (subreg:GPR
2797           (mult:<DMODE> (any_extend:<DMODE>
2798                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2799                         (any_extend:<DMODE>
2800                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2801          0))]
2802   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2803   "mulh<wd><u> %0,%1,%2"
2804   [(set_attr "type" "mul")
2805    (set_attr "size" "<bits>")])
2807 (define_insn "<su>mulsi3_highpart_le"
2808   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2809         (subreg:SI
2810           (mult:DI (any_extend:DI
2811                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2812                    (any_extend:DI
2813                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2814          4))]
2815   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2816   "mulhw<u> %0,%1,%2"
2817   [(set_attr "type" "mul")])
2819 (define_insn "<su>muldi3_highpart_le"
2820   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2821         (subreg:DI
2822           (mult:TI (any_extend:TI
2823                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2824                    (any_extend:TI
2825                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2826          8))]
2827   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2828   "mulhd<u> %0,%1,%2"
2829   [(set_attr "type" "mul")
2830    (set_attr "size" "64")])
2832 (define_insn "<su>mulsi3_highpart_64"
2833   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2834         (truncate:SI
2835           (lshiftrt:DI
2836             (mult:DI (any_extend:DI
2837                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2838                      (any_extend:DI
2839                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2840             (const_int 32))))]
2841   "TARGET_POWERPC64"
2842   "mulhw<u> %0,%1,%2"
2843   [(set_attr "type" "mul")])
2845 (define_expand "<u>mul<mode><dmode>3"
2846   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2847         (mult:<DMODE> (any_extend:<DMODE>
2848                         (match_operand:GPR 1 "gpc_reg_operand"))
2849                       (any_extend:<DMODE>
2850                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2851   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2853   rtx l = gen_reg_rtx (<MODE>mode);
2854   rtx h = gen_reg_rtx (<MODE>mode);
2855   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2856   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2857   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2858   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2859   DONE;
2862 (define_insn "*maddld4"
2863   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2864         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2865                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2866                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2867   "TARGET_MADDLD"
2868   "maddld %0,%1,%2,%3"
2869   [(set_attr "type" "mul")])
2871 (define_insn "udiv<mode>3"
2872   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2873         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2874                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2875   ""
2876   "div<wd>u %0,%1,%2"
2877   [(set_attr "type" "div")
2878    (set_attr "size" "<bits>")])
2881 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2882 ;; modulus.  If it isn't a power of two, force operands into register and do
2883 ;; a normal divide.
2884 (define_expand "div<mode>3"
2885   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2886         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2887                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2888   ""
2890   if (CONST_INT_P (operands[2])
2891       && INTVAL (operands[2]) > 0
2892       && exact_log2 (INTVAL (operands[2])) >= 0)
2893     {
2894       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2895       DONE;
2896     }
2898   operands[2] = force_reg (<MODE>mode, operands[2]);
2901 (define_insn "*div<mode>3"
2902   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2903         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2904                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2905   ""
2906   "div<wd> %0,%1,%2"
2907   [(set_attr "type" "div")
2908    (set_attr "size" "<bits>")])
2910 (define_insn "div<mode>3_sra"
2911   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2912         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2913                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2914    (clobber (reg:GPR CA_REGNO))]
2915   ""
2916   "sra<wd>i %0,%1,%p2\;addze %0,%0"
2917   [(set_attr "type" "two")
2918    (set_attr "length" "8")])
2920 (define_insn_and_split "*div<mode>3_sra_dot"
2921   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2922         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2923                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2924                     (const_int 0)))
2925    (clobber (match_scratch:GPR 0 "=r,r"))
2926    (clobber (reg:GPR CA_REGNO))]
2927   "<MODE>mode == Pmode"
2928   "@
2929    sra<wd>i %0,%1,%p2\;addze. %0,%0
2930    #"
2931   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2932   [(parallel [(set (match_dup 0)
2933                    (div:GPR (match_dup 1)
2934                             (match_dup 2)))
2935               (clobber (reg:GPR CA_REGNO))])
2936    (set (match_dup 3)
2937         (compare:CC (match_dup 0)
2938                     (const_int 0)))]
2939   ""
2940   [(set_attr "type" "two")
2941    (set_attr "length" "8,12")
2942    (set_attr "cell_micro" "not")])
2944 (define_insn_and_split "*div<mode>3_sra_dot2"
2945   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2946         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2947                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2948                     (const_int 0)))
2949    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2950         (div:GPR (match_dup 1)
2951                  (match_dup 2)))
2952    (clobber (reg:GPR CA_REGNO))]
2953   "<MODE>mode == Pmode"
2954   "@
2955    sra<wd>i %0,%1,%p2\;addze. %0,%0
2956    #"
2957   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2958   [(parallel [(set (match_dup 0)
2959                    (div:GPR (match_dup 1)
2960                             (match_dup 2)))
2961               (clobber (reg:GPR CA_REGNO))])
2962    (set (match_dup 3)
2963         (compare:CC (match_dup 0)
2964                     (const_int 0)))]
2965   ""
2966   [(set_attr "type" "two")
2967    (set_attr "length" "8,12")
2968    (set_attr "cell_micro" "not")])
2970 (define_expand "mod<mode>3"
2971   [(set (match_operand:GPR 0 "gpc_reg_operand")
2972         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
2973                  (match_operand:GPR 2 "reg_or_cint_operand")))]
2974   ""
2976   int i;
2977   rtx temp1;
2978   rtx temp2;
2980   if (GET_CODE (operands[2]) != CONST_INT
2981       || INTVAL (operands[2]) <= 0
2982       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
2983     {
2984       if (!TARGET_MODULO)
2985         FAIL;
2987       operands[2] = force_reg (<MODE>mode, operands[2]);
2988     }
2989   else
2990     {
2991       temp1 = gen_reg_rtx (<MODE>mode);
2992       temp2 = gen_reg_rtx (<MODE>mode);
2994       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
2995       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
2996       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
2997       DONE;
2998     }
3001 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3002 ;; mod, prefer putting the result of mod into a different register
3003 (define_insn "*mod<mode>3"
3004   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3005         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3006                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3007   "TARGET_MODULO"
3008   "mods<wd> %0,%1,%2"
3009   [(set_attr "type" "div")
3010    (set_attr "size" "<bits>")])
3013 (define_insn "umod<mode>3"
3014   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3015         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3016                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3017   "TARGET_MODULO"
3018   "modu<wd> %0,%1,%2"
3019   [(set_attr "type" "div")
3020    (set_attr "size" "<bits>")])
3022 ;; On machines with modulo support, do a combined div/mod the old fashioned
3023 ;; method, since the multiply/subtract is faster than doing the mod instruction
3024 ;; after a divide.
3026 (define_peephole2
3027   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3028         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3029                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3030    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3031         (mod:GPR (match_dup 1)
3032                  (match_dup 2)))]
3033   "TARGET_MODULO
3034    && ! reg_mentioned_p (operands[0], operands[1])
3035    && ! reg_mentioned_p (operands[0], operands[2])
3036    && ! reg_mentioned_p (operands[3], operands[1])
3037    && ! reg_mentioned_p (operands[3], operands[2])"
3038   [(set (match_dup 0)
3039         (div:GPR (match_dup 1)
3040                  (match_dup 2)))
3041    (set (match_dup 3)
3042         (mult:GPR (match_dup 0)
3043                   (match_dup 2)))
3044    (set (match_dup 3)
3045         (minus:GPR (match_dup 1)
3046                    (match_dup 3)))])
3048 (define_peephole2
3049   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3050         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3051                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3052    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3053         (umod:GPR (match_dup 1)
3054                   (match_dup 2)))]
3055   "TARGET_MODULO
3056    && ! reg_mentioned_p (operands[0], operands[1])
3057    && ! reg_mentioned_p (operands[0], operands[2])
3058    && ! reg_mentioned_p (operands[3], operands[1])
3059    && ! reg_mentioned_p (operands[3], operands[2])"
3060   [(set (match_dup 0)
3061         (div:GPR (match_dup 1)
3062                  (match_dup 2)))
3063    (set (match_dup 3)
3064         (mult:GPR (match_dup 0)
3065                   (match_dup 2)))
3066    (set (match_dup 3)
3067         (minus:GPR (match_dup 1)
3068                    (match_dup 3)))])
3071 ;; Logical instructions
3072 ;; The logical instructions are mostly combined by using match_operator,
3073 ;; but the plain AND insns are somewhat different because there is no
3074 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3075 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3077 (define_expand "and<mode>3"
3078   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3079         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3080                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3081   ""
3083   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3084     {
3085       rs6000_split_logical (operands, AND, false, false, false);
3086       DONE;
3087     }
3089   if (CONST_INT_P (operands[2]))
3090     {
3091       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3092         {
3093           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3094           DONE;
3095         }
3097       if (logical_const_operand (operands[2], <MODE>mode)
3098           && rs6000_gen_cell_microcode)
3099         {
3100           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3101           DONE;
3102         }
3104       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3105         {
3106           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3107           DONE;
3108         }
3110       operands[2] = force_reg (<MODE>mode, operands[2]);
3111     }
3115 (define_insn "and<mode>3_imm"
3116   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3117         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3118                  (match_operand:GPR 2 "logical_const_operand" "n")))
3119    (clobber (match_scratch:CC 3 "=x"))]
3120   "rs6000_gen_cell_microcode
3121    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3122   "andi%e2. %0,%1,%u2"
3123   [(set_attr "type" "logical")
3124    (set_attr "dot" "yes")])
3126 (define_insn_and_split "*and<mode>3_imm_dot"
3127   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3128         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3129                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3130                     (const_int 0)))
3131    (clobber (match_scratch:GPR 0 "=r,r"))
3132    (clobber (match_scratch:CC 4 "=X,x"))]
3133   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3134    && rs6000_gen_cell_microcode
3135    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3136   "@
3137    andi%e2. %0,%1,%u2
3138    #"
3139   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3140   [(parallel [(set (match_dup 0)
3141                    (and:GPR (match_dup 1)
3142                             (match_dup 2)))
3143               (clobber (match_dup 4))])
3144    (set (match_dup 3)
3145         (compare:CC (match_dup 0)
3146                     (const_int 0)))]
3147   ""
3148   [(set_attr "type" "logical")
3149    (set_attr "dot" "yes")
3150    (set_attr "length" "4,8")])
3152 (define_insn_and_split "*and<mode>3_imm_dot2"
3153   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3154         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3155                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3156                     (const_int 0)))
3157    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3158         (and:GPR (match_dup 1)
3159                  (match_dup 2)))
3160    (clobber (match_scratch:CC 4 "=X,x"))]
3161   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3162    && rs6000_gen_cell_microcode
3163    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3164   "@
3165    andi%e2. %0,%1,%u2
3166    #"
3167   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3168   [(parallel [(set (match_dup 0)
3169                    (and:GPR (match_dup 1)
3170                             (match_dup 2)))
3171               (clobber (match_dup 4))])
3172    (set (match_dup 3)
3173         (compare:CC (match_dup 0)
3174                     (const_int 0)))]
3175   ""
3176   [(set_attr "type" "logical")
3177    (set_attr "dot" "yes")
3178    (set_attr "length" "4,8")])
3180 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3181   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3182         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3183                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3184                     (const_int 0)))
3185    (clobber (match_scratch:GPR 0 "=r,r"))]
3186   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3187    && rs6000_gen_cell_microcode"
3188   "@
3189    andi%e2. %0,%1,%u2
3190    #"
3191   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3192   [(set (match_dup 0)
3193         (and:GPR (match_dup 1)
3194                  (match_dup 2)))
3195    (set (match_dup 3)
3196         (compare:CC (match_dup 0)
3197                     (const_int 0)))]
3198   ""
3199   [(set_attr "type" "logical")
3200    (set_attr "dot" "yes")
3201    (set_attr "length" "4,8")])
3203 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3204   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3205         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3206                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3207                     (const_int 0)))
3208    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3209         (and:GPR (match_dup 1)
3210                  (match_dup 2)))]
3211   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3212    && rs6000_gen_cell_microcode"
3213   "@
3214    andi%e2. %0,%1,%u2
3215    #"
3216   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3217   [(set (match_dup 0)
3218         (and:GPR (match_dup 1)
3219                  (match_dup 2)))
3220    (set (match_dup 3)
3221         (compare:CC (match_dup 0)
3222                     (const_int 0)))]
3223   ""
3224   [(set_attr "type" "logical")
3225    (set_attr "dot" "yes")
3226    (set_attr "length" "4,8")])
3228 (define_insn "*and<mode>3_imm_dot_shifted"
3229   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3230         (compare:CC
3231           (and:GPR
3232             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3233                           (match_operand:SI 4 "const_int_operand" "n"))
3234             (match_operand:GPR 2 "const_int_operand" "n"))
3235           (const_int 0)))
3236    (clobber (match_scratch:GPR 0 "=r"))]
3237   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3238                                    << INTVAL (operands[4])),
3239                           DImode)
3240    && (<MODE>mode == Pmode
3241        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3242    && rs6000_gen_cell_microcode"
3244   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3245   return "andi%e2. %0,%1,%u2";
3247   [(set_attr "type" "logical")
3248    (set_attr "dot" "yes")])
3251 (define_insn "and<mode>3_mask"
3252   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3253         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3254                  (match_operand:GPR 2 "const_int_operand" "n")))]
3255   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3257   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3259   [(set_attr "type" "shift")])
3261 (define_insn_and_split "*and<mode>3_mask_dot"
3262   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3263         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3264                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3265                     (const_int 0)))
3266    (clobber (match_scratch:GPR 0 "=r,r"))]
3267   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3268    && rs6000_gen_cell_microcode
3269    && !logical_const_operand (operands[2], <MODE>mode)
3270    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3272   if (which_alternative == 0)
3273     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3274   else
3275     return "#";
3277   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3278   [(set (match_dup 0)
3279         (and:GPR (match_dup 1)
3280                  (match_dup 2)))
3281    (set (match_dup 3)
3282         (compare:CC (match_dup 0)
3283                     (const_int 0)))]
3284   ""
3285   [(set_attr "type" "shift")
3286    (set_attr "dot" "yes")
3287    (set_attr "length" "4,8")])
3289 (define_insn_and_split "*and<mode>3_mask_dot2"
3290   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3291         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3292                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3293                     (const_int 0)))
3294    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3295         (and:GPR (match_dup 1)
3296                  (match_dup 2)))]
3297   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3298    && rs6000_gen_cell_microcode
3299    && !logical_const_operand (operands[2], <MODE>mode)
3300    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3302   if (which_alternative == 0)
3303     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3304   else
3305     return "#";
3307   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3308   [(set (match_dup 0)
3309         (and:GPR (match_dup 1)
3310                  (match_dup 2)))
3311    (set (match_dup 3)
3312         (compare:CC (match_dup 0)
3313                     (const_int 0)))]
3314   ""
3315   [(set_attr "type" "shift")
3316    (set_attr "dot" "yes")
3317    (set_attr "length" "4,8")])
3320 (define_insn_and_split "*and<mode>3_2insn"
3321   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3322         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3323                  (match_operand:GPR 2 "const_int_operand" "n")))]
3324   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3325    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3326         || (logical_const_operand (operands[2], <MODE>mode)
3327             && rs6000_gen_cell_microcode))"
3328   "#"
3329   "&& 1"
3330   [(pc)]
3332   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3333   DONE;
3335   [(set_attr "type" "shift")
3336    (set_attr "length" "8")])
3338 (define_insn_and_split "*and<mode>3_2insn_dot"
3339   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3340         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3341                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3342                     (const_int 0)))
3343    (clobber (match_scratch:GPR 0 "=r,r"))]
3344   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3345    && rs6000_gen_cell_microcode
3346    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3347    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3348         || (logical_const_operand (operands[2], <MODE>mode)
3349             && rs6000_gen_cell_microcode))"
3350   "#"
3351   "&& reload_completed"
3352   [(pc)]
3354   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3355   DONE;
3357   [(set_attr "type" "shift")
3358    (set_attr "dot" "yes")
3359    (set_attr "length" "8,12")])
3361 (define_insn_and_split "*and<mode>3_2insn_dot2"
3362   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3363         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3364                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3365                     (const_int 0)))
3366    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3367         (and:GPR (match_dup 1)
3368                  (match_dup 2)))]
3369   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3370    && rs6000_gen_cell_microcode
3371    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3372    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3373         || (logical_const_operand (operands[2], <MODE>mode)
3374             && rs6000_gen_cell_microcode))"
3375   "#"
3376   "&& reload_completed"
3377   [(pc)]
3379   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3380   DONE;
3382   [(set_attr "type" "shift")
3383    (set_attr "dot" "yes")
3384    (set_attr "length" "8,12")])
3387 (define_expand "<code><mode>3"
3388   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3389         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3390                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3391   ""
3393   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3394     {
3395       rs6000_split_logical (operands, <CODE>, false, false, false);
3396       DONE;
3397     }
3399   if (non_logical_cint_operand (operands[2], <MODE>mode))
3400     {
3401       rtx tmp = ((!can_create_pseudo_p ()
3402                   || rtx_equal_p (operands[0], operands[1]))
3403                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3405       HOST_WIDE_INT value = INTVAL (operands[2]);
3406       HOST_WIDE_INT lo = value & 0xffff;
3407       HOST_WIDE_INT hi = value - lo;
3409       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3410       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3411       DONE;
3412     }
3414   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3415     operands[2] = force_reg (<MODE>mode, operands[2]);
3418 (define_split
3419   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3420         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3421                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3422   ""
3423   [(set (match_dup 3)
3424         (iorxor:GPR (match_dup 1)
3425                     (match_dup 4)))
3426    (set (match_dup 0)
3427         (iorxor:GPR (match_dup 3)
3428                     (match_dup 5)))]
3430   operands[3] = ((!can_create_pseudo_p ()
3431                   || rtx_equal_p (operands[0], operands[1]))
3432                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3434   HOST_WIDE_INT value = INTVAL (operands[2]);
3435   HOST_WIDE_INT lo = value & 0xffff;
3436   HOST_WIDE_INT hi = value - lo;
3438   operands[4] = GEN_INT (hi);
3439   operands[5] = GEN_INT (lo);
3442 (define_insn "*bool<mode>3_imm"
3443   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3444         (match_operator:GPR 3 "boolean_or_operator"
3445          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3446           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3447   ""
3448   "%q3i%e2 %0,%1,%u2"
3449   [(set_attr "type" "logical")])
3451 (define_insn "*bool<mode>3"
3452   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3453         (match_operator:GPR 3 "boolean_operator"
3454          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3455           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3456   ""
3457   "%q3 %0,%1,%2"
3458   [(set_attr "type" "logical")])
3460 (define_insn_and_split "*bool<mode>3_dot"
3461   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3462         (compare:CC (match_operator:GPR 3 "boolean_operator"
3463          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3464           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3465          (const_int 0)))
3466    (clobber (match_scratch:GPR 0 "=r,r"))]
3467   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3468   "@
3469    %q3. %0,%1,%2
3470    #"
3471   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3472   [(set (match_dup 0)
3473         (match_dup 3))
3474    (set (match_dup 4)
3475         (compare:CC (match_dup 0)
3476                     (const_int 0)))]
3477   ""
3478   [(set_attr "type" "logical")
3479    (set_attr "dot" "yes")
3480    (set_attr "length" "4,8")])
3482 (define_insn_and_split "*bool<mode>3_dot2"
3483   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3484         (compare:CC (match_operator:GPR 3 "boolean_operator"
3485          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3486           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3487          (const_int 0)))
3488    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3489         (match_dup 3))]
3490   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3491   "@
3492    %q3. %0,%1,%2
3493    #"
3494   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3495   [(set (match_dup 0)
3496         (match_dup 3))
3497    (set (match_dup 4)
3498         (compare:CC (match_dup 0)
3499                     (const_int 0)))]
3500   ""
3501   [(set_attr "type" "logical")
3502    (set_attr "dot" "yes")
3503    (set_attr "length" "4,8")])
3506 (define_insn "*boolc<mode>3"
3507   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3508         (match_operator:GPR 3 "boolean_operator"
3509          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3510           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3511   ""
3512   "%q3 %0,%1,%2"
3513   [(set_attr "type" "logical")])
3515 (define_insn_and_split "*boolc<mode>3_dot"
3516   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3517         (compare:CC (match_operator:GPR 3 "boolean_operator"
3518          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3519           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3520          (const_int 0)))
3521    (clobber (match_scratch:GPR 0 "=r,r"))]
3522   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3523   "@
3524    %q3. %0,%1,%2
3525    #"
3526   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3527   [(set (match_dup 0)
3528         (match_dup 3))
3529    (set (match_dup 4)
3530         (compare:CC (match_dup 0)
3531                     (const_int 0)))]
3532   ""
3533   [(set_attr "type" "logical")
3534    (set_attr "dot" "yes")
3535    (set_attr "length" "4,8")])
3537 (define_insn_and_split "*boolc<mode>3_dot2"
3538   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3539         (compare:CC (match_operator:GPR 3 "boolean_operator"
3540          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3541           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3542          (const_int 0)))
3543    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3544         (match_dup 3))]
3545   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3546   "@
3547    %q3. %0,%1,%2
3548    #"
3549   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3550   [(set (match_dup 0)
3551         (match_dup 3))
3552    (set (match_dup 4)
3553         (compare:CC (match_dup 0)
3554                     (const_int 0)))]
3555   ""
3556   [(set_attr "type" "logical")
3557    (set_attr "dot" "yes")
3558    (set_attr "length" "4,8")])
3561 (define_insn "*boolcc<mode>3"
3562   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3563         (match_operator:GPR 3 "boolean_operator"
3564          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3565           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3566   ""
3567   "%q3 %0,%1,%2"
3568   [(set_attr "type" "logical")])
3570 (define_insn_and_split "*boolcc<mode>3_dot"
3571   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3572         (compare:CC (match_operator:GPR 3 "boolean_operator"
3573          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3574           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3575          (const_int 0)))
3576    (clobber (match_scratch:GPR 0 "=r,r"))]
3577   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3578   "@
3579    %q3. %0,%1,%2
3580    #"
3581   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3582   [(set (match_dup 0)
3583         (match_dup 3))
3584    (set (match_dup 4)
3585         (compare:CC (match_dup 0)
3586                     (const_int 0)))]
3587   ""
3588   [(set_attr "type" "logical")
3589    (set_attr "dot" "yes")
3590    (set_attr "length" "4,8")])
3592 (define_insn_and_split "*boolcc<mode>3_dot2"
3593   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3594         (compare:CC (match_operator:GPR 3 "boolean_operator"
3595          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3596           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3597          (const_int 0)))
3598    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3599         (match_dup 3))]
3600   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3601   "@
3602    %q3. %0,%1,%2
3603    #"
3604   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3605   [(set (match_dup 0)
3606         (match_dup 3))
3607    (set (match_dup 4)
3608         (compare:CC (match_dup 0)
3609                     (const_int 0)))]
3610   ""
3611   [(set_attr "type" "logical")
3612    (set_attr "dot" "yes")
3613    (set_attr "length" "4,8")])
3616 ;; TODO: Should have dots of this as well.
3617 (define_insn "*eqv<mode>3"
3618   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3619         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3620                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3621   ""
3622   "eqv %0,%1,%2"
3623   [(set_attr "type" "logical")])
3625 ;; Rotate-and-mask and insert.
3627 (define_insn "*rotl<mode>3_mask"
3628   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3629         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3630                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3631                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3632                  (match_operand:GPR 3 "const_int_operand" "n")))]
3633   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3635   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3637   [(set_attr "type" "shift")
3638    (set_attr "maybe_var_shift" "yes")])
3640 (define_insn_and_split "*rotl<mode>3_mask_dot"
3641   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3642         (compare:CC
3643           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3644                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3645                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3646                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3647           (const_int 0)))
3648    (clobber (match_scratch:GPR 0 "=r,r"))]
3649   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3650    && rs6000_gen_cell_microcode
3651    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3653   if (which_alternative == 0)
3654     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3655   else
3656     return "#";
3658   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3659   [(set (match_dup 0)
3660         (and:GPR (match_dup 4)
3661                  (match_dup 3)))
3662    (set (match_dup 5)
3663         (compare:CC (match_dup 0)
3664                     (const_int 0)))]
3665   ""
3666   [(set_attr "type" "shift")
3667    (set_attr "maybe_var_shift" "yes")
3668    (set_attr "dot" "yes")
3669    (set_attr "length" "4,8")])
3671 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3672   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3673         (compare:CC
3674           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3675                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3676                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3677                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3678           (const_int 0)))
3679    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3680         (and:GPR (match_dup 4)
3681                  (match_dup 3)))]
3682   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3683    && rs6000_gen_cell_microcode
3684    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3686   if (which_alternative == 0)
3687     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3688   else
3689     return "#";
3691   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3692   [(set (match_dup 0)
3693         (and:GPR (match_dup 4)
3694                  (match_dup 3)))
3695    (set (match_dup 5)
3696         (compare:CC (match_dup 0)
3697                     (const_int 0)))]
3698   ""
3699   [(set_attr "type" "shift")
3700    (set_attr "maybe_var_shift" "yes")
3701    (set_attr "dot" "yes")
3702    (set_attr "length" "4,8")])
3704 ; Special case for less-than-0.  We can do it with just one machine
3705 ; instruction, but the generic optimizers do not realise it is cheap.
3706 (define_insn "*lt0_disi"
3707   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3708         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3709                (const_int 0)))]
3710   "TARGET_POWERPC64"
3711   "rlwinm %0,%1,1,31,31"
3712   [(set_attr "type" "shift")])
3716 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3717 ; both are an AND so are the same precedence).
3718 (define_insn "*rotl<mode>3_insert"
3719   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3720         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3721                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3722                             (match_operand:SI 2 "const_int_operand" "n")])
3723                           (match_operand:GPR 3 "const_int_operand" "n"))
3724                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3725                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3726   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3727    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3729   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3731   [(set_attr "type" "insert")])
3732 ; FIXME: this needs an attr "size", so that the scheduler can see the
3733 ; difference between rlwimi and rldimi.  We also might want dot forms,
3734 ; but not for rlwimi on POWER4 and similar processors.
3736 (define_insn "*rotl<mode>3_insert_2"
3737   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3738         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3739                           (match_operand:GPR 6 "const_int_operand" "n"))
3740                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3741                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3742                             (match_operand:SI 2 "const_int_operand" "n")])
3743                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3744   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3745    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3747   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3749   [(set_attr "type" "insert")])
3751 ; There are also some forms without one of the ANDs.
3752 (define_insn "*rotl<mode>3_insert_3"
3753   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3754         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3755                           (match_operand:GPR 4 "const_int_operand" "n"))
3756                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3757                              (match_operand:SI 2 "const_int_operand" "n"))))]
3758   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3760   if (<MODE>mode == SImode)
3761     return "rlwimi %0,%1,%h2,0,31-%h2";
3762   else
3763     return "rldimi %0,%1,%H2,0";
3765   [(set_attr "type" "insert")])
3767 (define_insn "*rotl<mode>3_insert_4"
3768   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3769         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3770                           (match_operand:GPR 4 "const_int_operand" "n"))
3771                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3772                                (match_operand:SI 2 "const_int_operand" "n"))))]
3773   "<MODE>mode == SImode &&
3774    GET_MODE_PRECISION (<MODE>mode)
3775    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3777   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3778                          - INTVAL (operands[2]));
3779   if (<MODE>mode == SImode)
3780     return "rlwimi %0,%1,%h2,32-%h2,31";
3781   else
3782     return "rldimi %0,%1,%H2,64-%H2";
3784   [(set_attr "type" "insert")])
3787 ; This handles the important case of multiple-precision shifts.  There is
3788 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3789 (define_split
3790   [(set (match_operand:GPR 0 "gpc_reg_operand")
3791         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3792                              (match_operand:SI 3 "const_int_operand"))
3793                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3794                                (match_operand:SI 4 "const_int_operand"))))]
3795   "can_create_pseudo_p ()
3796    && INTVAL (operands[3]) + INTVAL (operands[4])
3797       >= GET_MODE_PRECISION (<MODE>mode)"
3798   [(set (match_dup 5)
3799         (lshiftrt:GPR (match_dup 2)
3800                       (match_dup 4)))
3801    (set (match_dup 0)
3802         (ior:GPR (and:GPR (match_dup 5)
3803                           (match_dup 6))
3804                  (ashift:GPR (match_dup 1)
3805                              (match_dup 3))))]
3807   unsigned HOST_WIDE_INT mask = 1;
3808   mask = (mask << INTVAL (operands[3])) - 1;
3809   operands[5] = gen_reg_rtx (<MODE>mode);
3810   operands[6] = GEN_INT (mask);
3813 (define_split
3814   [(set (match_operand:GPR 0 "gpc_reg_operand")
3815         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3816                                (match_operand:SI 4 "const_int_operand"))
3817                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3818                              (match_operand:SI 3 "const_int_operand"))))]
3819   "can_create_pseudo_p ()
3820    && INTVAL (operands[3]) + INTVAL (operands[4])
3821       >= GET_MODE_PRECISION (<MODE>mode)"
3822   [(set (match_dup 5)
3823         (lshiftrt:GPR (match_dup 2)
3824                       (match_dup 4)))
3825    (set (match_dup 0)
3826         (ior:GPR (and:GPR (match_dup 5)
3827                           (match_dup 6))
3828                  (ashift:GPR (match_dup 1)
3829                              (match_dup 3))))]
3831   unsigned HOST_WIDE_INT mask = 1;
3832   mask = (mask << INTVAL (operands[3])) - 1;
3833   operands[5] = gen_reg_rtx (<MODE>mode);
3834   operands[6] = GEN_INT (mask);
3838 ; Another important case is setting some bits to 1; we can do that with
3839 ; an insert instruction, in many cases.
3840 (define_insn_and_split "*ior<mode>_mask"
3841   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3842         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3843                  (match_operand:GPR 2 "const_int_operand" "n")))
3844    (clobber (match_scratch:GPR 3 "=r"))]
3845   "!logical_const_operand (operands[2], <MODE>mode)
3846    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3847   "#"
3848   "&& 1"
3849   [(set (match_dup 3)
3850         (const_int -1))
3851    (set (match_dup 0)
3852         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3853                                       (match_dup 4))
3854                           (match_dup 2))
3855                  (and:GPR (match_dup 1)
3856                           (match_dup 5))))]
3858   int nb, ne;
3859   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3860   if (GET_CODE (operands[3]) == SCRATCH)
3861     operands[3] = gen_reg_rtx (<MODE>mode);
3862   operands[4] = GEN_INT (ne);
3863   operands[5] = GEN_INT (~UINTVAL (operands[2]));
3865   [(set_attr "type" "two")
3866    (set_attr "length" "8")])
3869 ;; Now the simple shifts.
3871 (define_insn "rotl<mode>3"
3872   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3873         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3874                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3875   ""
3876   "rotl<wd>%I2 %0,%1,%<hH>2"
3877   [(set_attr "type" "shift")
3878    (set_attr "maybe_var_shift" "yes")])
3880 (define_insn "*rotlsi3_64"
3881   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3882         (zero_extend:DI
3883             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3884                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3885   "TARGET_POWERPC64"
3886   "rotlw%I2 %0,%1,%h2"
3887   [(set_attr "type" "shift")
3888    (set_attr "maybe_var_shift" "yes")])
3890 (define_insn_and_split "*rotl<mode>3_dot"
3891   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3892         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3893                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3894                     (const_int 0)))
3895    (clobber (match_scratch:GPR 0 "=r,r"))]
3896   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3897   "@
3898    rotl<wd>%I2. %0,%1,%<hH>2
3899    #"
3900   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3901   [(set (match_dup 0)
3902         (rotate:GPR (match_dup 1)
3903                     (match_dup 2)))
3904    (set (match_dup 3)
3905         (compare:CC (match_dup 0)
3906                     (const_int 0)))]
3907   ""
3908   [(set_attr "type" "shift")
3909    (set_attr "maybe_var_shift" "yes")
3910    (set_attr "dot" "yes")
3911    (set_attr "length" "4,8")])
3913 (define_insn_and_split "*rotl<mode>3_dot2"
3914   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3915         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3916                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3917                     (const_int 0)))
3918    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3919         (rotate:GPR (match_dup 1)
3920                     (match_dup 2)))]
3921   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3922   "@
3923    rotl<wd>%I2. %0,%1,%<hH>2
3924    #"
3925   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3926   [(set (match_dup 0)
3927         (rotate:GPR (match_dup 1)
3928                     (match_dup 2)))
3929    (set (match_dup 3)
3930         (compare:CC (match_dup 0)
3931                     (const_int 0)))]
3932   ""
3933   [(set_attr "type" "shift")
3934    (set_attr "maybe_var_shift" "yes")
3935    (set_attr "dot" "yes")
3936    (set_attr "length" "4,8")])
3939 (define_insn "ashl<mode>3"
3940   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3941         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3942                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3943   ""
3944   "sl<wd>%I2 %0,%1,%<hH>2"
3945   [(set_attr "type" "shift")
3946    (set_attr "maybe_var_shift" "yes")])
3948 (define_insn "*ashlsi3_64"
3949   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3950         (zero_extend:DI
3951             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3952                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3953   "TARGET_POWERPC64"
3954   "slw%I2 %0,%1,%h2"
3955   [(set_attr "type" "shift")
3956    (set_attr "maybe_var_shift" "yes")])
3958 (define_insn_and_split "*ashl<mode>3_dot"
3959   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3960         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3961                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3962                     (const_int 0)))
3963    (clobber (match_scratch:GPR 0 "=r,r"))]
3964   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3965   "@
3966    sl<wd>%I2. %0,%1,%<hH>2
3967    #"
3968   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3969   [(set (match_dup 0)
3970         (ashift:GPR (match_dup 1)
3971                     (match_dup 2)))
3972    (set (match_dup 3)
3973         (compare:CC (match_dup 0)
3974                     (const_int 0)))]
3975   ""
3976   [(set_attr "type" "shift")
3977    (set_attr "maybe_var_shift" "yes")
3978    (set_attr "dot" "yes")
3979    (set_attr "length" "4,8")])
3981 (define_insn_and_split "*ashl<mode>3_dot2"
3982   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3983         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3984                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3985                     (const_int 0)))
3986    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3987         (ashift:GPR (match_dup 1)
3988                     (match_dup 2)))]
3989   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3990   "@
3991    sl<wd>%I2. %0,%1,%<hH>2
3992    #"
3993   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3994   [(set (match_dup 0)
3995         (ashift:GPR (match_dup 1)
3996                     (match_dup 2)))
3997    (set (match_dup 3)
3998         (compare:CC (match_dup 0)
3999                     (const_int 0)))]
4000   ""
4001   [(set_attr "type" "shift")
4002    (set_attr "maybe_var_shift" "yes")
4003    (set_attr "dot" "yes")
4004    (set_attr "length" "4,8")])
4006 ;; Pretend we have a memory form of extswsli until register allocation is done
4007 ;; so that we use LWZ to load the value from memory, instead of LWA.
4008 (define_insn_and_split "ashdi3_extswsli"
4009   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4010         (ashift:DI
4011          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4012          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4013   "TARGET_EXTSWSLI"
4014   "@
4015    extswsli %0,%1,%2
4016    #"
4017   "&& reload_completed && MEM_P (operands[1])"
4018   [(set (match_dup 3)
4019         (match_dup 1))
4020    (set (match_dup 0)
4021         (ashift:DI (sign_extend:DI (match_dup 3))
4022                    (match_dup 2)))]
4024   operands[3] = gen_lowpart (SImode, operands[0]);
4026   [(set_attr "type" "shift")
4027    (set_attr "maybe_var_shift" "no")])
4030 (define_insn_and_split "ashdi3_extswsli_dot"
4031   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4032         (compare:CC
4033          (ashift:DI
4034           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4035           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4036          (const_int 0)))
4037    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4038   "TARGET_EXTSWSLI"
4039   "@
4040    extswsli. %0,%1,%2
4041    #
4042    #
4043    #"
4044   "&& reload_completed
4045    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4046        || memory_operand (operands[1], SImode))"
4047   [(pc)]
4049   rtx dest = operands[0];
4050   rtx src = operands[1];
4051   rtx shift = operands[2];
4052   rtx cr = operands[3];
4053   rtx src2;
4055   if (!MEM_P (src))
4056     src2 = src;
4057   else
4058     {
4059       src2 = gen_lowpart (SImode, dest);
4060       emit_move_insn (src2, src);
4061     }
4063   if (REGNO (cr) == CR0_REGNO)
4064     {
4065       emit_insn (gen_ashdi3_extswsli_dot (dest, src2, shift, cr));
4066       DONE;
4067     }
4069   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4070   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4071   DONE;
4073   [(set_attr "type" "shift")
4074    (set_attr "maybe_var_shift" "no")
4075    (set_attr "dot" "yes")
4076    (set_attr "length" "4,8,8,12")])
4078 (define_insn_and_split "ashdi3_extswsli_dot2"
4079   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4080         (compare:CC
4081          (ashift:DI
4082           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4083           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4084          (const_int 0)))
4085    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4086         (ashift:DI (sign_extend:DI (match_dup 1))
4087                    (match_dup 2)))]
4088   "TARGET_EXTSWSLI"
4089   "@
4090    extswsli. %0,%1,%2
4091    #
4092    #
4093    #"
4094   "&& reload_completed
4095    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4096        || memory_operand (operands[1], SImode))"
4097   [(pc)]
4099   rtx dest = operands[0];
4100   rtx src = operands[1];
4101   rtx shift = operands[2];
4102   rtx cr = operands[3];
4103   rtx src2;
4105   if (!MEM_P (src))
4106     src2 = src;
4107   else
4108     {
4109       src2 = gen_lowpart (SImode, dest);
4110       emit_move_insn (src2, src);
4111     }
4113   if (REGNO (cr) == CR0_REGNO)
4114     {
4115       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4116       DONE;
4117     }
4119   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4120   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4121   DONE;
4123   [(set_attr "type" "shift")
4124    (set_attr "maybe_var_shift" "no")
4125    (set_attr "dot" "yes")
4126    (set_attr "length" "4,8,8,12")])
4128 (define_insn "lshr<mode>3"
4129   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4130         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4131                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4132   ""
4133   "sr<wd>%I2 %0,%1,%<hH>2"
4134   [(set_attr "type" "shift")
4135    (set_attr "maybe_var_shift" "yes")])
4137 (define_insn "*lshrsi3_64"
4138   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4139         (zero_extend:DI
4140             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4141                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4142   "TARGET_POWERPC64"
4143   "srw%I2 %0,%1,%h2"
4144   [(set_attr "type" "shift")
4145    (set_attr "maybe_var_shift" "yes")])
4147 (define_insn_and_split "*lshr<mode>3_dot"
4148   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4149         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4150                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4151                     (const_int 0)))
4152    (clobber (match_scratch:GPR 0 "=r,r"))]
4153   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4154   "@
4155    sr<wd>%I2. %0,%1,%<hH>2
4156    #"
4157   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4158   [(set (match_dup 0)
4159         (lshiftrt:GPR (match_dup 1)
4160                       (match_dup 2)))
4161    (set (match_dup 3)
4162         (compare:CC (match_dup 0)
4163                     (const_int 0)))]
4164   ""
4165   [(set_attr "type" "shift")
4166    (set_attr "maybe_var_shift" "yes")
4167    (set_attr "dot" "yes")
4168    (set_attr "length" "4,8")])
4170 (define_insn_and_split "*lshr<mode>3_dot2"
4171   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4172         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4173                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4174                     (const_int 0)))
4175    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4176         (lshiftrt:GPR (match_dup 1)
4177                       (match_dup 2)))]
4178   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4179   "@
4180    sr<wd>%I2. %0,%1,%<hH>2
4181    #"
4182   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4183   [(set (match_dup 0)
4184         (lshiftrt:GPR (match_dup 1)
4185                       (match_dup 2)))
4186    (set (match_dup 3)
4187         (compare:CC (match_dup 0)
4188                     (const_int 0)))]
4189   ""
4190   [(set_attr "type" "shift")
4191    (set_attr "maybe_var_shift" "yes")
4192    (set_attr "dot" "yes")
4193    (set_attr "length" "4,8")])
4196 (define_insn "ashr<mode>3"
4197   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4198         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4199                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4200    (clobber (reg:GPR CA_REGNO))]
4201   ""
4202   "sra<wd>%I2 %0,%1,%<hH>2"
4203   [(set_attr "type" "shift")
4204    (set_attr "maybe_var_shift" "yes")])
4206 (define_insn "*ashrsi3_64"
4207   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4208         (sign_extend:DI
4209             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4210                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4211    (clobber (reg:SI CA_REGNO))]
4212   "TARGET_POWERPC64"
4213   "sraw%I2 %0,%1,%h2"
4214   [(set_attr "type" "shift")
4215    (set_attr "maybe_var_shift" "yes")])
4217 (define_insn_and_split "*ashr<mode>3_dot"
4218   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4219         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4220                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4221                     (const_int 0)))
4222    (clobber (match_scratch:GPR 0 "=r,r"))
4223    (clobber (reg:GPR CA_REGNO))]
4224   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4225   "@
4226    sra<wd>%I2. %0,%1,%<hH>2
4227    #"
4228   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4229   [(parallel [(set (match_dup 0)
4230                    (ashiftrt:GPR (match_dup 1)
4231                                  (match_dup 2)))
4232               (clobber (reg:GPR CA_REGNO))])
4233    (set (match_dup 3)
4234         (compare:CC (match_dup 0)
4235                     (const_int 0)))]
4236   ""
4237   [(set_attr "type" "shift")
4238    (set_attr "maybe_var_shift" "yes")
4239    (set_attr "dot" "yes")
4240    (set_attr "length" "4,8")])
4242 (define_insn_and_split "*ashr<mode>3_dot2"
4243   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4244         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4245                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4246                     (const_int 0)))
4247    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4248         (ashiftrt:GPR (match_dup 1)
4249                       (match_dup 2)))
4250    (clobber (reg:GPR CA_REGNO))]
4251   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4252   "@
4253    sra<wd>%I2. %0,%1,%<hH>2
4254    #"
4255   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4256   [(parallel [(set (match_dup 0)
4257                    (ashiftrt:GPR (match_dup 1)
4258                                  (match_dup 2)))
4259               (clobber (reg:GPR CA_REGNO))])
4260    (set (match_dup 3)
4261         (compare:CC (match_dup 0)
4262                     (const_int 0)))]
4263   ""
4264   [(set_attr "type" "shift")
4265    (set_attr "maybe_var_shift" "yes")
4266    (set_attr "dot" "yes")
4267    (set_attr "length" "4,8")])
4269 ;; Builtins to replace a division to generate FRE reciprocal estimate
4270 ;; instructions and the necessary fixup instructions
4271 (define_expand "recip<mode>3"
4272   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4273    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4274    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4275   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4277    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4278    DONE;
4281 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4282 ;; hardware division.  This is only done before register allocation and with
4283 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4284 (define_split
4285   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4286         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4287                     (match_operand 2 "gpc_reg_operand" "")))]
4288   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4289    && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4290    && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4291   [(const_int 0)]
4293   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4294   DONE;
4297 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4298 ;; appropriate fixup.
4299 (define_expand "rsqrt<mode>2"
4300   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4301    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4302   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4304   rs6000_emit_swrsqrt (operands[0], operands[1]);
4305   DONE;
4308 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4309 ;; modes here, and also add in conditional vsx/power8-vector support to access
4310 ;; values in the traditional Altivec registers if the appropriate
4311 ;; -mupper-regs-{df,sf} option is enabled.
4313 (define_expand "abs<mode>2"
4314   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4315         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4316   "TARGET_<MODE>_INSN"
4317   "")
4319 (define_insn "*abs<mode>2_fpr"
4320   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4321         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4322   "TARGET_<MODE>_FPR"
4323   "@
4324    fabs %0,%1
4325    xsabsdp %x0,%x1"
4326   [(set_attr "type" "fp")
4327    (set_attr "fp_type" "fp_addsub_<Fs>")])
4329 (define_insn "*nabs<mode>2_fpr"
4330   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4331         (neg:SFDF
4332          (abs:SFDF
4333           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4334   "TARGET_<MODE>_FPR"
4335   "@
4336    fnabs %0,%1
4337    xsnabsdp %x0,%x1"
4338   [(set_attr "type" "fp")
4339    (set_attr "fp_type" "fp_addsub_<Fs>")])
4341 (define_expand "neg<mode>2"
4342   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4343         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4344   "TARGET_<MODE>_INSN"
4345   "")
4347 (define_insn "*neg<mode>2_fpr"
4348   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4349         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4350   "TARGET_<MODE>_FPR"
4351   "@
4352    fneg %0,%1
4353    xsnegdp %x0,%x1"
4354   [(set_attr "type" "fp")
4355    (set_attr "fp_type" "fp_addsub_<Fs>")])
4357 (define_expand "add<mode>3"
4358   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4359         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4360                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4361   "TARGET_<MODE>_INSN"
4362   "")
4364 (define_insn "*add<mode>3_fpr"
4365   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4366         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4367                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4368   "TARGET_<MODE>_FPR"
4369   "@
4370    fadd<Ftrad> %0,%1,%2
4371    xsadd<Fvsx> %x0,%x1,%x2"
4372   [(set_attr "type" "fp")
4373    (set_attr "fp_type" "fp_addsub_<Fs>")])
4375 (define_expand "sub<mode>3"
4376   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4377         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4378                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4379   "TARGET_<MODE>_INSN"
4380   "")
4382 (define_insn "*sub<mode>3_fpr"
4383   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4384         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4385                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4386   "TARGET_<MODE>_FPR"
4387   "@
4388    fsub<Ftrad> %0,%1,%2
4389    xssub<Fvsx> %x0,%x1,%x2"
4390   [(set_attr "type" "fp")
4391    (set_attr "fp_type" "fp_addsub_<Fs>")])
4393 (define_expand "mul<mode>3"
4394   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4395         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4396                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4397   "TARGET_<MODE>_INSN"
4398   "")
4400 (define_insn "*mul<mode>3_fpr"
4401   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4402         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4403                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4404   "TARGET_<MODE>_FPR"
4405   "@
4406    fmul<Ftrad> %0,%1,%2
4407    xsmul<Fvsx> %x0,%x1,%x2"
4408   [(set_attr "type" "dmul")
4409    (set_attr "fp_type" "fp_mul_<Fs>")])
4411 (define_expand "div<mode>3"
4412   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4413         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4414                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4415   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4416   "")
4418 (define_insn "*div<mode>3_fpr"
4419   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4420         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4421                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4422   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4423   "@
4424    fdiv<Ftrad> %0,%1,%2
4425    xsdiv<Fvsx> %x0,%x1,%x2"
4426   [(set_attr "type" "<Fs>div")
4427    (set_attr "fp_type" "fp_div_<Fs>")])
4429 (define_insn "sqrt<mode>2"
4430   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4431         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4432   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4433    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4434   "@
4435    fsqrt<Ftrad> %0,%1
4436    xssqrt<Fvsx> %x0,%x1"
4437   [(set_attr "type" "<Fs>sqrt")
4438    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4440 ;; Floating point reciprocal approximation
4441 (define_insn "fre<Fs>"
4442   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4443         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4444                      UNSPEC_FRES))]
4445   "TARGET_<FFRE>"
4446   "@
4447    fre<Ftrad> %0,%1
4448    xsre<Fvsx> %x0,%x1"
4449   [(set_attr "type" "fp")])
4451 (define_insn "*rsqrt<mode>2"
4452   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4453         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4454                      UNSPEC_RSQRT))]
4455   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4456   "@
4457    frsqrte<Ftrad> %0,%1
4458    xsrsqrte<Fvsx> %x0,%x1"
4459   [(set_attr "type" "fp")])
4461 ;; Floating point comparisons
4462 (define_insn "*cmp<mode>_fpr"
4463   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4464         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4465                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4466   "TARGET_<MODE>_FPR"
4467   "@
4468    fcmpu %0,%1,%2
4469    xscmpudp %0,%x1,%x2"
4470   [(set_attr "type" "fpcompare")])
4472 ;; Floating point conversions
4473 (define_expand "extendsfdf2"
4474   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4475         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4476   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4477   "")
4479 (define_insn_and_split "*extendsfdf2_fpr"
4480   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4481         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))]
4482   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4483   "@
4484    #
4485    fmr %0,%1
4486    lfs%U1%X1 %0,%1
4487    #
4488    xscpsgndp %x0,%x1,%x1
4489    lxsspx %x0,%y1
4490    lxssp %0,%1"
4491   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4492   [(const_int 0)]
4494   emit_note (NOTE_INSN_DELETED);
4495   DONE;
4497   [(set_attr "type" "fp,fp,fpload,fp,fp,fpload,fpload")])
4499 (define_expand "truncdfsf2"
4500   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4501         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4502   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4503   "")
4505 (define_insn "*truncdfsf2_fpr"
4506   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4507         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4508   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4509   "@
4510    frsp %0,%1
4511    xsrsp %x0,%x1"
4512   [(set_attr "type" "fp")])
4514 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4515 ;; builtins.c and optabs.c that are not correct for IBM long double
4516 ;; when little-endian.
4517 (define_expand "signbit<mode>2"
4518   [(set (match_dup 2)
4519         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "")))
4520    (set (match_dup 3)
4521         (subreg:DI (match_dup 2) 0))
4522    (set (match_dup 4)
4523         (match_dup 5))
4524    (set (match_operand:SI 0 "gpc_reg_operand" "")
4525         (match_dup 6))]
4526   "TARGET_HARD_FLOAT
4527    && (TARGET_FPRS || TARGET_E500_DOUBLE)"
4529   operands[2] = gen_reg_rtx (DFmode);
4530   operands[3] = gen_reg_rtx (DImode);
4531   if (TARGET_POWERPC64)
4532     {
4533       operands[4] = gen_reg_rtx (DImode);
4534       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4535       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4536                                     WORDS_BIG_ENDIAN ? 4 : 0);
4537     }
4538   else
4539     {
4540       operands[4] = gen_reg_rtx (SImode);
4541       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4542                                     WORDS_BIG_ENDIAN ? 0 : 4);
4543       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4544     }
4547 (define_expand "copysign<mode>3"
4548   [(set (match_dup 3)
4549         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4550    (set (match_dup 4)
4551         (neg:SFDF (abs:SFDF (match_dup 1))))
4552    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4553         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4554                                (match_dup 5))
4555                          (match_dup 3)
4556                          (match_dup 4)))]
4557   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4558    && ((TARGET_PPC_GFXOPT
4559         && !HONOR_NANS (<MODE>mode)
4560         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4561        || TARGET_CMPB
4562        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4564   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4565     {
4566       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4567                                              operands[2]));
4568       DONE;
4569     }
4571    operands[3] = gen_reg_rtx (<MODE>mode);
4572    operands[4] = gen_reg_rtx (<MODE>mode);
4573    operands[5] = CONST0_RTX (<MODE>mode);
4574   })
4576 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4577 ;; compiler from optimizing -0.0
4578 (define_insn "copysign<mode>3_fcpsgn"
4579   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4580         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4581                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4582                      UNSPEC_COPYSIGN))]
4583   "TARGET_<MODE>_FPR && TARGET_CMPB"
4584   "@
4585    fcpsgn %0,%2,%1
4586    xscpsgndp %x0,%x2,%x1"
4587   [(set_attr "type" "fp")])
4589 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4590 ;; fsel instruction and some auxiliary computations.  Then we just have a
4591 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4592 ;; combine.
4593 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4594 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4595 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4596 ;; define_splits to make them if made by combine.  On VSX machines we have the
4597 ;; min/max instructions.
4599 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4600 ;; to allow either DF/SF to use only traditional registers.
4602 (define_expand "smax<mode>3"
4603   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4604         (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4605                                (match_operand:SFDF 2 "gpc_reg_operand" ""))
4606                            (match_dup 1)
4607                            (match_dup 2)))]
4608   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4610   rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
4611   DONE;
4614 (define_insn "*smax<mode>3_vsx"
4615   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4616         (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4617                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4618   "TARGET_<MODE>_FPR && TARGET_VSX"
4619   "xsmaxdp %x0,%x1,%x2"
4620   [(set_attr "type" "fp")])
4622 (define_expand "smin<mode>3"
4623   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4624         (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4625                                (match_operand:SFDF 2 "gpc_reg_operand" ""))
4626                            (match_dup 2)
4627                            (match_dup 1)))]
4628   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4630   rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
4631   DONE;
4634 (define_insn "*smin<mode>3_vsx"
4635   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4636         (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4637                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4638   "TARGET_<MODE>_FPR && TARGET_VSX"
4639   "xsmindp %x0,%x1,%x2"
4640   [(set_attr "type" "fp")])
4642 (define_split
4643   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4644         (match_operator:SFDF 3 "min_max_operator"
4645          [(match_operand:SFDF 1 "gpc_reg_operand" "")
4646           (match_operand:SFDF 2 "gpc_reg_operand" "")]))]
4647   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math
4648    && !TARGET_VSX"
4649   [(const_int 0)]
4651   rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1],
4652                       operands[2]);
4653   DONE;
4656 (define_split
4657   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4658         (match_operator:SF 3 "min_max_operator"
4659          [(match_operand:SF 1 "gpc_reg_operand" "")
4660           (match_operand:SF 2 "gpc_reg_operand" "")]))]
4661   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
4662    && TARGET_SINGLE_FLOAT && !flag_trapping_math"
4663   [(const_int 0)]
4664   "
4665 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4666                       operands[1], operands[2]);
4667   DONE;
4670 (define_expand "mov<mode>cc"
4671    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4672          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4673                            (match_operand:GPR 2 "gpc_reg_operand" "")
4674                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4675   "TARGET_ISEL<sel>"
4676   "
4678   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4679     DONE;
4680   else
4681     FAIL;
4684 ;; We use the BASE_REGS for the isel input operands because, if rA is
4685 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4686 ;; because we may switch the operands and rB may end up being rA.
4688 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4689 ;; leave out the mode in operand 4 and use one pattern, but reload can
4690 ;; change the mode underneath our feet and then gets confused trying
4691 ;; to reload the value.
4692 (define_insn "isel_signed_<mode>"
4693   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4694         (if_then_else:GPR
4695          (match_operator 1 "scc_comparison_operator"
4696                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4697                           (const_int 0)])
4698          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4699          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4700   "TARGET_ISEL<sel>"
4701   "*
4702 { return output_isel (operands); }"
4703   [(set_attr "type" "isel")
4704    (set_attr "length" "4")])
4706 (define_insn "isel_unsigned_<mode>"
4707   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4708         (if_then_else:GPR
4709          (match_operator 1 "scc_comparison_operator"
4710                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4711                           (const_int 0)])
4712          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4713          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4714   "TARGET_ISEL<sel>"
4715   "*
4716 { return output_isel (operands); }"
4717   [(set_attr "type" "isel")
4718    (set_attr "length" "4")])
4720 ;; These patterns can be useful for combine; they let combine know that
4721 ;; isel can handle reversed comparisons so long as the operands are
4722 ;; registers.
4724 (define_insn "*isel_reversed_signed_<mode>"
4725   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4726         (if_then_else:GPR
4727          (match_operator 1 "scc_rev_comparison_operator"
4728                          [(match_operand:CC 4 "cc_reg_operand" "y")
4729                           (const_int 0)])
4730          (match_operand:GPR 2 "gpc_reg_operand" "b")
4731          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4732   "TARGET_ISEL<sel>"
4733   "*
4734 { return output_isel (operands); }"
4735   [(set_attr "type" "isel")
4736    (set_attr "length" "4")])
4738 (define_insn "*isel_reversed_unsigned_<mode>"
4739   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4740         (if_then_else:GPR
4741          (match_operator 1 "scc_rev_comparison_operator"
4742                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4743                           (const_int 0)])
4744          (match_operand:GPR 2 "gpc_reg_operand" "b")
4745          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4746   "TARGET_ISEL<sel>"
4747   "*
4748 { return output_isel (operands); }"
4749   [(set_attr "type" "isel")
4750    (set_attr "length" "4")])
4752 (define_expand "movsfcc"
4753    [(set (match_operand:SF 0 "gpc_reg_operand" "")
4754          (if_then_else:SF (match_operand 1 "comparison_operator" "")
4755                           (match_operand:SF 2 "gpc_reg_operand" "")
4756                           (match_operand:SF 3 "gpc_reg_operand" "")))]
4757   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4758   "
4760   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4761     DONE;
4762   else
4763     FAIL;
4766 (define_insn "*fselsfsf4"
4767   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4768         (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4769                              (match_operand:SF 4 "zero_fp_constant" "F"))
4770                          (match_operand:SF 2 "gpc_reg_operand" "f")
4771                          (match_operand:SF 3 "gpc_reg_operand" "f")))]
4772   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4773   "fsel %0,%1,%2,%3"
4774   [(set_attr "type" "fp")])
4776 (define_insn "*fseldfsf4"
4777   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4778         (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4779                              (match_operand:DF 4 "zero_fp_constant" "F"))
4780                          (match_operand:SF 2 "gpc_reg_operand" "f")
4781                          (match_operand:SF 3 "gpc_reg_operand" "f")))]
4782   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4783   "fsel %0,%1,%2,%3"
4784   [(set_attr "type" "fp")])
4786 ;; The conditional move instructions allow us to perform max and min
4787 ;; operations even when
4789 (define_split
4790   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4791         (match_operator:DF 3 "min_max_operator"
4792          [(match_operand:DF 1 "gpc_reg_operand" "")
4793           (match_operand:DF 2 "gpc_reg_operand" "")]))]
4794   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
4795    && !flag_trapping_math"
4796   [(const_int 0)]
4797   "
4798 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4799                       operands[1], operands[2]);
4800   DONE;
4803 (define_expand "movdfcc"
4804    [(set (match_operand:DF 0 "gpc_reg_operand" "")
4805          (if_then_else:DF (match_operand 1 "comparison_operator" "")
4806                           (match_operand:DF 2 "gpc_reg_operand" "")
4807                           (match_operand:DF 3 "gpc_reg_operand" "")))]
4808   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4809   "
4811   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4812     DONE;
4813   else
4814     FAIL;
4817 (define_insn "*fseldfdf4"
4818   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4819         (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4820                              (match_operand:DF 4 "zero_fp_constant" "F"))
4821                          (match_operand:DF 2 "gpc_reg_operand" "d")
4822                          (match_operand:DF 3 "gpc_reg_operand" "d")))]
4823   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4824   "fsel %0,%1,%2,%3"
4825   [(set_attr "type" "fp")])
4827 (define_insn "*fselsfdf4"
4828   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4829         (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4830                              (match_operand:SF 4 "zero_fp_constant" "F"))
4831                          (match_operand:DF 2 "gpc_reg_operand" "d")
4832                          (match_operand:DF 3 "gpc_reg_operand" "d")))]
4833   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4834   "fsel %0,%1,%2,%3"
4835   [(set_attr "type" "fp")])
4837 ;; Conversions to and from floating-point.
4839 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4840 ; don't want to support putting SImode in FPR registers.
4841 (define_insn "lfiwax"
4842   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4843         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4844                    UNSPEC_LFIWAX))]
4845   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4846   "@
4847    lfiwax %0,%y1
4848    lxsiwax %x0,%y1
4849    mtvsrwa %x0,%1"
4850   [(set_attr "type" "fpload,fpload,mffgpr")])
4852 ; This split must be run before register allocation because it allocates the
4853 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
4854 ; it earlier to allow for the combiner to merge insns together where it might
4855 ; not be needed and also in case the insns are deleted as dead code.
4857 (define_insn_and_split "floatsi<mode>2_lfiwax"
4858   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4859         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4860    (clobber (match_scratch:DI 2 "=wj"))]
4861   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4862    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4863   "#"
4864   ""
4865   [(pc)]
4866   "
4868   rtx dest = operands[0];
4869   rtx src = operands[1];
4870   rtx tmp;
4872   if (!MEM_P (src) && TARGET_POWERPC64
4873       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4874     tmp = convert_to_mode (DImode, src, false);
4875   else
4876     {
4877       tmp = operands[2];
4878       if (GET_CODE (tmp) == SCRATCH)
4879         tmp = gen_reg_rtx (DImode);
4880       if (MEM_P (src))
4881         {
4882           src = rs6000_address_for_fpconvert (src);
4883           emit_insn (gen_lfiwax (tmp, src));
4884         }
4885       else
4886         {
4887           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4888           emit_move_insn (stack, src);
4889           emit_insn (gen_lfiwax (tmp, stack));
4890         }
4891     }
4892   emit_insn (gen_floatdi<mode>2 (dest, tmp));
4893   DONE;
4895   [(set_attr "length" "12")
4896    (set_attr "type" "fpload")])
4898 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
4899   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4900         (float:SFDF
4901          (sign_extend:DI
4902           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4903    (clobber (match_scratch:DI 2 "=0,d"))]
4904   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4905    && <SI_CONVERT_FP>"
4906   "#"
4907   ""
4908   [(pc)]
4909   "
4911   operands[1] = rs6000_address_for_fpconvert (operands[1]);
4912   if (GET_CODE (operands[2]) == SCRATCH)
4913     operands[2] = gen_reg_rtx (DImode);
4914   emit_insn (gen_lfiwax (operands[2], operands[1]));
4915   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4916   DONE;
4918   [(set_attr "length" "8")
4919    (set_attr "type" "fpload")])
4921 (define_insn "lfiwzx"
4922   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4923         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4924                    UNSPEC_LFIWZX))]
4925   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
4926   "@
4927    lfiwzx %0,%y1
4928    lxsiwzx %x0,%y1
4929    mtvsrwz %x0,%1"
4930   [(set_attr "type" "fpload,fpload,mftgpr")])
4932 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
4933   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4934         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4935    (clobber (match_scratch:DI 2 "=wj"))]
4936   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4937    && <SI_CONVERT_FP>"
4938   "#"
4939   ""
4940   [(pc)]
4941   "
4943   rtx dest = operands[0];
4944   rtx src = operands[1];
4945   rtx tmp;
4947   if (!MEM_P (src) && TARGET_POWERPC64
4948       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4949     tmp = convert_to_mode (DImode, src, true);
4950   else
4951     {
4952       tmp = operands[2];
4953       if (GET_CODE (tmp) == SCRATCH)
4954         tmp = gen_reg_rtx (DImode);
4955       if (MEM_P (src))
4956         {
4957           src = rs6000_address_for_fpconvert (src);
4958           emit_insn (gen_lfiwzx (tmp, src));
4959         }
4960       else
4961         {
4962           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4963           emit_move_insn (stack, src);
4964           emit_insn (gen_lfiwzx (tmp, stack));
4965         }
4966     }
4967   emit_insn (gen_floatdi<mode>2 (dest, tmp));
4968   DONE;
4970   [(set_attr "length" "12")
4971    (set_attr "type" "fpload")])
4973 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
4974   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4975         (unsigned_float:SFDF
4976          (zero_extend:DI
4977           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4978    (clobber (match_scratch:DI 2 "=0,d"))]
4979   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4980    && <SI_CONVERT_FP>"
4981   "#"
4982   ""
4983   [(pc)]
4984   "
4986   operands[1] = rs6000_address_for_fpconvert (operands[1]);
4987   if (GET_CODE (operands[2]) == SCRATCH)
4988     operands[2] = gen_reg_rtx (DImode);
4989   emit_insn (gen_lfiwzx (operands[2], operands[1]));
4990   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4991   DONE;
4993   [(set_attr "length" "8")
4994    (set_attr "type" "fpload")])
4996 ; For each of these conversions, there is a define_expand, a define_insn
4997 ; with a '#' template, and a define_split (with C code).  The idea is
4998 ; to allow constant folding with the template of the define_insn,
4999 ; then to have the insns split later (between sched1 and final).
5001 (define_expand "floatsidf2"
5002   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5003                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5004               (use (match_dup 2))
5005               (use (match_dup 3))
5006               (clobber (match_dup 4))
5007               (clobber (match_dup 5))
5008               (clobber (match_dup 6))])]
5009   "TARGET_HARD_FLOAT 
5010    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5011   "
5013   if (TARGET_E500_DOUBLE)
5014     {
5015       if (!REG_P (operands[1]))
5016         operands[1] = force_reg (SImode, operands[1]);
5017       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5018       DONE;
5019     }
5020   else if (TARGET_LFIWAX && TARGET_FCFID)
5021     {
5022       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5023       DONE;
5024     }
5025   else if (TARGET_FCFID)
5026     {
5027       rtx dreg = operands[1];
5028       if (!REG_P (dreg))
5029         dreg = force_reg (SImode, dreg);
5030       dreg = convert_to_mode (DImode, dreg, false);
5031       emit_insn (gen_floatdidf2 (operands[0], dreg));
5032       DONE;
5033     }
5035   if (!REG_P (operands[1]))
5036     operands[1] = force_reg (SImode, operands[1]);
5037   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5038   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5039   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5040   operands[5] = gen_reg_rtx (DFmode);
5041   operands[6] = gen_reg_rtx (SImode);
5044 (define_insn_and_split "*floatsidf2_internal"
5045   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5046         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5047    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5048    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5049    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5050    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5051    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5052   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5053   "#"
5054   ""
5055   [(pc)]
5056   "
5058   rtx lowword, highword;
5059   gcc_assert (MEM_P (operands[4]));
5060   highword = adjust_address (operands[4], SImode, 0);
5061   lowword = adjust_address (operands[4], SImode, 4);
5062   if (! WORDS_BIG_ENDIAN)
5063     std::swap (lowword, highword);
5065   emit_insn (gen_xorsi3 (operands[6], operands[1],
5066                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5067   emit_move_insn (lowword, operands[6]);
5068   emit_move_insn (highword, operands[2]);
5069   emit_move_insn (operands[5], operands[4]);
5070   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5071   DONE;
5073   [(set_attr "length" "24")
5074    (set_attr "type" "fp")])
5076 ;; If we don't have a direct conversion to single precision, don't enable this
5077 ;; conversion for 32-bit without fast math, because we don't have the insn to
5078 ;; generate the fixup swizzle to avoid double rounding problems.
5079 (define_expand "floatunssisf2"
5080   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5081         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5082   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5083    && (!TARGET_FPRS
5084        || (TARGET_FPRS
5085            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5086                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5087                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5088   "
5090   if (!TARGET_FPRS)
5091     {
5092       if (!REG_P (operands[1]))
5093         operands[1] = force_reg (SImode, operands[1]);
5094     }
5095   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5096     {
5097       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5098       DONE;
5099     }
5100   else
5101     {
5102       rtx dreg = operands[1];
5103       if (!REG_P (dreg))
5104         dreg = force_reg (SImode, dreg);
5105       dreg = convert_to_mode (DImode, dreg, true);
5106       emit_insn (gen_floatdisf2 (operands[0], dreg));
5107       DONE;
5108     }
5111 (define_expand "floatunssidf2"
5112   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5113                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5114               (use (match_dup 2))
5115               (use (match_dup 3))
5116               (clobber (match_dup 4))
5117               (clobber (match_dup 5))])]
5118   "TARGET_HARD_FLOAT
5119    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5120   "
5122   if (TARGET_E500_DOUBLE)
5123     {
5124       if (!REG_P (operands[1]))
5125         operands[1] = force_reg (SImode, operands[1]);
5126       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5127       DONE;
5128     }
5129   else if (TARGET_LFIWZX && TARGET_FCFID)
5130     {
5131       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5132       DONE;
5133     }
5134   else if (TARGET_FCFID)
5135     {
5136       rtx dreg = operands[1];
5137       if (!REG_P (dreg))
5138         dreg = force_reg (SImode, dreg);
5139       dreg = convert_to_mode (DImode, dreg, true);
5140       emit_insn (gen_floatdidf2 (operands[0], dreg));
5141       DONE;
5142     }
5144   if (!REG_P (operands[1]))
5145     operands[1] = force_reg (SImode, operands[1]);
5146   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5147   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5148   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5149   operands[5] = gen_reg_rtx (DFmode);
5152 (define_insn_and_split "*floatunssidf2_internal"
5153   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5154         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5155    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5156    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5157    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5158    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5159   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5160    && !(TARGET_FCFID && TARGET_POWERPC64)"
5161   "#"
5162   ""
5163   [(pc)]
5164   "
5166   rtx lowword, highword;
5167   gcc_assert (MEM_P (operands[4]));
5168   highword = adjust_address (operands[4], SImode, 0);
5169   lowword = adjust_address (operands[4], SImode, 4);
5170   if (! WORDS_BIG_ENDIAN)
5171     std::swap (lowword, highword);
5173   emit_move_insn (lowword, operands[1]);
5174   emit_move_insn (highword, operands[2]);
5175   emit_move_insn (operands[5], operands[4]);
5176   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5177   DONE;
5179   [(set_attr "length" "20")
5180    (set_attr "type" "fp")])
5182 (define_expand "fix_trunc<mode>si2"
5183   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5184         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5185   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5186   "
5188   if (!<E500_CONVERT>)
5189     {
5190       rtx tmp, stack;
5192       if (TARGET_STFIWX)
5193         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5194       else
5195         {
5196           tmp = gen_reg_rtx (DImode);
5197           stack = rs6000_allocate_stack_temp (DImode, true, false);
5198           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5199                                                       tmp, stack));
5200         }
5201       DONE;
5202     }
5205 ; Like the convert to float patterns, this insn must be split before
5206 ; register allocation so that it can allocate the memory slot if it
5207 ; needed
5208 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5209   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5210         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5211    (clobber (match_scratch:DI 2 "=d"))]
5212   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5213    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5214    && TARGET_STFIWX && can_create_pseudo_p ()"
5215   "#"
5216   ""
5217   [(pc)]
5219   rtx dest = operands[0];
5220   rtx src = operands[1];
5221   rtx tmp = operands[2];
5223   if (GET_CODE (tmp) == SCRATCH)
5224     tmp = gen_reg_rtx (DImode);
5226   emit_insn (gen_fctiwz_<mode> (tmp, src));
5227   if (MEM_P (dest))
5228     {
5229       dest = rs6000_address_for_fpconvert (dest);
5230       emit_insn (gen_stfiwx (dest, tmp));
5231       DONE;
5232     }
5233   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5234     {
5235       dest = gen_lowpart (DImode, dest);
5236       emit_move_insn (dest, tmp);
5237       DONE;
5238     }
5239   else
5240     {
5241       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5242       emit_insn (gen_stfiwx (stack, tmp));
5243       emit_move_insn (dest, stack);
5244       DONE;
5245     }
5247   [(set_attr "length" "12")
5248    (set_attr "type" "fp")])
5250 (define_insn_and_split "fix_trunc<mode>si2_internal"
5251   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5252         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5253    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5254    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5255   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5256   "#"
5257   ""
5258   [(pc)]
5259   "
5261   rtx lowword;
5262   gcc_assert (MEM_P (operands[3]));
5263   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5265   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5266   emit_move_insn (operands[3], operands[2]);
5267   emit_move_insn (operands[0], lowword);
5268   DONE;
5270   [(set_attr "length" "16")
5271    (set_attr "type" "fp")])
5273 (define_expand "fix_trunc<mode>di2"
5274   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5275         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5276   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5277    && TARGET_FCFID"
5278   "")
5280 (define_insn "*fix_trunc<mode>di2_fctidz"
5281   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5282         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5283   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5284     && TARGET_FCFID"
5285   "@
5286    fctidz %0,%1
5287    xscvdpsxds %x0,%x1"
5288   [(set_attr "type" "fp")])
5290 (define_expand "fixuns_trunc<mode>si2"
5291   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5292         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5293   "TARGET_HARD_FLOAT
5294    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5295        || <E500_CONVERT>)"
5296   "
5298   if (!<E500_CONVERT>)
5299     {
5300       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5301       DONE;
5302     }
5305 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5306   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5307         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5308    (clobber (match_scratch:DI 2 "=d"))]
5309   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5310    && TARGET_STFIWX && can_create_pseudo_p ()"
5311   "#"
5312   ""
5313   [(pc)]
5315   rtx dest = operands[0];
5316   rtx src = operands[1];
5317   rtx tmp = operands[2];
5319   if (GET_CODE (tmp) == SCRATCH)
5320     tmp = gen_reg_rtx (DImode);
5322   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5323   if (MEM_P (dest))
5324     {
5325       dest = rs6000_address_for_fpconvert (dest);
5326       emit_insn (gen_stfiwx (dest, tmp));
5327       DONE;
5328     }
5329   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5330     {
5331       dest = gen_lowpart (DImode, dest);
5332       emit_move_insn (dest, tmp);
5333       DONE;
5334     }
5335   else
5336     {
5337       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5338       emit_insn (gen_stfiwx (stack, tmp));
5339       emit_move_insn (dest, stack);
5340       DONE;
5341     }
5343   [(set_attr "length" "12")
5344    (set_attr "type" "fp")])
5346 (define_expand "fixuns_trunc<mode>di2"
5347   [(set (match_operand:DI 0 "register_operand" "")
5348         (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5349   "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5350   "")
5352 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5353   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5354         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5355   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5356     && TARGET_FCTIDUZ"
5357   "@
5358    fctiduz %0,%1
5359    xscvdpuxds %x0,%x1"
5360   [(set_attr "type" "fp")])
5362 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5363 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5364 ; because the first makes it clear that operand 0 is not live
5365 ; before the instruction.
5366 (define_insn "fctiwz_<mode>"
5367   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5368         (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5369                    UNSPEC_FCTIWZ))]
5370   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5371   "@
5372    fctiwz %0,%1
5373    xscvdpsxws %x0,%x1"
5374   [(set_attr "type" "fp")])
5376 (define_insn "fctiwuz_<mode>"
5377   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5378         (unspec:DI [(unsigned_fix:SI
5379                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5380                    UNSPEC_FCTIWUZ))]
5381   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5382   "@
5383    fctiwuz %0,%1
5384    xscvdpuxws %x0,%x1"
5385   [(set_attr "type" "fp")])
5387 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5388 ;; since the friz instruction does not truncate the value if the floating
5389 ;; point value is < LONG_MIN or > LONG_MAX.
5390 (define_insn "*friz"
5391   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5392         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5393   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5394    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5395   "@
5396    friz %0,%1
5397    xsrdpiz %x0,%x1"
5398   [(set_attr "type" "fp")])
5400 ;; Since FCTIWZ doesn't sign extend the upper bits, we have to do a store and a
5401 ;; load to properly sign extend the value, but at least doing a store, load
5402 ;; into a GPR to sign extend, a store from the GPR and a load back into the FPR
5403 ;; if we have 32-bit memory ops
5404 (define_insn_and_split "*round32<mode>2_fprs"
5405   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5406         (float:SFDF
5407          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5408    (clobber (match_scratch:DI 2 "=d"))
5409    (clobber (match_scratch:DI 3 "=d"))]
5410   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5411    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5412    && can_create_pseudo_p ()"
5413   "#"
5414   ""
5415   [(pc)]
5417   rtx dest = operands[0];
5418   rtx src = operands[1];
5419   rtx tmp1 = operands[2];
5420   rtx tmp2 = operands[3];
5421   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5423   if (GET_CODE (tmp1) == SCRATCH)
5424     tmp1 = gen_reg_rtx (DImode);
5425   if (GET_CODE (tmp2) == SCRATCH)
5426     tmp2 = gen_reg_rtx (DImode);
5428   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5429   emit_insn (gen_stfiwx (stack, tmp1));
5430   emit_insn (gen_lfiwax (tmp2, stack));
5431   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5432   DONE;
5434   [(set_attr "type" "fpload")
5435    (set_attr "length" "16")])
5437 (define_insn_and_split "*roundu32<mode>2_fprs"
5438   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5439         (unsigned_float:SFDF
5440          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5441    (clobber (match_scratch:DI 2 "=d"))
5442    (clobber (match_scratch:DI 3 "=d"))]
5443   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5444    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU
5445    && can_create_pseudo_p ()"
5446   "#"
5447   ""
5448   [(pc)]
5450   rtx dest = operands[0];
5451   rtx src = operands[1];
5452   rtx tmp1 = operands[2];
5453   rtx tmp2 = operands[3];
5454   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5456   if (GET_CODE (tmp1) == SCRATCH)
5457     tmp1 = gen_reg_rtx (DImode);
5458   if (GET_CODE (tmp2) == SCRATCH)
5459     tmp2 = gen_reg_rtx (DImode);
5461   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5462   emit_insn (gen_stfiwx (stack, tmp1));
5463   emit_insn (gen_lfiwzx (tmp2, stack));
5464   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5465   DONE;
5467   [(set_attr "type" "fpload")
5468    (set_attr "length" "16")])
5470 ;; No VSX equivalent to fctid
5471 (define_insn "lrint<mode>di2"
5472   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5473         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5474                    UNSPEC_FCTID))]
5475   "TARGET_<MODE>_FPR && TARGET_FPRND"
5476   "fctid %0,%1"
5477   [(set_attr "type" "fp")])
5479 (define_insn "btrunc<mode>2"
5480   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5481         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5482                      UNSPEC_FRIZ))]
5483   "TARGET_<MODE>_FPR && TARGET_FPRND"
5484   "@
5485    friz %0,%1
5486    xsrdpiz %x0,%x1"
5487   [(set_attr "type" "fp")
5488    (set_attr "fp_type" "fp_addsub_<Fs>")])
5490 (define_insn "ceil<mode>2"
5491   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5492         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5493                      UNSPEC_FRIP))]
5494   "TARGET_<MODE>_FPR && TARGET_FPRND"
5495   "@
5496    frip %0,%1
5497    xsrdpip %x0,%x1"
5498   [(set_attr "type" "fp")
5499    (set_attr "fp_type" "fp_addsub_<Fs>")])
5501 (define_insn "floor<mode>2"
5502   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5503         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5504                      UNSPEC_FRIM))]
5505   "TARGET_<MODE>_FPR && TARGET_FPRND"
5506   "@
5507    frim %0,%1
5508    xsrdpim %x0,%x1"
5509   [(set_attr "type" "fp")
5510    (set_attr "fp_type" "fp_addsub_<Fs>")])
5512 ;; No VSX equivalent to frin
5513 (define_insn "round<mode>2"
5514   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5515         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5516                      UNSPEC_FRIN))]
5517   "TARGET_<MODE>_FPR && TARGET_FPRND"
5518   "frin %0,%1"
5519   [(set_attr "type" "fp")
5520    (set_attr "fp_type" "fp_addsub_<Fs>")])
5522 (define_insn "*xsrdpi<mode>2"
5523   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5524         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5525                      UNSPEC_XSRDPI))]
5526   "TARGET_<MODE>_FPR && TARGET_VSX"
5527   "xsrdpi %x0,%x1"
5528   [(set_attr "type" "fp")
5529    (set_attr "fp_type" "fp_addsub_<Fs>")])
5531 (define_expand "lround<mode>di2"
5532   [(set (match_dup 2)
5533         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5534                      UNSPEC_XSRDPI))
5535    (set (match_operand:DI 0 "gpc_reg_operand" "")
5536         (unspec:DI [(match_dup 2)]
5537                    UNSPEC_FCTID))]
5538   "TARGET_<MODE>_FPR && TARGET_VSX"
5540   operands[2] = gen_reg_rtx (<MODE>mode);
5543 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5544 (define_insn "stfiwx"
5545   [(set (match_operand:SI 0 "memory_operand" "=Z")
5546         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
5547                    UNSPEC_STFIWX))]
5548   "TARGET_PPC_GFXOPT"
5549   "stfiwx %1,%y0"
5550   [(set_attr "type" "fpstore")])
5552 ;; If we don't have a direct conversion to single precision, don't enable this
5553 ;; conversion for 32-bit without fast math, because we don't have the insn to
5554 ;; generate the fixup swizzle to avoid double rounding problems.
5555 (define_expand "floatsisf2"
5556   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5557         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5558   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5559    && (!TARGET_FPRS
5560        || (TARGET_FPRS
5561            && ((TARGET_FCFIDS && TARGET_LFIWAX)
5562                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5563                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5564   "
5566   if (!TARGET_FPRS)
5567     {
5568       if (!REG_P (operands[1]))
5569         operands[1] = force_reg (SImode, operands[1]);
5570     }
5571   else if (TARGET_FCFIDS && TARGET_LFIWAX)
5572     {
5573       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5574       DONE;
5575     }
5576   else if (TARGET_FCFID && TARGET_LFIWAX)
5577     {
5578       rtx dfreg = gen_reg_rtx (DFmode);
5579       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5580       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5581       DONE;
5582     }
5583   else
5584     {
5585       rtx dreg = operands[1];
5586       if (!REG_P (dreg))
5587         dreg = force_reg (SImode, dreg);
5588       dreg = convert_to_mode (DImode, dreg, false);
5589       emit_insn (gen_floatdisf2 (operands[0], dreg));
5590       DONE;
5591     }
5594 (define_expand "floatdidf2"
5595   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5596         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5597   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5598   "")
5600 (define_insn "*floatdidf2_fpr"
5601   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5602         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5603   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5604   "@
5605    fcfid %0,%1
5606    xscvsxddp %x0,%x1"
5607   [(set_attr "type" "fp")])
5609 ; Allow the combiner to merge source memory operands to the conversion so that
5610 ; the optimizer/register allocator doesn't try to load the value too early in a
5611 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5612 ; hit.  We will split after reload to avoid the trip through the GPRs
5614 (define_insn_and_split "*floatdidf2_mem"
5615   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5616         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5617    (clobber (match_scratch:DI 2 "=d,wi"))]
5618   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5619   "#"
5620   "&& reload_completed"
5621   [(set (match_dup 2) (match_dup 1))
5622    (set (match_dup 0) (float:DF (match_dup 2)))]
5623   ""
5624   [(set_attr "length" "8")
5625    (set_attr "type" "fpload")])
5627 (define_expand "floatunsdidf2"
5628   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5629         (unsigned_float:DF
5630          (match_operand:DI 1 "gpc_reg_operand" "")))]
5631   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5632   "")
5634 (define_insn "*floatunsdidf2_fcfidu"
5635   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5636         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5637   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5638   "@
5639    fcfidu %0,%1
5640    xscvuxddp %x0,%x1"
5641   [(set_attr "type" "fp")
5642    (set_attr "length" "4")])
5644 (define_insn_and_split "*floatunsdidf2_mem"
5645   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5646         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5647    (clobber (match_scratch:DI 2 "=d,wi"))]
5648   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5649   "#"
5650   "&& reload_completed"
5651   [(set (match_dup 2) (match_dup 1))
5652    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5653   ""
5654   [(set_attr "length" "8")
5655    (set_attr "type" "fpload")])
5657 (define_expand "floatdisf2"
5658   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5659         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5660   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5661    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5662   "
5664   if (!TARGET_FCFIDS)
5665     {
5666       rtx val = operands[1];
5667       if (!flag_unsafe_math_optimizations)
5668         {
5669           rtx label = gen_label_rtx ();
5670           val = gen_reg_rtx (DImode);
5671           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5672           emit_label (label);
5673         }
5674       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5675       DONE;
5676     }
5679 (define_insn "floatdisf2_fcfids"
5680   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5681         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5682   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5683    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5684   "@
5685    fcfids %0,%1
5686    xscvsxdsp %x0,%x1"
5687   [(set_attr "type" "fp")])
5689 (define_insn_and_split "*floatdisf2_mem"
5690   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5691         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5692    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5693   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5694    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5695   "#"
5696   "&& reload_completed"
5697   [(pc)]
5698   "
5700   emit_move_insn (operands[2], operands[1]);
5701   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5702   DONE;
5704   [(set_attr "length" "8")])
5706 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5707 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5708 ;; from double rounding.
5709 ;; Instead of creating a new cpu type for two FP operations, just use fp
5710 (define_insn_and_split "floatdisf2_internal1"
5711   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5712         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5713    (clobber (match_scratch:DF 2 "=d"))]
5714   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5715    && !TARGET_FCFIDS"
5716   "#"
5717   "&& reload_completed"
5718   [(set (match_dup 2)
5719         (float:DF (match_dup 1)))
5720    (set (match_dup 0)
5721         (float_truncate:SF (match_dup 2)))]
5722   ""
5723   [(set_attr "length" "8")
5724    (set_attr "type" "fp")])
5726 ;; Twiddles bits to avoid double rounding.
5727 ;; Bits that might be truncated when converting to DFmode are replaced
5728 ;; by a bit that won't be lost at that stage, but is below the SFmode
5729 ;; rounding position.
5730 (define_expand "floatdisf2_internal2"
5731   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5732                                               (const_int 53)))
5733               (clobber (reg:DI CA_REGNO))])
5734    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5735                                            (const_int 2047)))
5736    (set (match_dup 3) (plus:DI (match_dup 3)
5737                                (const_int 1)))
5738    (set (match_dup 0) (plus:DI (match_dup 0)
5739                                (const_int 2047)))
5740    (set (match_dup 4) (compare:CCUNS (match_dup 3)
5741                                      (const_int 2)))
5742    (set (match_dup 0) (ior:DI (match_dup 0)
5743                               (match_dup 1)))
5744    (set (match_dup 0) (and:DI (match_dup 0)
5745                               (const_int -2048)))
5746    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5747                            (label_ref (match_operand:DI 2 "" ""))
5748                            (pc)))
5749    (set (match_dup 0) (match_dup 1))]
5750   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5751    && !TARGET_FCFIDS"
5752   "
5754   operands[3] = gen_reg_rtx (DImode);
5755   operands[4] = gen_reg_rtx (CCUNSmode);
5758 (define_expand "floatunsdisf2"
5759   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5760         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5761   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5762    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5763   "")
5765 (define_insn "floatunsdisf2_fcfidus"
5766   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5767         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5768   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5769    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5770   "@
5771    fcfidus %0,%1
5772    xscvuxdsp %x0,%x1"
5773   [(set_attr "type" "fp")])
5775 (define_insn_and_split "*floatunsdisf2_mem"
5776   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5777         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5778    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5779   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5780    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5781   "#"
5782   "&& reload_completed"
5783   [(pc)]
5784   "
5786   emit_move_insn (operands[2], operands[1]);
5787   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
5788   DONE;
5790   [(set_attr "length" "8")
5791    (set_attr "type" "fpload")])
5793 ;; Define the TImode operations that can be done in a small number
5794 ;; of instructions.  The & constraints are to prevent the register
5795 ;; allocator from allocating registers that overlap with the inputs
5796 ;; (for example, having an input in 7,8 and an output in 6,7).  We
5797 ;; also allow for the output being the same as one of the inputs.
5799 (define_expand "addti3"
5800   [(set (match_operand:TI 0 "gpc_reg_operand" "")
5801         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
5802                  (match_operand:TI 2 "reg_or_short_operand" "")))]
5803   "TARGET_64BIT"
5805   rtx lo0 = gen_lowpart (DImode, operands[0]);
5806   rtx lo1 = gen_lowpart (DImode, operands[1]);
5807   rtx lo2 = gen_lowpart (DImode, operands[2]);
5808   rtx hi0 = gen_highpart (DImode, operands[0]);
5809   rtx hi1 = gen_highpart (DImode, operands[1]);
5810   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
5812   if (!reg_or_short_operand (lo2, DImode))
5813     lo2 = force_reg (DImode, lo2);
5814   if (!adde_operand (hi2, DImode))
5815     hi2 = force_reg (DImode, hi2);
5817   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
5818   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
5819   DONE;
5822 (define_expand "subti3"
5823   [(set (match_operand:TI 0 "gpc_reg_operand" "")
5824         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
5825                   (match_operand:TI 2 "gpc_reg_operand" "")))]
5826   "TARGET_64BIT"
5828   rtx lo0 = gen_lowpart (DImode, operands[0]);
5829   rtx lo1 = gen_lowpart (DImode, operands[1]);
5830   rtx lo2 = gen_lowpart (DImode, operands[2]);
5831   rtx hi0 = gen_highpart (DImode, operands[0]);
5832   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
5833   rtx hi2 = gen_highpart (DImode, operands[2]);
5835   if (!reg_or_short_operand (lo1, DImode))
5836     lo1 = force_reg (DImode, lo1);
5837   if (!adde_operand (hi1, DImode))
5838     hi1 = force_reg (DImode, hi1);
5840   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
5841   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
5842   DONE;
5845 ;; 128-bit logical operations expanders
5847 (define_expand "and<mode>3"
5848   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5849         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5850                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5851   ""
5852   "")
5854 (define_expand "ior<mode>3"
5855   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5856         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5857                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5858   ""
5859   "")
5861 (define_expand "xor<mode>3"
5862   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5863         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5864                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5865   ""
5866   "")
5868 (define_expand "one_cmpl<mode>2"
5869   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5870         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5871   ""
5872   "")
5874 (define_expand "nor<mode>3"
5875   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5876         (and:BOOL_128
5877          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5878          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5879   ""
5880   "")
5882 (define_expand "andc<mode>3"
5883   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5884         (and:BOOL_128
5885          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5886          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5887   ""
5888   "")
5890 ;; Power8 vector logical instructions.
5891 (define_expand "eqv<mode>3"
5892   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5893         (not:BOOL_128
5894          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5895                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5896   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5897   "")
5899 ;; Rewrite nand into canonical form
5900 (define_expand "nand<mode>3"
5901   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5902         (ior:BOOL_128
5903          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5904          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5905   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5906   "")
5908 ;; The canonical form is to have the negated element first, so we need to
5909 ;; reverse arguments.
5910 (define_expand "orc<mode>3"
5911   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5912         (ior:BOOL_128
5913          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5914          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5915   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5916   "")
5918 ;; 128-bit logical operations insns and split operations
5919 (define_insn_and_split "*and<mode>3_internal"
5920   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5921         (and:BOOL_128
5922          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
5923          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
5924   ""
5926   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
5927     return "xxland %x0,%x1,%x2";
5929   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
5930     return "vand %0,%1,%2";
5932   return "#";
5934   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
5935   [(const_int 0)]
5937   rs6000_split_logical (operands, AND, false, false, false);
5938   DONE;
5940   [(set (attr "type")
5941       (if_then_else
5942         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5943         (const_string "vecsimple")
5944         (const_string "integer")))
5945    (set (attr "length")
5946       (if_then_else
5947         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5948         (const_string "4")
5949         (if_then_else
5950          (match_test "TARGET_POWERPC64")
5951          (const_string "8")
5952          (const_string "16"))))])
5954 ;; 128-bit IOR/XOR
5955 (define_insn_and_split "*bool<mode>3_internal"
5956   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5957         (match_operator:BOOL_128 3 "boolean_or_operator"
5958          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
5959           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
5960   ""
5962   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
5963     return "xxl%q3 %x0,%x1,%x2";
5965   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
5966     return "v%q3 %0,%1,%2";
5968   return "#";
5970   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
5971   [(const_int 0)]
5973   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
5974   DONE;
5976   [(set (attr "type")
5977       (if_then_else
5978         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5979         (const_string "vecsimple")
5980         (const_string "integer")))
5981    (set (attr "length")
5982       (if_then_else
5983         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5984         (const_string "4")
5985         (if_then_else
5986          (match_test "TARGET_POWERPC64")
5987          (const_string "8")
5988          (const_string "16"))))])
5990 ;; 128-bit ANDC/ORC
5991 (define_insn_and_split "*boolc<mode>3_internal1"
5992   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5993         (match_operator:BOOL_128 3 "boolean_operator"
5994          [(not:BOOL_128
5995            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
5996           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
5997   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
5999   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6000     return "xxl%q3 %x0,%x1,%x2";
6002   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6003     return "v%q3 %0,%1,%2";
6005   return "#";
6007   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6008    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6009   [(const_int 0)]
6011   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6012   DONE;
6014   [(set (attr "type")
6015       (if_then_else
6016         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6017         (const_string "vecsimple")
6018         (const_string "integer")))
6019    (set (attr "length")
6020       (if_then_else
6021         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6022         (const_string "4")
6023         (if_then_else
6024          (match_test "TARGET_POWERPC64")
6025          (const_string "8")
6026          (const_string "16"))))])
6028 (define_insn_and_split "*boolc<mode>3_internal2"
6029   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6030         (match_operator:TI2 3 "boolean_operator"
6031          [(not:TI2
6032            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6033           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6034   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6035   "#"
6036   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6037   [(const_int 0)]
6039   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6040   DONE;
6042   [(set_attr "type" "integer")
6043    (set (attr "length")
6044         (if_then_else
6045          (match_test "TARGET_POWERPC64")
6046          (const_string "8")
6047          (const_string "16")))])
6049 ;; 128-bit NAND/NOR
6050 (define_insn_and_split "*boolcc<mode>3_internal1"
6051   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6052         (match_operator:BOOL_128 3 "boolean_operator"
6053          [(not:BOOL_128
6054            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6055           (not:BOOL_128
6056            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6057   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6059   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6060     return "xxl%q3 %x0,%x1,%x2";
6062   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6063     return "v%q3 %0,%1,%2";
6065   return "#";
6067   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6068    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6069   [(const_int 0)]
6071   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6072   DONE;
6074   [(set (attr "type")
6075       (if_then_else
6076         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6077         (const_string "vecsimple")
6078         (const_string "integer")))
6079    (set (attr "length")
6080       (if_then_else
6081         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6082         (const_string "4")
6083         (if_then_else
6084          (match_test "TARGET_POWERPC64")
6085          (const_string "8")
6086          (const_string "16"))))])
6088 (define_insn_and_split "*boolcc<mode>3_internal2"
6089   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6090         (match_operator:TI2 3 "boolean_operator"
6091          [(not:TI2
6092            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6093           (not:TI2
6094            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6095   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6096   "#"
6097   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6098   [(const_int 0)]
6100   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6101   DONE;
6103   [(set_attr "type" "integer")
6104    (set (attr "length")
6105         (if_then_else
6106          (match_test "TARGET_POWERPC64")
6107          (const_string "8")
6108          (const_string "16")))])
6111 ;; 128-bit EQV
6112 (define_insn_and_split "*eqv<mode>3_internal1"
6113   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6114         (not:BOOL_128
6115          (xor:BOOL_128
6116           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6117           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6118   "TARGET_P8_VECTOR"
6120   if (vsx_register_operand (operands[0], <MODE>mode))
6121     return "xxleqv %x0,%x1,%x2";
6123   return "#";
6125   "TARGET_P8_VECTOR && reload_completed
6126    && int_reg_operand (operands[0], <MODE>mode)"
6127   [(const_int 0)]
6129   rs6000_split_logical (operands, XOR, true, false, false);
6130   DONE;
6132   [(set (attr "type")
6133       (if_then_else
6134         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6135         (const_string "vecsimple")
6136         (const_string "integer")))
6137    (set (attr "length")
6138       (if_then_else
6139         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6140         (const_string "4")
6141         (if_then_else
6142          (match_test "TARGET_POWERPC64")
6143          (const_string "8")
6144          (const_string "16"))))])
6146 (define_insn_and_split "*eqv<mode>3_internal2"
6147   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6148         (not:TI2
6149          (xor:TI2
6150           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6151           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6152   "!TARGET_P8_VECTOR"
6153   "#"
6154   "reload_completed && !TARGET_P8_VECTOR"
6155   [(const_int 0)]
6157   rs6000_split_logical (operands, XOR, true, false, false);
6158   DONE;
6160   [(set_attr "type" "integer")
6161    (set (attr "length")
6162         (if_then_else
6163          (match_test "TARGET_POWERPC64")
6164          (const_string "8")
6165          (const_string "16")))])
6167 ;; 128-bit one's complement
6168 (define_insn_and_split "*one_cmpl<mode>3_internal"
6169   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6170         (not:BOOL_128
6171           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6172   ""
6174   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6175     return "xxlnor %x0,%x1,%x1";
6177   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6178     return "vnor %0,%1,%1";
6180   return "#";
6182   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6183   [(const_int 0)]
6185   rs6000_split_logical (operands, NOT, false, false, false);
6186   DONE;
6188   [(set (attr "type")
6189       (if_then_else
6190         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6191         (const_string "vecsimple")
6192         (const_string "integer")))
6193    (set (attr "length")
6194       (if_then_else
6195         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6196         (const_string "4")
6197         (if_then_else
6198          (match_test "TARGET_POWERPC64")
6199          (const_string "8")
6200          (const_string "16"))))])
6203 ;; Now define ways of moving data around.
6205 ;; Set up a register with a value from the GOT table
6207 (define_expand "movsi_got"
6208   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6209         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6210                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6211   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6212   "
6214   if (GET_CODE (operands[1]) == CONST)
6215     {
6216       rtx offset = const0_rtx;
6217       HOST_WIDE_INT value;
6219       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6220       value = INTVAL (offset);
6221       if (value != 0)
6222         {
6223           rtx tmp = (!can_create_pseudo_p ()
6224                      ? operands[0]
6225                      : gen_reg_rtx (Pmode));
6226           emit_insn (gen_movsi_got (tmp, operands[1]));
6227           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6228           DONE;
6229         }
6230     }
6232   operands[2] = rs6000_got_register (operands[1]);
6235 (define_insn "*movsi_got_internal"
6236   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6237         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6238                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6239                    UNSPEC_MOVSI_GOT))]
6240   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6241   "lwz %0,%a1@got(%2)"
6242   [(set_attr "type" "load")])
6244 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6245 ;; didn't get allocated to a hard register.
6246 (define_split
6247   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6248         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6249                     (match_operand:SI 2 "memory_operand" "")]
6250                    UNSPEC_MOVSI_GOT))]
6251   "DEFAULT_ABI == ABI_V4
6252     && flag_pic == 1
6253     && (reload_in_progress || reload_completed)"
6254   [(set (match_dup 0) (match_dup 2))
6255    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6256                                  UNSPEC_MOVSI_GOT))]
6257   "")
6259 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6260 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6261 ;; and this is even supposed to be faster, but it is simpler not to get
6262 ;; integers in the TOC.
6263 (define_insn "movsi_low"
6264   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6265         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6266                            (match_operand 2 "" ""))))]
6267   "TARGET_MACHO && ! TARGET_64BIT"
6268   "lwz %0,lo16(%2)(%1)"
6269   [(set_attr "type" "load")
6270    (set_attr "length" "4")])
6272 (define_insn "*movsi_internal1"
6273   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6274         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6275   "!TARGET_SINGLE_FPU &&
6276    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6277   "@
6278    mr %0,%1
6279    la %0,%a1
6280    lwz%U1%X1 %0,%1
6281    stw%U0%X0 %1,%0
6282    li %0,%1
6283    lis %0,%v1
6284    #
6285    mf%1 %0
6286    mt%0 %1
6287    mt%0 %1
6288    nop"
6289   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6290    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6292 (define_insn "*movsi_internal1_single"
6293   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6294         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6295   "TARGET_SINGLE_FPU &&
6296    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6297   "@
6298    mr %0,%1
6299    la %0,%a1
6300    lwz%U1%X1 %0,%1
6301    stw%U0%X0 %1,%0
6302    li %0,%1
6303    lis %0,%v1
6304    #
6305    mf%1 %0
6306    mt%0 %1
6307    mt%0 %1
6308    nop
6309    stfs%U0%X0 %1,%0
6310    lfs%U1%X1 %0,%1"
6311   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6312    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6314 ;; Split a load of a large constant into the appropriate two-insn
6315 ;; sequence.
6317 (define_split
6318   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6319         (match_operand:SI 1 "const_int_operand" ""))]
6320   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6321    && (INTVAL (operands[1]) & 0xffff) != 0"
6322   [(set (match_dup 0)
6323         (match_dup 2))
6324    (set (match_dup 0)
6325         (ior:SI (match_dup 0)
6326                 (match_dup 3)))]
6327   "
6329   if (rs6000_emit_set_const (operands[0], operands[1]))
6330     DONE;
6331   else
6332     FAIL;
6335 (define_insn "*mov<mode>_internal2"
6336   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6337         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6338                     (const_int 0)))
6339    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6340   ""
6341   "@
6342    cmp<wd>i %2,%0,0
6343    mr. %0,%1
6344    #"
6345   [(set_attr "type" "cmp,logical,cmp")
6346    (set_attr "dot" "yes")
6347    (set_attr "length" "4,4,8")])
6349 (define_split
6350   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6351         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6352                     (const_int 0)))
6353    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6354   "reload_completed"
6355   [(set (match_dup 0) (match_dup 1))
6356    (set (match_dup 2)
6357         (compare:CC (match_dup 0)
6358                     (const_int 0)))]
6359   "")
6361 (define_insn "*movhi_internal"
6362   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6363         (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6364   "gpc_reg_operand (operands[0], HImode)
6365    || gpc_reg_operand (operands[1], HImode)"
6366   "@
6367    mr %0,%1
6368    lhz%U1%X1 %0,%1
6369    sth%U0%X0 %1,%0
6370    li %0,%w1
6371    mf%1 %0
6372    mt%0 %1
6373    nop"
6374   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6376 (define_expand "mov<mode>"
6377   [(set (match_operand:INT 0 "general_operand" "")
6378         (match_operand:INT 1 "any_operand" ""))]
6379   ""
6380   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6382 (define_insn "*movqi_internal"
6383   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6384         (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6385   "gpc_reg_operand (operands[0], QImode)
6386    || gpc_reg_operand (operands[1], QImode)"
6387   "@
6388    mr %0,%1
6389    lbz%U1%X1 %0,%1
6390    stb%U0%X0 %1,%0
6391    li %0,%1
6392    mf%1 %0
6393    mt%0 %1
6394    nop"
6395   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6397 ;; Here is how to move condition codes around.  When we store CC data in
6398 ;; an integer register or memory, we store just the high-order 4 bits.
6399 ;; This lets us not shift in the most common case of CR0.
6400 (define_expand "movcc"
6401   [(set (match_operand:CC 0 "nonimmediate_operand" "")
6402         (match_operand:CC 1 "nonimmediate_operand" ""))]
6403   ""
6404   "")
6406 (define_insn "*movcc_internal1"
6407   [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6408         (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6409   "register_operand (operands[0], CCmode)
6410    || register_operand (operands[1], CCmode)"
6411   "@
6412    mcrf %0,%1
6413    mtcrf 128,%1
6414    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6415    crxor %0,%0,%0
6416    mfcr %0%Q1
6417    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6418    mr %0,%1
6419    li %0,%1
6420    mf%1 %0
6421    mt%0 %1
6422    lwz%U1%X1 %0,%1
6423    stw%U0%X0 %1,%0"
6424   [(set (attr "type")
6425      (cond [(eq_attr "alternative" "0,3")
6426                 (const_string "cr_logical")
6427             (eq_attr "alternative" "1,2")
6428                 (const_string "mtcr")
6429             (eq_attr "alternative" "6,7")
6430                 (const_string "integer")
6431             (eq_attr "alternative" "8")
6432                 (const_string "mfjmpr")
6433             (eq_attr "alternative" "9")
6434                 (const_string "mtjmpr")
6435             (eq_attr "alternative" "10")
6436                 (const_string "load")
6437             (eq_attr "alternative" "11")
6438                 (const_string "store")
6439             (match_test "TARGET_MFCRF")
6440                 (const_string "mfcrf")
6441            ]
6442         (const_string "mfcr")))
6443    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6445 ;; For floating-point, we normally deal with the floating-point registers
6446 ;; unless -msoft-float is used.  The sole exception is that parameter passing
6447 ;; can produce floating-point values in fixed-point registers.  Unless the
6448 ;; value is a simple constant or already in memory, we deal with this by
6449 ;; allocating memory and copying the value explicitly via that memory location.
6451 ;; Move 32-bit binary/decimal floating point
6452 (define_expand "mov<mode>"
6453   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6454         (match_operand:FMOVE32 1 "any_operand" ""))]
6455   "<fmove_ok>"
6456   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6458 (define_split
6459   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6460         (match_operand:FMOVE32 1 "const_double_operand" ""))]
6461   "reload_completed
6462    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6463        || (GET_CODE (operands[0]) == SUBREG
6464            && GET_CODE (SUBREG_REG (operands[0])) == REG
6465            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6466   [(set (match_dup 2) (match_dup 3))]
6467   "
6469   long l;
6471   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6473   if (! TARGET_POWERPC64)
6474     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6475   else
6476     operands[2] = gen_lowpart (SImode, operands[0]);
6478   operands[3] = gen_int_mode (l, SImode);
6481 (define_insn "mov<mode>_hardfloat"
6482   [(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")
6483         (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,j,<f32_lm>,<f32_lm2>,<f32_sr>,<f32_sr2>,Z,<f32_av>,r,<f32_dm>,r,h,0"))]
6484   "(gpc_reg_operand (operands[0], <MODE>mode)
6485    || gpc_reg_operand (operands[1], <MODE>mode))
6486    && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6487   "@
6488    mr %0,%1
6489    lwz%U1%X1 %0,%1
6490    stw%U0%X0 %1,%0
6491    fmr %0,%1
6492    xscpsgndp %x0,%x1,%x1
6493    xxlxor %x0,%x0,%x0
6494    li %0,0
6495    <f32_li>
6496    <f32_li2>
6497    <f32_si>
6498    <f32_si2>
6499    <f32_lv>
6500    <f32_sv>
6501    mtvsrwz %x0,%1
6502    mfvsrwz %0,%x1
6503    mt%0 %1
6504    mf%1 %0
6505    nop"
6506   [(set_attr "type" "*,load,store,fp,fp,vecsimple,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*")
6507    (set_attr "length" "4")])
6509 (define_insn "*mov<mode>_softfloat"
6510   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6511         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6512   "(gpc_reg_operand (operands[0], <MODE>mode)
6513    || gpc_reg_operand (operands[1], <MODE>mode))
6514    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6515   "@
6516    mr %0,%1
6517    mt%0 %1
6518    mf%1 %0
6519    lwz%U1%X1 %0,%1
6520    stw%U0%X0 %1,%0
6521    li %0,%1
6522    lis %0,%v1
6523    #
6524    #
6525    nop"
6526   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6527    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6530 ;; Move 64-bit binary/decimal floating point
6531 (define_expand "mov<mode>"
6532   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6533         (match_operand:FMOVE64 1 "any_operand" ""))]
6534   ""
6535   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6537 (define_split
6538   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6539         (match_operand:FMOVE64 1 "const_int_operand" ""))]
6540   "! TARGET_POWERPC64 && reload_completed
6541    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6542        || (GET_CODE (operands[0]) == SUBREG
6543            && GET_CODE (SUBREG_REG (operands[0])) == REG
6544            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6545   [(set (match_dup 2) (match_dup 4))
6546    (set (match_dup 3) (match_dup 1))]
6547   "
6549   int endian = (WORDS_BIG_ENDIAN == 0);
6550   HOST_WIDE_INT value = INTVAL (operands[1]);
6552   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6553   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6554   operands[4] = GEN_INT (value >> 32);
6555   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6558 (define_split
6559   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6560         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6561   "! TARGET_POWERPC64 && reload_completed
6562    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6563        || (GET_CODE (operands[0]) == SUBREG
6564            && GET_CODE (SUBREG_REG (operands[0])) == REG
6565            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6566   [(set (match_dup 2) (match_dup 4))
6567    (set (match_dup 3) (match_dup 5))]
6568   "
6570   int endian = (WORDS_BIG_ENDIAN == 0);
6571   long l[2];
6573   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6575   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6576   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6577   operands[4] = gen_int_mode (l[endian], SImode);
6578   operands[5] = gen_int_mode (l[1 - endian], SImode);
6581 (define_split
6582   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6583         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6584   "TARGET_POWERPC64 && reload_completed
6585    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6586        || (GET_CODE (operands[0]) == SUBREG
6587            && GET_CODE (SUBREG_REG (operands[0])) == REG
6588            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6589   [(set (match_dup 2) (match_dup 3))]
6590   "
6592   int endian = (WORDS_BIG_ENDIAN == 0);
6593   long l[2];
6594   HOST_WIDE_INT val;
6596   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6598   operands[2] = gen_lowpart (DImode, operands[0]);
6599   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
6600   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6601          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6603   operands[3] = gen_int_mode (val, DImode);
6606 ;; Don't have reload use general registers to load a constant.  It is
6607 ;; less efficient than loading the constant into an FP register, since
6608 ;; it will probably be used there.
6610 ;; The move constraints are ordered to prefer floating point registers before
6611 ;; general purpose registers to avoid doing a store and a load to get the value
6612 ;; into a floating point register when it is needed for a floating point
6613 ;; operation.  Prefer traditional floating point registers over VSX registers,
6614 ;; since the D-form version of the memory instructions does not need a GPR for
6615 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6616 ;; registers.
6618 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6619 ;; except for 0.0 which can be created on VSX with an xor instruction.
6621 (define_insn "*mov<mode>_hardfloat32"
6622   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,o,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6623         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,o,<f64_p9>,<f64_vsx>,j,j,r,Y,r"))]
6624   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
6625    && (gpc_reg_operand (operands[0], <MODE>mode)
6626        || gpc_reg_operand (operands[1], <MODE>mode))"
6627   "@
6628    stfd%U0%X0 %1,%0
6629    lfd%U1%X1 %0,%1
6630    fmr %0,%1
6631    lxsd%U1x %x0,%y1
6632    stxsd%U0x %x1,%y0
6633    lxsd %0,%1
6634    stxsd %1,%0
6635    xxlor %x0,%x1,%x1
6636    xxlxor %x0,%x0,%x0
6637    #
6638    #
6639    #
6640    #"
6641   [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,two,store,load,two")
6642    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6644 (define_insn "*mov<mode>_softfloat32"
6645   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6646         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6647   "! TARGET_POWERPC64 
6648    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
6649        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6650        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6651    && (gpc_reg_operand (operands[0], <MODE>mode)
6652        || gpc_reg_operand (operands[1], <MODE>mode))"
6653   "#"
6654   [(set_attr "type" "store,load,two,*,*,*")
6655    (set_attr "length" "8,8,8,8,12,16")])
6657 ; ld/std require word-aligned displacements -> 'Y' constraint.
6658 ; List Y->r and r->Y before r->r for reload.
6659 (define_insn "*mov<mode>_hardfloat64"
6660   [(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>")
6661         (match_operand:FMOVE64 1 "input_operand" "d,m,d,o,<f64_p9>,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
6662   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6663    && (gpc_reg_operand (operands[0], <MODE>mode)
6664        || gpc_reg_operand (operands[1], <MODE>mode))"
6665   "@
6666    stfd%U0%X0 %1,%0
6667    lfd%U1%X1 %0,%1
6668    fmr %0,%1
6669    lxsd %0,%1
6670    stxsd %1,%0
6671    lxsd%U1x %x0,%y1
6672    stxsd%U0x %x1,%y0
6673    xxlor %x0,%x1,%x1
6674    xxlxor %x0,%x0,%x0
6675    li %0,0
6676    std%U0%X0 %1,%0
6677    ld%U1%X1 %0,%1
6678    mr %0,%1
6679    mt%0 %1
6680    mf%1 %0
6681    nop
6682    mftgpr %0,%1
6683    mffgpr %0,%1
6684    mfvsrd %0,%x1
6685    mtvsrd %x0,%1"
6686   [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6687    (set_attr "length" "4")])
6689 (define_insn "*mov<mode>_softfloat64"
6690   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6691         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6692   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6693    && (gpc_reg_operand (operands[0], <MODE>mode)
6694        || gpc_reg_operand (operands[1], <MODE>mode))"
6695   "@
6696    std%U0%X0 %1,%0
6697    ld%U1%X1 %0,%1
6698    mr %0,%1
6699    mt%0 %1
6700    mf%1 %0
6701    #
6702    #
6703    #
6704    nop"
6705   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6706    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6708 (define_expand "mov<mode>"
6709   [(set (match_operand:FMOVE128 0 "general_operand" "")
6710         (match_operand:FMOVE128 1 "any_operand" ""))]
6711   ""
6712   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6714 ;; It's important to list Y->r and r->Y before r->r because otherwise
6715 ;; reload, given m->r, will try to pick r->r and reload it, which
6716 ;; doesn't make progress.
6718 ;; We can't split little endian direct moves of TDmode, because the words are
6719 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
6720 ;; problematical.  Don't allow direct move for this case.
6722 (define_insn_and_split "*mov<mode>_64bit_dm"
6723   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r,r,wm")
6724         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,j,r,jY,r,wm,r"))]
6725   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6726    && FLOAT128_2REG_P (<MODE>mode)
6727    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6728    && (gpc_reg_operand (operands[0], <MODE>mode)
6729        || gpc_reg_operand (operands[1], <MODE>mode))"
6730   "#"
6731   "&& reload_completed"
6732   [(pc)]
6733 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6734   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6736 (define_insn_and_split "*movtd_64bit_nodm"
6737   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
6738         (match_operand:TD 1 "input_operand" "d,m,d,j,r,jY,r"))]
6739   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6740    && (gpc_reg_operand (operands[0], TDmode)
6741        || gpc_reg_operand (operands[1], TDmode))"
6742   "#"
6743   "&& reload_completed"
6744   [(pc)]
6745 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6746   [(set_attr "length" "8,8,8,8,12,12,8")])
6748 (define_insn_and_split "*mov<mode>_32bit"
6749   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
6750         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,j,r,jY,r"))]
6751   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
6752    && (FLOAT128_2REG_P (<MODE>mode)
6753        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
6754        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
6755    && (gpc_reg_operand (operands[0], <MODE>mode)
6756        || gpc_reg_operand (operands[1], <MODE>mode))"
6757   "#"
6758   "&& reload_completed"
6759   [(pc)]
6760 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6761   [(set_attr "length" "8,8,8,8,20,20,16")])
6763 (define_insn_and_split "*mov<mode>_softfloat"
6764   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
6765         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
6766   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
6767    && (gpc_reg_operand (operands[0], <MODE>mode)
6768        || gpc_reg_operand (operands[1], <MODE>mode))"
6769   "#"
6770   "&& reload_completed"
6771   [(pc)]
6772 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6773   [(set_attr "length" "20,20,16")])
6775 (define_expand "extenddf<mode>2"
6776   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6777         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
6778   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
6779    && TARGET_LONG_DOUBLE_128"
6781   if (FLOAT128_IEEE_P (<MODE>mode))
6782     rs6000_expand_float128_convert (operands[0], operands[1], false);
6783   else if (TARGET_E500_DOUBLE)
6784     {
6785       gcc_assert (<MODE>mode == TFmode);
6786       emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
6787     }
6788   else if (TARGET_VSX)
6789     {
6790       if (<MODE>mode == TFmode)
6791         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
6792       else if (<MODE>mode == IFmode)
6793         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
6794       else
6795         gcc_unreachable ();
6796     }
6797    else
6798     {
6799       rtx zero = gen_reg_rtx (DFmode);
6800       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
6802       if (<MODE>mode == TFmode)
6803         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
6804       else if (<MODE>mode == IFmode)
6805         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
6806       else
6807         gcc_unreachable ();
6808     }
6809   DONE;
6812 ;; Allow memory operands for the source to be created by the combiner.
6813 (define_insn_and_split "extenddf<mode>2_fprs"
6814   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
6815         (float_extend:IBM128
6816          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
6817    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
6818   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6819    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6820   "#"
6821   "&& reload_completed"
6822   [(set (match_dup 3) (match_dup 1))
6823    (set (match_dup 4) (match_dup 2))]
6825   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6826   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6828   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6829   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6832 (define_insn_and_split "extenddf<mode>2_vsx"
6833   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
6834         (float_extend:IBM128
6835          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
6836   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
6837   "#"
6838   "&& reload_completed"
6839   [(set (match_dup 2) (match_dup 1))
6840    (set (match_dup 3) (match_dup 4))]
6842   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6843   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6845   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6846   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6847   operands[4] = CONST0_RTX (DFmode);
6850 (define_expand "extendsf<mode>2"
6851   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6852         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
6853   "TARGET_HARD_FLOAT
6854    && (TARGET_FPRS || TARGET_E500_DOUBLE)
6855    && TARGET_LONG_DOUBLE_128"
6857   if (FLOAT128_IEEE_P (<MODE>mode))
6858     rs6000_expand_float128_convert (operands[0], operands[1], false);
6859   else
6860     {
6861       rtx tmp = gen_reg_rtx (DFmode);
6862       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
6863       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
6864     }
6865   DONE;
6868 (define_expand "trunc<mode>df2"
6869   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6870         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6871   "TARGET_HARD_FLOAT
6872    && (TARGET_FPRS || TARGET_E500_DOUBLE)
6873    && TARGET_LONG_DOUBLE_128"
6875   if (FLOAT128_IEEE_P (<MODE>mode))
6876     {
6877       rs6000_expand_float128_convert (operands[0], operands[1], false);
6878       DONE;
6879     }
6882 (define_insn_and_split "trunc<mode>df2_internal1"
6883   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
6884         (float_truncate:DF
6885          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
6886   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
6887    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
6888   "@
6889    #
6890    fmr %0,%1"
6891   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
6892   [(const_int 0)]
6894   emit_note (NOTE_INSN_DELETED);
6895   DONE;
6897   [(set_attr "type" "fp")])
6899 (define_insn "trunc<mode>df2_internal2"
6900   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6901         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
6902   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
6903    && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
6904   "fadd %0,%1,%L1"
6905   [(set_attr "type" "fp")
6906    (set_attr "fp_type" "fp_addsub_d")])
6908 (define_expand "trunc<mode>sf2"
6909   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6910         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6911   "TARGET_HARD_FLOAT
6912    && (TARGET_FPRS || TARGET_E500_DOUBLE)
6913    && TARGET_LONG_DOUBLE_128"
6915   if (FLOAT128_IEEE_P (<MODE>mode))
6916     rs6000_expand_float128_convert (operands[0], operands[1], false);
6917   else if (TARGET_E500_DOUBLE)
6918     {
6919       gcc_assert (<MODE>mode == TFmode);
6920       emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
6921     }
6922   else if (<MODE>mode == TFmode)
6923     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
6924   else if (<MODE>mode == IFmode)
6925     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
6926   else
6927     gcc_unreachable ();
6928   DONE;
6931 (define_insn_and_split "trunc<mode>sf2_fprs"
6932   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6933         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
6934    (clobber (match_scratch:DF 2 "=d"))]
6935   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
6936    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6937   "#"
6938   "&& reload_completed"
6939   [(set (match_dup 2)
6940         (float_truncate:DF (match_dup 1)))
6941    (set (match_dup 0)
6942         (float_truncate:SF (match_dup 2)))]
6943   "")
6945 (define_expand "floatsi<mode>2"
6946   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6947         (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
6948   "TARGET_HARD_FLOAT
6949    && (TARGET_FPRS || TARGET_E500_DOUBLE)
6950    && TARGET_LONG_DOUBLE_128"
6952   if (FLOAT128_IEEE_P (<MODE>mode))
6953     rs6000_expand_float128_convert (operands[0], operands[1], false);
6954   else
6955     {
6956       rtx tmp = gen_reg_rtx (DFmode);
6957       expand_float (tmp, operands[1], false);
6958       if (<MODE>mode == TFmode)
6959         emit_insn (gen_extenddftf2 (operands[0], tmp));
6960       else if (<MODE>mode == IFmode)
6961         emit_insn (gen_extenddfif2 (operands[0], tmp));
6962       else
6963         gcc_unreachable ();
6964     }
6965   DONE;
6968 ; fadd, but rounding towards zero.
6969 ; This is probably not the optimal code sequence.
6970 (define_insn "fix_trunc_helper<mode>"
6971   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6972         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
6973                    UNSPEC_FIX_TRUNC_TF))
6974    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
6975   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6976    && FLOAT128_IBM_P (<MODE>mode)"
6977   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
6978   [(set_attr "type" "fp")
6979    (set_attr "length" "20")])
6981 (define_expand "fix_trunc<mode>si2"
6982   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6983         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6984   "TARGET_HARD_FLOAT
6985    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
6987   if (FLOAT128_IEEE_P (<MODE>mode))
6988     rs6000_expand_float128_convert (operands[0], operands[1], false);
6989   else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
6990     emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
6991   else if (<MODE>mode == TFmode)
6992     emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
6993   else if (<MODE>mode == IFmode)
6994     emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
6995   else
6996     gcc_unreachable ();
6997   DONE;
7000 (define_expand "fix_trunc<mode>si2_fprs"
7001   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7002                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7003               (clobber (match_dup 2))
7004               (clobber (match_dup 3))
7005               (clobber (match_dup 4))
7006               (clobber (match_dup 5))])]
7007   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7009   operands[2] = gen_reg_rtx (DFmode);
7010   operands[3] = gen_reg_rtx (DFmode);
7011   operands[4] = gen_reg_rtx (DImode);
7012   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7015 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7016   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7017         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7018    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7019    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7020    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7021    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7022   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7023   "#"
7024   ""
7025   [(pc)]
7027   rtx lowword;
7028   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7029                                          operands[3]));
7031   gcc_assert (MEM_P (operands[5]));
7032   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7034   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7035   emit_move_insn (operands[5], operands[4]);
7036   emit_move_insn (operands[0], lowword);
7037   DONE;
7040 (define_expand "fix_trunc<mode>di2"
7041   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7042         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7043   "TARGET_FLOAT128"
7045   rs6000_expand_float128_convert (operands[0], operands[1], false);
7046   DONE;
7049 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7050   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7051         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7052   "TARGET_FLOAT128"
7054   rs6000_expand_float128_convert (operands[0], operands[1], true);
7055   DONE;
7058 (define_expand "floatdi<mode>2"
7059   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7060         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7061   "TARGET_FLOAT128"
7063   rs6000_expand_float128_convert (operands[0], operands[1], false);
7064   DONE;
7067 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7068   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7069         (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7070   "TARGET_FLOAT128"
7072   rs6000_expand_float128_convert (operands[0], operands[1], true);
7073   DONE;
7076 (define_expand "neg<mode>2"
7077   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7078         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7079   "FLOAT128_IEEE_P (<MODE>mode)
7080    || (FLOAT128_IBM_P (<MODE>mode)
7081        && TARGET_HARD_FLOAT
7082        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7083   "
7085   if (FLOAT128_IEEE_P (<MODE>mode))
7086     {
7087       if (TARGET_FLOAT128_HW)
7088         {
7089           if (<MODE>mode == TFmode)
7090             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7091           else if (<MODE>mode == KFmode)
7092             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7093           else
7094             gcc_unreachable ();
7095         }
7096       else if (TARGET_FLOAT128)
7097         {
7098           if (<MODE>mode == TFmode)
7099             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7100           else if (<MODE>mode == KFmode)
7101             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7102           else
7103             gcc_unreachable ();
7104         }
7105       else
7106         {
7107           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7108           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7109                                                 <MODE>mode, 1,
7110                                                 operands[1], <MODE>mode);
7112           if (target && !rtx_equal_p (target, operands[0]))
7113             emit_move_insn (operands[0], target);
7114         }
7115       DONE;
7116     }
7119 (define_insn "neg<mode>2_internal"
7120   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7121         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7122   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7123   "*
7125   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7126     return \"fneg %L0,%L1\;fneg %0,%1\";
7127   else
7128     return \"fneg %0,%1\;fneg %L0,%L1\";
7130   [(set_attr "type" "fp")
7131    (set_attr "length" "8")])
7133 (define_expand "abs<mode>2"
7134   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7135         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7136   "FLOAT128_IEEE_P (<MODE>mode)
7137    || (FLOAT128_IBM_P (<MODE>mode)
7138        && TARGET_HARD_FLOAT
7139        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7140   "
7142   rtx label;
7144   if (FLOAT128_IEEE_P (<MODE>mode))
7145     {
7146       if (TARGET_FLOAT128_HW)
7147         {
7148           if (<MODE>mode == TFmode)
7149             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7150           else if (<MODE>mode == KFmode)
7151             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7152           else
7153             FAIL;
7154           DONE;
7155         }
7156       else if (TARGET_FLOAT128)
7157         {
7158           if (<MODE>mode == TFmode)
7159             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7160           else if (<MODE>mode == KFmode)
7161             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7162           else
7163             FAIL;
7164           DONE;
7165         }
7166       else
7167         FAIL;
7168     }
7170   label = gen_label_rtx ();
7171   if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7172     {
7173       if (flag_finite_math_only && !flag_trapping_math)
7174         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7175       else
7176         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7177     }
7178   else if (<MODE>mode == TFmode)
7179     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7180   else if (<MODE>mode == TFmode)
7181     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7182   else
7183     FAIL;
7184   emit_label (label);
7185   DONE;
7188 (define_expand "abs<mode>2_internal"
7189   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7190         (match_operand:IBM128 1 "gpc_reg_operand" ""))
7191    (set (match_dup 3) (match_dup 5))
7192    (set (match_dup 5) (abs:DF (match_dup 5)))
7193    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7194    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7195                            (label_ref (match_operand 2 "" ""))
7196                            (pc)))
7197    (set (match_dup 6) (neg:DF (match_dup 6)))]
7198   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7199    && TARGET_LONG_DOUBLE_128"
7200   "
7202   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7203   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7204   operands[3] = gen_reg_rtx (DFmode);
7205   operands[4] = gen_reg_rtx (CCFPmode);
7206   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7207   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7211 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7212 ;; register
7214 (define_expand "ieee_128bit_negative_zero"
7215   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7216   "TARGET_FLOAT128"
7218   rtvec v = rtvec_alloc (16);
7219   int i, high;
7221   for (i = 0; i < 16; i++)
7222     RTVEC_ELT (v, i) = const0_rtx;
7224   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7225   RTVEC_ELT (v, high) = GEN_INT (0x80);
7227   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7228   DONE;
7231 ;; IEEE 128-bit negate
7233 ;; We have 2 insns here for negate and absolute value.  The first uses
7234 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7235 ;; insns, and second insn after the first split pass loads up the bit to
7236 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
7237 ;; neg/abs to create the constant just once.
7239 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7240   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7241         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7242    (clobber (match_scratch:V16QI 2 "=v"))]
7243   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7244   "#"
7245   "&& 1"
7246   [(parallel [(set (match_dup 0)
7247                    (neg:IEEE128 (match_dup 1)))
7248               (use (match_dup 2))])]
7250   if (GET_CODE (operands[2]) == SCRATCH)
7251     operands[2] = gen_reg_rtx (V16QImode);
7253   operands[3] = gen_reg_rtx (V16QImode);
7254   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7256   [(set_attr "length" "8")
7257    (set_attr "type" "vecsimple")])
7259 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7260   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7261         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7262    (use (match_operand:V16QI 2 "register_operand" "=v"))]
7263   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7264   "xxlxor %x0,%x1,%x2"
7265   [(set_attr "type" "vecsimple")])
7267 ;; IEEE 128-bit absolute value
7268 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7269   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7270         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7271    (clobber (match_scratch:V16QI 2 "=v"))]
7272   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7273   "#"
7274   "&& 1"
7275   [(parallel [(set (match_dup 0)
7276                    (abs:IEEE128 (match_dup 1)))
7277               (use (match_dup 2))])]
7279   if (GET_CODE (operands[2]) == SCRATCH)
7280     operands[2] = gen_reg_rtx (V16QImode);
7282   operands[3] = gen_reg_rtx (V16QImode);
7283   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7285   [(set_attr "length" "8")
7286    (set_attr "type" "vecsimple")])
7288 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7289   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7290         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7291    (use (match_operand:V16QI 2 "register_operand" "=v"))]
7292   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7293   "xxlandc %x0,%x1,%x2"
7294   [(set_attr "type" "vecsimple")])
7296 ;; IEEE 128-bit negative absolute value
7297 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7298   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7299         (neg:IEEE128
7300          (abs:IEEE128
7301           (match_operand:IEEE128 1 "register_operand" "wa"))))
7302    (clobber (match_scratch:V16QI 2 "=v"))]
7303   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7304   "#"
7305   "&& 1"
7306   [(parallel [(set (match_dup 0)
7307                    (abs:IEEE128 (match_dup 1)))
7308               (use (match_dup 2))])]
7310   if (GET_CODE (operands[2]) == SCRATCH)
7311     operands[2] = gen_reg_rtx (V16QImode);
7313   operands[3] = gen_reg_rtx (V16QImode);
7314   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7316   [(set_attr "length" "8")
7317    (set_attr "type" "vecsimple")])
7319 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7320   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7321         (neg:IEEE128
7322          (abs:IEEE128
7323           (match_operand:IEEE128 1 "register_operand" "wa"))))
7324    (use (match_operand:V16QI 2 "register_operand" "=v"))]
7325   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7326   "xxlor %x0,%x1,%x2"
7327   [(set_attr "type" "vecsimple")])
7329 ;; Float128 conversion functions.  These expand to library function calls.
7330 ;; We use expand to convert from IBM double double to IEEE 128-bit
7331 ;; and trunc for the opposite.
7332 (define_expand "extendiftf2"
7333   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7334         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7335   "TARGET_FLOAT128"
7337   rs6000_expand_float128_convert (operands[0], operands[1], false);
7338   DONE;
7341 (define_expand "extendifkf2"
7342   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7343         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7344   "TARGET_FLOAT128"
7346   rs6000_expand_float128_convert (operands[0], operands[1], false);
7347   DONE;
7350 (define_expand "extendtfkf2"
7351   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7352         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7353   "TARGET_FLOAT128"
7355   rs6000_expand_float128_convert (operands[0], operands[1], false);
7356   DONE;
7359 (define_expand "trunciftf2"
7360   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7361         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7362   "TARGET_FLOAT128"
7364   rs6000_expand_float128_convert (operands[0], operands[1], false);
7365   DONE;
7368 (define_expand "truncifkf2"
7369   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7370         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7371   "TARGET_FLOAT128"
7373   rs6000_expand_float128_convert (operands[0], operands[1], false);
7374   DONE;
7377 (define_expand "trunckftf2"
7378   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7379         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7380   "TARGET_FLOAT128"
7382   rs6000_expand_float128_convert (operands[0], operands[1], false);
7383   DONE;
7386 (define_expand "trunctfif2"
7387   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7388         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7389   "TARGET_FLOAT128"
7391   rs6000_expand_float128_convert (operands[0], operands[1], false);
7392   DONE;
7396 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
7397 ;; must have 3 arguments, and scratch register constraint must be a single
7398 ;; constraint.
7400 ;; Reload patterns to support gpr load/store with misaligned mem.
7401 ;; and multiple gpr load/store at offset >= 0xfffc
7402 (define_expand "reload_<mode>_store"
7403   [(parallel [(match_operand 0 "memory_operand" "=m")
7404               (match_operand 1 "gpc_reg_operand" "r")
7405               (match_operand:GPR 2 "register_operand" "=&b")])]
7406   ""
7408   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7409   DONE;
7412 (define_expand "reload_<mode>_load"
7413   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7414               (match_operand 1 "memory_operand" "m")
7415               (match_operand:GPR 2 "register_operand" "=b")])]
7416   ""
7418   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7419   DONE;
7423 ;; Reload patterns for various types using the vector registers.  We may need
7424 ;; an additional base register to convert the reg+offset addressing to reg+reg
7425 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7426 ;; index register for gpr registers.
7427 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7428   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7429               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7430               (match_operand:P 2 "register_operand" "=b")])]
7431   "<P:tptrsize>"
7433   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7434   DONE;
7437 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7438   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7439               (match_operand:RELOAD 1 "memory_operand" "m")
7440               (match_operand:P 2 "register_operand" "=b")])]
7441   "<P:tptrsize>"
7443   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7444   DONE;
7448 ;; Reload sometimes tries to move the address to a GPR, and can generate
7449 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
7450 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7452 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7453   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7454         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7455                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
7456                (const_int -16)))]
7457   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7458   "#"
7459   "&& reload_completed"
7460   [(set (match_dup 0)
7461         (plus:P (match_dup 1)
7462                 (match_dup 2)))
7463    (set (match_dup 0)
7464         (and:P (match_dup 0)
7465                (const_int -16)))])
7467 ;; Power8 merge instructions to allow direct move to/from floating point
7468 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
7469 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
7470 ;; value, since it is allocated in reload and not all of the flow information
7471 ;; is setup for it.  We have two patterns to do the two moves between gprs and
7472 ;; fprs.  There isn't a dependancy between the two, but we could potentially
7473 ;; schedule other instructions between the two instructions.  TFmode is
7474 ;; currently limited to traditional FPR registers.  If/when this is changed, we
7475 ;; will need to revist %L to make sure it works with VSX registers, or add an
7476 ;; %x version of %L.
7478 (define_insn "p8_fmrgow_<mode>"
7479   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7480         (unspec:FMOVE64X [(match_operand:TF 1 "register_operand" "d")]
7481                          UNSPEC_P8V_FMRGOW))]
7482   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7483   "fmrgow %0,%1,%L1"
7484   [(set_attr "type" "vecperm")])
7486 (define_insn "p8_mtvsrwz_1"
7487   [(set (match_operand:TF 0 "register_operand" "=d")
7488         (unspec:TF [(match_operand:SI 1 "register_operand" "r")]
7489                    UNSPEC_P8V_MTVSRWZ))]
7490   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7491   "mtvsrwz %x0,%1"
7492   [(set_attr "type" "mftgpr")])
7494 (define_insn "p8_mtvsrwz_2"
7495   [(set (match_operand:TF 0 "register_operand" "+d")
7496         (unspec:TF [(match_dup 0)
7497                     (match_operand:SI 1 "register_operand" "r")]
7498                    UNSPEC_P8V_MTVSRWZ))]
7499   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7500   "mtvsrwz %L0,%1"
7501   [(set_attr "type" "mftgpr")])
7503 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7504   [(set (match_operand:FMOVE64X 0 "register_operand" "=ws")
7505         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7506                          UNSPEC_P8V_RELOAD_FROM_GPR))
7507    (clobber (match_operand:TF 2 "register_operand" "=d"))]
7508   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7509   "#"
7510   "&& reload_completed"
7511   [(const_int 0)]
7513   rtx dest = operands[0];
7514   rtx src = operands[1];
7515   rtx tmp = operands[2];
7516   rtx gpr_hi_reg = gen_highpart (SImode, src);
7517   rtx gpr_lo_reg = gen_lowpart (SImode, src);
7519   emit_insn (gen_p8_mtvsrwz_1 (tmp, gpr_hi_reg));
7520   emit_insn (gen_p8_mtvsrwz_2 (tmp, gpr_lo_reg));
7521   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp));
7522   DONE;
7524   [(set_attr "length" "12")
7525    (set_attr "type" "three")])
7527 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7528 (define_insn "p8_mtvsrd_1"
7529   [(set (match_operand:TF 0 "register_operand" "=ws")
7530         (unspec:TF [(match_operand:DI 1 "register_operand" "r")]
7531                    UNSPEC_P8V_MTVSRD))]
7532   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7533   "mtvsrd %0,%1"
7534   [(set_attr "type" "mftgpr")])
7536 (define_insn "p8_mtvsrd_2"
7537   [(set (match_operand:TF 0 "register_operand" "+ws")
7538         (unspec:TF [(match_dup 0)
7539                     (match_operand:DI 1 "register_operand" "r")]
7540                    UNSPEC_P8V_MTVSRD))]
7541   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7542   "mtvsrd %L0,%1"
7543   [(set_attr "type" "mftgpr")])
7545 (define_insn "p8_xxpermdi_<mode>"
7546   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7547         (unspec:FMOVE128_GPR [(match_operand:TF 1 "register_operand" "ws")]
7548                              UNSPEC_P8V_XXPERMDI))]
7549   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7550   "xxpermdi %x0,%1,%L1,0"
7551   [(set_attr "type" "vecperm")])
7553 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7554   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7555         (unspec:FMOVE128_GPR
7556          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7557          UNSPEC_P8V_RELOAD_FROM_GPR))
7558    (clobber (match_operand:TF 2 "register_operand" "=ws"))]
7559   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7560   "#"
7561   "&& reload_completed"
7562   [(const_int 0)]
7564   rtx dest = operands[0];
7565   rtx src = operands[1];
7566   rtx tmp = operands[2];
7567   rtx gpr_hi_reg = gen_highpart (DImode, src);
7568   rtx gpr_lo_reg = gen_lowpart (DImode, src);
7570   emit_insn (gen_p8_mtvsrd_1 (tmp, gpr_hi_reg));
7571   emit_insn (gen_p8_mtvsrd_2 (tmp, gpr_lo_reg));
7572   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp));
7573   DONE;
7575   [(set_attr "length" "12")
7576    (set_attr "type" "three")])
7578 (define_split
7579   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7580         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7581   "reload_completed
7582    && (int_reg_operand (operands[0], <MODE>mode)
7583        || int_reg_operand (operands[1], <MODE>mode))
7584    && (!TARGET_DIRECT_MOVE_128
7585        || (!vsx_register_operand (operands[0], <MODE>mode)
7586            && !vsx_register_operand (operands[1], <MODE>mode)))"
7587   [(pc)]
7588 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7590 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
7591 ;; type is stored internally as double precision in the VSX registers, we have
7592 ;; to convert it from the vector format.
7594 (define_insn_and_split "reload_vsx_from_gprsf"
7595   [(set (match_operand:SF 0 "register_operand" "=wa")
7596         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7597                    UNSPEC_P8V_RELOAD_FROM_GPR))
7598    (clobber (match_operand:DI 2 "register_operand" "=r"))]
7599   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7600   "#"
7601   "&& reload_completed"
7602   [(const_int 0)]
7604   rtx op0 = operands[0];
7605   rtx op1 = operands[1];
7606   rtx op2 = operands[2];
7607   /* Also use the destination register to hold the unconverted DImode value.
7608      This is conceptually a separate value from OP0, so we use gen_rtx_REG
7609      rather than simplify_gen_subreg.  */
7610   rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
7611   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7613   /* Move SF value to upper 32-bits for xscvspdpn.  */
7614   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7615   emit_move_insn (op0_di, op2);
7616   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0_di));
7617   DONE;
7619   [(set_attr "length" "8")
7620    (set_attr "type" "two")])
7622 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7623 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7624 ;; and then doing a move of that.
7625 (define_insn "p8_mfvsrd_3_<mode>"
7626   [(set (match_operand:DF 0 "register_operand" "=r")
7627         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7628                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7629   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7630   "mfvsrd %0,%x1"
7631   [(set_attr "type" "mftgpr")])
7633 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7634   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7635         (unspec:FMOVE128_GPR
7636          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7637          UNSPEC_P8V_RELOAD_FROM_VSX))
7638    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7639   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7640   "#"
7641   "&& reload_completed"
7642   [(const_int 0)]
7644   rtx dest = operands[0];
7645   rtx src = operands[1];
7646   rtx tmp = operands[2];
7647   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7648   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7650   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7651   emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7652   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7653   DONE;
7655   [(set_attr "length" "12")
7656    (set_attr "type" "three")])
7658 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
7659 ;; type is stored internally as double precision, we have to convert it to the
7660 ;; vector format.
7662 (define_insn_and_split "reload_gpr_from_vsxsf"
7663   [(set (match_operand:SF 0 "register_operand" "=r")
7664         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7665                    UNSPEC_P8V_RELOAD_FROM_VSX))
7666    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7667   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7668   "#"
7669   "&& reload_completed"
7670   [(const_int 0)]
7672   rtx op0 = operands[0];
7673   rtx op1 = operands[1];
7674   rtx op2 = operands[2];
7675   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7677   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7678   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7679   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7680   DONE;
7682   [(set_attr "length" "12")
7683    (set_attr "type" "three")])
7685 (define_insn "p8_mfvsrd_4_disf"
7686   [(set (match_operand:DI 0 "register_operand" "=r")
7687         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7688                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7689   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7690   "mfvsrd %0,%x1"
7691   [(set_attr "type" "mftgpr")])
7694 ;; Next come the multi-word integer load and store and the load and store
7695 ;; multiple insns.
7697 ;; List r->r after r->Y, otherwise reload will try to reload a
7698 ;; non-offsettable address by using r->r which won't make progress.
7699 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7700 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7701 (define_insn "*movdi_internal32"
7702   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
7703         (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
7704   "! TARGET_POWERPC64
7705    && (gpc_reg_operand (operands[0], DImode)
7706        || gpc_reg_operand (operands[1], DImode))"
7707   "@
7708    #
7709    #
7710    #
7711    stfd%U0%X0 %1,%0
7712    lfd%U1%X1 %0,%1
7713    fmr %0,%1
7714    #"
7715   [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
7717 (define_split
7718   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7719         (match_operand:DI 1 "const_int_operand" ""))]
7720   "! TARGET_POWERPC64 && reload_completed
7721    && gpr_or_gpr_p (operands[0], operands[1])
7722    && !direct_move_p (operands[0], operands[1])"
7723   [(set (match_dup 2) (match_dup 4))
7724    (set (match_dup 3) (match_dup 1))]
7725   "
7727   HOST_WIDE_INT value = INTVAL (operands[1]);
7728   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7729                                        DImode);
7730   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7731                                        DImode);
7732   operands[4] = GEN_INT (value >> 32);
7733   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7736 (define_split
7737   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7738         (match_operand:DIFD 1 "input_operand" ""))]
7739   "reload_completed && !TARGET_POWERPC64
7740    && gpr_or_gpr_p (operands[0], operands[1])
7741    && !direct_move_p (operands[0], operands[1])"
7742   [(pc)]
7743 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7745 (define_insn "*movdi_internal64"
7746   [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi")
7747         (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))]
7748   "TARGET_POWERPC64
7749    && (gpc_reg_operand (operands[0], DImode)
7750        || gpc_reg_operand (operands[1], DImode))"
7751   "@
7752    std%U0%X0 %1,%0
7753    ld%U1%X1 %0,%1
7754    mr %0,%1
7755    li %0,%1
7756    lis %0,%v1
7757    #
7758    stfd%U0%X0 %1,%0
7759    lfd%U1%X1 %0,%1
7760    fmr %0,%1
7761    mf%1 %0
7762    mt%0 %1
7763    nop
7764    mftgpr %0,%1
7765    mffgpr %0,%1
7766    mfvsrd %0,%x1
7767    mtvsrd %x0,%1
7768    xxlxor %x0,%x0,%x0"
7769   [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
7770    (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
7772 ; Some DImode loads are best done as a load of -1 followed by a mask
7773 ; instruction.
7774 (define_split
7775   [(set (match_operand:DI 0 "gpc_reg_operand")
7776         (match_operand:DI 1 "const_int_operand"))]
7777   "TARGET_POWERPC64
7778    && num_insns_constant (operands[1], DImode) > 1
7779    && rs6000_is_valid_and_mask (operands[1], DImode)"
7780   [(set (match_dup 0)
7781         (const_int -1))
7782    (set (match_dup 0)
7783         (and:DI (match_dup 0)
7784                 (match_dup 1)))]
7785   "")
7787 ;; Split a load of a large constant into the appropriate five-instruction
7788 ;; sequence.  Handle anything in a constant number of insns.
7789 ;; When non-easy constants can go in the TOC, this should use
7790 ;; easy_fp_constant predicate.
7791 (define_split
7792   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7793         (match_operand:DI 1 "const_int_operand" ""))]
7794   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7795   [(set (match_dup 0) (match_dup 2))
7796    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7797   "
7799   if (rs6000_emit_set_const (operands[0], operands[1]))
7800     DONE;
7801   else
7802     FAIL;
7805 (define_split
7806   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7807         (match_operand:DI 1 "const_scalar_int_operand" ""))]
7808   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7809   [(set (match_dup 0) (match_dup 2))
7810    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7811   "
7813   if (rs6000_emit_set_const (operands[0], operands[1]))
7814     DONE;
7815   else
7816     FAIL;
7819 ;; TImode/PTImode is similar, except that we usually want to compute the
7820 ;; address into a register and use lsi/stsi (the exception is during reload).
7822 (define_insn "*mov<mode>_string"
7823   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
7824         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
7825   "! TARGET_POWERPC64
7826    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
7827    && (gpc_reg_operand (operands[0], <MODE>mode)
7828        || gpc_reg_operand (operands[1], <MODE>mode))"
7829   "*
7831   switch (which_alternative)
7832     {
7833     default:
7834       gcc_unreachable ();
7835     case 0:
7836       if (TARGET_STRING)
7837         return \"stswi %1,%P0,16\";
7838     case 1:
7839       return \"#\";
7840     case 2:
7841       /* If the address is not used in the output, we can use lsi.  Otherwise,
7842          fall through to generating four loads.  */
7843       if (TARGET_STRING
7844           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
7845         return \"lswi %0,%P1,16\";
7846       /* ... fall through ...  */
7847     case 3:
7848     case 4:
7849     case 5:
7850       return \"#\";
7851     }
7853   [(set_attr "type" "store,store,load,load,*,*")
7854    (set_attr "update" "yes")
7855    (set_attr "indexed" "yes")
7856    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
7857                                           (const_string "always")
7858                                           (const_string "conditional")))])
7860 (define_insn "*mov<mode>_ppc64"
7861   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
7862         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
7863   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
7864    && (gpc_reg_operand (operands[0], <MODE>mode)
7865        || gpc_reg_operand (operands[1], <MODE>mode)))"
7867   return rs6000_output_move_128bit (operands);
7869   [(set_attr "type" "store,store,load,load,*,*")
7870    (set_attr "length" "8")])
7872 (define_split
7873   [(set (match_operand:TI2 0 "int_reg_operand" "")
7874         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
7875   "TARGET_POWERPC64
7876    && (VECTOR_MEM_NONE_P (<MODE>mode)
7877        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
7878   [(set (match_dup 2) (match_dup 4))
7879    (set (match_dup 3) (match_dup 5))]
7880   "
7882   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7883                                        <MODE>mode);
7884   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7885                                        <MODE>mode);
7886   if (CONST_WIDE_INT_P (operands[1]))
7887     {
7888       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
7889       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
7890     }
7891   else if (CONST_INT_P (operands[1]))
7892     {
7893       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
7894       operands[5] = operands[1];
7895     }
7896   else
7897     FAIL;
7900 (define_split
7901   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
7902         (match_operand:TI2 1 "input_operand" ""))]
7903   "reload_completed
7904    && gpr_or_gpr_p (operands[0], operands[1])
7905    && !direct_move_p (operands[0], operands[1])
7906    && !quad_load_store_p (operands[0], operands[1])"
7907   [(pc)]
7908 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7910 (define_expand "load_multiple"
7911   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7912                           (match_operand:SI 1 "" ""))
7913                      (use (match_operand:SI 2 "" ""))])]
7914   "TARGET_STRING && !TARGET_POWERPC64"
7915   "
7917   int regno;
7918   int count;
7919   rtx op1;
7920   int i;
7922   /* Support only loading a constant number of fixed-point registers from
7923      memory and only bother with this if more than two; the machine
7924      doesn't support more than eight.  */
7925   if (GET_CODE (operands[2]) != CONST_INT
7926       || INTVAL (operands[2]) <= 2
7927       || INTVAL (operands[2]) > 8
7928       || GET_CODE (operands[1]) != MEM
7929       || GET_CODE (operands[0]) != REG
7930       || REGNO (operands[0]) >= 32)
7931     FAIL;
7933   count = INTVAL (operands[2]);
7934   regno = REGNO (operands[0]);
7936   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
7937   op1 = replace_equiv_address (operands[1],
7938                                force_reg (SImode, XEXP (operands[1], 0)));
7940   for (i = 0; i < count; i++)
7941     XVECEXP (operands[3], 0, i)
7942       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
7943                      adjust_address_nv (op1, SImode, i * 4));
7946 (define_insn "*ldmsi8"
7947   [(match_parallel 0 "load_multiple_operation"
7948     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7949           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7950      (set (match_operand:SI 3 "gpc_reg_operand" "")
7951           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7952      (set (match_operand:SI 4 "gpc_reg_operand" "")
7953           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7954      (set (match_operand:SI 5 "gpc_reg_operand" "")
7955           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7956      (set (match_operand:SI 6 "gpc_reg_operand" "")
7957           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7958      (set (match_operand:SI 7 "gpc_reg_operand" "")
7959           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
7960      (set (match_operand:SI 8 "gpc_reg_operand" "")
7961           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
7962      (set (match_operand:SI 9 "gpc_reg_operand" "")
7963           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
7964   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
7965   "*
7966 { return rs6000_output_load_multiple (operands); }"
7967   [(set_attr "type" "load")
7968    (set_attr "update" "yes")
7969    (set_attr "indexed" "yes")
7970    (set_attr "length" "32")])
7972 (define_insn "*ldmsi7"
7973   [(match_parallel 0 "load_multiple_operation"
7974     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7975           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7976      (set (match_operand:SI 3 "gpc_reg_operand" "")
7977           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7978      (set (match_operand:SI 4 "gpc_reg_operand" "")
7979           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7980      (set (match_operand:SI 5 "gpc_reg_operand" "")
7981           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7982      (set (match_operand:SI 6 "gpc_reg_operand" "")
7983           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7984      (set (match_operand:SI 7 "gpc_reg_operand" "")
7985           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
7986      (set (match_operand:SI 8 "gpc_reg_operand" "")
7987           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
7988   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
7989   "*
7990 { return rs6000_output_load_multiple (operands); }"
7991   [(set_attr "type" "load")
7992    (set_attr "update" "yes")
7993    (set_attr "indexed" "yes")
7994    (set_attr "length" "32")])
7996 (define_insn "*ldmsi6"
7997   [(match_parallel 0 "load_multiple_operation"
7998     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7999           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8000      (set (match_operand:SI 3 "gpc_reg_operand" "")
8001           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8002      (set (match_operand:SI 4 "gpc_reg_operand" "")
8003           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8004      (set (match_operand:SI 5 "gpc_reg_operand" "")
8005           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8006      (set (match_operand:SI 6 "gpc_reg_operand" "")
8007           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8008      (set (match_operand:SI 7 "gpc_reg_operand" "")
8009           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8010   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8011   "*
8012 { return rs6000_output_load_multiple (operands); }"
8013   [(set_attr "type" "load")
8014    (set_attr "update" "yes")
8015    (set_attr "indexed" "yes")
8016    (set_attr "length" "32")])
8018 (define_insn "*ldmsi5"
8019   [(match_parallel 0 "load_multiple_operation"
8020     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8021           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8022      (set (match_operand:SI 3 "gpc_reg_operand" "")
8023           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8024      (set (match_operand:SI 4 "gpc_reg_operand" "")
8025           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8026      (set (match_operand:SI 5 "gpc_reg_operand" "")
8027           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8028      (set (match_operand:SI 6 "gpc_reg_operand" "")
8029           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8030   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8031   "*
8032 { return rs6000_output_load_multiple (operands); }"
8033   [(set_attr "type" "load")
8034    (set_attr "update" "yes")
8035    (set_attr "indexed" "yes")
8036    (set_attr "length" "32")])
8038 (define_insn "*ldmsi4"
8039   [(match_parallel 0 "load_multiple_operation"
8040     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8041           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8042      (set (match_operand:SI 3 "gpc_reg_operand" "")
8043           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8044      (set (match_operand:SI 4 "gpc_reg_operand" "")
8045           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8046      (set (match_operand:SI 5 "gpc_reg_operand" "")
8047           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8048   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8049   "*
8050 { return rs6000_output_load_multiple (operands); }"
8051   [(set_attr "type" "load")
8052    (set_attr "update" "yes")
8053    (set_attr "indexed" "yes")
8054    (set_attr "length" "32")])
8056 (define_insn "*ldmsi3"
8057   [(match_parallel 0 "load_multiple_operation"
8058     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8059           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8060      (set (match_operand:SI 3 "gpc_reg_operand" "")
8061           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8062      (set (match_operand:SI 4 "gpc_reg_operand" "")
8063           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8064   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8065   "*
8066 { return rs6000_output_load_multiple (operands); }"
8067   [(set_attr "type" "load")
8068    (set_attr "update" "yes")
8069    (set_attr "indexed" "yes")
8070    (set_attr "length" "32")])
8072 (define_expand "store_multiple"
8073   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8074                           (match_operand:SI 1 "" ""))
8075                      (clobber (scratch:SI))
8076                      (use (match_operand:SI 2 "" ""))])]
8077   "TARGET_STRING && !TARGET_POWERPC64"
8078   "
8080   int regno;
8081   int count;
8082   rtx to;
8083   rtx op0;
8084   int i;
8086   /* Support only storing a constant number of fixed-point registers to
8087      memory and only bother with this if more than two; the machine
8088      doesn't support more than eight.  */
8089   if (GET_CODE (operands[2]) != CONST_INT
8090       || INTVAL (operands[2]) <= 2
8091       || INTVAL (operands[2]) > 8
8092       || GET_CODE (operands[0]) != MEM
8093       || GET_CODE (operands[1]) != REG
8094       || REGNO (operands[1]) >= 32)
8095     FAIL;
8097   count = INTVAL (operands[2]);
8098   regno = REGNO (operands[1]);
8100   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8101   to = force_reg (SImode, XEXP (operands[0], 0));
8102   op0 = replace_equiv_address (operands[0], to);
8104   XVECEXP (operands[3], 0, 0)
8105     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8106   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8107                                                  gen_rtx_SCRATCH (SImode));
8109   for (i = 1; i < count; i++)
8110     XVECEXP (operands[3], 0, i + 1)
8111       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8112                      gen_rtx_REG (SImode, regno + i));
8115 (define_insn "*stmsi8"
8116   [(match_parallel 0 "store_multiple_operation"
8117     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8118           (match_operand:SI 2 "gpc_reg_operand" "r"))
8119      (clobber (match_scratch:SI 3 "=X"))
8120      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8121           (match_operand:SI 4 "gpc_reg_operand" "r"))
8122      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8123           (match_operand:SI 5 "gpc_reg_operand" "r"))
8124      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8125           (match_operand:SI 6 "gpc_reg_operand" "r"))
8126      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8127           (match_operand:SI 7 "gpc_reg_operand" "r"))
8128      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8129           (match_operand:SI 8 "gpc_reg_operand" "r"))
8130      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8131           (match_operand:SI 9 "gpc_reg_operand" "r"))
8132      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8133           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8134   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8135   "stswi %2,%1,%O0"
8136   [(set_attr "type" "store")
8137    (set_attr "update" "yes")
8138    (set_attr "indexed" "yes")
8139    (set_attr "cell_micro" "always")])
8141 (define_insn "*stmsi7"
8142   [(match_parallel 0 "store_multiple_operation"
8143     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8144           (match_operand:SI 2 "gpc_reg_operand" "r"))
8145      (clobber (match_scratch:SI 3 "=X"))
8146      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8147           (match_operand:SI 4 "gpc_reg_operand" "r"))
8148      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8149           (match_operand:SI 5 "gpc_reg_operand" "r"))
8150      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8151           (match_operand:SI 6 "gpc_reg_operand" "r"))
8152      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8153           (match_operand:SI 7 "gpc_reg_operand" "r"))
8154      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8155           (match_operand:SI 8 "gpc_reg_operand" "r"))
8156      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8157           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8158   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8159   "stswi %2,%1,%O0"
8160   [(set_attr "type" "store")
8161    (set_attr "update" "yes")
8162    (set_attr "indexed" "yes")
8163    (set_attr "cell_micro" "always")])
8165 (define_insn "*stmsi6"
8166   [(match_parallel 0 "store_multiple_operation"
8167     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8168           (match_operand:SI 2 "gpc_reg_operand" "r"))
8169      (clobber (match_scratch:SI 3 "=X"))
8170      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8171           (match_operand:SI 4 "gpc_reg_operand" "r"))
8172      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8173           (match_operand:SI 5 "gpc_reg_operand" "r"))
8174      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8175           (match_operand:SI 6 "gpc_reg_operand" "r"))
8176      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8177           (match_operand:SI 7 "gpc_reg_operand" "r"))
8178      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8179           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8180   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8181   "stswi %2,%1,%O0"
8182   [(set_attr "type" "store")
8183    (set_attr "update" "yes")
8184    (set_attr "indexed" "yes")
8185    (set_attr "cell_micro" "always")])
8187 (define_insn "*stmsi5"
8188   [(match_parallel 0 "store_multiple_operation"
8189     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8190           (match_operand:SI 2 "gpc_reg_operand" "r"))
8191      (clobber (match_scratch:SI 3 "=X"))
8192      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8193           (match_operand:SI 4 "gpc_reg_operand" "r"))
8194      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8195           (match_operand:SI 5 "gpc_reg_operand" "r"))
8196      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8197           (match_operand:SI 6 "gpc_reg_operand" "r"))
8198      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8199           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8200   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8201   "stswi %2,%1,%O0"
8202   [(set_attr "type" "store")
8203    (set_attr "update" "yes")
8204    (set_attr "indexed" "yes")
8205    (set_attr "cell_micro" "always")])
8207 (define_insn "*stmsi4"
8208   [(match_parallel 0 "store_multiple_operation"
8209     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8210           (match_operand:SI 2 "gpc_reg_operand" "r"))
8211      (clobber (match_scratch:SI 3 "=X"))
8212      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8213           (match_operand:SI 4 "gpc_reg_operand" "r"))
8214      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8215           (match_operand:SI 5 "gpc_reg_operand" "r"))
8216      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8217           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8218   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8219   "stswi %2,%1,%O0"
8220   [(set_attr "type" "store")
8221    (set_attr "update" "yes")
8222    (set_attr "indexed" "yes")
8223    (set_attr "cell_micro" "always")])
8225 (define_insn "*stmsi3"
8226   [(match_parallel 0 "store_multiple_operation"
8227     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8228           (match_operand:SI 2 "gpc_reg_operand" "r"))
8229      (clobber (match_scratch:SI 3 "=X"))
8230      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8231           (match_operand:SI 4 "gpc_reg_operand" "r"))
8232      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8233           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8234   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8235   "stswi %2,%1,%O0"
8236   [(set_attr "type" "store")
8237    (set_attr "update" "yes")
8238    (set_attr "indexed" "yes")
8239    (set_attr "cell_micro" "always")])
8241 (define_expand "setmemsi"
8242   [(parallel [(set (match_operand:BLK 0 "" "")
8243                    (match_operand 2 "const_int_operand" ""))
8244               (use (match_operand:SI 1 "" ""))
8245               (use (match_operand:SI 3 "" ""))])]
8246   ""
8247   "
8249   /* If value to set is not zero, use the library routine.  */
8250   if (operands[2] != const0_rtx)
8251     FAIL;
8253   if (expand_block_clear (operands))
8254     DONE;
8255   else
8256     FAIL;
8259 ;; String/block move insn.
8260 ;; Argument 0 is the destination
8261 ;; Argument 1 is the source
8262 ;; Argument 2 is the length
8263 ;; Argument 3 is the alignment
8265 (define_expand "movmemsi"
8266   [(parallel [(set (match_operand:BLK 0 "" "")
8267                    (match_operand:BLK 1 "" ""))
8268               (use (match_operand:SI 2 "" ""))
8269               (use (match_operand:SI 3 "" ""))])]
8270   ""
8271   "
8273   if (expand_block_move (operands))
8274     DONE;
8275   else
8276     FAIL;
8279 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
8280 ;; register allocator doesn't have a clue about allocating 8 word registers.
8281 ;; rD/rS = r5 is preferred, efficient form.
8282 (define_expand "movmemsi_8reg"
8283   [(parallel [(set (match_operand 0 "" "")
8284                    (match_operand 1 "" ""))
8285               (use (match_operand 2 "" ""))
8286               (use (match_operand 3 "" ""))
8287               (clobber (reg:SI  5))
8288               (clobber (reg:SI  6))
8289               (clobber (reg:SI  7))
8290               (clobber (reg:SI  8))
8291               (clobber (reg:SI  9))
8292               (clobber (reg:SI 10))
8293               (clobber (reg:SI 11))
8294               (clobber (reg:SI 12))
8295               (clobber (match_scratch:SI 4 ""))])]
8296   "TARGET_STRING"
8297   "")
8299 (define_insn ""
8300   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8301         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8302    (use (match_operand:SI 2 "immediate_operand" "i"))
8303    (use (match_operand:SI 3 "immediate_operand" "i"))
8304    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8305    (clobber (reg:SI  6))
8306    (clobber (reg:SI  7))
8307    (clobber (reg:SI  8))
8308    (clobber (reg:SI  9))
8309    (clobber (reg:SI 10))
8310    (clobber (reg:SI 11))
8311    (clobber (reg:SI 12))
8312    (clobber (match_scratch:SI 5 "=X"))]
8313   "TARGET_STRING
8314    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8315        || INTVAL (operands[2]) == 0)
8316    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8317    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8318    && REGNO (operands[4]) == 5"
8319   "lswi %4,%1,%2\;stswi %4,%0,%2"
8320   [(set_attr "type" "store")
8321    (set_attr "update" "yes")
8322    (set_attr "indexed" "yes")
8323    (set_attr "cell_micro" "always")
8324    (set_attr "length" "8")])
8326 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
8327 ;; register allocator doesn't have a clue about allocating 6 word registers.
8328 ;; rD/rS = r5 is preferred, efficient form.
8329 (define_expand "movmemsi_6reg"
8330   [(parallel [(set (match_operand 0 "" "")
8331                    (match_operand 1 "" ""))
8332               (use (match_operand 2 "" ""))
8333               (use (match_operand 3 "" ""))
8334               (clobber (reg:SI  5))
8335               (clobber (reg:SI  6))
8336               (clobber (reg:SI  7))
8337               (clobber (reg:SI  8))
8338               (clobber (reg:SI  9))
8339               (clobber (reg:SI 10))
8340               (clobber (match_scratch:SI 4 ""))])]
8341   "TARGET_STRING"
8342   "")
8344 (define_insn ""
8345   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8346         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8347    (use (match_operand:SI 2 "immediate_operand" "i"))
8348    (use (match_operand:SI 3 "immediate_operand" "i"))
8349    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8350    (clobber (reg:SI  6))
8351    (clobber (reg:SI  7))
8352    (clobber (reg:SI  8))
8353    (clobber (reg:SI  9))
8354    (clobber (reg:SI 10))
8355    (clobber (match_scratch:SI 5 "=X"))]
8356   "TARGET_STRING
8357    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8358    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8359    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8360    && REGNO (operands[4]) == 5"
8361   "lswi %4,%1,%2\;stswi %4,%0,%2"
8362   [(set_attr "type" "store")
8363    (set_attr "update" "yes")
8364    (set_attr "indexed" "yes")
8365    (set_attr "cell_micro" "always")
8366    (set_attr "length" "8")])
8368 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8369 ;; problems with TImode.
8370 ;; rD/rS = r5 is preferred, efficient form.
8371 (define_expand "movmemsi_4reg"
8372   [(parallel [(set (match_operand 0 "" "")
8373                    (match_operand 1 "" ""))
8374               (use (match_operand 2 "" ""))
8375               (use (match_operand 3 "" ""))
8376               (clobber (reg:SI 5))
8377               (clobber (reg:SI 6))
8378               (clobber (reg:SI 7))
8379               (clobber (reg:SI 8))
8380               (clobber (match_scratch:SI 4 ""))])]
8381   "TARGET_STRING"
8382   "")
8384 (define_insn ""
8385   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8386         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8387    (use (match_operand:SI 2 "immediate_operand" "i"))
8388    (use (match_operand:SI 3 "immediate_operand" "i"))
8389    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8390    (clobber (reg:SI 6))
8391    (clobber (reg:SI 7))
8392    (clobber (reg:SI 8))
8393    (clobber (match_scratch:SI 5 "=X"))]
8394   "TARGET_STRING
8395    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8396    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8397    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8398    && REGNO (operands[4]) == 5"
8399   "lswi %4,%1,%2\;stswi %4,%0,%2"
8400   [(set_attr "type" "store")
8401    (set_attr "update" "yes")
8402    (set_attr "indexed" "yes")
8403    (set_attr "cell_micro" "always")
8404    (set_attr "length" "8")])
8406 ;; Move up to 8 bytes at a time.
8407 (define_expand "movmemsi_2reg"
8408   [(parallel [(set (match_operand 0 "" "")
8409                    (match_operand 1 "" ""))
8410               (use (match_operand 2 "" ""))
8411               (use (match_operand 3 "" ""))
8412               (clobber (match_scratch:DI 4 ""))
8413               (clobber (match_scratch:SI 5 ""))])]
8414   "TARGET_STRING && ! TARGET_POWERPC64"
8415   "")
8417 (define_insn ""
8418   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8419         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8420    (use (match_operand:SI 2 "immediate_operand" "i"))
8421    (use (match_operand:SI 3 "immediate_operand" "i"))
8422    (clobber (match_scratch:DI 4 "=&r"))
8423    (clobber (match_scratch:SI 5 "=X"))]
8424   "TARGET_STRING && ! TARGET_POWERPC64
8425    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8426   "lswi %4,%1,%2\;stswi %4,%0,%2"
8427   [(set_attr "type" "store")
8428    (set_attr "update" "yes")
8429    (set_attr "indexed" "yes")
8430    (set_attr "cell_micro" "always")
8431    (set_attr "length" "8")])
8433 ;; Move up to 4 bytes at a time.
8434 (define_expand "movmemsi_1reg"
8435   [(parallel [(set (match_operand 0 "" "")
8436                    (match_operand 1 "" ""))
8437               (use (match_operand 2 "" ""))
8438               (use (match_operand 3 "" ""))
8439               (clobber (match_scratch:SI 4 ""))
8440               (clobber (match_scratch:SI 5 ""))])]
8441   "TARGET_STRING"
8442   "")
8444 (define_insn ""
8445   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8446         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8447    (use (match_operand:SI 2 "immediate_operand" "i"))
8448    (use (match_operand:SI 3 "immediate_operand" "i"))
8449    (clobber (match_scratch:SI 4 "=&r"))
8450    (clobber (match_scratch:SI 5 "=X"))]
8451   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8452   "lswi %4,%1,%2\;stswi %4,%0,%2"
8453   [(set_attr "type" "store")
8454    (set_attr "update" "yes")
8455    (set_attr "indexed" "yes")
8456    (set_attr "cell_micro" "always")
8457    (set_attr "length" "8")])
8459 ;; Define insns that do load or store with update.  Some of these we can
8460 ;; get by using pre-decrement or pre-increment, but the hardware can also
8461 ;; do cases where the increment is not the size of the object.
8463 ;; In all these cases, we use operands 0 and 1 for the register being
8464 ;; incremented because those are the operands that local-alloc will
8465 ;; tie and these are the pair most likely to be tieable (and the ones
8466 ;; that will benefit the most).
8468 (define_insn "*movdi_update1"
8469   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8470         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8471                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8472    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8473         (plus:DI (match_dup 1) (match_dup 2)))]
8474   "TARGET_POWERPC64 && TARGET_UPDATE
8475    && (!avoiding_indexed_address_p (DImode)
8476        || !gpc_reg_operand (operands[2], DImode))"
8477   "@
8478    ldux %3,%0,%2
8479    ldu %3,%2(%0)"
8480   [(set_attr "type" "load")
8481    (set_attr "update" "yes")
8482    (set_attr "indexed" "yes,no")])
8484 (define_insn "movdi_<mode>_update"
8485   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8486                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8487         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8488    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8489         (plus:P (match_dup 1) (match_dup 2)))]
8490   "TARGET_POWERPC64 && TARGET_UPDATE
8491    && (!avoiding_indexed_address_p (Pmode)
8492        || !gpc_reg_operand (operands[2], Pmode)
8493        || (REG_P (operands[0])
8494            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8495   "@
8496    stdux %3,%0,%2
8497    stdu %3,%2(%0)"
8498   [(set_attr "type" "store")
8499    (set_attr "update" "yes")
8500    (set_attr "indexed" "yes,no")])
8502 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8503 ;; needed for stack allocation, even if the user passes -mno-update.
8504 (define_insn "movdi_<mode>_update_stack"
8505   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8506                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8507         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8508    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8509         (plus:P (match_dup 1) (match_dup 2)))]
8510   "TARGET_POWERPC64"
8511   "@
8512    stdux %3,%0,%2
8513    stdu %3,%2(%0)"
8514   [(set_attr "type" "store")
8515    (set_attr "update" "yes")
8516    (set_attr "indexed" "yes,no")])
8518 (define_insn "*movsi_update1"
8519   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8520         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8521                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8522    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8523         (plus:SI (match_dup 1) (match_dup 2)))]
8524   "TARGET_UPDATE
8525    && (!avoiding_indexed_address_p (SImode)
8526        || !gpc_reg_operand (operands[2], SImode))"
8527   "@
8528    lwzux %3,%0,%2
8529    lwzu %3,%2(%0)"
8530   [(set_attr "type" "load")
8531    (set_attr "update" "yes")
8532    (set_attr "indexed" "yes,no")])
8534 (define_insn "*movsi_update2"
8535   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8536         (sign_extend:DI
8537          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8538                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
8539    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8540         (plus:DI (match_dup 1) (match_dup 2)))]
8541   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8542    && !avoiding_indexed_address_p (DImode)"
8543   "lwaux %3,%0,%2"
8544   [(set_attr "type" "load")
8545    (set_attr "sign_extend" "yes")
8546    (set_attr "update" "yes")
8547    (set_attr "indexed" "yes")])
8549 (define_insn "movsi_update"
8550   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8551                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8552         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8553    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8554         (plus:SI (match_dup 1) (match_dup 2)))]
8555   "TARGET_UPDATE
8556    && (!avoiding_indexed_address_p (SImode)
8557        || !gpc_reg_operand (operands[2], SImode)
8558        || (REG_P (operands[0])
8559            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8560   "@
8561    stwux %3,%0,%2
8562    stwu %3,%2(%0)"
8563   [(set_attr "type" "store")
8564    (set_attr "update" "yes")
8565    (set_attr "indexed" "yes,no")])
8567 ;; This is an unconditional pattern; needed for stack allocation, even
8568 ;; if the user passes -mno-update.
8569 (define_insn "movsi_update_stack"
8570   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8571                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8572         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8573    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8574         (plus:SI (match_dup 1) (match_dup 2)))]
8575   ""
8576   "@
8577    stwux %3,%0,%2
8578    stwu %3,%2(%0)"
8579   [(set_attr "type" "store")
8580    (set_attr "update" "yes")
8581    (set_attr "indexed" "yes,no")])
8583 (define_insn "*movhi_update1"
8584   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8585         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8586                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8587    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8588         (plus:SI (match_dup 1) (match_dup 2)))]
8589   "TARGET_UPDATE
8590    && (!avoiding_indexed_address_p (SImode)
8591        || !gpc_reg_operand (operands[2], SImode))"
8592   "@
8593    lhzux %3,%0,%2
8594    lhzu %3,%2(%0)"
8595   [(set_attr "type" "load")
8596    (set_attr "update" "yes")
8597    (set_attr "indexed" "yes,no")])
8599 (define_insn "*movhi_update2"
8600   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8601         (zero_extend:SI
8602          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8603                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8604    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8605         (plus:SI (match_dup 1) (match_dup 2)))]
8606   "TARGET_UPDATE
8607    && (!avoiding_indexed_address_p (SImode)
8608        || !gpc_reg_operand (operands[2], SImode))"
8609   "@
8610    lhzux %3,%0,%2
8611    lhzu %3,%2(%0)"
8612   [(set_attr "type" "load")
8613    (set_attr "update" "yes")
8614    (set_attr "indexed" "yes,no")])
8616 (define_insn "*movhi_update3"
8617   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8618         (sign_extend:SI
8619          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8620                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8621    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8622         (plus:SI (match_dup 1) (match_dup 2)))]
8623   "TARGET_UPDATE && rs6000_gen_cell_microcode
8624    && (!avoiding_indexed_address_p (SImode)
8625        || !gpc_reg_operand (operands[2], SImode))"
8626   "@
8627    lhaux %3,%0,%2
8628    lhau %3,%2(%0)"
8629   [(set_attr "type" "load")
8630    (set_attr "sign_extend" "yes")
8631    (set_attr "update" "yes")
8632    (set_attr "indexed" "yes,no")])
8634 (define_insn "*movhi_update4"
8635   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8636                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8637         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8638    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8639         (plus:SI (match_dup 1) (match_dup 2)))]
8640   "TARGET_UPDATE
8641    && (!avoiding_indexed_address_p (SImode)
8642        || !gpc_reg_operand (operands[2], SImode))"
8643   "@
8644    sthux %3,%0,%2
8645    sthu %3,%2(%0)"
8646   [(set_attr "type" "store")
8647    (set_attr "update" "yes")
8648    (set_attr "indexed" "yes,no")])
8650 (define_insn "*movqi_update1"
8651   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8652         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8653                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8654    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8655         (plus:SI (match_dup 1) (match_dup 2)))]
8656   "TARGET_UPDATE
8657    && (!avoiding_indexed_address_p (SImode)
8658        || !gpc_reg_operand (operands[2], SImode))"
8659   "@
8660    lbzux %3,%0,%2
8661    lbzu %3,%2(%0)"
8662   [(set_attr "type" "load")
8663    (set_attr "update" "yes")
8664    (set_attr "indexed" "yes,no")])
8666 (define_insn "*movqi_update2"
8667   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8668         (zero_extend:SI
8669          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8670                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8671    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8672         (plus:SI (match_dup 1) (match_dup 2)))]
8673   "TARGET_UPDATE
8674    && (!avoiding_indexed_address_p (SImode)
8675        || !gpc_reg_operand (operands[2], SImode))"
8676   "@
8677    lbzux %3,%0,%2
8678    lbzu %3,%2(%0)"
8679   [(set_attr "type" "load")
8680    (set_attr "update" "yes")
8681    (set_attr "indexed" "yes,no")])
8683 (define_insn "*movqi_update3"
8684   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8685                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8686         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
8687    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8688         (plus:SI (match_dup 1) (match_dup 2)))]
8689   "TARGET_UPDATE
8690    && (!avoiding_indexed_address_p (SImode)
8691        || !gpc_reg_operand (operands[2], SImode))"
8692   "@
8693    stbux %3,%0,%2
8694    stbu %3,%2(%0)"
8695   [(set_attr "type" "store")
8696    (set_attr "update" "yes")
8697    (set_attr "indexed" "yes,no")])
8699 (define_insn "*movsf_update1"
8700   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
8701         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8702                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8703    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8704         (plus:SI (match_dup 1) (match_dup 2)))]
8705   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8706    && (!avoiding_indexed_address_p (SImode)
8707        || !gpc_reg_operand (operands[2], SImode))"
8708   "@
8709    lfsux %3,%0,%2
8710    lfsu %3,%2(%0)"
8711   [(set_attr "type" "fpload")
8712    (set_attr "update" "yes")
8713    (set_attr "indexed" "yes,no")])
8715 (define_insn "*movsf_update2"
8716   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8717                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8718         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
8719    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8720         (plus:SI (match_dup 1) (match_dup 2)))]
8721   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8722    && (!avoiding_indexed_address_p (SImode)
8723        || !gpc_reg_operand (operands[2], SImode))"
8724   "@
8725    stfsux %3,%0,%2
8726    stfsu %3,%2(%0)"
8727   [(set_attr "type" "fpstore")
8728    (set_attr "update" "yes")
8729    (set_attr "indexed" "yes,no")])
8731 (define_insn "*movsf_update3"
8732   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
8733         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8734                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8735    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8736         (plus:SI (match_dup 1) (match_dup 2)))]
8737   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8738    && (!avoiding_indexed_address_p (SImode)
8739        || !gpc_reg_operand (operands[2], SImode))"
8740   "@
8741    lwzux %3,%0,%2
8742    lwzu %3,%2(%0)"
8743   [(set_attr "type" "load")
8744    (set_attr "update" "yes")
8745    (set_attr "indexed" "yes,no")])
8747 (define_insn "*movsf_update4"
8748   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8749                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8750         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
8751    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8752         (plus:SI (match_dup 1) (match_dup 2)))]
8753   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8754    && (!avoiding_indexed_address_p (SImode)
8755        || !gpc_reg_operand (operands[2], SImode))"
8756   "@
8757    stwux %3,%0,%2
8758    stwu %3,%2(%0)"
8759   [(set_attr "type" "store")
8760    (set_attr "update" "yes")
8761    (set_attr "indexed" "yes,no")])
8763 (define_insn "*movdf_update1"
8764   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
8765         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8766                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8767    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8768         (plus:SI (match_dup 1) (match_dup 2)))]
8769   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8770    && (!avoiding_indexed_address_p (SImode)
8771        || !gpc_reg_operand (operands[2], SImode))"
8772   "@
8773    lfdux %3,%0,%2
8774    lfdu %3,%2(%0)"
8775   [(set_attr "type" "fpload")
8776    (set_attr "update" "yes")
8777    (set_attr "indexed" "yes,no")])
8779 (define_insn "*movdf_update2"
8780   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8781                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8782         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
8783    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8784         (plus:SI (match_dup 1) (match_dup 2)))]
8785   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8786    && (!avoiding_indexed_address_p (SImode)
8787        || !gpc_reg_operand (operands[2], SImode))"
8788   "@
8789    stfdux %3,%0,%2
8790    stfdu %3,%2(%0)"
8791   [(set_attr "type" "fpstore")
8792    (set_attr "update" "yes")
8793    (set_attr "indexed" "yes,no")])
8796 ;; After inserting conditional returns we can sometimes have
8797 ;; unnecessary register moves.  Unfortunately we cannot have a
8798 ;; modeless peephole here, because some single SImode sets have early
8799 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
8800 ;; sequences, using get_attr_length here will smash the operands
8801 ;; array.  Neither is there an early_cobbler_p predicate.
8802 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
8803 ;; Also this optimization interferes with scalars going into
8804 ;; altivec registers (the code does reloading through the FPRs).
8805 (define_peephole2
8806   [(set (match_operand:DF 0 "gpc_reg_operand" "")
8807         (match_operand:DF 1 "any_operand" ""))
8808    (set (match_operand:DF 2 "gpc_reg_operand" "")
8809         (match_dup 0))]
8810   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
8811    && !TARGET_UPPER_REGS_DF
8812    && peep2_reg_dead_p (2, operands[0])"
8813   [(set (match_dup 2) (match_dup 1))])
8815 (define_peephole2
8816   [(set (match_operand:SF 0 "gpc_reg_operand" "")
8817         (match_operand:SF 1 "any_operand" ""))
8818    (set (match_operand:SF 2 "gpc_reg_operand" "")
8819         (match_dup 0))]
8820   "!TARGET_UPPER_REGS_SF
8821    && peep2_reg_dead_p (2, operands[0])"
8822   [(set (match_dup 2) (match_dup 1))])
8825 ;; TLS support.
8827 ;; Mode attributes for different ABIs.
8828 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
8829 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
8830 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
8831 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
8833 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
8834   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8835         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8836               (match_operand 4 "" "g")))
8837    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8838                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8839                    UNSPEC_TLSGD)
8840    (clobber (reg:SI LR_REGNO))]
8841   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8843   if (TARGET_CMODEL != CMODEL_SMALL)
8844     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
8845            "bl %z3\;nop";
8846   else
8847     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
8849   "&& TARGET_TLS_MARKERS"
8850   [(set (match_dup 0)
8851         (unspec:TLSmode [(match_dup 1)
8852                          (match_dup 2)]
8853                         UNSPEC_TLSGD))
8854    (parallel [(set (match_dup 0)
8855                    (call (mem:TLSmode (match_dup 3))
8856                          (match_dup 4)))
8857               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8858               (clobber (reg:SI LR_REGNO))])]
8859   ""
8860   [(set_attr "type" "two")
8861    (set (attr "length")
8862      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8863                    (const_int 16)
8864                    (const_int 12)))])
8866 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
8867   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8868         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8869               (match_operand 4 "" "g")))
8870    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8871                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8872                    UNSPEC_TLSGD)
8873    (clobber (reg:SI LR_REGNO))]
8874   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
8876   if (flag_pic)
8877     {
8878       if (TARGET_SECURE_PLT && flag_pic == 2)
8879         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
8880       else
8881         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
8882     }
8883   else
8884     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
8886   "&& TARGET_TLS_MARKERS"
8887   [(set (match_dup 0)
8888         (unspec:TLSmode [(match_dup 1)
8889                          (match_dup 2)]
8890                         UNSPEC_TLSGD))
8891    (parallel [(set (match_dup 0)
8892                    (call (mem:TLSmode (match_dup 3))
8893                          (match_dup 4)))
8894               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8895               (clobber (reg:SI LR_REGNO))])]
8896   ""
8897   [(set_attr "type" "two")
8898    (set_attr "length" "8")])
8900 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
8901   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8902         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8903                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8904                         UNSPEC_TLSGD))]
8905   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
8906   "addi %0,%1,%2@got@tlsgd"
8907   "&& TARGET_CMODEL != CMODEL_SMALL"
8908   [(set (match_dup 3)
8909         (high:TLSmode
8910             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
8911    (set (match_dup 0)
8912         (lo_sum:TLSmode (match_dup 3)
8913             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
8914   "
8916   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
8918   [(set (attr "length")
8919      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8920                    (const_int 8)
8921                    (const_int 4)))])
8923 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
8924   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8925      (high:TLSmode
8926        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8927                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8928                        UNSPEC_TLSGD)))]
8929   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8930   "addis %0,%1,%2@got@tlsgd@ha"
8931   [(set_attr "length" "4")])
8933 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
8934   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8935      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
8936        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
8937                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8938                        UNSPEC_TLSGD)))]
8939   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8940   "addi %0,%1,%2@got@tlsgd@l"
8941   [(set_attr "length" "4")])
8943 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
8944   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8945         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8946               (match_operand 2 "" "g")))
8947    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8948                    UNSPEC_TLSGD)
8949    (clobber (reg:SI LR_REGNO))]
8950   "HAVE_AS_TLS && TARGET_TLS_MARKERS
8951    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8952   "bl %z1(%3@tlsgd)\;nop"
8953   [(set_attr "type" "branch")
8954    (set_attr "length" "8")])
8956 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
8957   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8958         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8959               (match_operand 2 "" "g")))
8960    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8961                    UNSPEC_TLSGD)
8962    (clobber (reg:SI LR_REGNO))]
8963   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
8965   if (flag_pic)
8966     {
8967       if (TARGET_SECURE_PLT && flag_pic == 2)
8968         return "bl %z1+32768(%3@tlsgd)@plt";
8969       return "bl %z1(%3@tlsgd)@plt";
8970     }
8971   return "bl %z1(%3@tlsgd)";
8973   [(set_attr "type" "branch")
8974    (set_attr "length" "4")])
8976 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
8977   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8978         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
8979               (match_operand 3 "" "g")))
8980    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
8981                    UNSPEC_TLSLD)
8982    (clobber (reg:SI LR_REGNO))]
8983   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8985   if (TARGET_CMODEL != CMODEL_SMALL)
8986     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
8987            "bl %z2\;nop";
8988   else
8989     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
8991   "&& TARGET_TLS_MARKERS"
8992   [(set (match_dup 0)
8993         (unspec:TLSmode [(match_dup 1)]
8994                         UNSPEC_TLSLD))
8995    (parallel [(set (match_dup 0)
8996                    (call (mem:TLSmode (match_dup 2))
8997                          (match_dup 3)))
8998               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
8999               (clobber (reg:SI LR_REGNO))])]
9000   ""
9001   [(set_attr "type" "two")
9002    (set (attr "length")
9003      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9004                    (const_int 16)
9005                    (const_int 12)))])
9007 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9008   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9009         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9010               (match_operand 3 "" "g")))
9011    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9012                    UNSPEC_TLSLD)
9013    (clobber (reg:SI LR_REGNO))]
9014   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9016   if (flag_pic)
9017     {
9018       if (TARGET_SECURE_PLT && flag_pic == 2)
9019         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9020       else
9021         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9022     }
9023   else
9024     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9026   "&& TARGET_TLS_MARKERS"
9027   [(set (match_dup 0)
9028         (unspec:TLSmode [(match_dup 1)]
9029                         UNSPEC_TLSLD))
9030    (parallel [(set (match_dup 0)
9031                    (call (mem:TLSmode (match_dup 2))
9032                          (match_dup 3)))
9033               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9034               (clobber (reg:SI LR_REGNO))])]
9035   ""
9036   [(set_attr "length" "8")])
9038 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9039   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9040         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9041                         UNSPEC_TLSLD))]
9042   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9043   "addi %0,%1,%&@got@tlsld"
9044   "&& TARGET_CMODEL != CMODEL_SMALL"
9045   [(set (match_dup 2)
9046         (high:TLSmode
9047             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9048    (set (match_dup 0)
9049         (lo_sum:TLSmode (match_dup 2)
9050             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9051   "
9053   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9055   [(set (attr "length")
9056      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9057                    (const_int 8)
9058                    (const_int 4)))])
9060 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9061   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9062      (high:TLSmode
9063        (unspec:TLSmode [(const_int 0)
9064                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9065                        UNSPEC_TLSLD)))]
9066   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9067   "addis %0,%1,%&@got@tlsld@ha"
9068   [(set_attr "length" "4")])
9070 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9071   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9072      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9073        (unspec:TLSmode [(const_int 0)
9074                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9075                        UNSPEC_TLSLD)))]
9076   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9077   "addi %0,%1,%&@got@tlsld@l"
9078   [(set_attr "length" "4")])
9080 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9081   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9082         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9083               (match_operand 2 "" "g")))
9084    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9085    (clobber (reg:SI LR_REGNO))]
9086   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9087    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9088   "bl %z1(%&@tlsld)\;nop"
9089   [(set_attr "type" "branch")
9090    (set_attr "length" "8")])
9092 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9093   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9094         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9095               (match_operand 2 "" "g")))
9096    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9097    (clobber (reg:SI LR_REGNO))]
9098   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9100   if (flag_pic)
9101     {
9102       if (TARGET_SECURE_PLT && flag_pic == 2)
9103         return "bl %z1+32768(%&@tlsld)@plt";
9104       return "bl %z1(%&@tlsld)@plt";
9105     }
9106   return "bl %z1(%&@tlsld)";
9108   [(set_attr "type" "branch")
9109    (set_attr "length" "4")])
9111 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9112   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9113         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9114                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9115                         UNSPEC_TLSDTPREL))]
9116   "HAVE_AS_TLS"
9117   "addi %0,%1,%2@dtprel")
9119 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9120   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9121         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9122                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9123                         UNSPEC_TLSDTPRELHA))]
9124   "HAVE_AS_TLS"
9125   "addis %0,%1,%2@dtprel@ha")
9127 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9128   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9129         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9130                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9131                         UNSPEC_TLSDTPRELLO))]
9132   "HAVE_AS_TLS"
9133   "addi %0,%1,%2@dtprel@l")
9135 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9136   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9137         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9138                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9139                         UNSPEC_TLSGOTDTPREL))]
9140   "HAVE_AS_TLS"
9141   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9142   "&& TARGET_CMODEL != CMODEL_SMALL"
9143   [(set (match_dup 3)
9144         (high:TLSmode
9145             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9146    (set (match_dup 0)
9147         (lo_sum:TLSmode (match_dup 3)
9148             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9149   "
9151   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9153   [(set (attr "length")
9154      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9155                    (const_int 8)
9156                    (const_int 4)))])
9158 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9159   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9160      (high:TLSmode
9161        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9162                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9163                        UNSPEC_TLSGOTDTPREL)))]
9164   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9165   "addis %0,%1,%2@got@dtprel@ha"
9166   [(set_attr "length" "4")])
9168 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9169   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9170      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9171          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9172                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9173                          UNSPEC_TLSGOTDTPREL)))]
9174   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9175   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9176   [(set_attr "length" "4")])
9178 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9179   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9180         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9181                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9182                         UNSPEC_TLSTPREL))]
9183   "HAVE_AS_TLS"
9184   "addi %0,%1,%2@tprel")
9186 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9187   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9188         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9189                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9190                         UNSPEC_TLSTPRELHA))]
9191   "HAVE_AS_TLS"
9192   "addis %0,%1,%2@tprel@ha")
9194 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9195   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9196         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9197                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9198                         UNSPEC_TLSTPRELLO))]
9199   "HAVE_AS_TLS"
9200   "addi %0,%1,%2@tprel@l")
9202 ;; "b" output constraint here and on tls_tls input to support linker tls
9203 ;; optimization.  The linker may edit the instructions emitted by a
9204 ;; tls_got_tprel/tls_tls pair to addis,addi.
9205 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9206   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9207         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9208                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9209                         UNSPEC_TLSGOTTPREL))]
9210   "HAVE_AS_TLS"
9211   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9212   "&& TARGET_CMODEL != CMODEL_SMALL"
9213   [(set (match_dup 3)
9214         (high:TLSmode
9215             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9216    (set (match_dup 0)
9217         (lo_sum:TLSmode (match_dup 3)
9218             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9219   "
9221   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9223   [(set (attr "length")
9224      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9225                    (const_int 8)
9226                    (const_int 4)))])
9228 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9229   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9230      (high:TLSmode
9231        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9232                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9233                        UNSPEC_TLSGOTTPREL)))]
9234   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9235   "addis %0,%1,%2@got@tprel@ha"
9236   [(set_attr "length" "4")])
9238 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9239   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9240      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9241          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9242                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9243                          UNSPEC_TLSGOTTPREL)))]
9244   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9245   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9246   [(set_attr "length" "4")])
9248 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9249   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9250         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9251                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9252                         UNSPEC_TLSTLS))]
9253   "TARGET_ELF && HAVE_AS_TLS"
9254   "add %0,%1,%2@tls")
9256 (define_expand "tls_get_tpointer"
9257   [(set (match_operand:SI 0 "gpc_reg_operand" "")
9258         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9259   "TARGET_XCOFF && HAVE_AS_TLS"
9260   "
9262   emit_insn (gen_tls_get_tpointer_internal ());
9263   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9264   DONE;
9267 (define_insn "tls_get_tpointer_internal"
9268   [(set (reg:SI 3)
9269         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9270    (clobber (reg:SI LR_REGNO))]
9271   "TARGET_XCOFF && HAVE_AS_TLS"
9272   "bla __get_tpointer")
9274 (define_expand "tls_get_addr<mode>"
9275   [(set (match_operand:P 0 "gpc_reg_operand" "")
9276         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9277                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9278   "TARGET_XCOFF && HAVE_AS_TLS"
9279   "
9281   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9282   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9283   emit_insn (gen_tls_get_addr_internal<mode> ());
9284   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9285   DONE;
9288 (define_insn "tls_get_addr_internal<mode>"
9289   [(set (reg:P 3)
9290         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9291    (clobber (reg:P 0))
9292    (clobber (reg:P 4))
9293    (clobber (reg:P 5))
9294    (clobber (reg:P 11))
9295    (clobber (reg:CC CR0_REGNO))
9296    (clobber (reg:P LR_REGNO))]
9297   "TARGET_XCOFF && HAVE_AS_TLS"
9298   "bla __tls_get_addr")
9300 ;; Next come insns related to the calling sequence.
9302 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9303 ;; We move the back-chain and decrement the stack pointer.
9305 (define_expand "allocate_stack"
9306   [(set (match_operand 0 "gpc_reg_operand" "")
9307         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9308    (set (reg 1)
9309         (minus (reg 1) (match_dup 1)))]
9310   ""
9311   "
9312 { rtx chain = gen_reg_rtx (Pmode);
9313   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9314   rtx neg_op0;
9315   rtx insn, par, set, mem;
9317   emit_move_insn (chain, stack_bot);
9319   /* Check stack bounds if necessary.  */
9320   if (crtl->limit_stack)
9321     {
9322       rtx available;
9323       available = expand_binop (Pmode, sub_optab,
9324                                 stack_pointer_rtx, stack_limit_rtx,
9325                                 NULL_RTX, 1, OPTAB_WIDEN);
9326       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9327     }
9329   if (GET_CODE (operands[1]) != CONST_INT
9330       || INTVAL (operands[1]) < -32767
9331       || INTVAL (operands[1]) > 32768)
9332     {
9333       neg_op0 = gen_reg_rtx (Pmode);
9334       if (TARGET_32BIT)
9335         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9336       else
9337         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9338     }
9339   else
9340     neg_op0 = GEN_INT (- INTVAL (operands[1]));
9342   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9343                                        : gen_movdi_di_update_stack))
9344                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9345                          chain));
9346   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9347      it now and set the alias set/attributes. The above gen_*_update
9348      calls will generate a PARALLEL with the MEM set being the first
9349      operation. */
9350   par = PATTERN (insn);
9351   gcc_assert (GET_CODE (par) == PARALLEL);
9352   set = XVECEXP (par, 0, 0);
9353   gcc_assert (GET_CODE (set) == SET);
9354   mem = SET_DEST (set);
9355   gcc_assert (MEM_P (mem));
9356   MEM_NOTRAP_P (mem) = 1;
9357   set_mem_alias_set (mem, get_frame_alias_set ());
9359   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9360   DONE;
9363 ;; These patterns say how to save and restore the stack pointer.  We need not
9364 ;; save the stack pointer at function level since we are careful to
9365 ;; preserve the backchain.  At block level, we have to restore the backchain
9366 ;; when we restore the stack pointer.
9368 ;; For nonlocal gotos, we must save both the stack pointer and its
9369 ;; backchain and restore both.  Note that in the nonlocal case, the
9370 ;; save area is a memory location.
9372 (define_expand "save_stack_function"
9373   [(match_operand 0 "any_operand" "")
9374    (match_operand 1 "any_operand" "")]
9375   ""
9376   "DONE;")
9378 (define_expand "restore_stack_function"
9379   [(match_operand 0 "any_operand" "")
9380    (match_operand 1 "any_operand" "")]
9381   ""
9382   "DONE;")
9384 ;; Adjust stack pointer (op0) to a new value (op1).
9385 ;; First copy old stack backchain to new location, and ensure that the
9386 ;; scheduler won't reorder the sp assignment before the backchain write.
9387 (define_expand "restore_stack_block"
9388   [(set (match_dup 2) (match_dup 3))
9389    (set (match_dup 4) (match_dup 2))
9390    (match_dup 5)
9391    (set (match_operand 0 "register_operand" "")
9392         (match_operand 1 "register_operand" ""))]
9393   ""
9394   "
9396   rtvec p;
9398   operands[1] = force_reg (Pmode, operands[1]);
9399   operands[2] = gen_reg_rtx (Pmode);
9400   operands[3] = gen_frame_mem (Pmode, operands[0]);
9401   operands[4] = gen_frame_mem (Pmode, operands[1]);
9402   p = rtvec_alloc (1);
9403   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9404                                   const0_rtx);
9405   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9408 (define_expand "save_stack_nonlocal"
9409   [(set (match_dup 3) (match_dup 4))
9410    (set (match_operand 0 "memory_operand" "") (match_dup 3))
9411    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9412   ""
9413   "
9415   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9417   /* Copy the backchain to the first word, sp to the second.  */
9418   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9419   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9420   operands[3] = gen_reg_rtx (Pmode);
9421   operands[4] = gen_frame_mem (Pmode, operands[1]);
9424 (define_expand "restore_stack_nonlocal"
9425   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9426    (set (match_dup 3) (match_dup 4))
9427    (set (match_dup 5) (match_dup 2))
9428    (match_dup 6)
9429    (set (match_operand 0 "register_operand" "") (match_dup 3))]
9430   ""
9431   "
9433   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9434   rtvec p;
9436   /* Restore the backchain from the first word, sp from the second.  */
9437   operands[2] = gen_reg_rtx (Pmode);
9438   operands[3] = gen_reg_rtx (Pmode);
9439   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9440   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9441   operands[5] = gen_frame_mem (Pmode, operands[3]);
9442   p = rtvec_alloc (1);
9443   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9444                                   const0_rtx);
9445   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9448 ;; TOC register handling.
9450 ;; Code to initialize the TOC register...
9452 (define_insn "load_toc_aix_si"
9453   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9454                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9455               (use (reg:SI 2))])]
9456   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9457   "*
9459   char buf[30];
9460   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9461   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9462   operands[2] = gen_rtx_REG (Pmode, 2);
9463   return \"lwz %0,%1(%2)\";
9465   [(set_attr "type" "load")
9466    (set_attr "update" "no")
9467    (set_attr "indexed" "no")])
9469 (define_insn "load_toc_aix_di"
9470   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9471                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9472               (use (reg:DI 2))])]
9473   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9474   "*
9476   char buf[30];
9477 #ifdef TARGET_RELOCATABLE
9478   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9479                                !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
9480 #else
9481   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9482 #endif
9483   if (TARGET_ELF)
9484     strcat (buf, \"@toc\");
9485   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9486   operands[2] = gen_rtx_REG (Pmode, 2);
9487   return \"ld %0,%1(%2)\";
9489   [(set_attr "type" "load")
9490    (set_attr "update" "no")
9491    (set_attr "indexed" "no")])
9493 (define_insn "load_toc_v4_pic_si"
9494   [(set (reg:SI LR_REGNO)
9495         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9496   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9497   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9498   [(set_attr "type" "branch")
9499    (set_attr "length" "4")])
9501 (define_expand "load_toc_v4_PIC_1"
9502   [(parallel [(set (reg:SI LR_REGNO)
9503                    (match_operand:SI 0 "immediate_operand" "s"))
9504               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9505   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9506    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9507   "")
9509 (define_insn "load_toc_v4_PIC_1_normal"
9510   [(set (reg:SI LR_REGNO)
9511         (match_operand:SI 0 "immediate_operand" "s"))
9512    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9513   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9514    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9515   "bcl 20,31,%0\\n%0:"
9516   [(set_attr "type" "branch")
9517    (set_attr "length" "4")
9518    (set_attr "cannot_copy" "yes")])
9520 (define_insn "load_toc_v4_PIC_1_476"
9521   [(set (reg:SI LR_REGNO)
9522         (match_operand:SI 0 "immediate_operand" "s"))
9523    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9524   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9525    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9526   "*
9528   char name[32];
9529   static char templ[32];
9531   get_ppc476_thunk_name (name);
9532   sprintf (templ, \"bl %s\\n%%0:\", name);
9533   return templ;
9535   [(set_attr "type" "branch")
9536    (set_attr "length" "4")
9537    (set_attr "cannot_copy" "yes")])
9539 (define_expand "load_toc_v4_PIC_1b"
9540   [(parallel [(set (reg:SI LR_REGNO)
9541                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9542                                (label_ref (match_operand 1 "" ""))]
9543                            UNSPEC_TOCPTR))
9544               (match_dup 1)])]
9545   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9546   "")
9548 (define_insn "load_toc_v4_PIC_1b_normal"
9549   [(set (reg:SI LR_REGNO)
9550         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9551                     (label_ref (match_operand 1 "" ""))]
9552                 UNSPEC_TOCPTR))
9553    (match_dup 1)]
9554   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9555   "bcl 20,31,$+8\;.long %0-$"
9556   [(set_attr "type" "branch")
9557    (set_attr "length" "8")])
9559 (define_insn "load_toc_v4_PIC_1b_476"
9560   [(set (reg:SI LR_REGNO)
9561         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9562                     (label_ref (match_operand 1 "" ""))]
9563                 UNSPEC_TOCPTR))
9564    (match_dup 1)]
9565   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9566   "*
9568   char name[32];
9569   static char templ[32];
9571   get_ppc476_thunk_name (name);
9572   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9573   return templ;
9575   [(set_attr "type" "branch")
9576    (set_attr "length" "16")])
9578 (define_insn "load_toc_v4_PIC_2"
9579   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9580         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9581                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9582                              (match_operand:SI 3 "immediate_operand" "s")))))]
9583   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9584   "lwz %0,%2-%3(%1)"
9585   [(set_attr "type" "load")])
9587 (define_insn "load_toc_v4_PIC_3b"
9588   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9589         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9590                  (high:SI
9591                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9592                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9593   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9594   "addis %0,%1,%2-%3@ha")
9596 (define_insn "load_toc_v4_PIC_3c"
9597   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9598         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9599                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9600                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9601   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9602   "addi %0,%1,%2-%3@l")
9604 ;; If the TOC is shared over a translation unit, as happens with all
9605 ;; the kinds of PIC that we support, we need to restore the TOC
9606 ;; pointer only when jumping over units of translation.
9607 ;; On Darwin, we need to reload the picbase.
9609 (define_expand "builtin_setjmp_receiver"
9610   [(use (label_ref (match_operand 0 "" "")))]
9611   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9612    || (TARGET_TOC && TARGET_MINIMAL_TOC)
9613    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9614   "
9616 #if TARGET_MACHO
9617   if (DEFAULT_ABI == ABI_DARWIN)
9618     {
9619       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9620       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9621       rtx tmplabrtx;
9622       char tmplab[20];
9624       crtl->uses_pic_offset_table = 1;
9625       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9626                                   CODE_LABEL_NUMBER (operands[0]));
9627       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9629       emit_insn (gen_load_macho_picbase (tmplabrtx));
9630       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9631       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9632     }
9633   else
9634 #endif
9635     rs6000_emit_load_toc_table (FALSE);
9636   DONE;
9639 ;; Largetoc support
9640 (define_insn "*largetoc_high"
9641   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9642         (high:DI
9643           (unspec [(match_operand:DI 1 "" "")
9644                    (match_operand:DI 2 "gpc_reg_operand" "b")]
9645                   UNSPEC_TOCREL)))]
9646    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9647    "addis %0,%2,%1@toc@ha")
9649 (define_insn "*largetoc_high_aix<mode>"
9650   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9651         (high:P
9652           (unspec [(match_operand:P 1 "" "")
9653                    (match_operand:P 2 "gpc_reg_operand" "b")]
9654                   UNSPEC_TOCREL)))]
9655    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9656    "addis %0,%1@u(%2)")
9658 (define_insn "*largetoc_high_plus"
9659   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9660         (high:DI
9661           (plus:DI
9662             (unspec [(match_operand:DI 1 "" "")
9663                      (match_operand:DI 2 "gpc_reg_operand" "b")]
9664                     UNSPEC_TOCREL)
9665             (match_operand:DI 3 "add_cint_operand" "n"))))]
9666    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9667    "addis %0,%2,%1+%3@toc@ha")
9669 (define_insn "*largetoc_high_plus_aix<mode>"
9670   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9671         (high:P
9672           (plus:P
9673             (unspec [(match_operand:P 1 "" "")
9674                      (match_operand:P 2 "gpc_reg_operand" "b")]
9675                     UNSPEC_TOCREL)
9676             (match_operand:P 3 "add_cint_operand" "n"))))]
9677    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9678    "addis %0,%1+%3@u(%2)")
9680 (define_insn "*largetoc_low"
9681   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9682         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9683                    (match_operand:DI 2 "" "")))]
9684    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9685    "addi %0,%1,%2@l")
9687 (define_insn "*largetoc_low_aix<mode>"
9688   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9689         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9690                    (match_operand:P 2 "" "")))]
9691    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9692    "la %0,%2@l(%1)")
9694 (define_insn_and_split "*tocref<mode>"
9695   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9696         (match_operand:P 1 "small_toc_ref" "R"))]
9697    "TARGET_TOC"
9698    "la %0,%a1"
9699    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
9700   [(set (match_dup 0) (high:P (match_dup 1)))
9701    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
9703 ;; Elf specific ways of loading addresses for non-PIC code.
9704 ;; The output of this could be r0, but we make a very strong
9705 ;; preference for a base register because it will usually
9706 ;; be needed there.
9707 (define_insn "elf_high"
9708   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
9709         (high:SI (match_operand 1 "" "")))]
9710   "TARGET_ELF && ! TARGET_64BIT"
9711   "lis %0,%1@ha")
9713 (define_insn "elf_low"
9714   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9715         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9716                    (match_operand 2 "" "")))]
9717    "TARGET_ELF && ! TARGET_64BIT"
9718    "la %0,%2@l(%1)")
9720 ;; Call and call_value insns
9721 (define_expand "call"
9722   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
9723                     (match_operand 1 "" ""))
9724               (use (match_operand 2 "" ""))
9725               (clobber (reg:SI LR_REGNO))])]
9726   ""
9727   "
9729 #if TARGET_MACHO
9730   if (MACHOPIC_INDIRECT)
9731     operands[0] = machopic_indirect_call_target (operands[0]);
9732 #endif
9734   gcc_assert (GET_CODE (operands[0]) == MEM);
9735   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
9737   operands[0] = XEXP (operands[0], 0);
9739   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9740     {
9741       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
9742       DONE;
9743     }
9745   if (GET_CODE (operands[0]) != SYMBOL_REF
9746       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
9747     {
9748       if (INTVAL (operands[2]) & CALL_LONG)
9749         operands[0] = rs6000_longcall_ref (operands[0]);
9751       switch (DEFAULT_ABI)
9752         {
9753         case ABI_V4:
9754         case ABI_DARWIN:
9755           operands[0] = force_reg (Pmode, operands[0]);
9756           break;
9758         default:
9759           gcc_unreachable ();
9760         }
9761     }
9764 (define_expand "call_value"
9765   [(parallel [(set (match_operand 0 "" "")
9766                    (call (mem:SI (match_operand 1 "address_operand" ""))
9767                          (match_operand 2 "" "")))
9768               (use (match_operand 3 "" ""))
9769               (clobber (reg:SI LR_REGNO))])]
9770   ""
9771   "
9773 #if TARGET_MACHO
9774   if (MACHOPIC_INDIRECT)
9775     operands[1] = machopic_indirect_call_target (operands[1]);
9776 #endif
9778   gcc_assert (GET_CODE (operands[1]) == MEM);
9779   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
9781   operands[1] = XEXP (operands[1], 0);
9783   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9784     {
9785       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
9786       DONE;
9787     }
9789   if (GET_CODE (operands[1]) != SYMBOL_REF
9790       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
9791     {
9792       if (INTVAL (operands[3]) & CALL_LONG)
9793         operands[1] = rs6000_longcall_ref (operands[1]);
9795       switch (DEFAULT_ABI)
9796         {
9797         case ABI_V4:
9798         case ABI_DARWIN:
9799           operands[1] = force_reg (Pmode, operands[1]);
9800           break;
9802         default:
9803           gcc_unreachable ();
9804         }
9805     }
9808 ;; Call to function in current module.  No TOC pointer reload needed.
9809 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
9810 ;; either the function was not prototyped, or it was prototyped as a
9811 ;; variable argument function.  It is > 0 if FP registers were passed
9812 ;; and < 0 if they were not.
9814 (define_insn "*call_local32"
9815   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
9816          (match_operand 1 "" "g,g"))
9817    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9818    (clobber (reg:SI LR_REGNO))]
9819   "(INTVAL (operands[2]) & CALL_LONG) == 0"
9820   "*
9822   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9823     output_asm_insn (\"crxor 6,6,6\", operands);
9825   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9826     output_asm_insn (\"creqv 6,6,6\", operands);
9828   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9830   [(set_attr "type" "branch")
9831    (set_attr "length" "4,8")])
9833 (define_insn "*call_local64"
9834   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
9835          (match_operand 1 "" "g,g"))
9836    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9837    (clobber (reg:SI LR_REGNO))]
9838   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
9839   "*
9841   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9842     output_asm_insn (\"crxor 6,6,6\", operands);
9844   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9845     output_asm_insn (\"creqv 6,6,6\", operands);
9847   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9849   [(set_attr "type" "branch")
9850    (set_attr "length" "4,8")])
9852 (define_insn "*call_value_local32"
9853   [(set (match_operand 0 "" "")
9854         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
9855               (match_operand 2 "" "g,g")))
9856    (use (match_operand:SI 3 "immediate_operand" "O,n"))
9857    (clobber (reg:SI LR_REGNO))]
9858   "(INTVAL (operands[3]) & CALL_LONG) == 0"
9859   "*
9861   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9862     output_asm_insn (\"crxor 6,6,6\", operands);
9864   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9865     output_asm_insn (\"creqv 6,6,6\", operands);
9867   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9869   [(set_attr "type" "branch")
9870    (set_attr "length" "4,8")])
9873 (define_insn "*call_value_local64"
9874   [(set (match_operand 0 "" "")
9875         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
9876               (match_operand 2 "" "g,g")))
9877    (use (match_operand:SI 3 "immediate_operand" "O,n"))
9878    (clobber (reg:SI LR_REGNO))]
9879   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
9880   "*
9882   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9883     output_asm_insn (\"crxor 6,6,6\", operands);
9885   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9886     output_asm_insn (\"creqv 6,6,6\", operands);
9888   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9890   [(set_attr "type" "branch")
9891    (set_attr "length" "4,8")])
9894 ;; A function pointer under System V is just a normal pointer
9895 ;; operands[0] is the function pointer
9896 ;; operands[1] is the stack size to clean up
9897 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
9898 ;; which indicates how to set cr1
9900 (define_insn "*call_indirect_nonlocal_sysv<mode>"
9901   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
9902          (match_operand 1 "" "g,g,g,g"))
9903    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
9904    (clobber (reg:SI LR_REGNO))]
9905   "DEFAULT_ABI == ABI_V4
9906    || DEFAULT_ABI == ABI_DARWIN"
9908   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9909     output_asm_insn ("crxor 6,6,6", operands);
9911   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9912     output_asm_insn ("creqv 6,6,6", operands);
9914   return "b%T0l";
9916   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
9917    (set_attr "length" "4,4,8,8")])
9919 (define_insn_and_split "*call_nonlocal_sysv<mode>"
9920   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9921          (match_operand 1 "" "g,g"))
9922    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9923    (clobber (reg:SI LR_REGNO))]
9924   "(DEFAULT_ABI == ABI_DARWIN
9925    || (DEFAULT_ABI == ABI_V4
9926        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
9928   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9929     output_asm_insn ("crxor 6,6,6", operands);
9931   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9932     output_asm_insn ("creqv 6,6,6", operands);
9934 #if TARGET_MACHO
9935   return output_call(insn, operands, 0, 2);
9936 #else
9937   if (DEFAULT_ABI == ABI_V4 && flag_pic)
9938     {
9939       gcc_assert (!TARGET_SECURE_PLT);
9940       return "bl %z0@plt";
9941     }
9942   else
9943     return "bl %z0";
9944 #endif
9946   "DEFAULT_ABI == ABI_V4
9947    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9948    && (INTVAL (operands[2]) & CALL_LONG) == 0"
9949   [(parallel [(call (mem:SI (match_dup 0))
9950                     (match_dup 1))
9951               (use (match_dup 2))
9952               (use (match_dup 3))
9953               (clobber (reg:SI LR_REGNO))])]
9955   operands[3] = pic_offset_table_rtx;
9957   [(set_attr "type" "branch,branch")
9958    (set_attr "length" "4,8")])
9960 (define_insn "*call_nonlocal_sysv_secure<mode>"
9961   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9962          (match_operand 1 "" "g,g"))
9963    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9964    (use (match_operand:SI 3 "register_operand" "r,r"))
9965    (clobber (reg:SI LR_REGNO))]
9966   "(DEFAULT_ABI == ABI_V4
9967     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9968     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
9970   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9971     output_asm_insn ("crxor 6,6,6", operands);
9973   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9974     output_asm_insn ("creqv 6,6,6", operands);
9976   if (flag_pic == 2)
9977     /* The magic 32768 offset here and in the other sysv call insns
9978        corresponds to the offset of r30 in .got2, as given by LCTOC1.
9979        See sysv4.h:toc_section.  */
9980     return "bl %z0+32768@plt";
9981   else
9982     return "bl %z0@plt";
9984   [(set_attr "type" "branch,branch")
9985    (set_attr "length" "4,8")])
9987 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
9988   [(set (match_operand 0 "" "")
9989         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
9990               (match_operand 2 "" "g,g,g,g")))
9991    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
9992    (clobber (reg:SI LR_REGNO))]
9993   "DEFAULT_ABI == ABI_V4
9994    || DEFAULT_ABI == ABI_DARWIN"
9996   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9997     output_asm_insn ("crxor 6,6,6", operands);
9999   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10000     output_asm_insn ("creqv 6,6,6", operands);
10002   return "b%T1l";
10004   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10005    (set_attr "length" "4,4,8,8")])
10007 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10008   [(set (match_operand 0 "" "")
10009         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10010               (match_operand 2 "" "g,g")))
10011    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10012    (clobber (reg:SI LR_REGNO))]
10013   "(DEFAULT_ABI == ABI_DARWIN
10014    || (DEFAULT_ABI == ABI_V4
10015        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10017   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10018     output_asm_insn ("crxor 6,6,6", operands);
10020   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10021     output_asm_insn ("creqv 6,6,6", operands);
10023 #if TARGET_MACHO
10024   return output_call(insn, operands, 1, 3);
10025 #else
10026   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10027     {
10028       gcc_assert (!TARGET_SECURE_PLT);
10029       return "bl %z1@plt";
10030     }
10031   else
10032     return "bl %z1";
10033 #endif
10035   "DEFAULT_ABI == ABI_V4
10036    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10037    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10038   [(parallel [(set (match_dup 0)
10039                    (call (mem:SI (match_dup 1))
10040                          (match_dup 2)))
10041               (use (match_dup 3))
10042               (use (match_dup 4))
10043               (clobber (reg:SI LR_REGNO))])]
10045   operands[4] = pic_offset_table_rtx;
10047   [(set_attr "type" "branch,branch")
10048    (set_attr "length" "4,8")])
10050 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10051   [(set (match_operand 0 "" "")
10052         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10053               (match_operand 2 "" "g,g")))
10054    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10055    (use (match_operand:SI 4 "register_operand" "r,r"))
10056    (clobber (reg:SI LR_REGNO))]
10057   "(DEFAULT_ABI == ABI_V4
10058     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10059     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10061   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10062     output_asm_insn ("crxor 6,6,6", operands);
10064   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10065     output_asm_insn ("creqv 6,6,6", operands);
10067   if (flag_pic == 2)
10068     return "bl %z1+32768@plt";
10069   else
10070     return "bl %z1@plt";
10072   [(set_attr "type" "branch,branch")
10073    (set_attr "length" "4,8")])
10076 ;; Call to AIX abi function in the same module.
10078 (define_insn "*call_local_aix<mode>"
10079   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10080          (match_operand 1 "" "g"))
10081    (clobber (reg:P LR_REGNO))]
10082   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10083   "bl %z0"
10084   [(set_attr "type" "branch")
10085    (set_attr "length" "4")])
10087 (define_insn "*call_value_local_aix<mode>"
10088   [(set (match_operand 0 "" "")
10089         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10090               (match_operand 2 "" "g")))
10091    (clobber (reg:P LR_REGNO))]
10092   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10093   "bl %z1"
10094   [(set_attr "type" "branch")
10095    (set_attr "length" "4")])
10097 ;; Call to AIX abi function which may be in another module.
10098 ;; Restore the TOC pointer (r2) after the call.
10100 (define_insn "*call_nonlocal_aix<mode>"
10101   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10102          (match_operand 1 "" "g"))
10103    (clobber (reg:P LR_REGNO))]
10104   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10105   "bl %z0\;nop"
10106   [(set_attr "type" "branch")
10107    (set_attr "length" "8")])
10109 (define_insn "*call_value_nonlocal_aix<mode>"
10110   [(set (match_operand 0 "" "")
10111         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10112               (match_operand 2 "" "g")))
10113    (clobber (reg:P LR_REGNO))]
10114   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10115   "bl %z1\;nop"
10116   [(set_attr "type" "branch")
10117    (set_attr "length" "8")])
10119 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10120 ;; Operand0 is the addresss of the function to call
10121 ;; Operand2 is the location in the function descriptor to load r2 from
10122 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10124 (define_insn "*call_indirect_aix<mode>"
10125   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10126          (match_operand 1 "" "g,g"))
10127    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10128    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10129    (clobber (reg:P LR_REGNO))]
10130   "DEFAULT_ABI == ABI_AIX"
10131   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10132   [(set_attr "type" "jmpreg")
10133    (set_attr "length" "12")])
10135 (define_insn "*call_value_indirect_aix<mode>"
10136   [(set (match_operand 0 "" "")
10137         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10138               (match_operand 2 "" "g,g")))
10139    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10140    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10141    (clobber (reg:P LR_REGNO))]
10142   "DEFAULT_ABI == ABI_AIX"
10143   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10144   [(set_attr "type" "jmpreg")
10145    (set_attr "length" "12")])
10147 ;; Call to indirect functions with the ELFv2 ABI.
10148 ;; Operand0 is the addresss of the function to call
10149 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10151 (define_insn "*call_indirect_elfv2<mode>"
10152   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10153          (match_operand 1 "" "g,g"))
10154    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10155    (clobber (reg:P LR_REGNO))]
10156   "DEFAULT_ABI == ABI_ELFv2"
10157   "b%T0l\;<ptrload> 2,%2(1)"
10158   [(set_attr "type" "jmpreg")
10159    (set_attr "length" "8")])
10161 (define_insn "*call_value_indirect_elfv2<mode>"
10162   [(set (match_operand 0 "" "")
10163         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10164               (match_operand 2 "" "g,g")))
10165    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10166    (clobber (reg:P LR_REGNO))]
10167   "DEFAULT_ABI == ABI_ELFv2"
10168   "b%T1l\;<ptrload> 2,%3(1)"
10169   [(set_attr "type" "jmpreg")
10170    (set_attr "length" "8")])
10173 ;; Call subroutine returning any type.
10174 (define_expand "untyped_call"
10175   [(parallel [(call (match_operand 0 "" "")
10176                     (const_int 0))
10177               (match_operand 1 "" "")
10178               (match_operand 2 "" "")])]
10179   ""
10180   "
10182   int i;
10184   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10186   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10187     {
10188       rtx set = XVECEXP (operands[2], 0, i);
10189       emit_move_insn (SET_DEST (set), SET_SRC (set));
10190     }
10192   /* The optimizer does not know that the call sets the function value
10193      registers we stored in the result block.  We avoid problems by
10194      claiming that all hard registers are used and clobbered at this
10195      point.  */
10196   emit_insn (gen_blockage ());
10198   DONE;
10201 ;; sibling call patterns
10202 (define_expand "sibcall"
10203   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10204                     (match_operand 1 "" ""))
10205               (use (match_operand 2 "" ""))
10206               (use (reg:SI LR_REGNO))
10207               (simple_return)])]
10208   ""
10209   "
10211 #if TARGET_MACHO
10212   if (MACHOPIC_INDIRECT)
10213     operands[0] = machopic_indirect_call_target (operands[0]);
10214 #endif
10216   gcc_assert (GET_CODE (operands[0]) == MEM);
10217   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10219   operands[0] = XEXP (operands[0], 0);
10221   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10222     {
10223       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10224       DONE;
10225     }
10228 (define_expand "sibcall_value"
10229   [(parallel [(set (match_operand 0 "register_operand" "")
10230                 (call (mem:SI (match_operand 1 "address_operand" ""))
10231                       (match_operand 2 "" "")))
10232               (use (match_operand 3 "" ""))
10233               (use (reg:SI LR_REGNO))
10234               (simple_return)])]
10235   ""
10236   "
10238 #if TARGET_MACHO
10239   if (MACHOPIC_INDIRECT)
10240     operands[1] = machopic_indirect_call_target (operands[1]);
10241 #endif
10243   gcc_assert (GET_CODE (operands[1]) == MEM);
10244   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10246   operands[1] = XEXP (operands[1], 0);
10248   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10249     {
10250       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10251       DONE;
10252     }
10255 ;; this and similar patterns must be marked as using LR, otherwise
10256 ;; dataflow will try to delete the store into it.  This is true
10257 ;; even when the actual reg to jump to is in CTR, when LR was
10258 ;; saved and restored around the PIC-setting BCL.
10259 (define_insn "*sibcall_local32"
10260   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10261          (match_operand 1 "" "g,g"))
10262    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10263    (use (reg:SI LR_REGNO))
10264    (simple_return)]
10265   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10266   "*
10268   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10269     output_asm_insn (\"crxor 6,6,6\", operands);
10271   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10272     output_asm_insn (\"creqv 6,6,6\", operands);
10274   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10276   [(set_attr "type" "branch")
10277    (set_attr "length" "4,8")])
10279 (define_insn "*sibcall_local64"
10280   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10281          (match_operand 1 "" "g,g"))
10282    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10283    (use (reg:SI LR_REGNO))
10284    (simple_return)]
10285   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10286   "*
10288   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10289     output_asm_insn (\"crxor 6,6,6\", operands);
10291   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10292     output_asm_insn (\"creqv 6,6,6\", operands);
10294   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10296   [(set_attr "type" "branch")
10297    (set_attr "length" "4,8")])
10299 (define_insn "*sibcall_value_local32"
10300   [(set (match_operand 0 "" "")
10301         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10302               (match_operand 2 "" "g,g")))
10303    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10304    (use (reg:SI LR_REGNO))
10305    (simple_return)]
10306   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10307   "*
10309   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10310     output_asm_insn (\"crxor 6,6,6\", operands);
10312   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10313     output_asm_insn (\"creqv 6,6,6\", operands);
10315   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10317   [(set_attr "type" "branch")
10318    (set_attr "length" "4,8")])
10320 (define_insn "*sibcall_value_local64"
10321   [(set (match_operand 0 "" "")
10322         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10323               (match_operand 2 "" "g,g")))
10324    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10325    (use (reg:SI LR_REGNO))
10326    (simple_return)]
10327   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10328   "*
10330   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10331     output_asm_insn (\"crxor 6,6,6\", operands);
10333   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10334     output_asm_insn (\"creqv 6,6,6\", operands);
10336   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10338   [(set_attr "type" "branch")
10339    (set_attr "length" "4,8")])
10341 (define_insn "*sibcall_nonlocal_sysv<mode>"
10342   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10343          (match_operand 1 "" ""))
10344    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10345    (use (reg:SI LR_REGNO))
10346    (simple_return)]
10347   "(DEFAULT_ABI == ABI_DARWIN
10348     || DEFAULT_ABI == ABI_V4)
10349    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10350   "*
10352   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10353     output_asm_insn (\"crxor 6,6,6\", operands);
10355   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10356     output_asm_insn (\"creqv 6,6,6\", operands);
10358   if (which_alternative >= 2)
10359     return \"b%T0\";
10360   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10361     {
10362       gcc_assert (!TARGET_SECURE_PLT);
10363       return \"b %z0@plt\";
10364     }
10365   else
10366     return \"b %z0\";
10368   [(set_attr "type" "branch")
10369    (set_attr "length" "4,8,4,8")])
10371 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10372   [(set (match_operand 0 "" "")
10373         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10374               (match_operand 2 "" "")))
10375    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10376    (use (reg:SI LR_REGNO))
10377    (simple_return)]
10378   "(DEFAULT_ABI == ABI_DARWIN
10379     || DEFAULT_ABI == ABI_V4)
10380    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10381   "*
10383   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10384     output_asm_insn (\"crxor 6,6,6\", operands);
10386   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10387     output_asm_insn (\"creqv 6,6,6\", operands);
10389   if (which_alternative >= 2)
10390     return \"b%T1\";
10391   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10392     {
10393       gcc_assert (!TARGET_SECURE_PLT);
10394       return \"b %z1@plt\";
10395     }
10396   else
10397     return \"b %z1\";
10399   [(set_attr "type" "branch")
10400    (set_attr "length" "4,8,4,8")])
10402 ;; AIX ABI sibling call patterns.
10404 (define_insn "*sibcall_aix<mode>"
10405   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10406          (match_operand 1 "" "g,g"))
10407    (simple_return)]
10408   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10409   "@
10410    b %z0
10411    b%T0"
10412   [(set_attr "type" "branch")
10413    (set_attr "length" "4")])
10415 (define_insn "*sibcall_value_aix<mode>"
10416   [(set (match_operand 0 "" "")
10417         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10418               (match_operand 2 "" "g,g")))
10419    (simple_return)]
10420   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10421   "@
10422    b %z1
10423    b%T1"
10424   [(set_attr "type" "branch")
10425    (set_attr "length" "4")])
10427 (define_expand "sibcall_epilogue"
10428   [(use (const_int 0))]
10429   ""
10431   if (!TARGET_SCHED_PROLOG)
10432     emit_insn (gen_blockage ());
10433   rs6000_emit_epilogue (TRUE);
10434   DONE;
10437 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10438 ;; all of memory.  This blocks insns from being moved across this point.
10440 (define_insn "blockage"
10441   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10442   ""
10443   "")
10445 (define_expand "probe_stack_address"
10446   [(use (match_operand 0 "address_operand"))]
10447   ""
10449   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10450   MEM_VOLATILE_P (operands[0]) = 1;
10452   if (TARGET_64BIT)
10453     emit_insn (gen_probe_stack_di (operands[0]));
10454   else
10455     emit_insn (gen_probe_stack_si (operands[0]));
10456   DONE;
10459 (define_insn "probe_stack_<mode>"
10460   [(set (match_operand:P 0 "memory_operand" "=m")
10461         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10462   ""
10464   operands[1] = gen_rtx_REG (Pmode, 0);
10465   return "st<wd>%U0%X0 %1,%0";
10467   [(set_attr "type" "store")
10468    (set (attr "update")
10469         (if_then_else (match_operand 0 "update_address_mem")
10470                       (const_string "yes")
10471                       (const_string "no")))
10472    (set (attr "indexed")
10473         (if_then_else (match_operand 0 "indexed_address_mem")
10474                       (const_string "yes")
10475                       (const_string "no")))
10476    (set_attr "length" "4")])
10478 (define_insn "probe_stack_range<P:mode>"
10479   [(set (match_operand:P 0 "register_operand" "=r")
10480         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10481                             (match_operand:P 2 "register_operand" "r")]
10482                            UNSPECV_PROBE_STACK_RANGE))]
10483   ""
10484   "* return output_probe_stack_range (operands[0], operands[2]);"
10485   [(set_attr "type" "three")])
10487 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
10488 ;; signed & unsigned, and one type of branch.
10490 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10491 ;; insns, and branches.
10493 (define_expand "cbranch<mode>4"
10494   [(use (match_operator 0 "rs6000_cbranch_operator"
10495          [(match_operand:GPR 1 "gpc_reg_operand" "")
10496           (match_operand:GPR 2 "reg_or_short_operand" "")]))
10497    (use (match_operand 3 ""))]
10498   ""
10499   "
10501   /* Take care of the possibility that operands[2] might be negative but
10502      this might be a logical operation.  That insn doesn't exist.  */
10503   if (GET_CODE (operands[2]) == CONST_INT
10504       && INTVAL (operands[2]) < 0)
10505     {
10506       operands[2] = force_reg (<MODE>mode, operands[2]);
10507       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10508                                     GET_MODE (operands[0]),
10509                                     operands[1], operands[2]);
10510    }
10512   rs6000_emit_cbranch (<MODE>mode, operands);
10513   DONE;
10516 (define_expand "cbranch<mode>4"
10517   [(use (match_operator 0 "rs6000_cbranch_operator"
10518          [(match_operand:FP 1 "gpc_reg_operand" "")
10519           (match_operand:FP 2 "gpc_reg_operand" "")]))
10520    (use (match_operand 3 ""))]
10521   ""
10522   "
10524   rs6000_emit_cbranch (<MODE>mode, operands);
10525   DONE;
10528 (define_expand "cstore<mode>4_unsigned"
10529   [(use (match_operator 1 "unsigned_comparison_operator"
10530          [(match_operand:P 2 "gpc_reg_operand" "")
10531           (match_operand:P 3 "reg_or_short_operand" "")]))
10532    (clobber (match_operand:P 0 "register_operand"))]
10533   ""
10535   enum rtx_code cond_code = GET_CODE (operands[1]);
10537   rtx op0 = operands[0];
10538   rtx op1 = operands[2];
10539   rtx op2 = operands[3];
10541   if (cond_code == GEU || cond_code == LTU)
10542     {
10543       cond_code = swap_condition (cond_code);
10544       op1 = operands[3];
10545       op2 = operands[2];
10546     }
10548   if (!gpc_reg_operand (op1, <MODE>mode))
10549     op1 = force_reg (<MODE>mode, op1);
10550   if (!reg_or_short_operand (op2, <MODE>mode))
10551     op2 = force_reg (<MODE>mode, op2);
10553   rtx tmp = gen_reg_rtx (<MODE>mode);
10554   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10556   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10557   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10559   if (cond_code == LEU)
10560     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10561   else
10562     emit_insn (gen_neg<mode>2 (op0, tmp2));
10564   DONE;
10567 (define_expand "cstore_si_as_di"
10568   [(use (match_operator 1 "unsigned_comparison_operator"
10569          [(match_operand:SI 2 "gpc_reg_operand")
10570           (match_operand:SI 3 "reg_or_short_operand")]))
10571    (clobber (match_operand:SI 0 "register_operand"))]
10572   ""
10574   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10575   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10577   rtx op1 = gen_reg_rtx (DImode);
10578   rtx op2 = gen_reg_rtx (DImode);
10579   convert_move (op1, operands[2], uns_flag);
10580   convert_move (op2, operands[3], uns_flag);
10582   if (cond_code == GT || cond_code == LE)
10583     {
10584       cond_code = swap_condition (cond_code);
10585       std::swap (op1, op2);
10586     }
10588   rtx tmp = gen_reg_rtx (DImode);
10589   rtx tmp2 = gen_reg_rtx (DImode);
10590   emit_insn (gen_subdi3 (tmp, op1, op2));
10591   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
10593   rtx tmp3;
10594   switch (cond_code)
10595     {
10596     default:
10597       gcc_unreachable ();
10598     case LT:
10599       tmp3 = tmp2;
10600       break;
10601     case GE:
10602       tmp3 = gen_reg_rtx (DImode);
10603       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
10604       break;
10605     }
10607   convert_move (operands[0], tmp3, 1);
10609   DONE;
10612 (define_expand "cstore<mode>4_signed_imm"
10613   [(use (match_operator 1 "signed_comparison_operator"
10614          [(match_operand:GPR 2 "gpc_reg_operand")
10615           (match_operand:GPR 3 "immediate_operand")]))
10616    (clobber (match_operand:GPR 0 "register_operand"))]
10617   ""
10619   bool invert = false;
10621   enum rtx_code cond_code = GET_CODE (operands[1]);
10623   rtx op0 = operands[0];
10624   rtx op1 = operands[2];
10625   HOST_WIDE_INT val = INTVAL (operands[3]);
10627   if (cond_code == GE || cond_code == GT)
10628     {
10629       cond_code = reverse_condition (cond_code);
10630       invert = true;
10631     }
10633   if (cond_code == LE)
10634     val++;
10636   rtx tmp = gen_reg_rtx (<MODE>mode);
10637   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10638   rtx x = gen_reg_rtx (<MODE>mode);
10639   if (val < 0)
10640     emit_insn (gen_and<mode>3 (x, op1, tmp));
10641   else
10642     emit_insn (gen_ior<mode>3 (x, op1, tmp));
10644   if (invert)
10645     {
10646       rtx tmp = gen_reg_rtx (<MODE>mode);
10647       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10648       x = tmp;
10649     }
10651   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10652   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10654   DONE;
10657 (define_expand "cstore<mode>4_unsigned_imm"
10658   [(use (match_operator 1 "unsigned_comparison_operator"
10659          [(match_operand:GPR 2 "gpc_reg_operand")
10660           (match_operand:GPR 3 "immediate_operand")]))
10661    (clobber (match_operand:GPR 0 "register_operand"))]
10662   ""
10664   bool invert = false;
10666   enum rtx_code cond_code = GET_CODE (operands[1]);
10668   rtx op0 = operands[0];
10669   rtx op1 = operands[2];
10670   HOST_WIDE_INT val = INTVAL (operands[3]);
10672   if (cond_code == GEU || cond_code == GTU)
10673     {
10674       cond_code = reverse_condition (cond_code);
10675       invert = true;
10676     }
10678   if (cond_code == LEU)
10679     val++;
10681   rtx tmp = gen_reg_rtx (<MODE>mode);
10682   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10683   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10684   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
10685   rtx x = gen_reg_rtx (<MODE>mode);
10686   if (val < 0)
10687     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
10688   else
10689     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
10691   if (invert)
10692     {
10693       rtx tmp = gen_reg_rtx (<MODE>mode);
10694       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10695       x = tmp;
10696     }
10698   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10699   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10701   DONE;
10704 (define_expand "cstore<mode>4"
10705   [(use (match_operator 1 "rs6000_cbranch_operator"
10706          [(match_operand:GPR 2 "gpc_reg_operand")
10707           (match_operand:GPR 3 "reg_or_short_operand")]))
10708    (clobber (match_operand:GPR 0 "register_operand"))]
10709   ""
10711   /* Use ISEL if the user asked for it.  */
10712   if (TARGET_ISEL)
10713     rs6000_emit_sISEL (<MODE>mode, operands);
10715   /* Expanding EQ and NE directly to some machine instructions does not help
10716      but does hurt combine.  So don't.  */
10717   else if (GET_CODE (operands[1]) == EQ)
10718     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
10719   else if (<MODE>mode == Pmode
10720            && GET_CODE (operands[1]) == NE)
10721     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
10722   else if (GET_CODE (operands[1]) == NE)
10723     {
10724       rtx tmp = gen_reg_rtx (<MODE>mode);
10725       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
10726       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
10727     }
10729   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
10730      etc. combinations magically work out just right.  */
10731   else if (<MODE>mode == Pmode
10732            && unsigned_comparison_operator (operands[1], VOIDmode))
10733     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
10734                                            operands[2], operands[3]));
10736   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
10737   else if (<MODE>mode == SImode && Pmode == DImode)
10738     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
10739                                     operands[2], operands[3]));
10741   /* For signed comparisons against a constant, we can do some simple
10742      bit-twiddling.  */
10743   else if (signed_comparison_operator (operands[1], VOIDmode)
10744            && CONST_INT_P (operands[3]))
10745     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
10746                                              operands[2], operands[3]));
10748   /* And similarly for unsigned comparisons.  */
10749   else if (unsigned_comparison_operator (operands[1], VOIDmode)
10750            && CONST_INT_P (operands[3]))
10751     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
10752                                                operands[2], operands[3]));
10754   /* Everything else, use the mfcr brute force.  */
10755   else
10756     rs6000_emit_sCOND (<MODE>mode, operands);
10758   DONE;
10761 (define_expand "cstore<mode>4"
10762   [(use (match_operator 1 "rs6000_cbranch_operator"
10763          [(match_operand:FP 2 "gpc_reg_operand" "")
10764           (match_operand:FP 3 "gpc_reg_operand" "")]))
10765    (clobber (match_operand:SI 0 "register_operand"))]
10766   ""
10768   rs6000_emit_sCOND (<MODE>mode, operands);
10769   DONE;
10773 (define_expand "stack_protect_set"
10774   [(match_operand 0 "memory_operand" "")
10775    (match_operand 1 "memory_operand" "")]
10776   ""
10778 #ifdef TARGET_THREAD_SSP_OFFSET
10779   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10780   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10781   operands[1] = gen_rtx_MEM (Pmode, addr);
10782 #endif
10783   if (TARGET_64BIT)
10784     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10785   else
10786     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10787   DONE;
10790 (define_insn "stack_protect_setsi"
10791   [(set (match_operand:SI 0 "memory_operand" "=m")
10792         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
10793    (set (match_scratch:SI 2 "=&r") (const_int 0))]
10794   "TARGET_32BIT"
10795   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
10796   [(set_attr "type" "three")
10797    (set_attr "length" "12")])
10799 (define_insn "stack_protect_setdi"
10800   [(set (match_operand:DI 0 "memory_operand" "=Y")
10801         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
10802    (set (match_scratch:DI 2 "=&r") (const_int 0))]
10803   "TARGET_64BIT"
10804   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
10805   [(set_attr "type" "three")
10806    (set_attr "length" "12")])
10808 (define_expand "stack_protect_test"
10809   [(match_operand 0 "memory_operand" "")
10810    (match_operand 1 "memory_operand" "")
10811    (match_operand 2 "" "")]
10812   ""
10814   rtx test, op0, op1;
10815 #ifdef TARGET_THREAD_SSP_OFFSET
10816   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10817   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10818   operands[1] = gen_rtx_MEM (Pmode, addr);
10819 #endif
10820   op0 = operands[0];
10821   op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
10822   test = gen_rtx_EQ (VOIDmode, op0, op1);
10823   emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
10824   DONE;
10827 (define_insn "stack_protect_testsi"
10828   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10829         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
10830                       (match_operand:SI 2 "memory_operand" "m,m")]
10831                      UNSPEC_SP_TEST))
10832    (set (match_scratch:SI 4 "=r,r") (const_int 0))
10833    (clobber (match_scratch:SI 3 "=&r,&r"))]
10834   "TARGET_32BIT"
10835   "@
10836    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10837    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
10838   [(set_attr "length" "16,20")])
10840 (define_insn "stack_protect_testdi"
10841   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10842         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
10843                       (match_operand:DI 2 "memory_operand" "Y,Y")]
10844                      UNSPEC_SP_TEST))
10845    (set (match_scratch:DI 4 "=r,r") (const_int 0))
10846    (clobber (match_scratch:DI 3 "=&r,&r"))]
10847   "TARGET_64BIT"
10848   "@
10849    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10850    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
10851   [(set_attr "length" "16,20")])
10854 ;; Here are the actual compare insns.
10855 (define_insn "*cmp<mode>_signed"
10856   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
10857         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
10858                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
10859   ""
10860   "cmp<wd>%I2 %0,%1,%2"
10861   [(set_attr "type" "cmp")])
10863 (define_insn "*cmp<mode>_unsigned"
10864   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
10865         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
10866                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
10867   ""
10868   "cmpl<wd>%I2 %0,%1,%2"
10869   [(set_attr "type" "cmp")])
10871 ;; If we are comparing a register for equality with a large constant,
10872 ;; we can do this with an XOR followed by a compare.  But this is profitable
10873 ;; only if the large constant is only used for the comparison (and in this
10874 ;; case we already have a register to reuse as scratch).
10876 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
10877 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
10879 (define_peephole2
10880   [(set (match_operand:SI 0 "register_operand")
10881         (match_operand:SI 1 "logical_const_operand" ""))
10882    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
10883                        [(match_dup 0)
10884                         (match_operand:SI 2 "logical_const_operand" "")]))
10885    (set (match_operand:CC 4 "cc_reg_operand" "")
10886         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
10887                     (match_dup 0)))
10888    (set (pc)
10889         (if_then_else (match_operator 6 "equality_operator"
10890                        [(match_dup 4) (const_int 0)])
10891                       (match_operand 7 "" "")
10892                       (match_operand 8 "" "")))]
10893   "peep2_reg_dead_p (3, operands[0])
10894    && peep2_reg_dead_p (4, operands[4])
10895    && REGNO (operands[0]) != REGNO (operands[5])"
10896  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
10897   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
10898   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
10901   /* Get the constant we are comparing against, and see what it looks like
10902      when sign-extended from 16 to 32 bits.  Then see what constant we could
10903      XOR with SEXTC to get the sign-extended value.  */
10904   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
10905                                               SImode,
10906                                               operands[1], operands[2]);
10907   HOST_WIDE_INT c = INTVAL (cnst);
10908   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
10909   HOST_WIDE_INT xorv = c ^ sextc;
10911   operands[9] = GEN_INT (xorv);
10912   operands[10] = GEN_INT (sextc);
10915 ;; The following two insns don't exist as single insns, but if we provide
10916 ;; them, we can swap an add and compare, which will enable us to overlap more
10917 ;; of the required delay between a compare and branch.  We generate code for
10918 ;; them by splitting.
10920 (define_insn ""
10921   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
10922         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
10923                     (match_operand:SI 2 "short_cint_operand" "i")))
10924    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
10925         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
10926   ""
10927   "#"
10928   [(set_attr "length" "8")])
10930 (define_insn ""
10931   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
10932         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
10933                        (match_operand:SI 2 "u_short_cint_operand" "i")))
10934    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
10935         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
10936   ""
10937   "#"
10938   [(set_attr "length" "8")])
10940 (define_split
10941   [(set (match_operand:CC 3 "cc_reg_operand" "")
10942         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
10943                     (match_operand:SI 2 "short_cint_operand" "")))
10944    (set (match_operand:SI 0 "gpc_reg_operand" "")
10945         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
10946   ""
10947   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
10948    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
10950 (define_split
10951   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
10952         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
10953                        (match_operand:SI 2 "u_short_cint_operand" "")))
10954    (set (match_operand:SI 0 "gpc_reg_operand" "")
10955         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
10956   ""
10957   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
10958    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
10960 ;; Only need to compare second words if first words equal
10961 (define_insn "*cmp<mode>_internal1"
10962   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
10963         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
10964                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
10965   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
10966    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
10967   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
10968   [(set_attr "type" "fpcompare")
10969    (set_attr "length" "12")])
10971 (define_insn_and_split "*cmp<mode>_internal2"
10972   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
10973         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
10974                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
10975     (clobber (match_scratch:DF 3 "=d"))
10976     (clobber (match_scratch:DF 4 "=d"))
10977     (clobber (match_scratch:DF 5 "=d"))
10978     (clobber (match_scratch:DF 6 "=d"))
10979     (clobber (match_scratch:DF 7 "=d"))
10980     (clobber (match_scratch:DF 8 "=d"))
10981     (clobber (match_scratch:DF 9 "=d"))
10982     (clobber (match_scratch:DF 10 "=d"))
10983     (clobber (match_scratch:GPR 11 "=b"))]
10984   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
10985    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
10986   "#"
10987   "&& reload_completed"
10988   [(set (match_dup 3) (match_dup 14))
10989    (set (match_dup 4) (match_dup 15))
10990    (set (match_dup 9) (abs:DF (match_dup 5)))
10991    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
10992    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
10993                            (label_ref (match_dup 12))
10994                            (pc)))
10995    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
10996    (set (pc) (label_ref (match_dup 13)))
10997    (match_dup 12)
10998    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
10999    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11000    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11001    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11002    (match_dup 13)]
11004   REAL_VALUE_TYPE rv;
11005   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11006   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11008   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11009   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11010   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11011   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11012   operands[12] = gen_label_rtx ();
11013   operands[13] = gen_label_rtx ();
11014   real_inf (&rv);
11015   operands[14] = force_const_mem (DFmode,
11016                                   const_double_from_real_value (rv, DFmode));
11017   operands[15] = force_const_mem (DFmode,
11018                                   const_double_from_real_value (dconst0,
11019                                                                 DFmode));
11020   if (TARGET_TOC)
11021     {
11022       rtx tocref;
11023       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11024       operands[14] = gen_const_mem (DFmode, tocref);
11025       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11026       operands[15] = gen_const_mem (DFmode, tocref);
11027       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11028       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11029     }
11032 ;; Now we have the scc insns.  We can do some combinations because of the
11033 ;; way the machine works.
11035 ;; Note that this is probably faster if we can put an insn between the
11036 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11037 ;; cases the insns below which don't use an intermediate CR field will
11038 ;; be used instead.
11039 (define_insn ""
11040   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11041         (match_operator:SI 1 "scc_comparison_operator"
11042                            [(match_operand 2 "cc_reg_operand" "y")
11043                             (const_int 0)]))]
11044   ""
11045   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11046   [(set (attr "type")
11047      (cond [(match_test "TARGET_MFCRF")
11048                 (const_string "mfcrf")
11049            ]
11050         (const_string "mfcr")))
11051    (set_attr "length" "8")])
11053 ;; Same as above, but get the GT bit.
11054 (define_insn "move_from_CR_gt_bit"
11055   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11056         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11057   "TARGET_HARD_FLOAT && !TARGET_FPRS"
11058   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11059   [(set_attr "type" "mfcr")
11060    (set_attr "length" "8")])
11062 ;; Same as above, but get the OV/ORDERED bit.
11063 (define_insn "move_from_CR_ov_bit"
11064   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11065         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11066                    UNSPEC_MV_CR_OV))]
11067   "TARGET_ISEL"
11068   "mfcr %0\;rlwinm %0,%0,%t1,1"
11069   [(set_attr "type" "mfcr")
11070    (set_attr "length" "8")])
11072 (define_insn ""
11073   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11074         (match_operator:DI 1 "scc_comparison_operator"
11075                            [(match_operand 2 "cc_reg_operand" "y")
11076                             (const_int 0)]))]
11077   "TARGET_POWERPC64"
11078   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11079   [(set (attr "type")
11080      (cond [(match_test "TARGET_MFCRF")
11081                 (const_string "mfcrf")
11082            ]
11083         (const_string "mfcr")))
11084    (set_attr "length" "8")])
11086 (define_insn ""
11087   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11088         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11089                                        [(match_operand 2 "cc_reg_operand" "y,y")
11090                                         (const_int 0)])
11091                     (const_int 0)))
11092    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11093         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11094   "TARGET_32BIT"
11095   "@
11096    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11097    #"
11098   [(set_attr "type" "shift")
11099    (set_attr "dot" "yes")
11100    (set_attr "length" "8,16")])
11102 (define_split
11103   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11104         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11105                                        [(match_operand 2 "cc_reg_operand" "")
11106                                         (const_int 0)])
11107                     (const_int 0)))
11108    (set (match_operand:SI 3 "gpc_reg_operand" "")
11109         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11110   "TARGET_32BIT && reload_completed"
11111   [(set (match_dup 3)
11112         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11113    (set (match_dup 0)
11114         (compare:CC (match_dup 3)
11115                     (const_int 0)))]
11116   "")
11118 (define_insn ""
11119   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11120         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11121                                       [(match_operand 2 "cc_reg_operand" "y")
11122                                        (const_int 0)])
11123                    (match_operand:SI 3 "const_int_operand" "n")))]
11124   ""
11125   "*
11127   int is_bit = ccr_bit (operands[1], 1);
11128   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11129   int count;
11131   if (is_bit >= put_bit)
11132     count = is_bit - put_bit;
11133   else
11134     count = 32 - (put_bit - is_bit);
11136   operands[4] = GEN_INT (count);
11137   operands[5] = GEN_INT (put_bit);
11139   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11141   [(set (attr "type")
11142      (cond [(match_test "TARGET_MFCRF")
11143                 (const_string "mfcrf")
11144            ]
11145         (const_string "mfcr")))
11146    (set_attr "length" "8")])
11148 (define_insn ""
11149   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11150         (compare:CC
11151          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11152                                        [(match_operand 2 "cc_reg_operand" "y,y")
11153                                         (const_int 0)])
11154                     (match_operand:SI 3 "const_int_operand" "n,n"))
11155          (const_int 0)))
11156    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11157         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11158                    (match_dup 3)))]
11159   ""
11160   "*
11162   int is_bit = ccr_bit (operands[1], 1);
11163   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11164   int count;
11166   /* Force split for non-cc0 compare.  */
11167   if (which_alternative == 1)
11168      return \"#\";
11170   if (is_bit >= put_bit)
11171     count = is_bit - put_bit;
11172   else
11173     count = 32 - (put_bit - is_bit);
11175   operands[5] = GEN_INT (count);
11176   operands[6] = GEN_INT (put_bit);
11178   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11180   [(set_attr "type" "shift")
11181    (set_attr "dot" "yes")
11182    (set_attr "length" "8,16")])
11184 (define_split
11185   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11186         (compare:CC
11187          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11188                                        [(match_operand 2 "cc_reg_operand" "")
11189                                         (const_int 0)])
11190                     (match_operand:SI 3 "const_int_operand" ""))
11191          (const_int 0)))
11192    (set (match_operand:SI 4 "gpc_reg_operand" "")
11193         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11194                    (match_dup 3)))]
11195   "reload_completed"
11196   [(set (match_dup 4)
11197         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11198                    (match_dup 3)))
11199    (set (match_dup 0)
11200         (compare:CC (match_dup 4)
11201                     (const_int 0)))]
11202   "")
11204 ;; There is a 3 cycle delay between consecutive mfcr instructions
11205 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
11207 (define_peephole
11208   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11209         (match_operator:SI 1 "scc_comparison_operator"
11210                            [(match_operand 2 "cc_reg_operand" "y")
11211                             (const_int 0)]))
11212    (set (match_operand:SI 3 "gpc_reg_operand" "=r")
11213         (match_operator:SI 4 "scc_comparison_operator"
11214                            [(match_operand 5 "cc_reg_operand" "y")
11215                             (const_int 0)]))]
11216   "REGNO (operands[2]) != REGNO (operands[5])"
11217   "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11218   [(set_attr "type" "mfcr")
11219    (set_attr "length" "12")])
11221 (define_peephole
11222   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11223         (match_operator:DI 1 "scc_comparison_operator"
11224                            [(match_operand 2 "cc_reg_operand" "y")
11225                             (const_int 0)]))
11226    (set (match_operand:DI 3 "gpc_reg_operand" "=r")
11227         (match_operator:DI 4 "scc_comparison_operator"
11228                            [(match_operand 5 "cc_reg_operand" "y")
11229                             (const_int 0)]))]
11230   "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
11231   "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11232   [(set_attr "type" "mfcr")
11233    (set_attr "length" "12")])
11236 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11237                               (DI "rKJI")])
11239 (define_insn_and_split "eq<mode>3"
11240   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11241         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11242                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11243    (clobber (match_scratch:GPR 3 "=r"))
11244    (clobber (match_scratch:GPR 4 "=r"))]
11245   ""
11246   "#"
11247   ""
11248   [(set (match_dup 4)
11249         (clz:GPR (match_dup 3)))
11250    (set (match_dup 0)
11251         (lshiftrt:GPR (match_dup 4)
11252                       (match_dup 5)))]
11254   operands[3] = rs6000_emit_eqne (<MODE>mode,
11255                                   operands[1], operands[2], operands[3]);
11257   if (GET_CODE (operands[4]) == SCRATCH)
11258     operands[4] = gen_reg_rtx (<MODE>mode);
11260   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11262   [(set (attr "length")
11263         (if_then_else (match_test "operands[2] == const0_rtx")
11264                       (const_string "8")
11265                       (const_string "12")))])
11267 (define_insn_and_split "ne<mode>3"
11268   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11269         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11270               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11271    (clobber (match_scratch:P 3 "=r"))
11272    (clobber (match_scratch:P 4 "=r"))
11273    (clobber (reg:P CA_REGNO))]
11274   "!TARGET_ISEL"
11275   "#"
11276   ""
11277   [(parallel [(set (match_dup 4)
11278                    (plus:P (match_dup 3)
11279                            (const_int -1)))
11280               (set (reg:P CA_REGNO)
11281                    (ne:P (match_dup 3)
11282                          (const_int 0)))])
11283    (parallel [(set (match_dup 0)
11284                    (plus:P (plus:P (not:P (match_dup 4))
11285                                    (reg:P CA_REGNO))
11286                            (match_dup 3)))
11287               (clobber (reg:P CA_REGNO))])]
11289   operands[3] = rs6000_emit_eqne (<MODE>mode,
11290                                   operands[1], operands[2], operands[3]);
11292   if (GET_CODE (operands[4]) == SCRATCH)
11293     operands[4] = gen_reg_rtx (<MODE>mode);
11295   [(set (attr "length")
11296         (if_then_else (match_test "operands[2] == const0_rtx")
11297                       (const_string "8")
11298                       (const_string "12")))])
11300 (define_insn_and_split "*neg_eq_<mode>"
11301   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11302         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11303                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11304    (clobber (match_scratch:P 3 "=r"))
11305    (clobber (match_scratch:P 4 "=r"))
11306    (clobber (reg:P CA_REGNO))]
11307   ""
11308   "#"
11309   ""
11310   [(parallel [(set (match_dup 4)
11311                    (plus:P (match_dup 3)
11312                            (const_int -1)))
11313               (set (reg:P CA_REGNO)
11314                    (ne:P (match_dup 3)
11315                          (const_int 0)))])
11316    (parallel [(set (match_dup 0)
11317                    (plus:P (reg:P CA_REGNO)
11318                            (const_int -1)))
11319               (clobber (reg:P CA_REGNO))])]
11321   operands[3] = rs6000_emit_eqne (<MODE>mode,
11322                                   operands[1], operands[2], operands[3]);
11324   if (GET_CODE (operands[4]) == SCRATCH)
11325     operands[4] = gen_reg_rtx (<MODE>mode);
11327   [(set (attr "length")
11328         (if_then_else (match_test "operands[2] == const0_rtx")
11329                       (const_string "8")
11330                       (const_string "12")))])
11332 (define_insn_and_split "*neg_ne_<mode>"
11333   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11334         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11335                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11336    (clobber (match_scratch:P 3 "=r"))
11337    (clobber (match_scratch:P 4 "=r"))
11338    (clobber (reg:P CA_REGNO))]
11339   ""
11340   "#"
11341   ""
11342   [(parallel [(set (match_dup 4)
11343                    (neg:P (match_dup 3)))
11344               (set (reg:P CA_REGNO)
11345                    (eq:P (match_dup 3)
11346                          (const_int 0)))])
11347    (parallel [(set (match_dup 0)
11348                    (plus:P (reg:P CA_REGNO)
11349                            (const_int -1)))
11350               (clobber (reg:P CA_REGNO))])]
11352   operands[3] = rs6000_emit_eqne (<MODE>mode,
11353                                   operands[1], operands[2], operands[3]);
11355   if (GET_CODE (operands[4]) == SCRATCH)
11356     operands[4] = gen_reg_rtx (<MODE>mode);
11358   [(set (attr "length")
11359         (if_then_else (match_test "operands[2] == const0_rtx")
11360                       (const_string "8")
11361                       (const_string "12")))])
11363 (define_insn_and_split "*plus_eq_<mode>"
11364   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11365         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11366                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11367                 (match_operand:P 3 "gpc_reg_operand" "r")))
11368    (clobber (match_scratch:P 4 "=r"))
11369    (clobber (match_scratch:P 5 "=r"))
11370    (clobber (reg:P CA_REGNO))]
11371   ""
11372   "#"
11373   ""
11374   [(parallel [(set (match_dup 5)
11375                    (neg:P (match_dup 4)))
11376               (set (reg:P CA_REGNO)
11377                    (eq:P (match_dup 4)
11378                          (const_int 0)))])
11379    (parallel [(set (match_dup 0)
11380                    (plus:P (match_dup 3)
11381                            (reg:P CA_REGNO)))
11382               (clobber (reg:P CA_REGNO))])]
11384   operands[4] = rs6000_emit_eqne (<MODE>mode,
11385                                   operands[1], operands[2], operands[4]);
11387   if (GET_CODE (operands[5]) == SCRATCH)
11388     operands[5] = gen_reg_rtx (<MODE>mode);
11390   [(set (attr "length")
11391         (if_then_else (match_test "operands[2] == const0_rtx")
11392                       (const_string "8")
11393                       (const_string "12")))])
11395 (define_insn_and_split "*plus_ne_<mode>"
11396   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11397         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11398                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11399                 (match_operand:P 3 "gpc_reg_operand" "r")))
11400    (clobber (match_scratch:P 4 "=r"))
11401    (clobber (match_scratch:P 5 "=r"))
11402    (clobber (reg:P CA_REGNO))]
11403   ""
11404   "#"
11405   ""
11406   [(parallel [(set (match_dup 5)
11407                    (plus:P (match_dup 4)
11408                            (const_int -1)))
11409               (set (reg:P CA_REGNO)
11410                    (ne:P (match_dup 4)
11411                          (const_int 0)))])
11412    (parallel [(set (match_dup 0)
11413                    (plus:P (match_dup 3)
11414                            (reg:P CA_REGNO)))
11415               (clobber (reg:P CA_REGNO))])]
11417   operands[4] = rs6000_emit_eqne (<MODE>mode,
11418                                   operands[1], operands[2], operands[4]);
11420   if (GET_CODE (operands[5]) == SCRATCH)
11421     operands[5] = gen_reg_rtx (<MODE>mode);
11423   [(set (attr "length")
11424         (if_then_else (match_test "operands[2] == const0_rtx")
11425                       (const_string "8")
11426                       (const_string "12")))])
11428 (define_insn_and_split "*minus_eq_<mode>"
11429   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11430         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11431                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11432                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11433    (clobber (match_scratch:P 4 "=r"))
11434    (clobber (match_scratch:P 5 "=r"))
11435    (clobber (reg:P CA_REGNO))]
11436   ""
11437   "#"
11438   ""
11439   [(parallel [(set (match_dup 5)
11440                    (plus:P (match_dup 4)
11441                            (const_int -1)))
11442               (set (reg:P CA_REGNO)
11443                    (ne:P (match_dup 4)
11444                          (const_int 0)))])
11445    (parallel [(set (match_dup 0)
11446                    (plus:P (plus:P (match_dup 3)
11447                                    (reg:P CA_REGNO))
11448                            (const_int -1)))
11449               (clobber (reg:P CA_REGNO))])]
11451   operands[4] = rs6000_emit_eqne (<MODE>mode,
11452                                   operands[1], operands[2], operands[4]);
11454   if (GET_CODE (operands[5]) == SCRATCH)
11455     operands[5] = gen_reg_rtx (<MODE>mode);
11457   [(set (attr "length")
11458         (if_then_else (match_test "operands[2] == const0_rtx")
11459                       (const_string "8")
11460                       (const_string "12")))])
11462 (define_insn_and_split "*minus_ne_<mode>"
11463   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11464         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11465                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11466                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11467    (clobber (match_scratch:P 4 "=r"))
11468    (clobber (match_scratch:P 5 "=r"))
11469    (clobber (reg:P CA_REGNO))]
11470   ""
11471   "#"
11472   ""
11473   [(parallel [(set (match_dup 5)
11474                    (neg:P (match_dup 4)))
11475               (set (reg:P CA_REGNO)
11476                    (eq:P (match_dup 4)
11477                          (const_int 0)))])
11478    (parallel [(set (match_dup 0)
11479                    (plus:P (plus:P (match_dup 3)
11480                                    (reg:P CA_REGNO))
11481                            (const_int -1)))
11482               (clobber (reg:P CA_REGNO))])]
11484   operands[4] = rs6000_emit_eqne (<MODE>mode,
11485                                   operands[1], operands[2], operands[4]);
11487   if (GET_CODE (operands[5]) == SCRATCH)
11488     operands[5] = gen_reg_rtx (<MODE>mode);
11490   [(set (attr "length")
11491         (if_then_else (match_test "operands[2] == const0_rtx")
11492                       (const_string "8")
11493                       (const_string "12")))])
11495 (define_insn_and_split "*eqsi3_ext<mode>"
11496   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11497         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11498                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11499    (clobber (match_scratch:SI 3 "=r"))
11500    (clobber (match_scratch:SI 4 "=r"))]
11501   ""
11502   "#"
11503   ""
11504   [(set (match_dup 4)
11505         (clz:SI (match_dup 3)))
11506    (set (match_dup 0)
11507         (zero_extend:EXTSI
11508           (lshiftrt:SI (match_dup 4)
11509                        (const_int 5))))]
11511   operands[3] = rs6000_emit_eqne (SImode,
11512                                   operands[1], operands[2], operands[3]);
11514   if (GET_CODE (operands[4]) == SCRATCH)
11515     operands[4] = gen_reg_rtx (SImode);
11517   [(set (attr "length")
11518         (if_then_else (match_test "operands[2] == const0_rtx")
11519                       (const_string "8")
11520                       (const_string "12")))])
11522 (define_insn_and_split "*nesi3_ext<mode>"
11523   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11524         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11525                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11526    (clobber (match_scratch:SI 3 "=r"))
11527    (clobber (match_scratch:SI 4 "=r"))
11528    (clobber (match_scratch:EXTSI 5 "=r"))]
11529   ""
11530   "#"
11531   ""
11532   [(set (match_dup 4)
11533         (clz:SI (match_dup 3)))
11534    (set (match_dup 5)
11535         (zero_extend:EXTSI
11536           (lshiftrt:SI (match_dup 4)
11537                        (const_int 5))))
11538    (set (match_dup 0)
11539         (xor:EXTSI (match_dup 5)
11540                    (const_int 1)))]
11542   operands[3] = rs6000_emit_eqne (SImode,
11543                                   operands[1], operands[2], operands[3]);
11545   if (GET_CODE (operands[4]) == SCRATCH)
11546     operands[4] = gen_reg_rtx (SImode);
11547   if (GET_CODE (operands[5]) == SCRATCH)
11548     operands[5] = gen_reg_rtx (<MODE>mode);
11550   [(set (attr "length")
11551         (if_then_else (match_test "operands[2] == const0_rtx")
11552                       (const_string "12")
11553                       (const_string "16")))])
11555 ;; Define both directions of branch and return.  If we need a reload
11556 ;; register, we'd rather use CR0 since it is much easier to copy a
11557 ;; register CC value to there.
11559 (define_insn ""
11560   [(set (pc)
11561         (if_then_else (match_operator 1 "branch_comparison_operator"
11562                                       [(match_operand 2
11563                                                       "cc_reg_operand" "y")
11564                                        (const_int 0)])
11565                       (label_ref (match_operand 0 "" ""))
11566                       (pc)))]
11567   ""
11568   "*
11570   return output_cbranch (operands[1], \"%l0\", 0, insn);
11572   [(set_attr "type" "branch")])
11574 (define_insn ""
11575   [(set (pc)
11576         (if_then_else (match_operator 0 "branch_comparison_operator"
11577                                       [(match_operand 1
11578                                                       "cc_reg_operand" "y")
11579                                        (const_int 0)])
11580                       (any_return)
11581                       (pc)))]
11582   "<return_pred>"
11583   "*
11585   return output_cbranch (operands[0], NULL, 0, insn);
11587   [(set_attr "type" "jmpreg")
11588    (set_attr "length" "4")])
11590 (define_insn ""
11591   [(set (pc)
11592         (if_then_else (match_operator 1 "branch_comparison_operator"
11593                                       [(match_operand 2
11594                                                       "cc_reg_operand" "y")
11595                                        (const_int 0)])
11596                       (pc)
11597                       (label_ref (match_operand 0 "" ""))))]
11598   ""
11599   "*
11601   return output_cbranch (operands[1], \"%l0\", 1, insn);
11603   [(set_attr "type" "branch")])
11605 (define_insn ""
11606   [(set (pc)
11607         (if_then_else (match_operator 0 "branch_comparison_operator"
11608                                       [(match_operand 1
11609                                                       "cc_reg_operand" "y")
11610                                        (const_int 0)])
11611                       (pc)
11612                       (any_return)))]
11613   "<return_pred>"
11614   "*
11616   return output_cbranch (operands[0], NULL, 1, insn);
11618   [(set_attr "type" "jmpreg")
11619    (set_attr "length" "4")])
11621 ;; Logic on condition register values.
11623 ; This pattern matches things like
11624 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11625 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
11626 ;                                  (const_int 1)))
11627 ; which are generated by the branch logic.
11628 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11630 (define_insn "*cceq_ior_compare"
11631   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11632         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11633                         [(match_operator:SI 2
11634                                       "branch_positive_comparison_operator"
11635                                       [(match_operand 3
11636                                                       "cc_reg_operand" "y,y")
11637                                        (const_int 0)])
11638                          (match_operator:SI 4
11639                                       "branch_positive_comparison_operator"
11640                                       [(match_operand 5
11641                                                       "cc_reg_operand" "0,y")
11642                                        (const_int 0)])])
11643                       (const_int 1)))]
11644   ""
11645   "cr%q1 %E0,%j2,%j4"
11646   [(set_attr "type" "cr_logical,delayed_cr")])
11648 ; Why is the constant -1 here, but 1 in the previous pattern?
11649 ; Because ~1 has all but the low bit set.
11650 (define_insn ""
11651   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11652         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11653                         [(not:SI (match_operator:SI 2
11654                                       "branch_positive_comparison_operator"
11655                                       [(match_operand 3
11656                                                       "cc_reg_operand" "y,y")
11657                                        (const_int 0)]))
11658                          (match_operator:SI 4
11659                                 "branch_positive_comparison_operator"
11660                                 [(match_operand 5
11661                                                 "cc_reg_operand" "0,y")
11662                                  (const_int 0)])])
11663                       (const_int -1)))]
11664   ""
11665   "cr%q1 %E0,%j2,%j4"
11666   [(set_attr "type" "cr_logical,delayed_cr")])
11668 (define_insn "*cceq_rev_compare"
11669   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11670         (compare:CCEQ (match_operator:SI 1
11671                                       "branch_positive_comparison_operator"
11672                                       [(match_operand 2
11673                                                       "cc_reg_operand" "0,y")
11674                                        (const_int 0)])
11675                       (const_int 0)))]
11676   ""
11677   "crnot %E0,%j1"
11678   [(set_attr "type" "cr_logical,delayed_cr")])
11680 ;; If we are comparing the result of two comparisons, this can be done
11681 ;; using creqv or crxor.
11683 (define_insn_and_split ""
11684   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
11685         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
11686                               [(match_operand 2 "cc_reg_operand" "y")
11687                                (const_int 0)])
11688                       (match_operator 3 "branch_comparison_operator"
11689                               [(match_operand 4 "cc_reg_operand" "y")
11690                                (const_int 0)])))]
11691   ""
11692   "#"
11693   ""
11694   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
11695                                     (match_dup 5)))]
11696   "
11698   int positive_1, positive_2;
11700   positive_1 = branch_positive_comparison_operator (operands[1],
11701                                                     GET_MODE (operands[1]));
11702   positive_2 = branch_positive_comparison_operator (operands[3],
11703                                                     GET_MODE (operands[3]));
11705   if (! positive_1)
11706     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
11707                                                             GET_CODE (operands[1])),
11708                                   SImode,
11709                                   operands[2], const0_rtx);
11710   else if (GET_MODE (operands[1]) != SImode)
11711     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
11712                                   operands[2], const0_rtx);
11714   if (! positive_2)
11715     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
11716                                                             GET_CODE (operands[3])),
11717                                   SImode,
11718                                   operands[4], const0_rtx);
11719   else if (GET_MODE (operands[3]) != SImode)
11720     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
11721                                   operands[4], const0_rtx);
11723   if (positive_1 == positive_2)
11724     {
11725       operands[1] = gen_rtx_NOT (SImode, operands[1]);
11726       operands[5] = constm1_rtx;
11727     }
11728   else
11729     {
11730       operands[5] = const1_rtx;
11731     }
11734 ;; Unconditional branch and return.
11736 (define_insn "jump"
11737   [(set (pc)
11738         (label_ref (match_operand 0 "" "")))]
11739   ""
11740   "b %l0"
11741   [(set_attr "type" "branch")])
11743 (define_insn "<return_str>return"
11744   [(any_return)]
11745   "<return_pred>"
11746   "blr"
11747   [(set_attr "type" "jmpreg")])
11749 (define_expand "indirect_jump"
11750   [(set (pc) (match_operand 0 "register_operand" ""))])
11752 (define_insn "*indirect_jump<mode>"
11753   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
11754   ""
11755   "@
11756    bctr
11757    blr"
11758   [(set_attr "type" "jmpreg")])
11760 ;; Table jump for switch statements:
11761 (define_expand "tablejump"
11762   [(use (match_operand 0 "" ""))
11763    (use (label_ref (match_operand 1 "" "")))]
11764   ""
11765   "
11767   if (TARGET_32BIT)
11768     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
11769   else
11770     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
11771   DONE;
11774 (define_expand "tablejumpsi"
11775   [(set (match_dup 3)
11776         (plus:SI (match_operand:SI 0 "" "")
11777                  (match_dup 2)))
11778    (parallel [(set (pc) (match_dup 3))
11779               (use (label_ref (match_operand 1 "" "")))])]
11780   "TARGET_32BIT"
11781   "
11782 { operands[0] = force_reg (SImode, operands[0]);
11783   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
11784   operands[3] = gen_reg_rtx (SImode);
11787 (define_expand "tablejumpdi"
11788   [(set (match_dup 4)
11789         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
11790    (set (match_dup 3)
11791         (plus:DI (match_dup 4)
11792                  (match_dup 2)))
11793    (parallel [(set (pc) (match_dup 3))
11794               (use (label_ref (match_operand 1 "" "")))])]
11795   "TARGET_64BIT"
11796   "
11797 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
11798   operands[3] = gen_reg_rtx (DImode);
11799   operands[4] = gen_reg_rtx (DImode);
11802 (define_insn "*tablejump<mode>_internal1"
11803   [(set (pc)
11804         (match_operand:P 0 "register_operand" "c,*l"))
11805    (use (label_ref (match_operand 1 "" "")))]
11806   ""
11807   "@
11808    bctr
11809    blr"
11810   [(set_attr "type" "jmpreg")])
11812 (define_insn "nop"
11813   [(unspec [(const_int 0)] UNSPEC_NOP)]
11814   ""
11815   "nop")
11817 (define_insn "group_ending_nop"
11818   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
11819   ""
11820   "*
11822   if (rs6000_cpu_attr == CPU_POWER6)
11823     return \"ori 1,1,0\";
11824   return \"ori 2,2,0\";
11827 ;; Define the subtract-one-and-jump insns, starting with the template
11828 ;; so loop.c knows what to generate.
11830 (define_expand "doloop_end"
11831   [(use (match_operand 0 "" ""))        ; loop pseudo
11832    (use (match_operand 1 "" ""))]       ; label
11833   ""
11834   "
11836   if (TARGET_64BIT)
11837     {
11838       if (GET_MODE (operands[0]) != DImode)
11839         FAIL;
11840       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
11841     }
11842   else
11843     {
11844       if (GET_MODE (operands[0]) != SImode)
11845         FAIL;
11846       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
11847     }
11848   DONE;
11851 (define_expand "ctr<mode>"
11852   [(parallel [(set (pc)
11853                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
11854                                      (const_int 1))
11855                                  (label_ref (match_operand 1 "" ""))
11856                                  (pc)))
11857               (set (match_dup 0)
11858                    (plus:P (match_dup 0)
11859                             (const_int -1)))
11860               (clobber (match_scratch:CC 2 ""))
11861               (clobber (match_scratch:P 3 ""))])]
11862   ""
11863   "")
11865 ;; We need to be able to do this for any operand, including MEM, or we
11866 ;; will cause reload to blow up since we don't allow output reloads on
11867 ;; JUMP_INSNs.
11868 ;; For the length attribute to be calculated correctly, the
11869 ;; label MUST be operand 0.
11871 (define_insn "*ctr<mode>_internal1"
11872   [(set (pc)
11873         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11874                           (const_int 1))
11875                       (label_ref (match_operand 0 "" ""))
11876                       (pc)))
11877    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11878         (plus:P (match_dup 1)
11879                  (const_int -1)))
11880    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11881    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11882   ""
11883   "*
11885   if (which_alternative != 0)
11886     return \"#\";
11887   else if (get_attr_length (insn) == 4)
11888     return \"bdnz %l0\";
11889   else
11890     return \"bdz $+8\;b %l0\";
11892   [(set_attr "type" "branch")
11893    (set_attr "length" "*,16,20,20")])
11895 (define_insn "*ctr<mode>_internal2"
11896   [(set (pc)
11897         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11898                           (const_int 1))
11899                       (pc)
11900                       (label_ref (match_operand 0 "" ""))))
11901    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11902         (plus:P (match_dup 1)
11903                  (const_int -1)))
11904    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11905    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11906   ""
11907   "*
11909   if (which_alternative != 0)
11910     return \"#\";
11911   else if (get_attr_length (insn) == 4)
11912     return \"bdz %l0\";
11913   else
11914     return \"bdnz $+8\;b %l0\";
11916   [(set_attr "type" "branch")
11917    (set_attr "length" "*,16,20,20")])
11919 ;; Similar but use EQ
11921 (define_insn "*ctr<mode>_internal5"
11922   [(set (pc)
11923         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11924                           (const_int 1))
11925                       (label_ref (match_operand 0 "" ""))
11926                       (pc)))
11927    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11928         (plus:P (match_dup 1)
11929                  (const_int -1)))
11930    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11931    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11932   ""
11933   "*
11935   if (which_alternative != 0)
11936     return \"#\";
11937   else if (get_attr_length (insn) == 4)
11938     return \"bdz %l0\";
11939   else
11940     return \"bdnz $+8\;b %l0\";
11942   [(set_attr "type" "branch")
11943    (set_attr "length" "*,16,20,20")])
11945 (define_insn "*ctr<mode>_internal6"
11946   [(set (pc)
11947         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11948                           (const_int 1))
11949                       (pc)
11950                       (label_ref (match_operand 0 "" ""))))
11951    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11952         (plus:P (match_dup 1)
11953                  (const_int -1)))
11954    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11955    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11956   ""
11957   "*
11959   if (which_alternative != 0)
11960     return \"#\";
11961   else if (get_attr_length (insn) == 4)
11962     return \"bdnz %l0\";
11963   else
11964     return \"bdz $+8\;b %l0\";
11966   [(set_attr "type" "branch")
11967    (set_attr "length" "*,16,20,20")])
11969 ;; Now the splitters if we could not allocate the CTR register
11971 (define_split
11972   [(set (pc)
11973         (if_then_else (match_operator 2 "comparison_operator"
11974                                       [(match_operand:P 1 "gpc_reg_operand" "")
11975                                        (const_int 1)])
11976                       (match_operand 5 "" "")
11977                       (match_operand 6 "" "")))
11978    (set (match_operand:P 0 "gpc_reg_operand" "")
11979         (plus:P (match_dup 1) (const_int -1)))
11980    (clobber (match_scratch:CC 3 ""))
11981    (clobber (match_scratch:P 4 ""))]
11982   "reload_completed"
11983   [(set (match_dup 3)
11984         (compare:CC (match_dup 1)
11985                     (const_int 1)))
11986    (set (match_dup 0)
11987         (plus:P (match_dup 1)
11988                 (const_int -1)))
11989    (set (pc) (if_then_else (match_dup 7)
11990                            (match_dup 5)
11991                            (match_dup 6)))]
11992   "
11993 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
11994                                 operands[3], const0_rtx); }")
11996 (define_split
11997   [(set (pc)
11998         (if_then_else (match_operator 2 "comparison_operator"
11999                                       [(match_operand:P 1 "gpc_reg_operand" "")
12000                                        (const_int 1)])
12001                       (match_operand 5 "" "")
12002                       (match_operand 6 "" "")))
12003    (set (match_operand:P 0 "nonimmediate_operand" "")
12004         (plus:P (match_dup 1) (const_int -1)))
12005    (clobber (match_scratch:CC 3 ""))
12006    (clobber (match_scratch:P 4 ""))]
12007   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12008   [(set (match_dup 3)
12009         (compare:CC (match_dup 1)
12010                     (const_int 1)))
12011    (set (match_dup 4)
12012         (plus:P (match_dup 1)
12013                 (const_int -1)))
12014    (set (match_dup 0)
12015         (match_dup 4))
12016    (set (pc) (if_then_else (match_dup 7)
12017                            (match_dup 5)
12018                            (match_dup 6)))]
12019   "
12020 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12021                                 operands[3], const0_rtx); }")
12023 (define_insn "trap"
12024   [(trap_if (const_int 1) (const_int 0))]
12025   ""
12026   "trap"
12027   [(set_attr "type" "trap")])
12029 (define_expand "ctrap<mode>4"
12030   [(trap_if (match_operator 0 "ordered_comparison_operator"
12031                             [(match_operand:GPR 1 "register_operand")
12032                              (match_operand:GPR 2 "reg_or_short_operand")])
12033             (match_operand 3 "zero_constant" ""))]
12034   ""
12035   "")
12037 (define_insn ""
12038   [(trap_if (match_operator 0 "ordered_comparison_operator"
12039                             [(match_operand:GPR 1 "register_operand" "r")
12040                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12041             (const_int 0))]
12042   ""
12043   "t<wd>%V0%I2 %1,%2"
12044   [(set_attr "type" "trap")])
12046 ;; Insns related to generating the function prologue and epilogue.
12048 (define_expand "prologue"
12049   [(use (const_int 0))]
12050   ""
12052   rs6000_emit_prologue ();
12053   if (!TARGET_SCHED_PROLOG)
12054     emit_insn (gen_blockage ());
12055   DONE;
12058 (define_insn "*movesi_from_cr_one"
12059   [(match_parallel 0 "mfcr_operation"
12060                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12061                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12062                                      (match_operand 3 "immediate_operand" "n")]
12063                           UNSPEC_MOVESI_FROM_CR))])]
12064   "TARGET_MFCRF"
12065   "*
12067   int mask = 0;
12068   int i;
12069   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12070   {
12071     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12072     operands[4] = GEN_INT (mask);
12073     output_asm_insn (\"mfcr %1,%4\", operands);
12074   }
12075   return \"\";
12077   [(set_attr "type" "mfcrf")])
12079 (define_insn "movesi_from_cr"
12080   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12081         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12082                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12083                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12084                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12085                    UNSPEC_MOVESI_FROM_CR))]
12086   ""
12087   "mfcr %0"
12088   [(set_attr "type" "mfcr")])
12090 (define_insn "*crsave"
12091   [(match_parallel 0 "crsave_operation"
12092                    [(set (match_operand:SI 1 "memory_operand" "=m")
12093                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12094   ""
12095   "stw %2,%1"
12096   [(set_attr "type" "store")])
12098 (define_insn "*stmw"
12099   [(match_parallel 0 "stmw_operation"
12100                    [(set (match_operand:SI 1 "memory_operand" "=m")
12101                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12102   "TARGET_MULTIPLE"
12103   "stmw %2,%1"
12104   [(set_attr "type" "store")
12105    (set_attr "update" "yes")
12106    (set_attr "indexed" "yes")])
12108 ; The following comment applies to:
12109 ;     save_gpregs_*
12110 ;     save_fpregs_*
12111 ;     restore_gpregs*
12112 ;     return_and_restore_gpregs*
12113 ;     return_and_restore_fpregs*
12114 ;     return_and_restore_fpregs_aix*
12116 ; The out-of-line save / restore functions expects one input argument.
12117 ; Since those are not standard call_insn's, we must avoid using
12118 ; MATCH_OPERAND for that argument. That way the register rename
12119 ; optimization will not try to rename this register.
12120 ; Each pattern is repeated for each possible register number used in 
12121 ; various ABIs (r11, r1, and for some functions r12)
12123 (define_insn "*save_gpregs_<mode>_r11"
12124   [(match_parallel 0 "any_parallel_operand"
12125                    [(clobber (reg:P 65))
12126                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12127                     (use (reg:P 11))
12128                     (set (match_operand:P 2 "memory_operand" "=m")
12129                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12130   ""
12131   "bl %1"
12132   [(set_attr "type" "branch")
12133    (set_attr "length" "4")])
12135 (define_insn "*save_gpregs_<mode>_r12"
12136   [(match_parallel 0 "any_parallel_operand"
12137                    [(clobber (reg:P 65))
12138                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12139                     (use (reg:P 12))
12140                     (set (match_operand:P 2 "memory_operand" "=m")
12141                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12142   ""
12143   "bl %1"
12144   [(set_attr "type" "branch")
12145    (set_attr "length" "4")])
12147 (define_insn "*save_gpregs_<mode>_r1"
12148   [(match_parallel 0 "any_parallel_operand"
12149                    [(clobber (reg:P 65))
12150                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12151                     (use (reg:P 1))
12152                     (set (match_operand:P 2 "memory_operand" "=m")
12153                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12154   ""
12155   "bl %1"
12156   [(set_attr "type" "branch")
12157    (set_attr "length" "4")])
12159 (define_insn "*save_fpregs_<mode>_r11"
12160   [(match_parallel 0 "any_parallel_operand"
12161                    [(clobber (reg:P 65))
12162                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12163                     (use (reg:P 11))
12164                     (set (match_operand:DF 2 "memory_operand" "=m")
12165                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12166   ""
12167   "bl %1"
12168   [(set_attr "type" "branch")
12169    (set_attr "length" "4")])
12171 (define_insn "*save_fpregs_<mode>_r12"
12172   [(match_parallel 0 "any_parallel_operand"
12173                    [(clobber (reg:P 65))
12174                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12175                     (use (reg:P 12))
12176                     (set (match_operand:DF 2 "memory_operand" "=m")
12177                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12178   ""
12179   "bl %1"
12180   [(set_attr "type" "branch")
12181    (set_attr "length" "4")])
12183 (define_insn "*save_fpregs_<mode>_r1"
12184   [(match_parallel 0 "any_parallel_operand"
12185                    [(clobber (reg:P 65))
12186                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12187                     (use (reg:P 1))
12188                     (set (match_operand:DF 2 "memory_operand" "=m")
12189                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12190   ""
12191   "bl %1"
12192   [(set_attr "type" "branch")
12193    (set_attr "length" "4")])
12195 ; This is to explain that changes to the stack pointer should
12196 ; not be moved over loads from or stores to stack memory.
12197 (define_insn "stack_tie"
12198   [(match_parallel 0 "tie_operand"
12199                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12200   ""
12201   ""
12202   [(set_attr "length" "0")])
12204 (define_expand "epilogue"
12205   [(use (const_int 0))]
12206   ""
12208   if (!TARGET_SCHED_PROLOG)
12209     emit_insn (gen_blockage ());
12210   rs6000_emit_epilogue (FALSE);
12211   DONE;
12214 ; On some processors, doing the mtcrf one CC register at a time is
12215 ; faster (like on the 604e).  On others, doing them all at once is
12216 ; faster; for instance, on the 601 and 750.
12218 (define_expand "movsi_to_cr_one"
12219   [(set (match_operand:CC 0 "cc_reg_operand" "")
12220         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12221                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12222   ""
12223   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12225 (define_insn "*movsi_to_cr"
12226   [(match_parallel 0 "mtcrf_operation"
12227                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12228                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12229                                      (match_operand 3 "immediate_operand" "n")]
12230                                     UNSPEC_MOVESI_TO_CR))])]
12231  ""
12232  "*
12234   int mask = 0;
12235   int i;
12236   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12237     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12238   operands[4] = GEN_INT (mask);
12239   return \"mtcrf %4,%2\";
12241   [(set_attr "type" "mtcr")])
12243 (define_insn "*mtcrfsi"
12244   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12245         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12246                     (match_operand 2 "immediate_operand" "n")]
12247                    UNSPEC_MOVESI_TO_CR))]
12248   "GET_CODE (operands[0]) == REG
12249    && CR_REGNO_P (REGNO (operands[0]))
12250    && GET_CODE (operands[2]) == CONST_INT
12251    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12252   "mtcrf %R0,%1"
12253   [(set_attr "type" "mtcr")])
12255 ; The load-multiple instructions have similar properties.
12256 ; Note that "load_multiple" is a name known to the machine-independent
12257 ; code that actually corresponds to the PowerPC load-string.
12259 (define_insn "*lmw"
12260   [(match_parallel 0 "lmw_operation"
12261                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12262                          (match_operand:SI 2 "memory_operand" "m"))])]
12263   "TARGET_MULTIPLE"
12264   "lmw %1,%2"
12265   [(set_attr "type" "load")
12266    (set_attr "update" "yes")
12267    (set_attr "indexed" "yes")
12268    (set_attr "cell_micro" "always")])
12270 (define_insn "*return_internal_<mode>"
12271   [(simple_return)
12272    (use (match_operand:P 0 "register_operand" "lc"))]
12273   ""
12274   "b%T0"
12275   [(set_attr "type" "jmpreg")])
12277 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12278 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
12280 ; The following comment applies to:
12281 ;     save_gpregs_*
12282 ;     save_fpregs_*
12283 ;     restore_gpregs*
12284 ;     return_and_restore_gpregs*
12285 ;     return_and_restore_fpregs*
12286 ;     return_and_restore_fpregs_aix*
12288 ; The out-of-line save / restore functions expects one input argument.
12289 ; Since those are not standard call_insn's, we must avoid using
12290 ; MATCH_OPERAND for that argument. That way the register rename
12291 ; optimization will not try to rename this register.
12292 ; Each pattern is repeated for each possible register number used in 
12293 ; various ABIs (r11, r1, and for some functions r12)
12295 (define_insn "*restore_gpregs_<mode>_r11"
12296  [(match_parallel 0 "any_parallel_operand"
12297                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12298                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12299                    (use (reg:P 11))
12300                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12301                         (match_operand:P 4 "memory_operand" "m"))])]
12302  ""
12303  "bl %2"
12304  [(set_attr "type" "branch")
12305   (set_attr "length" "4")])
12307 (define_insn "*restore_gpregs_<mode>_r12"
12308  [(match_parallel 0 "any_parallel_operand"
12309                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12310                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12311                    (use (reg:P 12))
12312                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12313                         (match_operand:P 4 "memory_operand" "m"))])]
12314  ""
12315  "bl %2"
12316  [(set_attr "type" "branch")
12317   (set_attr "length" "4")])
12319 (define_insn "*restore_gpregs_<mode>_r1"
12320  [(match_parallel 0 "any_parallel_operand"
12321                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12322                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12323                    (use (reg:P 1))
12324                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12325                         (match_operand:P 4 "memory_operand" "m"))])]
12326  ""
12327  "bl %2"
12328  [(set_attr "type" "branch")
12329   (set_attr "length" "4")])
12331 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12332  [(match_parallel 0 "any_parallel_operand"
12333                   [(return)
12334                    (clobber (match_operand:P 1 "register_operand" "=l"))
12335                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12336                    (use (reg:P 11))
12337                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12338                         (match_operand:P 4 "memory_operand" "m"))])]
12339  ""
12340  "b %2"
12341  [(set_attr "type" "branch")
12342   (set_attr "length" "4")])
12344 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12345  [(match_parallel 0 "any_parallel_operand"
12346                   [(return)
12347                    (clobber (match_operand:P 1 "register_operand" "=l"))
12348                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12349                    (use (reg:P 12))
12350                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12351                         (match_operand:P 4 "memory_operand" "m"))])]
12352  ""
12353  "b %2"
12354  [(set_attr "type" "branch")
12355   (set_attr "length" "4")])
12357 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12358  [(match_parallel 0 "any_parallel_operand"
12359                   [(return)
12360                    (clobber (match_operand:P 1 "register_operand" "=l"))
12361                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12362                    (use (reg:P 1))
12363                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12364                         (match_operand:P 4 "memory_operand" "m"))])]
12365  ""
12366  "b %2"
12367  [(set_attr "type" "branch")
12368   (set_attr "length" "4")])
12370 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12371  [(match_parallel 0 "any_parallel_operand"
12372                   [(return)
12373                    (clobber (match_operand:P 1 "register_operand" "=l"))
12374                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12375                    (use (reg:P 11))
12376                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12377                         (match_operand:DF 4 "memory_operand" "m"))])]
12378  ""
12379  "b %2"
12380  [(set_attr "type" "branch")
12381   (set_attr "length" "4")])
12383 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12384  [(match_parallel 0 "any_parallel_operand"
12385                   [(return)
12386                    (clobber (match_operand:P 1 "register_operand" "=l"))
12387                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12388                    (use (reg:P 12))
12389                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12390                         (match_operand:DF 4 "memory_operand" "m"))])]
12391  ""
12392  "b %2"
12393  [(set_attr "type" "branch")
12394   (set_attr "length" "4")])
12396 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12397  [(match_parallel 0 "any_parallel_operand"
12398                   [(return)
12399                    (clobber (match_operand:P 1 "register_operand" "=l"))
12400                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12401                    (use (reg:P 1))
12402                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12403                         (match_operand:DF 4 "memory_operand" "m"))])]
12404  ""
12405  "b %2"
12406  [(set_attr "type" "branch")
12407   (set_attr "length" "4")])
12409 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12410  [(match_parallel 0 "any_parallel_operand"
12411                   [(return)
12412                    (use (match_operand:P 1 "register_operand" "l"))
12413                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12414                    (use (reg:P 11))
12415                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12416                         (match_operand:DF 4 "memory_operand" "m"))])]
12417  ""
12418  "b %2"
12419  [(set_attr "type" "branch")
12420   (set_attr "length" "4")])
12422 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12423  [(match_parallel 0 "any_parallel_operand"
12424                   [(return)
12425                    (use (match_operand:P 1 "register_operand" "l"))
12426                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12427                    (use (reg:P 1))
12428                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12429                         (match_operand:DF 4 "memory_operand" "m"))])]
12430  ""
12431  "b %2"
12432  [(set_attr "type" "branch")
12433   (set_attr "length" "4")])
12435 ; This is used in compiling the unwind routines.
12436 (define_expand "eh_return"
12437   [(use (match_operand 0 "general_operand" ""))]
12438   ""
12439   "
12441   if (TARGET_32BIT)
12442     emit_insn (gen_eh_set_lr_si (operands[0]));
12443   else
12444     emit_insn (gen_eh_set_lr_di (operands[0]));
12445   DONE;
12448 ; We can't expand this before we know where the link register is stored.
12449 (define_insn "eh_set_lr_<mode>"
12450   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12451                     UNSPECV_EH_RR)
12452    (clobber (match_scratch:P 1 "=&b"))]
12453   ""
12454   "#")
12456 (define_split
12457   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12458    (clobber (match_scratch 1 ""))]
12459   "reload_completed"
12460   [(const_int 0)]
12461   "
12463   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12464   DONE;
12467 (define_insn "prefetch"
12468   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12469              (match_operand:SI 1 "const_int_operand" "n")
12470              (match_operand:SI 2 "const_int_operand" "n"))]
12471   ""
12472   "*
12474   if (GET_CODE (operands[0]) == REG)
12475     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12476   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12478   [(set_attr "type" "load")])
12480 ;; Handle -fsplit-stack.
12482 (define_expand "split_stack_prologue"
12483   [(const_int 0)]
12484   ""
12486   rs6000_expand_split_stack_prologue ();
12487   DONE;
12490 (define_expand "load_split_stack_limit"
12491   [(set (match_operand 0)
12492         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12493   ""
12495   emit_insn (gen_rtx_SET (operands[0],
12496                           gen_rtx_UNSPEC (Pmode,
12497                                           gen_rtvec (1, const0_rtx),
12498                                           UNSPEC_STACK_CHECK)));
12499   DONE;
12502 (define_insn "load_split_stack_limit_di"
12503   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12504         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12505   "TARGET_64BIT"
12506   "ld %0,-0x7040(13)"
12507   [(set_attr "type" "load")
12508    (set_attr "update" "no")
12509    (set_attr "indexed" "no")])
12511 (define_insn "load_split_stack_limit_si"
12512   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12513         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12514   "!TARGET_64BIT"
12515   "lwz %0,-0x7020(2)"
12516   [(set_attr "type" "load")
12517    (set_attr "update" "no")
12518    (set_attr "indexed" "no")])
12520 ;; A return instruction which the middle-end doesn't see.
12521 (define_insn "split_stack_return"
12522   [(unspec_volatile [(const_int 0)] UNSPECV_SPLIT_STACK_RETURN)]
12523   ""
12524   "blr"
12525   [(set_attr "type" "jmpreg")])
12527 ;; If there are operand 0 bytes available on the stack, jump to
12528 ;; operand 1.
12529 (define_expand "split_stack_space_check"
12530   [(set (match_dup 2)
12531         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12532    (set (match_dup 3)
12533         (minus (reg STACK_POINTER_REGNUM)
12534                (match_operand 0)))
12535    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12536    (set (pc) (if_then_else
12537               (geu (match_dup 4) (const_int 0))
12538               (label_ref (match_operand 1))
12539               (pc)))]
12540   ""
12542   rs6000_split_stack_space_check (operands[0], operands[1]);
12543   DONE;
12546 (define_insn "bpermd_<mode>"
12547   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12548         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12549                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12550   "TARGET_POPCNTD"
12551   "bpermd %0,%1,%2"
12552   [(set_attr "type" "popcnt")])
12555 ;; Builtin fma support.  Handle 
12556 ;; Note that the conditions for expansion are in the FMA_F iterator.
12558 (define_expand "fma<mode>4"
12559   [(set (match_operand:FMA_F 0 "register_operand" "")
12560         (fma:FMA_F
12561           (match_operand:FMA_F 1 "register_operand" "")
12562           (match_operand:FMA_F 2 "register_operand" "")
12563           (match_operand:FMA_F 3 "register_operand" "")))]
12564   ""
12565   "")
12567 (define_insn "*fma<mode>4_fpr"
12568   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12569         (fma:SFDF
12570           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12571           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12572           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12573   "TARGET_<MODE>_FPR"
12574   "@
12575    fmadd<Ftrad> %0,%1,%2,%3
12576    xsmadda<Fvsx> %x0,%x1,%x2
12577    xsmaddm<Fvsx> %x0,%x1,%x3"
12578   [(set_attr "type" "fp")
12579    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12581 ; Altivec only has fma and nfms.
12582 (define_expand "fms<mode>4"
12583   [(set (match_operand:FMA_F 0 "register_operand" "")
12584         (fma:FMA_F
12585           (match_operand:FMA_F 1 "register_operand" "")
12586           (match_operand:FMA_F 2 "register_operand" "")
12587           (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12588   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12589   "")
12591 (define_insn "*fms<mode>4_fpr"
12592   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12593         (fma:SFDF
12594          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12595          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12596          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12597   "TARGET_<MODE>_FPR"
12598   "@
12599    fmsub<Ftrad> %0,%1,%2,%3
12600    xsmsuba<Fvsx> %x0,%x1,%x2
12601    xsmsubm<Fvsx> %x0,%x1,%x3"
12602   [(set_attr "type" "fp")
12603    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12605 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12606 (define_expand "fnma<mode>4"
12607   [(set (match_operand:FMA_F 0 "register_operand" "")
12608         (neg:FMA_F
12609           (fma:FMA_F
12610             (match_operand:FMA_F 1 "register_operand" "")
12611             (match_operand:FMA_F 2 "register_operand" "")
12612             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12613   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12614   "")
12616 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12617 (define_expand "fnms<mode>4"
12618   [(set (match_operand:FMA_F 0 "register_operand" "")
12619         (neg:FMA_F
12620           (fma:FMA_F
12621             (match_operand:FMA_F 1 "register_operand" "")
12622             (match_operand:FMA_F 2 "register_operand" "")
12623             (match_operand:FMA_F 3 "register_operand" ""))))]
12624   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12625   "")
12627 ; Not an official optab name, but used from builtins.
12628 (define_expand "nfma<mode>4"
12629   [(set (match_operand:FMA_F 0 "register_operand" "")
12630         (neg:FMA_F
12631           (fma:FMA_F
12632             (match_operand:FMA_F 1 "register_operand" "")
12633             (match_operand:FMA_F 2 "register_operand" "")
12634             (match_operand:FMA_F 3 "register_operand" ""))))]
12635   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12636   "")
12638 (define_insn "*nfma<mode>4_fpr"
12639   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12640         (neg:SFDF
12641          (fma:SFDF
12642           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12643           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12644           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12645   "TARGET_<MODE>_FPR"
12646   "@
12647    fnmadd<Ftrad> %0,%1,%2,%3
12648    xsnmadda<Fvsx> %x0,%x1,%x2
12649    xsnmaddm<Fvsx> %x0,%x1,%x3"
12650   [(set_attr "type" "fp")
12651    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12653 ; Not an official optab name, but used from builtins.
12654 (define_expand "nfms<mode>4"
12655   [(set (match_operand:FMA_F 0 "register_operand" "")
12656         (neg:FMA_F
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   ""
12662   "")
12664 (define_insn "*nfmssf4_fpr"
12665   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12666         (neg:SFDF
12667          (fma:SFDF
12668           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12669           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12670           (neg:SFDF
12671            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
12672   "TARGET_<MODE>_FPR"
12673   "@
12674    fnmsub<Ftrad> %0,%1,%2,%3
12675    xsnmsuba<Fvsx> %x0,%x1,%x2
12676    xsnmsubm<Fvsx> %x0,%x1,%x3"
12677   [(set_attr "type" "fp")
12678    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12681 (define_expand "rs6000_get_timebase"
12682   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
12683   ""
12685   if (TARGET_POWERPC64)
12686     emit_insn (gen_rs6000_mftb_di (operands[0]));
12687   else
12688     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
12689   DONE;
12692 (define_insn "rs6000_get_timebase_ppc32"
12693   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12694         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
12695    (clobber (match_scratch:SI 1 "=r"))
12696    (clobber (match_scratch:CC 2 "=y"))]
12697   "!TARGET_POWERPC64"
12699   if (WORDS_BIG_ENDIAN)
12700     if (TARGET_MFCRF)
12701       {
12702         return "mfspr %0,269\;"
12703                "mfspr %L0,268\;"
12704                "mfspr %1,269\;"
12705                "cmpw %2,%0,%1\;"
12706                "bne- %2,$-16";
12707       }
12708     else
12709       {
12710         return "mftbu %0\;"
12711                "mftb %L0\;"
12712                "mftbu %1\;"
12713                "cmpw %2,%0,%1\;"
12714                "bne- %2,$-16";
12715       }
12716   else
12717     if (TARGET_MFCRF)
12718       {
12719         return "mfspr %L0,269\;"
12720                "mfspr %0,268\;"
12721                "mfspr %1,269\;"
12722                "cmpw %2,%L0,%1\;"
12723                "bne- %2,$-16";
12724       }
12725     else
12726       {
12727         return "mftbu %L0\;"
12728                "mftb %0\;"
12729                "mftbu %1\;"
12730                "cmpw %2,%L0,%1\;"
12731                "bne- %2,$-16";
12732       }
12734   [(set_attr "length" "20")])
12736 (define_insn "rs6000_mftb_<mode>"
12737   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12738         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
12739   ""
12741   if (TARGET_MFCRF)
12742     return "mfspr %0,268";
12743   else
12744     return "mftb %0";
12748 (define_insn "rs6000_mffs"
12749   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
12750         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
12751   "TARGET_HARD_FLOAT && TARGET_FPRS"
12752   "mffs %0")
12754 (define_insn "rs6000_mtfsf"
12755   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
12756                      (match_operand:DF 1 "gpc_reg_operand" "d")]
12757                     UNSPECV_MTFSF)]
12758   "TARGET_HARD_FLOAT && TARGET_FPRS"
12759   "mtfsf %0,%1")
12762 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
12763 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
12764 ;; register that is being loaded.  The fused ops must be physically adjacent.
12766 ;; There are two parts to addis fusion.  The support for fused TOCs occur
12767 ;; before register allocation, and is meant to reduce the lifetime for the
12768 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
12769 ;; to use the register that is being load.  The peephole2 then gathers any
12770 ;; other fused possibilities that it can find after register allocation.  If
12771 ;; power9 fusion is selected, we also fuse floating point loads/stores.
12773 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
12774 ;; before register allocation, so that we can avoid allocating a temporary base
12775 ;; register that won't be used, and that we try to load into base registers,
12776 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
12777 ;; (addis followed by load) even on power8.
12779 (define_split
12780   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
12781         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
12782   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
12783   [(parallel [(set (match_dup 0) (match_dup 2))
12784               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12785               (use (match_dup 3))
12786               (clobber (scratch:DI))])]
12788   operands[2] = fusion_wrap_memory_address (operands[1]);
12789   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
12792 (define_insn "*toc_fusionload_<mode>"
12793   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
12794         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
12795    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12796    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
12797    (clobber (match_scratch:DI 3 "=X,&b"))]
12798   "TARGET_TOC_FUSION_INT"
12800   if (base_reg_operand (operands[0], <MODE>mode))
12801     return emit_fusion_gpr_load (operands[0], operands[1]);
12803   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
12805   [(set_attr "type" "load")
12806    (set_attr "length" "8")])
12808 (define_insn "*toc_fusionload_di"
12809   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
12810         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
12811    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12812    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
12813    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
12814   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
12815    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
12817   if (base_reg_operand (operands[0], DImode))
12818     return emit_fusion_gpr_load (operands[0], operands[1]);
12820   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
12822   [(set_attr "type" "load")
12823    (set_attr "length" "8")])
12826 ;; Find cases where the addis that feeds into a load instruction is either used
12827 ;; once or is the same as the target register, and replace it with the fusion
12828 ;; insn
12830 (define_peephole2
12831   [(set (match_operand:P 0 "base_reg_operand" "")
12832         (match_operand:P 1 "fusion_gpr_addis" ""))
12833    (set (match_operand:INT1 2 "base_reg_operand" "")
12834         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
12835   "TARGET_P8_FUSION
12836    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
12837                          operands[3])"
12838   [(const_int 0)]
12840   expand_fusion_gpr_load (operands);
12841   DONE;
12844 ;; Fusion insn, created by the define_peephole2 above (and eventually by
12845 ;; reload)
12847 (define_insn "fusion_gpr_load_<mode>"
12848   [(set (match_operand:INT1 0 "base_reg_operand" "=&b")
12849         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "")]
12850                      UNSPEC_FUSION_GPR))]
12851   "TARGET_P8_FUSION"
12853   return emit_fusion_gpr_load (operands[0], operands[1]);
12855   [(set_attr "type" "load")
12856    (set_attr "length" "8")])
12859 ;; ISA 3.0 (power9) fusion support
12860 ;; Merge addis with floating load/store to FPRs (or GPRs).
12861 (define_peephole2
12862   [(set (match_operand:P 0 "base_reg_operand" "")
12863         (match_operand:P 1 "fusion_gpr_addis" ""))
12864    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
12865         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
12866   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
12867    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
12868   [(const_int 0)]
12870   expand_fusion_p9_load (operands);
12871   DONE;
12874 (define_peephole2
12875   [(set (match_operand:P 0 "base_reg_operand" "")
12876         (match_operand:P 1 "fusion_gpr_addis" ""))
12877    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
12878         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
12879   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
12880    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
12881   [(const_int 0)]
12883   expand_fusion_p9_store (operands);
12884   DONE;
12887 (define_peephole2
12888   [(set (match_operand:SDI 0 "int_reg_operand" "")
12889         (match_operand:SDI 1 "upper16_cint_operand" ""))
12890    (set (match_dup 0)
12891         (ior:SDI (match_dup 0)
12892                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
12893   "TARGET_P9_FUSION"
12894   [(set (match_dup 0)
12895         (unspec:SDI [(match_dup 1)
12896                      (match_dup 2)] UNSPEC_FUSION_P9))])
12898 (define_peephole2
12899   [(set (match_operand:SDI 0 "int_reg_operand" "")
12900         (match_operand:SDI 1 "upper16_cint_operand" ""))
12901    (set (match_operand:SDI 2 "int_reg_operand" "")
12902         (ior:SDI (match_dup 0)
12903                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
12904   "TARGET_P9_FUSION
12905    && !rtx_equal_p (operands[0], operands[2])
12906    && peep2_reg_dead_p (2, operands[0])"
12907   [(set (match_dup 2)
12908         (unspec:SDI [(match_dup 1)
12909                      (match_dup 3)] UNSPEC_FUSION_P9))])
12911 ;; Fusion insns, created by the define_peephole2 above (and eventually by
12912 ;; reload).  Because we want to eventually have secondary_reload generate
12913 ;; these, they have to have a single alternative that gives the register
12914 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
12915 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
12916   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
12917         (unspec:GPR_FUSION
12918          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
12919          UNSPEC_FUSION_P9))
12920    (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
12921   "TARGET_P9_FUSION"
12923   /* This insn is a secondary reload insn, which cannot have alternatives.
12924      If we are not loading up register 0, use the power8 fusion instead.  */
12925   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
12926     return emit_fusion_gpr_load (operands[0], operands[1]);
12928   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
12930   [(set_attr "type" "load")
12931    (set_attr "length" "8")])
12933 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
12934   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
12935         (unspec:GPR_FUSION
12936          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
12937          UNSPEC_FUSION_P9))
12938    (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
12939   "TARGET_P9_FUSION"
12941   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
12943   [(set_attr "type" "store")
12944    (set_attr "length" "8")])
12946 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
12947   [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
12948         (unspec:FPR_FUSION
12949          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
12950          UNSPEC_FUSION_P9))
12951    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
12952   "TARGET_P9_FUSION"
12954   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
12956   [(set_attr "type" "fpload")
12957    (set_attr "length" "8")])
12959 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
12960   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
12961         (unspec:FPR_FUSION
12962          [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
12963          UNSPEC_FUSION_P9))
12964    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
12965   "TARGET_P9_FUSION"
12967   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
12969   [(set_attr "type" "fpstore")
12970    (set_attr "length" "8")])
12972 (define_insn "*fusion_p9_<mode>_constant"
12973   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
12974         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
12975                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
12976                     UNSPEC_FUSION_P9))] 
12977   "TARGET_P9_FUSION"
12979   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
12980   return "ori %0,%0,%2";
12982   [(set_attr "type" "two")
12983    (set_attr "length" "8")])
12986 ;; Miscellaneous ISA 2.06 (power7) instructions
12987 (define_insn "addg6s"
12988   [(set (match_operand:SI 0 "register_operand" "=r")
12989         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
12990                     (match_operand:SI 2 "register_operand" "r")]
12991                    UNSPEC_ADDG6S))]
12992   "TARGET_POPCNTD"
12993   "addg6s %0,%1,%2"
12994   [(set_attr "type" "integer")
12995    (set_attr "length" "4")])
12997 (define_insn "cdtbcd"
12998   [(set (match_operand:SI 0 "register_operand" "=r")
12999         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13000                    UNSPEC_CDTBCD))]
13001   "TARGET_POPCNTD"
13002   "cdtbcd %0,%1"
13003   [(set_attr "type" "integer")
13004    (set_attr "length" "4")])
13006 (define_insn "cbcdtd"
13007   [(set (match_operand:SI 0 "register_operand" "=r")
13008         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13009                    UNSPEC_CBCDTD))]
13010   "TARGET_POPCNTD"
13011   "cbcdtd %0,%1"
13012   [(set_attr "type" "integer")
13013    (set_attr "length" "4")])
13015 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13016                                         UNSPEC_DIVEO
13017                                         UNSPEC_DIVEU
13018                                         UNSPEC_DIVEUO])
13020 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13021                              (UNSPEC_DIVEO      "eo")
13022                              (UNSPEC_DIVEU      "eu")
13023                              (UNSPEC_DIVEUO     "euo")])
13025 (define_insn "div<div_extend>_<mode>"
13026   [(set (match_operand:GPR 0 "register_operand" "=r")
13027         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13028                      (match_operand:GPR 2 "register_operand" "r")]
13029                     UNSPEC_DIV_EXTEND))]
13030   "TARGET_POPCNTD"
13031   "div<wd><div_extend> %0,%1,%2"
13032   [(set_attr "type" "div")
13033    (set_attr "size" "<bits>")])
13036 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13038 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13039 (define_mode_attr FP128_64 [(TF "DF")
13040                             (IF "DF")
13041                             (TD "DI")
13042                             (KF "DI")])
13044 (define_expand "unpack<mode>"
13045   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13046         (unspec:<FP128_64>
13047          [(match_operand:FMOVE128 1 "register_operand" "")
13048           (match_operand:QI 2 "const_0_to_1_operand" "")]
13049          UNSPEC_UNPACK_128BIT))]
13050   "FLOAT128_2REG_P (<MODE>mode)"
13051   "")
13053 (define_insn_and_split "unpack<mode>_dm"
13054   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13055         (unspec:<FP128_64>
13056          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13057           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13058          UNSPEC_UNPACK_128BIT))]
13059   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13060   "#"
13061   "&& reload_completed"
13062   [(set (match_dup 0) (match_dup 3))]
13064   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13066   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13067     {
13068       emit_note (NOTE_INSN_DELETED);
13069       DONE;
13070     }
13072   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13074   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13075    (set_attr "length" "4")])
13077 (define_insn_and_split "unpack<mode>_nodm"
13078   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13079         (unspec:<FP128_64>
13080          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13081           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13082          UNSPEC_UNPACK_128BIT))]
13083   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13084   "#"
13085   "&& reload_completed"
13086   [(set (match_dup 0) (match_dup 3))]
13088   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13090   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13091     {
13092       emit_note (NOTE_INSN_DELETED);
13093       DONE;
13094     }
13096   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13098   [(set_attr "type" "fp,fpstore")
13099    (set_attr "length" "4")])
13101 (define_insn_and_split "pack<mode>"
13102   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13103         (unspec:FMOVE128
13104          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13105           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13106          UNSPEC_PACK_128BIT))]
13107   "FLOAT128_2REG_P (<MODE>mode)"
13108   "@
13109    fmr %L0,%2
13110    #"
13111   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13112   [(set (match_dup 3) (match_dup 1))
13113    (set (match_dup 4) (match_dup 2))]
13115   unsigned dest_hi = REGNO (operands[0]);
13116   unsigned dest_lo = dest_hi + 1;
13118   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13119   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13121   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13122   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13124   [(set_attr "type" "fp,fp")
13125    (set_attr "length" "4,8")])
13127 (define_insn "unpack<mode>"
13128   [(set (match_operand:DI 0 "register_operand" "=d,d")
13129         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13130                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13131          UNSPEC_UNPACK_128BIT))]
13132   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13134   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13135     return ASM_COMMENT_START " xxpermdi to same register";
13137   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13138   return "xxpermdi %x0,%x1,%x1,%3";
13140   [(set_attr "type" "vecperm")])
13142 (define_insn "pack<mode>"
13143   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13144         (unspec:FMOVE128_VSX
13145          [(match_operand:DI 1 "register_operand" "d")
13146           (match_operand:DI 2 "register_operand" "d")]
13147          UNSPEC_PACK_128BIT))]
13148   "TARGET_VSX"
13149   "xxpermdi %x0,%x1,%x2,0"
13150   [(set_attr "type" "vecperm")])
13154 ;; ISA 2.08 IEEE 128-bit floating point support.
13156 (define_insn "add<mode>3"
13157   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13158         (plus:IEEE128
13159          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13160          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13161   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13162   "xsaddqp %0,%1,%2"
13163   [(set_attr "type" "vecfloat")])
13165 (define_insn "sub<mode>3"
13166   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13167         (minus:IEEE128
13168          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13169          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13170   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13171   "xssubqp %0,%1,%2"
13172   [(set_attr "type" "vecfloat")])
13174 (define_insn "mul<mode>3"
13175   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13176         (mult:IEEE128
13177          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13178          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13179   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13180   "xsmulqp %0,%1,%2"
13181   [(set_attr "type" "vecfloat")])
13183 (define_insn "div<mode>3"
13184   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13185         (div:IEEE128
13186          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13187          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13188   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13189   "xsdivqp %0,%1,%2"
13190   [(set_attr "type" "vecdiv")])
13192 (define_insn "sqrt<mode>2"
13193   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13194         (sqrt:IEEE128
13195          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13196   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13197    "xssqrtqp %0,%1"
13198   [(set_attr "type" "vecdiv")])
13200 (define_insn "copysign<mode>3"
13201   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13202         (unspec:IEEE128
13203          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13204           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13205          UNSPEC_COPYSIGN))]
13206   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13207    "xscpsgnqp %0,%2,%1"
13208   [(set_attr "type" "vecsimple")])
13210 (define_insn "neg<mode>2_hw"
13211   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13212         (neg:IEEE128
13213          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13214   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13215   "xsnegqp %0,%1"
13216   [(set_attr "type" "vecfloat")])
13219 (define_insn "abs<mode>2_hw"
13220   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13221         (abs:IEEE128
13222          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13223   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13224   "xsabsqp %0,%1"
13225   [(set_attr "type" "vecfloat")])
13228 (define_insn "*nabs<mode>2_hw"
13229   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13230         (neg:IEEE128
13231          (abs:IEEE128
13232           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13233   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13234   "xsnabsqp %0,%1"
13235   [(set_attr "type" "vecfloat")])
13237 ;; Initially don't worry about doing fusion
13238 (define_insn "*fma<mode>4_hw"
13239   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13240         (fma:IEEE128
13241          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13242          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13243          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13244   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13245   "xsmaddqp %0,%1,%2"
13246   [(set_attr "type" "vecfloat")])
13248 (define_insn "*fms<mode>4_hw"
13249   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13250         (fma:IEEE128
13251          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13252          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13253          (neg:IEEE128
13254           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13255   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13256   "xsmsubqp %0,%1,%2"
13257   [(set_attr "type" "vecfloat")])
13259 (define_insn "*nfma<mode>4_hw"
13260   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13261         (neg:IEEE128
13262          (fma:IEEE128
13263           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13264           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13265           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13266   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13267   "xsnmaddqp %0,%1,%2"
13268   [(set_attr "type" "vecfloat")])
13270 (define_insn "*nfms<mode>4_hw"
13271   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13272         (neg:IEEE128
13273          (fma:IEEE128
13274           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13275           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13276           (neg:IEEE128
13277            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13278   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13279   "xsnmsubqp %0,%1,%2"
13280   [(set_attr "type" "vecfloat")])
13282 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13283   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13284         (float_extend:IEEE128
13285          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13286   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13287   "xscvdpqp %0,%1"
13288   [(set_attr "type" "vecfloat")])
13290 (define_insn "trunc<mode>df2_hw"
13291   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13292         (float_truncate:DF
13293          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13294   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13295   "xscvqpdp %0,%1"
13296   [(set_attr "type" "vecfloat")])
13298 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13299 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13300 ;; conversion
13301 (define_insn_and_split "trunc<mode>sf2_hw"
13302   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13303         (float_truncate:SF
13304          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13305    (clobber (match_scratch:DF 2 "=v"))]
13306   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13307   "#"
13308   "&& 1"
13309   [(set (match_dup 2)
13310         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13311    (set (match_dup 0)
13312         (float_truncate:SF (match_dup 2)))]
13314   if (GET_CODE (operands[2]) == SCRATCH)
13315     operands[2] = gen_reg_rtx (DFmode);
13317   [(set_attr "type" "vecfloat")
13318    (set_attr "length" "8")])
13320 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13321 ;; allowed in the traditional floating point registers. Use V2DImode so that
13322 ;; we can get a value in an Altivec register.
13324 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13325   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13326         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13327    (clobber (match_scratch:V2DI 2 "=v,v"))]
13328   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13329   "#"
13330   "&& 1"
13331   [(pc)]
13333   convert_float128_to_int (operands, <CODE>);
13334   DONE;
13336   [(set_attr "length" "8")
13337    (set_attr "type" "mftgpr,fpstore")])
13339 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13340   [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13341         (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13342    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13343   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13344   "#"
13345   "&& 1"
13346   [(pc)]
13348   convert_float128_to_int (operands, <CODE>);
13349   DONE;
13351   [(set_attr "length" "8")
13352    (set_attr "type" "mftgpr,vecsimple,fpstore")])
13354 (define_insn_and_split "float<uns>_<mode>si2_hw"
13355   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13356         (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13357    (clobber (match_scratch:V2DI 2 "=v,v"))]
13358   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13359   "#"
13360   "&& 1"
13361   [(pc)]
13363   convert_int_to_float128 (operands, <CODE>);
13364   DONE;
13366   [(set_attr "length" "8")
13367    (set_attr "type" "vecfloat")])
13369 (define_insn_and_split "float<uns>_<mode>di2_hw"
13370   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13371         (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13372    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13373   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13374   "#"
13375   "&& 1"
13376   [(pc)]
13378   convert_int_to_float128 (operands, <CODE>);
13379   DONE;
13381   [(set_attr "length" "8")
13382    (set_attr "type" "vecfloat")])
13384 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13385 (define_insn "*xscvqp<su>wz_<mode>"
13386   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13387         (unspec:V2DI
13388          [(any_fix:SI
13389            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13390          UNSPEC_IEEE128_CONVERT))]
13391   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13392   "xscvqp<su>wz %0,%1"
13393   [(set_attr "type" "vecfloat")])
13395 (define_insn "*xscvqp<su>dz_<mode>"
13396   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13397         (unspec:V2DI
13398          [(any_fix:DI
13399            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13400          UNSPEC_IEEE128_CONVERT))]
13401   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13402   "xscvqp<su>dz %0,%1"
13403   [(set_attr "type" "vecfloat")])
13405 (define_insn "*xscv<su>dqp_<mode>"
13406   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13407         (any_float:IEEE128
13408          (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13409                     UNSPEC_IEEE128_CONVERT)))]
13410   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13411   "xscv<su>dqp %0,%1"
13412   [(set_attr "type" "vecfloat")])
13414 (define_insn "*ieee128_mfvsrd"
13415   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13416         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13417                    UNSPEC_IEEE128_MOVE))]
13418   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13419   "@
13420    mfvsrd %0,%x1
13421    stxsdx %x1,%y0
13422    xxlor %x0,%x1,%x1"
13423   [(set_attr "type" "mftgpr,vecsimple,fpstore")])
13425 (define_insn "*ieee128_mfvsrwz"
13426   [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13427         (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13428                    UNSPEC_IEEE128_MOVE))]
13429   "TARGET_FLOAT128_HW"
13430   "@
13431    mfvsrwz %0,%x1
13432    stxsiwx %x1,%y0"
13433   [(set_attr "type" "mftgpr,fpstore")])
13435 ;; 0 says do sign-extension, 1 says zero-extension
13436 (define_insn "*ieee128_mtvsrw"
13437   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13438         (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13439                       (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13440                      UNSPEC_IEEE128_MOVE))]
13441   "TARGET_FLOAT128_HW"
13442   "@
13443    mtvsrwa %x0,%1
13444    lxsiwax %x0,%y1
13445    mtvsrwz %x0,%1
13446    lxsiwzx %x0,%y1"
13447   [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13450 (define_insn "*ieee128_mtvsrd"
13451   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13452         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13453                      UNSPEC_IEEE128_MOVE))]
13454   "TARGET_FLOAT128_HW"
13455   "@
13456    mtvsrd %x0,%1
13457    lxsdx %x0,%y1
13458    xxlor %x0,%x1,%x1"
13459   [(set_attr "type" "mffgpr,fpload,vecsimple")])
13461 ;; IEEE 128-bit instructions with round to odd semantics
13462 (define_insn "*trunc<mode>df2_odd"
13463   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13464         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13465                    UNSPEC_ROUND_TO_ODD))]
13466   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13467   "xscvqpdpo %0,%1"
13468   [(set_attr "type" "vecfloat")])
13470 ;; IEEE 128-bit comparisons
13471 (define_insn "*cmp<mode>_hw"
13472   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13473         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13474                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13475   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13476    "xscmpuqp %0,%1,%2"
13477   [(set_attr "type" "fpcompare")])
13481 (include "sync.md")
13482 (include "vector.md")
13483 (include "vsx.md")
13484 (include "altivec.md")
13485 (include "spe.md")
13486 (include "dfp.md")
13487 (include "paired.md")
13488 (include "crypto.md")
13489 (include "htm.md")