2014-09-21 Segher Boessenkool <segher@kernel.crashing.org>
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob91bdb7d9d286bfcb38f93fc66d0e327b00c0a937
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2014 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_MOVSI_GOT
73    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
74    UNSPEC_FCTIWZ
75    UNSPEC_FRIM
76    UNSPEC_FRIN
77    UNSPEC_FRIP
78    UNSPEC_FRIZ
79    UNSPEC_LD_MPIC               ; load_macho_picbase
80    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
81    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
82    UNSPEC_TLSGD
83    UNSPEC_TLSLD
84    UNSPEC_MOVESI_FROM_CR
85    UNSPEC_MOVESI_TO_CR
86    UNSPEC_TLSDTPREL
87    UNSPEC_TLSDTPRELHA
88    UNSPEC_TLSDTPRELLO
89    UNSPEC_TLSGOTDTPREL
90    UNSPEC_TLSTPREL
91    UNSPEC_TLSTPRELHA
92    UNSPEC_TLSTPRELLO
93    UNSPEC_TLSGOTTPREL
94    UNSPEC_TLSTLS
95    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
96    UNSPEC_MV_CR_GT              ; move_from_CR_gt_bit
97    UNSPEC_STFIWX
98    UNSPEC_POPCNTB
99    UNSPEC_FRES
100    UNSPEC_SP_SET
101    UNSPEC_SP_TEST
102    UNSPEC_SYNC
103    UNSPEC_LWSYNC
104    UNSPEC_SYNC_OP
105    UNSPEC_ATOMIC
106    UNSPEC_CMPXCHG
107    UNSPEC_XCHG
108    UNSPEC_AND
109    UNSPEC_DLMZB
110    UNSPEC_DLMZB_CR
111    UNSPEC_DLMZB_STRLEN
112    UNSPEC_RSQRT
113    UNSPEC_TOCREL
114    UNSPEC_MACHOPIC_OFFSET
115    UNSPEC_BPERM
116    UNSPEC_COPYSIGN
117    UNSPEC_PARITY
118    UNSPEC_FCTIW
119    UNSPEC_FCTID
120    UNSPEC_LFIWAX
121    UNSPEC_LFIWZX
122    UNSPEC_FCTIWUZ
123    UNSPEC_GRP_END_NOP
124    UNSPEC_P8V_FMRGOW
125    UNSPEC_P8V_MTVSRWZ
126    UNSPEC_P8V_RELOAD_FROM_GPR
127    UNSPEC_P8V_MTVSRD
128    UNSPEC_P8V_XXPERMDI
129    UNSPEC_P8V_RELOAD_FROM_VSX
130    UNSPEC_ADDG6S
131    UNSPEC_CDTBCD
132    UNSPEC_CBCDTD
133    UNSPEC_DIVE
134    UNSPEC_DIVEO
135    UNSPEC_DIVEU
136    UNSPEC_DIVEUO
137    UNSPEC_UNPACK_128BIT
138    UNSPEC_PACK_128BIT
139    UNSPEC_LSQ
140    UNSPEC_FUSION_GPR
141   ])
144 ;; UNSPEC_VOLATILE usage
147 (define_c_enum "unspecv"
148   [UNSPECV_BLOCK
149    UNSPECV_LL                   ; load-locked
150    UNSPECV_SC                   ; store-conditional
151    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
152    UNSPECV_EH_RR                ; eh_reg_restore
153    UNSPECV_ISYNC                ; isync instruction
154    UNSPECV_MFTB                 ; move from time base
155    UNSPECV_NLGR                 ; non-local goto receiver
156    UNSPECV_MFFS                 ; Move from FPSCR
157    UNSPECV_MTFSF                ; Move to FPSCR Fields
158   ])
161 ;; Define an insn type attribute.  This is used in function unit delay
162 ;; computations.
163 (define_attr "type"
164   "integer,two,three,
165    add,logical,shift,insert,
166    mul,halfmul,div,
167    exts,cntlz,popcnt,isel,
168    load,store,fpload,fpstore,vecload,vecstore,
169    cmp,
170    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
171    compare,
172    cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
173    fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
174    brinc,
175    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
176    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
177    htm"
178   (const_string "integer"))
180 ;; What data size does this instruction work on?
181 ;; This is used for insert, mul.
182 (define_attr "size" "8,16,32,64" (const_string "32"))
184 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
185 ;; This is used for add, logical, shift, exts, mul.
186 (define_attr "dot" "no,yes" (const_string "no"))
188 ;; Does this instruction sign-extend its result?
189 ;; This is used for load insns.
190 (define_attr "sign_extend" "no,yes" (const_string "no"))
192 ;; Does this instruction use indexed (that is, reg+reg) addressing?
193 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
194 ;; it is automatically set based on that.  If a load or store instruction
195 ;; has fewer than two operands it needs to set this attribute manually
196 ;; or the compiler will crash.
197 (define_attr "indexed" "no,yes"
198   (if_then_else (ior (match_operand 0 "indexed_address_mem")
199                      (match_operand 1 "indexed_address_mem"))
200                 (const_string "yes")
201                 (const_string "no")))
203 ;; Does this instruction use update addressing?
204 ;; This is used for load and store insns.  See the comments for "indexed".
205 (define_attr "update" "no,yes"
206   (if_then_else (ior (match_operand 0 "update_address_mem")
207                      (match_operand 1 "update_address_mem"))
208                 (const_string "yes")
209                 (const_string "no")))
211 ;; Is this instruction using operands[2] as shift amount, and can that be a
212 ;; register?
213 ;; This is used for shift insns.
214 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
216 ;; Is this instruction using a shift amount from a register?
217 ;; This is used for shift insns.
218 (define_attr "var_shift" "no,yes"
219   (if_then_else (and (eq_attr "type" "shift")
220                      (eq_attr "maybe_var_shift" "yes"))
221                 (if_then_else (match_operand 2 "gpc_reg_operand")
222                               (const_string "yes")
223                               (const_string "no"))
224                 (const_string "no")))
226 ;; Define floating point instruction sub-types for use with Xfpu.md
227 (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"))
229 ;; Length (in bytes).
230 ; '(pc)' in the following doesn't include the instruction itself; it is
231 ; calculated as if the instruction had zero size.
232 (define_attr "length" ""
233   (if_then_else (eq_attr "type" "branch")
234                 (if_then_else (and (ge (minus (match_dup 0) (pc))
235                                        (const_int -32768))
236                                    (lt (minus (match_dup 0) (pc))
237                                        (const_int 32764)))
238                               (const_int 4)
239                               (const_int 8))
240                 (const_int 4)))
242 ;; Processor type -- this attribute must exactly match the processor_type
243 ;; enumeration in rs6000-opts.h.
244 (define_attr "cpu"
245   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
246    ppc750,ppc7400,ppc7450,
247    ppc403,ppc405,ppc440,ppc476,
248    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
249    power4,power5,power6,power7,power8,
250    rs64a,mpccore,cell,ppca2,titan"
251   (const (symbol_ref "rs6000_cpu_attr")))
254 ;; If this instruction is microcoded on the CELL processor
255 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
256 (define_attr "cell_micro" "not,conditional,always"
257   (if_then_else (ior (eq_attr "type" "compare")
258                      (and (eq_attr "type" "shift,exts,mul")
259                           (eq_attr "dot" "yes"))
260                      (and (eq_attr "type" "load")
261                           (eq_attr "sign_extend" "yes"))
262                      (and (eq_attr "type" "shift")
263                           (eq_attr "var_shift" "yes")))
264                 (const_string "always")
265                 (const_string "not")))
267 (automata_option "ndfa")
269 (include "rs64.md")
270 (include "mpc.md")
271 (include "40x.md")
272 (include "440.md")
273 (include "476.md")
274 (include "601.md")
275 (include "603.md")
276 (include "6xx.md")
277 (include "7xx.md")
278 (include "7450.md")
279 (include "8540.md")
280 (include "e300c2c3.md")
281 (include "e500mc.md")
282 (include "e500mc64.md")
283 (include "e5500.md")
284 (include "e6500.md")
285 (include "power4.md")
286 (include "power5.md")
287 (include "power6.md")
288 (include "power7.md")
289 (include "power8.md")
290 (include "cell.md")
291 (include "xfpu.md")
292 (include "a2.md")
293 (include "titan.md")
295 (include "predicates.md")
296 (include "constraints.md")
298 (include "darwin.md")
301 ;; Mode iterators
303 ; This mode iterator allows :GPR to be used to indicate the allowable size
304 ; of whole values in GPRs.
305 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
307 ; Any supported integer mode.
308 (define_mode_iterator INT [QI HI SI DI TI PTI])
310 ; Any supported integer mode that fits in one register.
311 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
313 ; Everything we can extend QImode to.
314 (define_mode_iterator EXTQI [HI SI (DI "TARGET_POWERPC64")])
316 ; Everything we can extend HImode to.
317 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
319 ; Everything we can extend SImode to.
320 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
322 ; QImode or HImode for small atomic ops
323 (define_mode_iterator QHI [QI HI])
325 ; HImode or SImode for sign extended fusion ops
326 (define_mode_iterator HSI [HI SI])
328 ; SImode or DImode, even if DImode doesn't fit in GPRs.
329 (define_mode_iterator SDI [SI DI])
331 ; The size of a pointer.  Also, the size of the value that a record-condition
332 ; (one with a '.') will compare; and the size used for arithmetic carries.
333 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
335 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
336 ; PTImode is GPR only)
337 (define_mode_iterator TI2 [TI PTI])
339 ; Any hardware-supported floating-point mode
340 (define_mode_iterator FP [
341   (SF "TARGET_HARD_FLOAT 
342    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
343   (DF "TARGET_HARD_FLOAT 
344    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
345   (TF "!TARGET_IEEEQUAD
346    && TARGET_HARD_FLOAT
347    && (TARGET_FPRS || TARGET_E500_DOUBLE)
348    && TARGET_LONG_DOUBLE_128")
349   (DD "TARGET_DFP")
350   (TD "TARGET_DFP")])
352 ; Any fma capable floating-point mode.
353 (define_mode_iterator FMA_F [
354   (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
355   (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
356        || VECTOR_UNIT_VSX_P (DFmode)")
357   (V2SF "TARGET_PAIRED_FLOAT")
358   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
359   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
360   ])
362 ; Floating point move iterators to combine binary and decimal moves
363 (define_mode_iterator FMOVE32 [SF SD])
364 (define_mode_iterator FMOVE64 [DF DD])
365 (define_mode_iterator FMOVE64X [DI DF DD])
366 (define_mode_iterator FMOVE128 [(TF "!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128")
367                                 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
369 ; Iterators for 128 bit types for direct move
370 (define_mode_iterator FMOVE128_GPR [(TI    "TARGET_VSX_TIMODE")
371                                     (V16QI "")
372                                     (V8HI  "")
373                                     (V4SI  "")
374                                     (V4SF  "")
375                                     (V2DI  "")
376                                     (V2DF  "")
377                                     (V1TI  "")])
379 ; Whether a floating point move is ok, don't allow SD without hardware FP
380 (define_mode_attr fmove_ok [(SF "")
381                             (DF "")
382                             (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
383                             (DD "")])
385 ; Convert REAL_VALUE to the appropriate bits
386 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
387                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
388                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
389                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
391 ; Definitions for load to 32-bit fpr register
392 (define_mode_attr f32_lr [(SF "f")               (SD "wz")])
393 (define_mode_attr f32_lm [(SF "m")               (SD "Z")])
394 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
395 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1")  (SD "lxsiwzx %x0,%y1")])
397 ; Definitions for store from 32-bit fpr register
398 (define_mode_attr f32_sr [(SF "f")                (SD "wx")])
399 (define_mode_attr f32_sm [(SF "m")                (SD "Z")])
400 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
401 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0")  (SD "stxsiwzx %x1,%y0")])
403 ; Definitions for 32-bit fpr direct move
404 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
406 ; These modes do not fit in integer registers in 32-bit mode.
407 ; but on e500v2, the gpr are 64 bit registers
408 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
410 ; Iterator for reciprocal estimate instructions
411 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
413 ; Iterator for just SF/DF
414 (define_mode_iterator SFDF [SF DF])
416 ; SF/DF suffix for traditional floating instructions
417 (define_mode_attr Ftrad         [(SF "s") (DF "")])
419 ; SF/DF suffix for VSX instructions
420 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
422 ; SF/DF constraint for arithmetic on traditional floating point registers
423 (define_mode_attr Ff            [(SF "f") (DF "d")])
425 ; SF/DF constraint for arithmetic on VSX registers
426 (define_mode_attr Fv            [(SF "wy") (DF "ws")])
428 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
429 (define_mode_attr Fs            [(SF "s")  (DF "d")])
431 ; FRE/FRES support
432 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
433 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
435 ; Conditional returns.
436 (define_code_iterator any_return [return simple_return])
437 (define_code_attr return_pred [(return "direct_return ()")
438                                (simple_return "1")])
439 (define_code_attr return_str [(return "") (simple_return "simple_")])
441 ; Logical operators.
442 (define_code_iterator iorxor [ior xor])
443 (define_code_attr iorxor [(ior "ior") (xor "xor")])
444 (define_code_attr IORXOR [(ior "IOR") (xor "XOR")])
446 ; Signed/unsigned variants of ops.
447 (define_code_iterator any_extend [sign_extend zero_extend])
448 (define_code_attr u [(sign_extend "") (zero_extend "u")])
449 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
451 ; Various instructions that come in SI and DI forms.
452 ; A generic w/d attribute, for things like cmpw/cmpd.
453 (define_mode_attr wd [(QI    "b")
454                       (HI    "h")
455                       (SI    "w")
456                       (DI    "d")
457                       (V16QI "b")
458                       (V8HI  "h")
459                       (V4SI  "w")
460                       (V2DI  "d")])
462 ;; How many bits in this mode?
463 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
465 ; DImode bits
466 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
468 ;; ISEL/ISEL64 target selection
469 (define_mode_attr sel [(SI "") (DI "64")])
471 ;; Bitmask for shift instructions
472 (define_mode_attr hH [(SI "h") (DI "H")])
474 ;; A mode twice the size of the given mode
475 (define_mode_attr dmode [(SI "di") (DI "ti")])
476 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
478 ;; Suffix for reload patterns
479 (define_mode_attr ptrsize [(SI "32bit")
480                            (DI "64bit")])
482 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
483                             (DI "TARGET_64BIT")])
485 (define_mode_attr mptrsize [(SI "si")
486                             (DI "di")])
488 (define_mode_attr ptrload [(SI "lwz")
489                            (DI "ld")])
491 (define_mode_attr ptrm [(SI "m")
492                         (DI "Y")])
494 (define_mode_attr rreg [(SF   "f")
495                         (DF   "ws")
496                         (TF   "f")
497                         (TD   "f")
498                         (V4SF "wf")
499                         (V2DF "wd")])
501 (define_mode_attr rreg2 [(SF   "f")
502                          (DF   "d")])
504 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
505                                  (DF "TARGET_FCFID")])
507 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
508                                 (DF "TARGET_E500_DOUBLE")])
510 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
511                                 (DF "TARGET_DOUBLE_FLOAT")])
513 ;; Mode iterator for logical operations on 128-bit types
514 (define_mode_iterator BOOL_128          [TI
515                                          PTI
516                                          (V16QI "TARGET_ALTIVEC")
517                                          (V8HI  "TARGET_ALTIVEC")
518                                          (V4SI  "TARGET_ALTIVEC")
519                                          (V4SF  "TARGET_ALTIVEC")
520                                          (V2DI  "TARGET_ALTIVEC")
521                                          (V2DF  "TARGET_ALTIVEC")
522                                          (V1TI  "TARGET_ALTIVEC")])
524 ;; For the GPRs we use 3 constraints for register outputs, two that are the
525 ;; same as the output register, and a third where the output register is an
526 ;; early clobber, so we don't have to deal with register overlaps.  For the
527 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
528 ;; either.
530 ;; Mode attribute for boolean operation register constraints for output
531 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wa,v")
532                                          (PTI   "&r,r,r")
533                                          (V16QI "wa,v,&?r,?r,?r")
534                                          (V8HI  "wa,v,&?r,?r,?r")
535                                          (V4SI  "wa,v,&?r,?r,?r")
536                                          (V4SF  "wa,v,&?r,?r,?r")
537                                          (V2DI  "wa,v,&?r,?r,?r")
538                                          (V2DF  "wa,v,&?r,?r,?r")
539                                          (V1TI  "wa,v,&?r,?r,?r")])
541 ;; Mode attribute for boolean operation register constraints for operand1
542 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wa,v")
543                                          (PTI   "r,0,r")
544                                          (V16QI "wa,v,r,0,r")
545                                          (V8HI  "wa,v,r,0,r")
546                                          (V4SI  "wa,v,r,0,r")
547                                          (V4SF  "wa,v,r,0,r")
548                                          (V2DI  "wa,v,r,0,r")
549                                          (V2DF  "wa,v,r,0,r")
550                                          (V1TI  "wa,v,r,0,r")])
552 ;; Mode attribute for boolean operation register constraints for operand2
553 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wa,v")
554                                          (PTI   "r,r,0")
555                                          (V16QI "wa,v,r,r,0")
556                                          (V8HI  "wa,v,r,r,0")
557                                          (V4SI  "wa,v,r,r,0")
558                                          (V4SF  "wa,v,r,r,0")
559                                          (V2DI  "wa,v,r,r,0")
560                                          (V2DF  "wa,v,r,r,0")
561                                          (V1TI  "wa,v,r,r,0")])
563 ;; Mode attribute for boolean operation register constraints for operand1
564 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
565 ;; is used for operand1 or operand2
566 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wa,v")
567                                          (PTI   "r,0,0")
568                                          (V16QI "wa,v,r,0,0")
569                                          (V8HI  "wa,v,r,0,0")
570                                          (V4SI  "wa,v,r,0,0")
571                                          (V4SF  "wa,v,r,0,0")
572                                          (V2DI  "wa,v,r,0,0")
573                                          (V2DF  "wa,v,r,0,0")
574                                          (V1TI  "wa,v,r,0,0")])
576 ;; Start with fixed-point load and store insns.  Here we put only the more
577 ;; complex forms.  Basic data transfer is done later.
579 (define_insn "zero_extendqi<mode>2"
580   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
581         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
582   ""
583   "@
584    lbz%U1%X1 %0,%1
585    rlwinm %0,%1,0,0xff"
586   [(set_attr "type" "load,shift")])
588 (define_insn_and_split "*zero_extendqi<mode>2_dot"
589   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
590         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
591                     (const_int 0)))
592    (clobber (match_scratch:EXTQI 0 "=r,r"))]
593   "rs6000_gen_cell_microcode"
594   "@
595    andi. %0,%1,0xff
596    #"
597   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
598   [(set (match_dup 0)
599         (zero_extend:EXTQI (match_dup 1)))
600    (set (match_dup 2)
601         (compare:CC (match_dup 0)
602                     (const_int 0)))]
603   ""
604   [(set_attr "type" "logical")
605    (set_attr "dot" "yes")
606    (set_attr "length" "4,8")])
608 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
609   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
610         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
611                     (const_int 0)))
612    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
613         (zero_extend:EXTQI (match_dup 1)))]
614   "rs6000_gen_cell_microcode"
615   "@
616    andi. %0,%1,0xff
617    #"
618   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
619   [(set (match_dup 0)
620         (zero_extend:EXTQI (match_dup 1)))
621    (set (match_dup 2)
622         (compare:CC (match_dup 0)
623                     (const_int 0)))]
624   ""
625   [(set_attr "type" "logical")
626    (set_attr "dot" "yes")
627    (set_attr "length" "4,8")])
630 (define_insn "zero_extendhi<mode>2"
631   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
632         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
633   ""
634   "@
635    lhz%U1%X1 %0,%1
636    rlwinm %0,%1,0,0xffff"
637   [(set_attr "type" "load,shift")])
639 (define_insn_and_split "*zero_extendhi<mode>2_dot"
640   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
641         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
642                     (const_int 0)))
643    (clobber (match_scratch:EXTHI 0 "=r,r"))]
644   "rs6000_gen_cell_microcode"
645   "@
646    andi. %0,%1,0xffff
647    #"
648   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
649   [(set (match_dup 0)
650         (zero_extend:EXTHI (match_dup 1)))
651    (set (match_dup 2)
652         (compare:CC (match_dup 0)
653                     (const_int 0)))]
654   ""
655   [(set_attr "type" "logical")
656    (set_attr "dot" "yes")
657    (set_attr "length" "4,8")])
659 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
660   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
661         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
662                     (const_int 0)))
663    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
664         (zero_extend:EXTHI (match_dup 1)))]
665   "rs6000_gen_cell_microcode"
666   "@
667    andi. %0,%1,0xffff
668    #"
669   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
670   [(set (match_dup 0)
671         (zero_extend:EXTHI (match_dup 1)))
672    (set (match_dup 2)
673         (compare:CC (match_dup 0)
674                     (const_int 0)))]
675   ""
676   [(set_attr "type" "logical")
677    (set_attr "dot" "yes")
678    (set_attr "length" "4,8")])
681 (define_insn "zero_extendsi<mode>2"
682   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
683         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
684   ""
685   "@
686    lwz%U1%X1 %0,%1
687    rldicl %0,%1,0,32
688    mtvsrwz %x0,%1
689    lfiwzx %0,%y1
690    lxsiwzx %x0,%y1"
691   [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
693 (define_insn_and_split "*zero_extendsi<mode>2_dot"
694   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
695         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
696                     (const_int 0)))
697    (clobber (match_scratch:EXTSI 0 "=r,r"))]
698   "rs6000_gen_cell_microcode"
699   "@
700    rldicl. %0,%1,0,32
701    #"
702   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
703   [(set (match_dup 0)
704         (zero_extend:DI (match_dup 1)))
705    (set (match_dup 2)
706         (compare:CC (match_dup 0)
707                     (const_int 0)))]
708   ""
709   [(set_attr "type" "shift")
710    (set_attr "dot" "yes")
711    (set_attr "length" "4,8")])
713 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
714   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
715         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
716                     (const_int 0)))
717    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
718         (zero_extend:EXTSI (match_dup 1)))]
719   "rs6000_gen_cell_microcode"
720   "@
721    rldicl. %0,%1,0,32
722    #"
723   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
724   [(set (match_dup 0)
725         (zero_extend:EXTSI (match_dup 1)))
726    (set (match_dup 2)
727         (compare:CC (match_dup 0)
728                     (const_int 0)))]
729   ""
730   [(set_attr "type" "shift")
731    (set_attr "dot" "yes")
732    (set_attr "length" "4,8")])
735 (define_insn "extendqi<mode>2"
736   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
737         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
738   ""
739   "extsb %0,%1"
740   [(set_attr "type" "exts")])
742 (define_insn_and_split "*extendqi<mode>2_dot"
743   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
744         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
745                     (const_int 0)))
746    (clobber (match_scratch:EXTQI 0 "=r,r"))]
747   "rs6000_gen_cell_microcode"
748   "@
749    extsb. %0,%1
750    #"
751   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
752   [(set (match_dup 0)
753         (sign_extend:EXTQI (match_dup 1)))
754    (set (match_dup 2)
755         (compare:CC (match_dup 0)
756                     (const_int 0)))]
757   ""
758   [(set_attr "type" "exts")
759    (set_attr "dot" "yes")
760    (set_attr "length" "4,8")])
762 (define_insn_and_split "*extendqi<mode>2_dot2"
763   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
764         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
765                     (const_int 0)))
766    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
767         (sign_extend:EXTQI (match_dup 1)))]
768   "rs6000_gen_cell_microcode"
769   "@
770    extsb. %0,%1
771    #"
772   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
773   [(set (match_dup 0)
774         (sign_extend:EXTQI (match_dup 1)))
775    (set (match_dup 2)
776         (compare:CC (match_dup 0)
777                     (const_int 0)))]
778   ""
779   [(set_attr "type" "exts")
780    (set_attr "dot" "yes")
781    (set_attr "length" "4,8")])
784 (define_expand "extendhi<mode>2"
785   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
786         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
787   ""
788   "")
790 (define_insn "*extendhi<mode>2"
791   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
792         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
793   "rs6000_gen_cell_microcode"
794   "@
795    lha%U1%X1 %0,%1
796    extsh %0,%1"
797   [(set_attr "type" "load,exts")
798    (set_attr "sign_extend" "yes")])
800 (define_insn "*extendhi<mode>2_noload"
801   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
802         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
803   "!rs6000_gen_cell_microcode"
804   "extsh %0,%1"
805   [(set_attr "type" "exts")])
807 (define_insn_and_split "*extendhi<mode>2_dot"
808   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
809         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
810                     (const_int 0)))
811    (clobber (match_scratch:EXTHI 0 "=r,r"))]
812   "rs6000_gen_cell_microcode"
813   "@
814    extsh. %0,%1
815    #"
816   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
817   [(set (match_dup 0)
818         (sign_extend:EXTHI (match_dup 1)))
819    (set (match_dup 2)
820         (compare:CC (match_dup 0)
821                     (const_int 0)))]
822   ""
823   [(set_attr "type" "exts")
824    (set_attr "dot" "yes")
825    (set_attr "length" "4,8")])
827 (define_insn_and_split "*extendhi<mode>2_dot2"
828   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
829         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
830                     (const_int 0)))
831    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
832         (sign_extend:EXTHI (match_dup 1)))]
833   "rs6000_gen_cell_microcode"
834   "@
835    extsh. %0,%1
836    #"
837   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
838   [(set (match_dup 0)
839         (sign_extend:EXTHI (match_dup 1)))
840    (set (match_dup 2)
841         (compare:CC (match_dup 0)
842                     (const_int 0)))]
843   ""
844   [(set_attr "type" "exts")
845    (set_attr "dot" "yes")
846    (set_attr "length" "4,8")])
849 (define_insn "extendsi<mode>2"
850   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
851         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
852   ""
853   "@
854    lwa%U1%X1 %0,%1
855    extsw %0,%1
856    mtvsrwa %x0,%1
857    lfiwax %0,%y1
858    lxsiwax %x0,%y1"
859   [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
860    (set_attr "sign_extend" "yes")])
862 (define_insn_and_split "*extendsi<mode>2_dot"
863   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
864         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
865                     (const_int 0)))
866    (clobber (match_scratch:EXTSI 0 "=r,r"))]
867   "rs6000_gen_cell_microcode"
868   "@
869    extsw. %0,%1
870    #"
871   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
872   [(set (match_dup 0)
873         (sign_extend:EXTSI (match_dup 1)))
874    (set (match_dup 2)
875         (compare:CC (match_dup 0)
876                     (const_int 0)))]
877   ""
878   [(set_attr "type" "exts")
879    (set_attr "dot" "yes")
880    (set_attr "length" "4,8")])
882 (define_insn_and_split "*extendsi<mode>2_dot2"
883   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
884         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
885                     (const_int 0)))
886    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
887         (sign_extend:EXTSI (match_dup 1)))]
888   "rs6000_gen_cell_microcode"
889   "@
890    extsw. %0,%1
891    #"
892   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
893   [(set (match_dup 0)
894         (sign_extend:EXTSI (match_dup 1)))
895    (set (match_dup 2)
896         (compare:CC (match_dup 0)
897                     (const_int 0)))]
898   ""
899   [(set_attr "type" "exts")
900    (set_attr "dot" "yes")
901    (set_attr "length" "4,8")])
903 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
905 (define_insn "*macchwc"
906   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
907         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
908                                        (match_operand:SI 2 "gpc_reg_operand" "r")
909                                        (const_int 16))
910                                       (sign_extend:SI
911                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
912                              (match_operand:SI 4 "gpc_reg_operand" "0"))
913                     (const_int 0)))
914    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
915         (plus:SI (mult:SI (ashiftrt:SI
916                            (match_dup 2)
917                            (const_int 16))
918                           (sign_extend:SI
919                            (match_dup 1)))
920                  (match_dup 4)))]
921   "TARGET_MULHW"
922   "macchw. %0,%1,%2"
923   [(set_attr "type" "halfmul")])
925 (define_insn "*macchw"
926   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
927         (plus:SI (mult:SI (ashiftrt:SI
928                            (match_operand:SI 2 "gpc_reg_operand" "r")
929                            (const_int 16))
930                           (sign_extend:SI
931                            (match_operand:HI 1 "gpc_reg_operand" "r")))
932                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
933   "TARGET_MULHW"
934   "macchw %0,%1,%2"
935   [(set_attr "type" "halfmul")])
937 (define_insn "*macchwuc"
938   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
939         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
940                                        (match_operand:SI 2 "gpc_reg_operand" "r")
941                                        (const_int 16))
942                                       (zero_extend:SI
943                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
944                              (match_operand:SI 4 "gpc_reg_operand" "0"))
945                     (const_int 0)))
946    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
947         (plus:SI (mult:SI (lshiftrt:SI
948                            (match_dup 2)
949                            (const_int 16))
950                           (zero_extend:SI
951                            (match_dup 1)))
952                  (match_dup 4)))]
953   "TARGET_MULHW"
954   "macchwu. %0,%1,%2"
955   [(set_attr "type" "halfmul")])
957 (define_insn "*macchwu"
958   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
959         (plus:SI (mult:SI (lshiftrt:SI
960                            (match_operand:SI 2 "gpc_reg_operand" "r")
961                            (const_int 16))
962                           (zero_extend:SI
963                            (match_operand:HI 1 "gpc_reg_operand" "r")))
964                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
965   "TARGET_MULHW"
966   "macchwu %0,%1,%2"
967   [(set_attr "type" "halfmul")])
969 (define_insn "*machhwc"
970   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
971         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
972                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
973                                        (const_int 16))
974                                       (ashiftrt:SI
975                                        (match_operand:SI 2 "gpc_reg_operand" "r")
976                                        (const_int 16)))
977                              (match_operand:SI 4 "gpc_reg_operand" "0"))
978                     (const_int 0)))
979    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
980         (plus:SI (mult:SI (ashiftrt:SI
981                            (match_dup 1)
982                            (const_int 16))
983                           (ashiftrt:SI
984                            (match_dup 2)
985                            (const_int 16)))
986                  (match_dup 4)))]
987   "TARGET_MULHW"
988   "machhw. %0,%1,%2"
989   [(set_attr "type" "halfmul")])
991 (define_insn "*machhw"
992   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
993         (plus:SI (mult:SI (ashiftrt:SI
994                            (match_operand:SI 1 "gpc_reg_operand" "%r")
995                            (const_int 16))
996                           (ashiftrt:SI
997                            (match_operand:SI 2 "gpc_reg_operand" "r")
998                            (const_int 16)))
999                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1000   "TARGET_MULHW"
1001   "machhw %0,%1,%2"
1002   [(set_attr "type" "halfmul")])
1004 (define_insn "*machhwuc"
1005   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1006         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1007                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1008                                        (const_int 16))
1009                                       (lshiftrt:SI
1010                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1011                                        (const_int 16)))
1012                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1013                     (const_int 0)))
1014    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1015         (plus:SI (mult:SI (lshiftrt:SI
1016                            (match_dup 1)
1017                            (const_int 16))
1018                           (lshiftrt:SI
1019                            (match_dup 2)
1020                            (const_int 16)))
1021                  (match_dup 4)))]
1022   "TARGET_MULHW"
1023   "machhwu. %0,%1,%2"
1024   [(set_attr "type" "halfmul")])
1026 (define_insn "*machhwu"
1027   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1028         (plus:SI (mult:SI (lshiftrt:SI
1029                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1030                            (const_int 16))
1031                           (lshiftrt:SI
1032                            (match_operand:SI 2 "gpc_reg_operand" "r")
1033                            (const_int 16)))
1034                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1035   "TARGET_MULHW"
1036   "machhwu %0,%1,%2"
1037   [(set_attr "type" "halfmul")])
1039 (define_insn "*maclhwc"
1040   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1041         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1042                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1043                                       (sign_extend:SI
1044                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1045                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1046                     (const_int 0)))
1047    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1048         (plus:SI (mult:SI (sign_extend:SI
1049                            (match_dup 1))
1050                           (sign_extend:SI
1051                            (match_dup 2)))
1052                  (match_dup 4)))]
1053   "TARGET_MULHW"
1054   "maclhw. %0,%1,%2"
1055   [(set_attr "type" "halfmul")])
1057 (define_insn "*maclhw"
1058   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1059         (plus:SI (mult:SI (sign_extend:SI
1060                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1061                           (sign_extend:SI
1062                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1063                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1064   "TARGET_MULHW"
1065   "maclhw %0,%1,%2"
1066   [(set_attr "type" "halfmul")])
1068 (define_insn "*maclhwuc"
1069   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1070         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1071                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1072                                       (zero_extend:SI
1073                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1074                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1075                     (const_int 0)))
1076    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1077         (plus:SI (mult:SI (zero_extend:SI
1078                            (match_dup 1))
1079                           (zero_extend:SI
1080                            (match_dup 2)))
1081                  (match_dup 4)))]
1082   "TARGET_MULHW"
1083   "maclhwu. %0,%1,%2"
1084   [(set_attr "type" "halfmul")])
1086 (define_insn "*maclhwu"
1087   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1088         (plus:SI (mult:SI (zero_extend:SI
1089                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1090                           (zero_extend:SI
1091                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1092                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1093   "TARGET_MULHW"
1094   "maclhwu %0,%1,%2"
1095   [(set_attr "type" "halfmul")])
1097 (define_insn "*nmacchwc"
1098   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1099         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1100                               (mult:SI (ashiftrt:SI
1101                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1102                                         (const_int 16))
1103                                        (sign_extend:SI
1104                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1105                     (const_int 0)))
1106    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1107         (minus:SI (match_dup 4)
1108                   (mult:SI (ashiftrt:SI
1109                             (match_dup 2)
1110                             (const_int 16))
1111                            (sign_extend:SI
1112                             (match_dup 1)))))]
1113   "TARGET_MULHW"
1114   "nmacchw. %0,%1,%2"
1115   [(set_attr "type" "halfmul")])
1117 (define_insn "*nmacchw"
1118   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1119         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1120                   (mult:SI (ashiftrt:SI
1121                             (match_operand:SI 2 "gpc_reg_operand" "r")
1122                             (const_int 16))
1123                            (sign_extend:SI
1124                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1125   "TARGET_MULHW"
1126   "nmacchw %0,%1,%2"
1127   [(set_attr "type" "halfmul")])
1129 (define_insn "*nmachhwc"
1130   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1131         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1132                               (mult:SI (ashiftrt:SI
1133                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1134                                         (const_int 16))
1135                                        (ashiftrt:SI
1136                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1137                                         (const_int 16))))
1138                     (const_int 0)))
1139    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1140         (minus:SI (match_dup 4)
1141                   (mult:SI (ashiftrt:SI
1142                             (match_dup 1)
1143                             (const_int 16))
1144                            (ashiftrt:SI
1145                             (match_dup 2)
1146                             (const_int 16)))))]
1147   "TARGET_MULHW"
1148   "nmachhw. %0,%1,%2"
1149   [(set_attr "type" "halfmul")])
1151 (define_insn "*nmachhw"
1152   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1153         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1154                   (mult:SI (ashiftrt:SI
1155                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1156                             (const_int 16))
1157                            (ashiftrt:SI
1158                             (match_operand:SI 2 "gpc_reg_operand" "r")
1159                             (const_int 16)))))]
1160   "TARGET_MULHW"
1161   "nmachhw %0,%1,%2"
1162   [(set_attr "type" "halfmul")])
1164 (define_insn "*nmaclhwc"
1165   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1166         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1167                               (mult:SI (sign_extend:SI
1168                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1169                                        (sign_extend:SI
1170                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1171                     (const_int 0)))
1172    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1173         (minus:SI (match_dup 4)
1174                   (mult:SI (sign_extend:SI
1175                             (match_dup 1))
1176                            (sign_extend:SI
1177                             (match_dup 2)))))]
1178   "TARGET_MULHW"
1179   "nmaclhw. %0,%1,%2"
1180   [(set_attr "type" "halfmul")])
1182 (define_insn "*nmaclhw"
1183   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1184         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1185                   (mult:SI (sign_extend:SI
1186                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1187                            (sign_extend:SI
1188                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1189   "TARGET_MULHW"
1190   "nmaclhw %0,%1,%2"
1191   [(set_attr "type" "halfmul")])
1193 (define_insn "*mulchwc"
1194   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1195         (compare:CC (mult:SI (ashiftrt:SI
1196                               (match_operand:SI 2 "gpc_reg_operand" "r")
1197                               (const_int 16))
1198                              (sign_extend:SI
1199                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1200                     (const_int 0)))
1201    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1202         (mult:SI (ashiftrt:SI
1203                   (match_dup 2)
1204                   (const_int 16))
1205                  (sign_extend:SI
1206                   (match_dup 1))))]
1207   "TARGET_MULHW"
1208   "mulchw. %0,%1,%2"
1209   [(set_attr "type" "halfmul")])
1211 (define_insn "*mulchw"
1212   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1213         (mult:SI (ashiftrt:SI
1214                   (match_operand:SI 2 "gpc_reg_operand" "r")
1215                   (const_int 16))
1216                  (sign_extend:SI
1217                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1218   "TARGET_MULHW"
1219   "mulchw %0,%1,%2"
1220   [(set_attr "type" "halfmul")])
1222 (define_insn "*mulchwuc"
1223   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1224         (compare:CC (mult:SI (lshiftrt:SI
1225                               (match_operand:SI 2 "gpc_reg_operand" "r")
1226                               (const_int 16))
1227                              (zero_extend:SI
1228                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1229                     (const_int 0)))
1230    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1231         (mult:SI (lshiftrt:SI
1232                   (match_dup 2)
1233                   (const_int 16))
1234                  (zero_extend:SI
1235                   (match_dup 1))))]
1236   "TARGET_MULHW"
1237   "mulchwu. %0,%1,%2"
1238   [(set_attr "type" "halfmul")])
1240 (define_insn "*mulchwu"
1241   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1242         (mult:SI (lshiftrt:SI
1243                   (match_operand:SI 2 "gpc_reg_operand" "r")
1244                   (const_int 16))
1245                  (zero_extend:SI
1246                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1247   "TARGET_MULHW"
1248   "mulchwu %0,%1,%2"
1249   [(set_attr "type" "halfmul")])
1251 (define_insn "*mulhhwc"
1252   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1253         (compare:CC (mult:SI (ashiftrt:SI
1254                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1255                               (const_int 16))
1256                              (ashiftrt:SI
1257                               (match_operand:SI 2 "gpc_reg_operand" "r")
1258                               (const_int 16)))
1259                     (const_int 0)))
1260    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1261         (mult:SI (ashiftrt:SI
1262                   (match_dup 1)
1263                   (const_int 16))
1264                  (ashiftrt:SI
1265                   (match_dup 2)
1266                   (const_int 16))))]
1267   "TARGET_MULHW"
1268   "mulhhw. %0,%1,%2"
1269   [(set_attr "type" "halfmul")])
1271 (define_insn "*mulhhw"
1272   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1273         (mult:SI (ashiftrt:SI
1274                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1275                   (const_int 16))
1276                  (ashiftrt:SI
1277                   (match_operand:SI 2 "gpc_reg_operand" "r")
1278                   (const_int 16))))]
1279   "TARGET_MULHW"
1280   "mulhhw %0,%1,%2"
1281   [(set_attr "type" "halfmul")])
1283 (define_insn "*mulhhwuc"
1284   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1285         (compare:CC (mult:SI (lshiftrt:SI
1286                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1287                               (const_int 16))
1288                              (lshiftrt:SI
1289                               (match_operand:SI 2 "gpc_reg_operand" "r")
1290                               (const_int 16)))
1291                     (const_int 0)))
1292    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1293         (mult:SI (lshiftrt:SI
1294                   (match_dup 1)
1295                   (const_int 16))
1296                  (lshiftrt:SI
1297                   (match_dup 2)
1298                   (const_int 16))))]
1299   "TARGET_MULHW"
1300   "mulhhwu. %0,%1,%2"
1301   [(set_attr "type" "halfmul")])
1303 (define_insn "*mulhhwu"
1304   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1305         (mult:SI (lshiftrt:SI
1306                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1307                   (const_int 16))
1308                  (lshiftrt:SI
1309                   (match_operand:SI 2 "gpc_reg_operand" "r")
1310                   (const_int 16))))]
1311   "TARGET_MULHW"
1312   "mulhhwu %0,%1,%2"
1313   [(set_attr "type" "halfmul")])
1315 (define_insn "*mullhwc"
1316   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1317         (compare:CC (mult:SI (sign_extend:SI
1318                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1319                              (sign_extend:SI
1320                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1321                     (const_int 0)))
1322    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1323         (mult:SI (sign_extend:SI
1324                   (match_dup 1))
1325                  (sign_extend:SI
1326                   (match_dup 2))))]
1327   "TARGET_MULHW"
1328   "mullhw. %0,%1,%2"
1329   [(set_attr "type" "halfmul")])
1331 (define_insn "*mullhw"
1332   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1333         (mult:SI (sign_extend:SI
1334                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1335                  (sign_extend:SI
1336                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1337   "TARGET_MULHW"
1338   "mullhw %0,%1,%2"
1339   [(set_attr "type" "halfmul")])
1341 (define_insn "*mullhwuc"
1342   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1343         (compare:CC (mult:SI (zero_extend:SI
1344                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1345                              (zero_extend:SI
1346                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1347                     (const_int 0)))
1348    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1349         (mult:SI (zero_extend:SI
1350                   (match_dup 1))
1351                  (zero_extend:SI
1352                   (match_dup 2))))]
1353   "TARGET_MULHW"
1354   "mullhwu. %0,%1,%2"
1355   [(set_attr "type" "halfmul")])
1357 (define_insn "*mullhwu"
1358   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1359         (mult:SI (zero_extend:SI
1360                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1361                  (zero_extend:SI
1362                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1363   "TARGET_MULHW"
1364   "mullhwu %0,%1,%2"
1365   [(set_attr "type" "halfmul")])
1367 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1368 (define_insn "dlmzb"
1369   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1370         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1371                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1372                    UNSPEC_DLMZB_CR))
1373    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1374         (unspec:SI [(match_dup 1)
1375                     (match_dup 2)]
1376                    UNSPEC_DLMZB))]
1377   "TARGET_DLMZB"
1378   "dlmzb. %0,%1,%2")
1380 (define_expand "strlensi"
1381   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1382         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1383                     (match_operand:QI 2 "const_int_operand" "")
1384                     (match_operand 3 "const_int_operand" "")]
1385                    UNSPEC_DLMZB_STRLEN))
1386    (clobber (match_scratch:CC 4 "=x"))]
1387   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1389   rtx result = operands[0];
1390   rtx src = operands[1];
1391   rtx search_char = operands[2];
1392   rtx align = operands[3];
1393   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1394   rtx loop_label, end_label, mem, cr0, cond;
1395   if (search_char != const0_rtx
1396       || GET_CODE (align) != CONST_INT
1397       || INTVAL (align) < 8)
1398         FAIL;
1399   word1 = gen_reg_rtx (SImode);
1400   word2 = gen_reg_rtx (SImode);
1401   scratch_dlmzb = gen_reg_rtx (SImode);
1402   scratch_string = gen_reg_rtx (Pmode);
1403   loop_label = gen_label_rtx ();
1404   end_label = gen_label_rtx ();
1405   addr = force_reg (Pmode, XEXP (src, 0));
1406   emit_move_insn (scratch_string, addr);
1407   emit_label (loop_label);
1408   mem = change_address (src, SImode, scratch_string);
1409   emit_move_insn (word1, mem);
1410   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1411   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1412   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1413   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1414   emit_jump_insn (gen_rtx_SET (VOIDmode,
1415                                pc_rtx,
1416                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1417                                                      cond,
1418                                                      gen_rtx_LABEL_REF
1419                                                        (VOIDmode,
1420                                                         end_label),
1421                                                      pc_rtx)));
1422   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1423   emit_jump_insn (gen_rtx_SET (VOIDmode,
1424                                pc_rtx,
1425                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1426   emit_barrier ();
1427   emit_label (end_label);
1428   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1429   emit_insn (gen_subsi3 (result, scratch_string, addr));
1430   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1431   DONE;
1434 ;; Fixed-point arithmetic insns.
1436 (define_expand "add<mode>3"
1437   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1438         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1439                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1440   ""
1442   if (<MODE>mode == DImode && ! TARGET_POWERPC64)
1443     {
1444       if (non_short_cint_operand (operands[2], DImode))
1445         FAIL;
1446     }
1447   else if (GET_CODE (operands[2]) == CONST_INT
1448            && ! add_operand (operands[2], <MODE>mode))
1449     {
1450       rtx tmp = ((!can_create_pseudo_p ()
1451                   || rtx_equal_p (operands[0], operands[1]))
1452                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1454       HOST_WIDE_INT val = INTVAL (operands[2]);
1455       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1456       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1458       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1459         FAIL;
1461       /* The ordering here is important for the prolog expander.
1462          When space is allocated from the stack, adding 'low' first may
1463          produce a temporary deallocation (which would be bad).  */
1464       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1465       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1466       DONE;
1467     }
1470 ;; Discourage ai/addic because of carry but provide it in an alternative
1471 ;; allowing register zero as source.
1472 (define_insn "*add<mode>3_internal1"
1473   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,?r,r")
1474         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,r,b")
1475                   (match_operand:GPR 2 "add_operand" "r,I,I,L")))]
1476   "!DECIMAL_FLOAT_MODE_P (GET_MODE (operands[0])) && !DECIMAL_FLOAT_MODE_P (GET_MODE (operands[1]))"
1477   "@
1478    add %0,%1,%2
1479    addi %0,%1,%2
1480    addic %0,%1,%2
1481    addis %0,%1,%v2"
1482   [(set_attr "type" "add")])
1484 (define_insn "addsi3_high"
1485   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1486         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1487                  (high:SI (match_operand 2 "" ""))))]
1488   "TARGET_MACHO && !TARGET_64BIT"
1489   "addis %0,%1,ha16(%2)"
1490   [(set_attr "type" "add")])
1492 (define_insn "*add<mode>3_internal2"
1493   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
1494         (compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r")
1495                             (match_operand:P 2 "reg_or_short_operand" "r,I,r,I"))
1496                     (const_int 0)))
1497    (clobber (match_scratch:P 3 "=r,r,r,r"))]
1498   ""
1499   "@
1500    add. %3,%1,%2
1501    addic. %3,%1,%2
1502    #
1503    #"
1504   [(set_attr "type" "add,compare,compare,compare")
1505    (set_attr "dot" "yes")
1506    (set_attr "length" "4,4,8,8")])
1508 (define_split
1509   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1510         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1511                               (match_operand:GPR 2 "reg_or_short_operand" ""))
1512                     (const_int 0)))
1513    (clobber (match_scratch:GPR 3 ""))]
1514   "reload_completed"
1515   [(set (match_dup 3)
1516         (plus:GPR (match_dup 1)
1517                  (match_dup 2)))
1518    (set (match_dup 0)
1519         (compare:CC (match_dup 3)
1520                     (const_int 0)))]
1521   "")
1523 (define_insn "*add<mode>3_internal3"
1524   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
1525         (compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r")
1526                             (match_operand:P 2 "reg_or_short_operand" "r,I,r,I"))
1527                     (const_int 0)))
1528    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r")
1529         (plus:P (match_dup 1)
1530                 (match_dup 2)))]
1531   ""
1532   "@
1533    add. %0,%1,%2
1534    addic. %0,%1,%2
1535    #
1536    #"
1537   [(set_attr "type" "add,compare,compare,compare")
1538    (set_attr "dot" "yes")
1539    (set_attr "length" "4,4,8,8")])
1541 (define_split
1542   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
1543         (compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "")
1544                             (match_operand:P 2 "reg_or_short_operand" ""))
1545                     (const_int 0)))
1546    (set (match_operand:P 0 "gpc_reg_operand" "")
1547         (plus:P (match_dup 1) (match_dup 2)))]
1548   "reload_completed"
1549   [(set (match_dup 0)
1550         (plus:P (match_dup 1)
1551                 (match_dup 2)))
1552    (set (match_dup 3)
1553         (compare:CC (match_dup 0)
1554                     (const_int 0)))]
1555   "")
1557 ;; Split an add that we can't do in one insn into two insns, each of which
1558 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1559 ;; add should be last in case the result gets used in an address.
1561 (define_split
1562   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1563         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1564                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1565   ""
1566   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1567    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1569   HOST_WIDE_INT val = INTVAL (operands[2]);
1570   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1571   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1573   operands[4] = GEN_INT (low);
1574   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1575     operands[3] = GEN_INT (rest);
1576   else if (can_create_pseudo_p ())
1577     {
1578       operands[3] = gen_reg_rtx (DImode);
1579       emit_move_insn (operands[3], operands[2]);
1580       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1581       DONE;
1582     }
1583   else
1584     FAIL;
1587 (define_expand "one_cmpl<mode>2"
1588   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1589         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1590   ""
1592   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1593     {
1594       rs6000_split_logical (operands, NOT, false, false, false);
1595       DONE;
1596     }
1599 (define_insn "*one_cmpl<mode>2"
1600   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1601         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1602   ""
1603   "not %0,%1")
1605 (define_insn_and_split "*one_cmpl<mode>2_dot"
1606   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1607         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1608                     (const_int 0)))
1609    (clobber (match_scratch:GPR 0 "=r,r"))]
1610   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1611   "@
1612    not. %0,%1
1613    #"
1614   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1615   [(set (match_dup 0)
1616         (not:GPR (match_dup 1)))
1617    (set (match_dup 2)
1618         (compare:CC (match_dup 0)
1619                     (const_int 0)))]
1620   ""
1621   [(set_attr "type" "logical")
1622    (set_attr "dot" "yes")
1623    (set_attr "length" "4,8")])
1625 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1626   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1627         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1628                     (const_int 0)))
1629    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1630         (not:GPR (match_dup 1)))]
1631   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1632   "@
1633    not. %0,%1
1634    #"
1635   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1636   [(set (match_dup 0)
1637         (not:GPR (match_dup 1)))
1638    (set (match_dup 2)
1639         (compare:CC (match_dup 0)
1640                     (const_int 0)))]
1641   ""
1642   [(set_attr "type" "logical")
1643    (set_attr "dot" "yes")
1644    (set_attr "length" "4,8")])
1647 (define_expand "sub<mode>3"
1648   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1649         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1650                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1651   ""
1653   if (short_cint_operand (operands[1], <MODE>mode)
1654       && !(<MODE>mode == DImode && !TARGET_POWERPC64))
1655     {
1656       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1657       DONE;
1658     }
1661 (define_insn "*subf<mode>3"
1662   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1663         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1664                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1665   ""
1666   "subf %0,%1,%2"
1667   [(set_attr "type" "add")])
1669 (define_insn_and_split "*subf<mode>3_dot"
1670   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1671         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1672                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1673                     (const_int 0)))
1674    (clobber (match_scratch:GPR 0 "=r,r"))]
1675   "<MODE>mode == Pmode"
1676   "@
1677    subf. %0,%1,%2
1678    #"
1679   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1680   [(set (match_dup 0)
1681         (minus:GPR (match_dup 2)
1682                    (match_dup 1)))
1683    (set (match_dup 3)
1684         (compare:CC (match_dup 0)
1685                     (const_int 0)))]
1686   ""
1687   [(set_attr "type" "add")
1688    (set_attr "dot" "yes")
1689    (set_attr "length" "4,8")])
1691 (define_insn_and_split "*subf<mode>3_dot2"
1692   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1693         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1694                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1695                     (const_int 0)))
1696    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1697         (minus:GPR (match_dup 2)
1698                    (match_dup 1)))]
1699   "<MODE>mode == Pmode"
1700   "@
1701    subf. %0,%1,%2
1702    #"
1703   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1704   [(set (match_dup 0)
1705         (minus:GPR (match_dup 2)
1706                    (match_dup 1)))
1707    (set (match_dup 3)
1708         (compare:CC (match_dup 0)
1709                     (const_int 0)))]
1710   ""
1711   [(set_attr "type" "add")
1712    (set_attr "dot" "yes")
1713    (set_attr "length" "4,8")])
1715 (define_insn "subf<mode>3_imm"
1716   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1717         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
1718                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
1719    (clobber (reg:GPR CA_REGNO))]
1720   ""
1721   "subfic %0,%1,%2"
1722   [(set_attr "type" "add")])
1725 (define_expand "neg<mode>2"
1726   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1727         (neg:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1728   ""
1729   "")
1731 (define_insn "*neg<mode>2"
1732   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1733         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1734   ""
1735   "neg %0,%1"
1736   [(set_attr "type" "add")])
1738 (define_insn_and_split "*neg<mode>2_dot"
1739   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1740         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1741                     (const_int 0)))
1742    (clobber (match_scratch:GPR 0 "=r,r"))]
1743   "<MODE>mode == Pmode"
1744   "@
1745    neg. %0,%1
1746    #"
1747   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1748   [(set (match_dup 0)
1749         (neg:GPR (match_dup 1)))
1750    (set (match_dup 2)
1751         (compare:CC (match_dup 0)
1752                     (const_int 0)))]
1753   ""
1754   [(set_attr "type" "add")
1755    (set_attr "dot" "yes")
1756    (set_attr "length" "4,8")])
1758 (define_insn_and_split "*neg<mode>2_dot2"
1759   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1760         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1761                     (const_int 0)))
1762    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1763         (neg:GPR (match_dup 1)))]
1764   "<MODE>mode == Pmode"
1765   "@
1766    neg. %0,%1
1767    #"
1768   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1769   [(set (match_dup 0)
1770         (neg:GPR (match_dup 1)))
1771    (set (match_dup 2)
1772         (compare:CC (match_dup 0)
1773                     (const_int 0)))]
1774   ""
1775   [(set_attr "type" "add")
1776    (set_attr "dot" "yes")
1777    (set_attr "length" "4,8")])
1780 (define_insn "clz<mode>2"
1781   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1782         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1783   ""
1784   "cntlz<wd> %0,%1"
1785   [(set_attr "type" "cntlz")])
1787 (define_expand "ctz<mode>2"
1788   [(set (match_dup 2)
1789         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
1790    (set (match_dup 3)
1791         (and:GPR (match_dup 1)
1792                  (match_dup 2)))
1793    (set (match_dup 4)
1794         (clz:GPR (match_dup 3)))
1795    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1796                    (minus:GPR (match_dup 5)
1797                               (match_dup 4)))
1798               (clobber (reg:GPR CA_REGNO))])]
1799   ""
1801   operands[2] = gen_reg_rtx (<MODE>mode);
1802   operands[3] = gen_reg_rtx (<MODE>mode);
1803   operands[4] = gen_reg_rtx (<MODE>mode);
1804   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
1807 (define_expand "ffs<mode>2"
1808   [(set (match_dup 2)
1809         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
1810    (set (match_dup 3)
1811         (and:GPR (match_dup 1)
1812                  (match_dup 2)))
1813    (set (match_dup 4)
1814         (clz:GPR (match_dup 3)))
1815    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1816                    (minus:GPR (match_dup 5)
1817                               (match_dup 4)))
1818               (clobber (reg:GPR CA_REGNO))])]
1819   ""
1821   operands[2] = gen_reg_rtx (<MODE>mode);
1822   operands[3] = gen_reg_rtx (<MODE>mode);
1823   operands[4] = gen_reg_rtx (<MODE>mode);
1824   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
1828 (define_expand "popcount<mode>2"
1829   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1830         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
1831   "TARGET_POPCNTB || TARGET_POPCNTD"
1833   rs6000_emit_popcount (operands[0], operands[1]);
1834   DONE;
1837 (define_insn "popcntb<mode>2"
1838   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1839         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
1840                     UNSPEC_POPCNTB))]
1841   "TARGET_POPCNTB"
1842   "popcntb %0,%1"
1843   [(set_attr "type" "popcnt")])
1845 (define_insn "popcntd<mode>2"
1846   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1847         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1848   "TARGET_POPCNTD"
1849   "popcnt<wd> %0,%1"
1850   [(set_attr "type" "popcnt")])
1853 (define_expand "parity<mode>2"
1854   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1855         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
1856   "TARGET_POPCNTB"
1858   rs6000_emit_parity (operands[0], operands[1]);
1859   DONE;
1862 (define_insn "parity<mode>2_cmpb"
1863   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1864         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
1865   "TARGET_CMPB && TARGET_POPCNTB"
1866   "prty<wd> %0,%1"
1867   [(set_attr "type" "popcnt")])
1870 ;; Since the hardware zeros the upper part of the register, save generating the
1871 ;; AND immediate if we are converting to unsigned
1872 (define_insn "*bswaphi2_extenddi"
1873   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1874         (zero_extend:DI
1875          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
1876   "TARGET_POWERPC64"
1877   "lhbrx %0,%y1"
1878   [(set_attr "length" "4")
1879    (set_attr "type" "load")])
1881 (define_insn "*bswaphi2_extendsi"
1882   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1883         (zero_extend:SI
1884          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
1885   ""
1886   "lhbrx %0,%y1"
1887   [(set_attr "length" "4")
1888    (set_attr "type" "load")])
1890 (define_expand "bswaphi2"
1891   [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
1892                    (bswap:HI
1893                     (match_operand:HI 1 "reg_or_mem_operand" "")))
1894               (clobber (match_scratch:SI 2 ""))])]
1895   ""
1897   if (!REG_P (operands[0]) && !REG_P (operands[1]))
1898     operands[1] = force_reg (HImode, operands[1]);
1901 (define_insn "bswaphi2_internal"
1902   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
1903         (bswap:HI
1904          (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
1905    (clobber (match_scratch:SI 2 "=X,X,&r"))]
1906   ""
1907   "@
1908    lhbrx %0,%y1
1909    sthbrx %1,%y0
1910    #"
1911   [(set_attr "length" "4,4,12")
1912    (set_attr "type" "load,store,*")])
1914 ;; We are always BITS_BIG_ENDIAN, so the (const_int 16) below is
1915 ;; correct for -mlittle as well as -mbig.
1916 (define_split
1917   [(set (match_operand:HI 0 "gpc_reg_operand" "")
1918         (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
1919    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
1920   "reload_completed"
1921   [(set (match_dup 3)
1922         (zero_extract:SI (match_dup 4)
1923                          (const_int 8)
1924                          (const_int 16)))
1925    (set (match_dup 2)
1926         (and:SI (ashift:SI (match_dup 4)
1927                            (const_int 8))
1928                 (const_int 65280)))             ;; 0xff00
1929    (set (match_dup 3)
1930         (ior:SI (match_dup 3)
1931                 (match_dup 2)))]
1932   "
1934   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
1935   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
1938 (define_insn "*bswapsi2_extenddi"
1939   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1940         (zero_extend:DI
1941          (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
1942   "TARGET_POWERPC64"
1943   "lwbrx %0,%y1"
1944   [(set_attr "length" "4")
1945    (set_attr "type" "load")])
1947 (define_expand "bswapsi2"
1948   [(set (match_operand:SI 0 "reg_or_mem_operand" "")
1949         (bswap:SI
1950          (match_operand:SI 1 "reg_or_mem_operand" "")))]
1951   ""
1953   if (!REG_P (operands[0]) && !REG_P (operands[1]))
1954     operands[1] = force_reg (SImode, operands[1]);
1957 (define_insn "*bswapsi2_internal"
1958   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
1959         (bswap:SI
1960          (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
1961   ""
1962   "@
1963    lwbrx %0,%y1
1964    stwbrx %1,%y0
1965    #"
1966   [(set_attr "length" "4,4,12")
1967    (set_attr "type" "load,store,*")])
1969 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
1970 ;; zero_extract insns do not change for -mlittle.
1971 (define_split
1972   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1973         (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
1974   "reload_completed"
1975   [(set (match_dup 0)
1976         (rotate:SI (match_dup 1) (const_int 8)))
1977    (set (zero_extract:SI (match_dup 0)
1978                          (const_int 8)
1979                          (const_int 0))
1980         (match_dup 1))
1981    (set (zero_extract:SI (match_dup 0)
1982                          (const_int 8)
1983                          (const_int 16))
1984         (rotate:SI (match_dup 1)
1985                    (const_int 16)))]
1986   "")
1988 (define_expand "bswapdi2"
1989   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
1990                    (bswap:DI
1991                     (match_operand:DI 1 "reg_or_mem_operand" "")))
1992               (clobber (match_scratch:DI 2 ""))
1993               (clobber (match_scratch:DI 3 ""))
1994               (clobber (match_scratch:DI 4 ""))])]
1995   ""
1997   if (!REG_P (operands[0]) && !REG_P (operands[1]))
1998     operands[1] = force_reg (DImode, operands[1]);
2000   if (!TARGET_POWERPC64)
2001     {
2002       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2003          that uses 64-bit registers needs the same scratch registers as 64-bit
2004          mode.  */
2005       emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2006       DONE;
2007     }
2010 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2011 (define_insn "*bswapdi2_ldbrx"
2012   [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
2013         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2014    (clobber (match_scratch:DI 2 "=X,X,&r"))
2015    (clobber (match_scratch:DI 3 "=X,X,&r"))
2016    (clobber (match_scratch:DI 4 "=X,X,&r"))]
2017   "TARGET_POWERPC64 && TARGET_LDBRX
2018    && (REG_P (operands[0]) || REG_P (operands[1]))"
2019   "@
2020    ldbrx %0,%y1
2021    stdbrx %1,%y0
2022    #"
2023   [(set_attr "length" "4,4,36")
2024    (set_attr "type" "load,store,*")])
2026 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2027 (define_insn "*bswapdi2_64bit"
2028   [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r")
2029         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2030    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2031    (clobber (match_scratch:DI 3 "=&r,&r,&r"))
2032    (clobber (match_scratch:DI 4 "=&r,X,&r"))]
2033   "TARGET_POWERPC64 && !TARGET_LDBRX
2034    && (REG_P (operands[0]) || REG_P (operands[1]))
2035    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2036    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2037   "#"
2038   [(set_attr "length" "16,12,36")])
2040 (define_split
2041   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2042         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2043    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2044    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
2045    (clobber (match_operand:DI 4 "gpc_reg_operand" ""))]
2046   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2047   [(const_int 0)]
2048   "
2050   rtx dest   = operands[0];
2051   rtx src    = operands[1];
2052   rtx op2    = operands[2];
2053   rtx op3    = operands[3];
2054   rtx op4    = operands[4];
2055   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2056                                     BYTES_BIG_ENDIAN ? 4 : 0);
2057   rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode,
2058                                     BYTES_BIG_ENDIAN ? 4 : 0);
2059   rtx addr1;
2060   rtx addr2;
2061   rtx word_high;
2062   rtx word_low;
2064   addr1 = XEXP (src, 0);
2065   if (GET_CODE (addr1) == PLUS)
2066     {
2067       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2068       if (TARGET_AVOID_XFORM)
2069         {
2070           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2071           addr2 = op2;
2072         }
2073       else
2074         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2075     }
2076   else if (TARGET_AVOID_XFORM)
2077     {
2078       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2079       addr2 = op2;
2080     }
2081   else
2082     {
2083       emit_move_insn (op2, GEN_INT (4));
2084       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2085     }
2087   if (BYTES_BIG_ENDIAN)
2088     {
2089       word_high = change_address (src, SImode, addr1);
2090       word_low  = change_address (src, SImode, addr2);
2091     }
2092   else
2093     {
2094       word_high = change_address (src, SImode, addr2);
2095       word_low  = change_address (src, SImode, addr1);
2096     }
2098   emit_insn (gen_bswapsi2 (op3_32, word_low));
2099   emit_insn (gen_bswapsi2 (op4_32, word_high));
2100   emit_insn (gen_ashldi3 (dest, op3, GEN_INT (32)));
2101   emit_insn (gen_iordi3 (dest, dest, op4));
2102   DONE;
2105 (define_split
2106   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2107         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2108    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2109    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
2110    (clobber (match_operand:DI 4 "" ""))]
2111   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2112   [(const_int 0)]
2113   "
2115   rtx dest   = operands[0];
2116   rtx src    = operands[1];
2117   rtx op2    = operands[2];
2118   rtx op3    = operands[3];
2119   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2120                                     BYTES_BIG_ENDIAN ? 4 : 0);
2121   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2122                                     BYTES_BIG_ENDIAN ? 4 : 0);
2123   rtx addr1;
2124   rtx addr2;
2125   rtx word_high;
2126   rtx word_low;
2128   addr1 = XEXP (dest, 0);
2129   if (GET_CODE (addr1) == PLUS)
2130     {
2131       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2132       if (TARGET_AVOID_XFORM)
2133         {
2134           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2135           addr2 = op2;
2136         }
2137       else
2138         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2139     }
2140   else if (TARGET_AVOID_XFORM)
2141     {
2142       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2143       addr2 = op2;
2144     }
2145   else
2146     {
2147       emit_move_insn (op2, GEN_INT (4));
2148       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2149     }
2151   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2152   if (BYTES_BIG_ENDIAN)
2153     {
2154       word_high = change_address (dest, SImode, addr1);
2155       word_low  = change_address (dest, SImode, addr2);
2156     }
2157   else
2158     {
2159       word_high = change_address (dest, SImode, addr2);
2160       word_low  = change_address (dest, SImode, addr1);
2161     }
2162   emit_insn (gen_bswapsi2 (word_high, src_si));
2163   emit_insn (gen_bswapsi2 (word_low, op3_si));
2164   DONE;
2167 (define_split
2168   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2169         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2170    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2171    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
2172    (clobber (match_operand:DI 4 "" ""))]
2173   "TARGET_POWERPC64 && reload_completed"
2174   [(const_int 0)]
2175   "
2177   rtx dest    = operands[0];
2178   rtx src     = operands[1];
2179   rtx op2     = operands[2];
2180   rtx op3     = operands[3];
2181   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2182   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2183   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2184   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2185   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2187   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2188   emit_insn (gen_bswapsi2 (dest_si, src_si));
2189   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2190   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2191   emit_insn (gen_iordi3 (dest, dest, op3));
2192   DONE;
2195 (define_insn "bswapdi2_32bit"
2196   [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r")
2197         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2198    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2199   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2200   "#"
2201   [(set_attr "length" "16,12,36")])
2203 (define_split
2204   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2205         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2206    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2207   "!TARGET_POWERPC64 && reload_completed"
2208   [(const_int 0)]
2209   "
2211   rtx dest  = operands[0];
2212   rtx src   = operands[1];
2213   rtx op2   = operands[2];
2214   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2215   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2216   rtx addr1;
2217   rtx addr2;
2218   rtx word1;
2219   rtx word2;
2221   addr1 = XEXP (src, 0);
2222   if (GET_CODE (addr1) == PLUS)
2223     {
2224       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2225       if (TARGET_AVOID_XFORM)
2226         {
2227           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2228           addr2 = op2;
2229         }
2230       else
2231         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2232     }
2233   else if (TARGET_AVOID_XFORM)
2234     {
2235       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2236       addr2 = op2;
2237     }
2238   else
2239     {
2240       emit_move_insn (op2, GEN_INT (4));
2241       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2242     }
2244   word1 = change_address (src, SImode, addr1);
2245   word2 = change_address (src, SImode, addr2);
2247   emit_insn (gen_bswapsi2 (dest2, word1));
2248   emit_insn (gen_bswapsi2 (dest1, word2));
2249   DONE;
2252 (define_split
2253   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2254         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2255    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2256   "!TARGET_POWERPC64 && reload_completed"
2257   [(const_int 0)]
2258   "
2260   rtx dest = operands[0];
2261   rtx src  = operands[1];
2262   rtx op2  = operands[2];
2263   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2264   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2265   rtx addr1;
2266   rtx addr2;
2267   rtx word1;
2268   rtx word2;
2270   addr1 = XEXP (dest, 0);
2271   if (GET_CODE (addr1) == PLUS)
2272     {
2273       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2274       if (TARGET_AVOID_XFORM)
2275         {
2276           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2277           addr2 = op2;
2278         }
2279       else
2280         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2281     }
2282   else if (TARGET_AVOID_XFORM)
2283     {
2284       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2285       addr2 = op2;
2286     }
2287   else
2288     {
2289       emit_move_insn (op2, GEN_INT (4));
2290       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2291     }
2293   word1 = change_address (dest, SImode, addr1);
2294   word2 = change_address (dest, SImode, addr2);
2296   emit_insn (gen_bswapsi2 (word2, src1));
2297   emit_insn (gen_bswapsi2 (word1, src2));
2298   DONE;
2301 (define_split
2302   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2303         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2304    (clobber (match_operand:SI 2 "" ""))]
2305   "!TARGET_POWERPC64 && reload_completed"
2306   [(const_int 0)]
2307   "
2309   rtx dest  = operands[0];
2310   rtx src   = operands[1];
2311   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2312   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2313   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2314   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2316   emit_insn (gen_bswapsi2 (dest1, src2));
2317   emit_insn (gen_bswapsi2 (dest2, src1));
2318   DONE;
2322 (define_insn "mul<mode>3"
2323   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2324         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2325                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2326   ""
2327   "@
2328    mull<wd> %0,%1,%2
2329    mulli %0,%1,%2"
2330    [(set_attr "type" "mul")
2331     (set (attr "size")
2332       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2333                 (const_string "8")
2334              (match_operand:GPR 2 "short_cint_operand" "")
2335                 (const_string "16")]
2336         (const_string "<bits>")))])
2338 (define_insn_and_split "*mul<mode>3_dot"
2339   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2340         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2341                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2342                     (const_int 0)))
2343    (clobber (match_scratch:GPR 0 "=r,r"))]
2344   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2345   "@
2346    mull<wd>. %0,%1,%2
2347    #"
2348   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2349   [(set (match_dup 0)
2350         (mult:GPR (match_dup 1)
2351                   (match_dup 2)))
2352    (set (match_dup 3)
2353         (compare:CC (match_dup 0)
2354                     (const_int 0)))]
2355   ""
2356   [(set_attr "type" "mul")
2357    (set_attr "size" "<bits>")
2358    (set_attr "dot" "yes")
2359    (set_attr "length" "4,8")])
2361 (define_insn_and_split "*mul<mode>3_dot2"
2362   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2363         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2364                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2365                     (const_int 0)))
2366    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2367         (mult:GPR (match_dup 1)
2368                   (match_dup 2)))]
2369   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2370   "@
2371    mull<wd>. %0,%1,%2
2372    #"
2373   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2374   [(set (match_dup 0)
2375         (mult:GPR (match_dup 1)
2376                   (match_dup 2)))
2377    (set (match_dup 3)
2378         (compare:CC (match_dup 0)
2379                     (const_int 0)))]
2380   ""
2381   [(set_attr "type" "mul")
2382    (set_attr "size" "<bits>")
2383    (set_attr "dot" "yes")
2384    (set_attr "length" "4,8")])
2387 (define_expand "<su>mul<mode>3_highpart"
2388   [(set (match_operand:GPR 0 "gpc_reg_operand")
2389         (subreg:GPR
2390           (mult:<DMODE> (any_extend:<DMODE>
2391                           (match_operand:GPR 1 "gpc_reg_operand"))
2392                         (any_extend:<DMODE>
2393                           (match_operand:GPR 2 "gpc_reg_operand")))
2394          0))]
2395   ""
2397   if (<MODE>mode == SImode && TARGET_POWERPC64)
2398     {
2399       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2400                                              operands[2]));
2401       DONE;
2402     }
2404   if (!WORDS_BIG_ENDIAN)
2405     {
2406       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2407                                                  operands[2]));
2408       DONE;
2409     }
2412 (define_insn "*<su>mul<mode>3_highpart"
2413   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2414         (subreg:GPR
2415           (mult:<DMODE> (any_extend:<DMODE>
2416                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2417                         (any_extend:<DMODE>
2418                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2419          0))]
2420   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2421   "mulh<wd><u> %0,%1,%2"
2422   [(set_attr "type" "mul")
2423    (set_attr "size" "<bits>")])
2425 (define_insn "<su>mulsi3_highpart_le"
2426   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2427         (subreg:SI
2428           (mult:DI (any_extend:DI
2429                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2430                    (any_extend:DI
2431                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2432          4))]
2433   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2434   "mulhw<u> %0,%1,%2"
2435   [(set_attr "type" "mul")])
2437 (define_insn "<su>muldi3_highpart_le"
2438   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2439         (subreg:DI
2440           (mult:TI (any_extend:TI
2441                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2442                    (any_extend:TI
2443                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2444          8))]
2445   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2446   "mulhd<u> %0,%1,%2"
2447   [(set_attr "type" "mul")
2448    (set_attr "size" "64")])
2450 (define_insn "<su>mulsi3_highpart_64"
2451   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2452         (truncate:SI
2453           (lshiftrt:DI
2454             (mult:DI (any_extend:DI
2455                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2456                      (any_extend:DI
2457                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2458             (const_int 32))))]
2459   "TARGET_POWERPC64"
2460   "mulhw<u> %0,%1,%2"
2461   [(set_attr "type" "mul")])
2463 (define_expand "<u>mul<mode><dmode>3"
2464   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2465         (mult:<DMODE> (any_extend:<DMODE>
2466                         (match_operand:GPR 1 "gpc_reg_operand"))
2467                       (any_extend:<DMODE>
2468                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2469   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2471   rtx l = gen_reg_rtx (<MODE>mode);
2472   rtx h = gen_reg_rtx (<MODE>mode);
2473   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2474   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2475   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2476   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2477   DONE;
2481 (define_insn "udiv<mode>3"
2482   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2483         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2484                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2485   ""
2486   "div<wd>u %0,%1,%2"
2487   [(set_attr "type" "div")
2488    (set_attr "size" "<bits>")])
2491 ;; For powers of two we can do srai/aze for divide and then adjust for
2492 ;; modulus.  If it isn't a power of two, force operands into register and do
2493 ;; a normal divide.
2494 (define_expand "div<mode>3"
2495   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2496         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2497                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2498   ""
2500   if (GET_CODE (operands[2]) != CONST_INT
2501       || INTVAL (operands[2]) <= 0
2502       || exact_log2 (INTVAL (operands[2])) < 0)
2503     operands[2] = force_reg (<MODE>mode, operands[2]);
2506 (define_insn "*div<mode>3"
2507   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2508         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2509                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2510   ""
2511   "div<wd> %0,%1,%2"
2512   [(set_attr "type" "div")
2513    (set_attr "size" "<bits>")])
2515 (define_expand "mod<mode>3"
2516   [(use (match_operand:GPR 0 "gpc_reg_operand" ""))
2517    (use (match_operand:GPR 1 "gpc_reg_operand" ""))
2518    (use (match_operand:GPR 2 "reg_or_cint_operand" ""))]
2519   ""
2520   "
2522   int i;
2523   rtx temp1;
2524   rtx temp2;
2526   if (GET_CODE (operands[2]) != CONST_INT
2527       || INTVAL (operands[2]) <= 0
2528       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
2529     FAIL;
2531   temp1 = gen_reg_rtx (<MODE>mode);
2532   temp2 = gen_reg_rtx (<MODE>mode);
2534   emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
2535   emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
2536   emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
2537   DONE;
2540 (define_insn ""
2541   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2542         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2543                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))]
2544   ""
2545   "sra<wd>i %0,%1,%p2\;addze %0,%0"
2546   [(set_attr "type" "two")
2547    (set_attr "length" "8")])
2549 (define_insn ""
2550   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
2551         (compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r")
2552                            (match_operand:P 2 "exact_log2_cint_operand" "N,N"))
2553                     (const_int 0)))
2554    (clobber (match_scratch:P 3 "=r,r"))]
2555   ""
2556   "@
2557    sra<wd>i %3,%1,%p2\;addze. %3,%3
2558    #"
2559   [(set_attr "type" "compare")
2560    (set_attr "length" "8,12")
2561    (set_attr "cell_micro" "not")])
2563 (define_split
2564   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
2565         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2566                              (match_operand:GPR 2 "exact_log2_cint_operand"
2567                               ""))
2568                     (const_int 0)))
2569    (clobber (match_scratch:GPR 3 ""))]
2570   "reload_completed"
2571   [(set (match_dup 3)
2572         (div:<MODE> (match_dup 1) (match_dup 2)))
2573    (set (match_dup 0)
2574         (compare:CC (match_dup 3)
2575                     (const_int 0)))]
2576   "")
2578 (define_insn ""
2579   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2580         (compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r")
2581                            (match_operand:P 2 "exact_log2_cint_operand" "N,N"))
2582                     (const_int 0)))
2583    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2584         (div:P (match_dup 1) (match_dup 2)))]
2585   ""
2586   "@
2587    sra<wd>i %0,%1,%p2\;addze. %0,%0
2588    #"
2589   [(set_attr "type" "compare")
2590    (set_attr "length" "8,12")
2591    (set_attr "cell_micro" "not")])
2593 (define_split
2594   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
2595         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2596                              (match_operand:GPR 2 "exact_log2_cint_operand"
2597                               ""))
2598                     (const_int 0)))
2599    (set (match_operand:GPR 0 "gpc_reg_operand" "")
2600         (div:GPR (match_dup 1) (match_dup 2)))]
2601   "reload_completed"
2602   [(set (match_dup 0)
2603         (div:<MODE> (match_dup 1) (match_dup 2)))
2604    (set (match_dup 3)
2605         (compare:CC (match_dup 0)
2606                     (const_int 0)))]
2607   "")
2609 ;; Logical instructions
2610 ;; The logical instructions are mostly combined by using match_operator,
2611 ;; but the plain AND insns are somewhat different because there is no
2612 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
2613 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
2615 (define_expand "and<mode>3"
2616   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2617         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
2618                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
2619   ""
2621   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2622     {
2623       rs6000_split_logical (operands, AND, false, false, false);
2624       DONE;
2625     }
2627   if (logical_const_operand (operands[2], <MODE>mode)
2628       && !any_mask_operand (operands[2], <MODE>mode))
2629     {
2630       emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
2631       DONE;
2632     }
2634   if ((<MODE>mode == DImode && !and64_2_operand (operands[2], <MODE>mode))
2635       || (<MODE>mode != DImode && !and_operand (operands[2], <MODE>mode)))
2636     operands[2] = force_reg (<MODE>mode, operands[2]);
2640 (define_insn "and<mode>3_imm"
2641   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2642         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
2643                  (match_operand:GPR 2 "logical_const_operand" "n")))
2644    (clobber (match_scratch:CC 3 "=x"))]
2645   "rs6000_gen_cell_microcode
2646    && !any_mask_operand (operands[2], <MODE>mode)"
2647   "andi%e2. %0,%1,%u2"
2648   [(set_attr "type" "logical")
2649    (set_attr "dot" "yes")])
2651 (define_insn_and_split "*and<mode>3_imm_dot"
2652   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2653         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2654                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
2655                     (const_int 0)))
2656    (clobber (match_scratch:GPR 0 "=r,r"))
2657    (clobber (match_scratch:CC 4 "=X,x"))]
2658   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2659    && rs6000_gen_cell_microcode
2660    && !any_mask_operand (operands[2], <MODE>mode)"
2661   "@
2662    andi%e2. %0,%1,%u2
2663    #"
2664   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2665   [(parallel [(set (match_dup 0)
2666                    (and:GPR (match_dup 1)
2667                             (match_dup 2)))
2668               (clobber (match_dup 4))])
2669    (set (match_dup 3)
2670         (compare:CC (match_dup 0)
2671                     (const_int 0)))]
2672   ""
2673   [(set_attr "type" "logical")
2674    (set_attr "dot" "yes")
2675    (set_attr "length" "4,8")])
2677 (define_insn_and_split "*and<mode>3_imm_dot2"
2678   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2679         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2680                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
2681                     (const_int 0)))
2682    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2683         (and:GPR (match_dup 1)
2684                  (match_dup 2)))
2685    (clobber (match_scratch:CC 4 "=X,x"))]
2686   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2687    && rs6000_gen_cell_microcode
2688    && !any_mask_operand (operands[2], <MODE>mode)"
2689   "@
2690    andi%e2. %0,%1,%u2
2691    #"
2692   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2693   [(parallel [(set (match_dup 0)
2694                    (and:GPR (match_dup 1)
2695                             (match_dup 2)))
2696               (clobber (match_dup 4))])
2697    (set (match_dup 3)
2698         (compare:CC (match_dup 0)
2699                     (const_int 0)))]
2700   ""
2701   [(set_attr "type" "logical")
2702    (set_attr "dot" "yes")
2703    (set_attr "length" "4,8")])
2705 (define_insn_and_split "*and<mode>3_imm_mask_dot"
2706   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2707         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2708                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
2709                     (const_int 0)))
2710    (clobber (match_scratch:GPR 0 "=r,r"))]
2711   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2712    && rs6000_gen_cell_microcode
2713    && any_mask_operand (operands[2], <MODE>mode)"
2714   "@
2715    andi%e2. %0,%1,%u2
2716    #"
2717   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2718   [(set (match_dup 0)
2719         (and:GPR (match_dup 1)
2720                  (match_dup 2)))
2721    (set (match_dup 3)
2722         (compare:CC (match_dup 0)
2723                     (const_int 0)))]
2724   ""
2725   [(set_attr "type" "logical")
2726    (set_attr "dot" "yes")
2727    (set_attr "length" "4,8")])
2729 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
2730   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2731         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2732                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
2733                     (const_int 0)))
2734    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2735         (and:GPR (match_dup 1)
2736                  (match_dup 2)))]
2737   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2738    && rs6000_gen_cell_microcode
2739    && any_mask_operand (operands[2], <MODE>mode)"
2740   "@
2741    andi%e2. %0,%1,%u2
2742    #"
2743   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2744   [(set (match_dup 0)
2745         (and:GPR (match_dup 1)
2746                  (match_dup 2)))
2747    (set (match_dup 3)
2748         (compare:CC (match_dup 0)
2749                     (const_int 0)))]
2750   ""
2751   [(set_attr "type" "logical")
2752    (set_attr "dot" "yes")
2753    (set_attr "length" "4,8")])
2756 (define_insn "*and<mode>3_mask"
2757   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2758         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2759                  (match_operand:GPR 2 "any_mask_operand" "S,T")))]
2760   ""
2761   "@
2762    rldic%B2 %0,%1,0,%S2
2763    rlwinm %0,%1,0,%m2,%M2"
2764   [(set_attr "type" "shift")])
2766 (define_insn_and_split "*and<mode>3_mask_dot"
2767   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
2768         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")
2769                              (match_operand:GPR 2 "any_mask_operand" "S,T,S,T"))
2770                     (const_int 0)))
2771    (clobber (match_scratch:GPR 0 "=r,r,r,r"))]
2772   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2773    && rs6000_gen_cell_microcode
2774    && !logical_const_operand (operands[2], <MODE>mode)"
2775   "@
2776    rldic%B2. %0,%1,0,%S2
2777    rlwinm. %0,%1,0,%m2,%M2
2778    #
2779    #"
2780   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2781   [(set (match_dup 0)
2782         (and:GPR (match_dup 1)
2783                  (match_dup 2)))
2784    (set (match_dup 3)
2785         (compare:CC (match_dup 0)
2786                     (const_int 0)))]
2787   ""
2788   [(set_attr "type" "shift")
2789    (set_attr "dot" "yes")
2790    (set_attr "length" "4,4,8,8")])
2792 (define_insn_and_split "*and<mode>3_mask_dot2"
2793   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
2794         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")
2795                              (match_operand:GPR 2 "any_mask_operand" "S,T,S,T"))
2796                     (const_int 0)))
2797    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
2798         (and:GPR (match_dup 1)
2799                  (match_dup 2)))]
2800   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2801    && rs6000_gen_cell_microcode
2802    && !logical_const_operand (operands[2], <MODE>mode)"
2803   "@
2804    rldic%B2. %0,%1,0,%S2
2805    rlwinm. %0,%1,0,%m2,%M2
2806    #
2807    #"
2808   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2809   [(set (match_dup 0)
2810         (and:GPR (match_dup 1)
2811                  (match_dup 2)))
2812    (set (match_dup 3)
2813         (compare:CC (match_dup 0)
2814                     (const_int 0)))]
2815   ""
2816   [(set_attr "type" "shift")
2817    (set_attr "dot" "yes")
2818    (set_attr "length" "4,4,8,8")])
2822 (define_insn "andsi3_internal0_nomc"
2823   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2824         (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
2825                 (match_operand:SI 2 "and_operand" "?r,T")))]
2826   "!rs6000_gen_cell_microcode"
2827   "@
2828    and %0,%1,%2
2829    rlwinm %0,%1,0,%m2,%M2"
2830   [(set_attr "type" "logical,shift")])
2833 ;; Handle the PowerPC64 rlwinm corner case
2835 (define_insn_and_split "*andsi3_internal6"
2836   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2837         (and:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2838                 (match_operand:SI 2 "mask_operand_wrap" "i")))]
2839   "TARGET_POWERPC64"
2840   "#"
2841   "TARGET_POWERPC64"
2842   [(set (match_dup 0)
2843         (and:SI (rotate:SI (match_dup 1) (match_dup 3))
2844                 (match_dup 4)))
2845    (set (match_dup 0)
2846         (rotate:SI (match_dup 0) (match_dup 5)))]
2847   "
2849   int mb = extract_MB (operands[2]);
2850   int me = extract_ME (operands[2]);
2851   operands[3] = GEN_INT (me + 1);
2852   operands[5] = GEN_INT (32 - (me + 1));
2853   operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
2855   [(set_attr "length" "8")])
2858 (define_expand "<iorxor><mode>3"
2859   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2860         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
2861                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
2862   ""
2864   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2865     {
2866       rs6000_split_logical (operands, <IORXOR>, false, false, false);
2867       DONE;
2868     }
2870   if (non_logical_cint_operand (operands[2], <MODE>mode))
2871     {
2872       rtx tmp = ((!can_create_pseudo_p ()
2873                   || rtx_equal_p (operands[0], operands[1]))
2874                  ? operands[0] : gen_reg_rtx (<MODE>mode));
2876       HOST_WIDE_INT value = INTVAL (operands[2]);
2877       HOST_WIDE_INT lo = value & 0xffff;
2878       HOST_WIDE_INT hi = value - lo;
2880       emit_insn (gen_<iorxor><mode>3 (tmp, operands[1], GEN_INT (hi)));
2881       emit_insn (gen_<iorxor><mode>3 (operands[0], tmp, GEN_INT (lo)));
2882       DONE;
2883     }
2885   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
2886     operands[2] = force_reg (<MODE>mode, operands[2]);
2889 (define_split
2890   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2891         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2892                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
2893   ""
2894   [(set (match_dup 3)
2895         (iorxor:GPR (match_dup 1)
2896                     (match_dup 4)))
2897    (set (match_dup 0)
2898         (iorxor:GPR (match_dup 3)
2899                     (match_dup 5)))]
2901   operands[3] = ((!can_create_pseudo_p ()
2902                   || rtx_equal_p (operands[0], operands[1]))
2903                  ? operands[0] : gen_reg_rtx (<MODE>mode));
2905   HOST_WIDE_INT value = INTVAL (operands[2]);
2906   HOST_WIDE_INT lo = value & 0xffff;
2907   HOST_WIDE_INT hi = value - lo;
2909   operands[4] = GEN_INT (hi);
2910   operands[5] = GEN_INT (lo);
2913 (define_insn "*bool<mode>3_imm"
2914   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2915         (match_operator:GPR 3 "boolean_or_operator"
2916          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
2917           (match_operand:GPR 2 "logical_const_operand" "n")]))]
2918   ""
2919   "%q3i%e2 %0,%1,%u2"
2920   [(set_attr "type" "logical")])
2922 (define_insn "*bool<mode>3"
2923   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2924         (match_operator:GPR 3 "boolean_operator"
2925          [(match_operand:GPR 1 "gpc_reg_operand" "r")
2926           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
2927   ""
2928   "%q3 %0,%1,%2"
2929   [(set_attr "type" "logical")])
2931 (define_insn_and_split "*bool<mode>3_dot"
2932   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
2933         (compare:CC (match_operator:GPR 3 "boolean_operator"
2934          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
2935           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
2936          (const_int 0)))
2937    (clobber (match_scratch:GPR 0 "=r,r"))]
2938   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2939   "@
2940    %q3. %0,%1,%2
2941    #"
2942   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
2943   [(set (match_dup 0)
2944         (match_dup 3))
2945    (set (match_dup 4)
2946         (compare:CC (match_dup 0)
2947                     (const_int 0)))]
2948   ""
2949   [(set_attr "type" "logical")
2950    (set_attr "dot" "yes")
2951    (set_attr "length" "4,8")])
2953 (define_insn_and_split "*bool<mode>3_dot2"
2954   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
2955         (compare:CC (match_operator:GPR 3 "boolean_operator"
2956          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
2957           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
2958          (const_int 0)))
2959    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2960         (match_dup 3))]
2961   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2962   "@
2963    %q3. %0,%1,%2
2964    #"
2965   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
2966   [(set (match_dup 0)
2967         (match_dup 3))
2968    (set (match_dup 4)
2969         (compare:CC (match_dup 0)
2970                     (const_int 0)))]
2971   ""
2972   [(set_attr "type" "logical")
2973    (set_attr "dot" "yes")
2974    (set_attr "length" "4,8")])
2977 (define_insn "*boolc<mode>3"
2978   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2979         (match_operator:GPR 3 "boolean_operator"
2980          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
2981           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
2982   ""
2983   "%q3 %0,%1,%2"
2984   [(set_attr "type" "logical")])
2986 (define_insn_and_split "*boolc<mode>3_dot"
2987   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
2988         (compare:CC (match_operator:GPR 3 "boolean_operator"
2989          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2990           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
2991          (const_int 0)))
2992    (clobber (match_scratch:GPR 0 "=r,r"))]
2993   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2994   "@
2995    %q3. %0,%1,%2
2996    #"
2997   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
2998   [(set (match_dup 0)
2999         (match_dup 3))
3000    (set (match_dup 4)
3001         (compare:CC (match_dup 0)
3002                     (const_int 0)))]
3003   ""
3004   [(set_attr "type" "logical")
3005    (set_attr "dot" "yes")
3006    (set_attr "length" "4,8")])
3008 (define_insn_and_split "*boolc<mode>3_dot2"
3009   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3010         (compare:CC (match_operator:GPR 3 "boolean_operator"
3011          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3012           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3013          (const_int 0)))
3014    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3015         (match_dup 3))]
3016   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3017   "@
3018    %q3. %0,%1,%2
3019    #"
3020   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3021   [(set (match_dup 0)
3022         (match_dup 3))
3023    (set (match_dup 4)
3024         (compare:CC (match_dup 0)
3025                     (const_int 0)))]
3026   ""
3027   [(set_attr "type" "logical")
3028    (set_attr "dot" "yes")
3029    (set_attr "length" "4,8")])
3032 (define_insn "*boolcc<mode>3"
3033   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3034         (match_operator:GPR 3 "boolean_operator"
3035          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3036           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3037   ""
3038   "%q3 %0,%1,%2"
3039   [(set_attr "type" "logical")])
3041 (define_insn_and_split "*boolcc<mode>3_dot"
3042   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3043         (compare:CC (match_operator:GPR 3 "boolean_operator"
3044          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3045           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3046          (const_int 0)))
3047    (clobber (match_scratch:GPR 0 "=r,r"))]
3048   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3049   "@
3050    %q3. %0,%1,%2
3051    #"
3052   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3053   [(set (match_dup 0)
3054         (match_dup 3))
3055    (set (match_dup 4)
3056         (compare:CC (match_dup 0)
3057                     (const_int 0)))]
3058   ""
3059   [(set_attr "type" "logical")
3060    (set_attr "dot" "yes")
3061    (set_attr "length" "4,8")])
3063 (define_insn_and_split "*boolcc<mode>3_dot2"
3064   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3065         (compare:CC (match_operator:GPR 3 "boolean_operator"
3066          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3067           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3068          (const_int 0)))
3069    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3070         (match_dup 3))]
3071   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3072   "@
3073    %q3. %0,%1,%2
3074    #"
3075   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3076   [(set (match_dup 0)
3077         (match_dup 3))
3078    (set (match_dup 4)
3079         (compare:CC (match_dup 0)
3080                     (const_int 0)))]
3081   ""
3082   [(set_attr "type" "logical")
3083    (set_attr "dot" "yes")
3084    (set_attr "length" "4,8")])
3087 ;; TODO: Should have dots of this as well.
3088 (define_insn "*eqv<mode>3"
3089   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3090         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3091                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3092   ""
3093   "eqv %0,%1,%2"
3094   [(set_attr "type" "logical")])
3096 ;; Rotate and shift insns, in all their variants.  These support shifts,
3097 ;; field inserts and extracts, and various combinations thereof.
3098 (define_expand "insv"
3099   [(set (zero_extract (match_operand 0 "gpc_reg_operand" "")
3100                        (match_operand:SI 1 "const_int_operand" "")
3101                        (match_operand:SI 2 "const_int_operand" ""))
3102         (match_operand 3 "gpc_reg_operand" ""))]
3103   ""
3104   "
3106   /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
3107      the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
3108      compiler if the address of the structure is taken later.  Likewise, do
3109      not handle invalid E500 subregs.  */
3110   if (GET_CODE (operands[0]) == SUBREG
3111       && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD
3112           || ((TARGET_E500_DOUBLE || TARGET_SPE)
3113               && invalid_e500_subreg (operands[0], GET_MODE (operands[0])))))
3114     FAIL;
3116   if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode)
3117     emit_insn (gen_insvdi_internal (operands[0], operands[1], operands[2],
3118                                     operands[3]));
3119   else
3120     emit_insn (gen_insvsi_internal (operands[0], operands[1], operands[2],
3121                                     operands[3]));
3122   DONE;
3125 (define_insn "insvsi_internal"
3126   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3127                          (match_operand:SI 1 "const_int_operand" "i")
3128                          (match_operand:SI 2 "const_int_operand" "i"))
3129         (match_operand:SI 3 "gpc_reg_operand" "r"))]
3130   ""
3131   "*
3133   int start = INTVAL (operands[2]) & 31;
3134   int size = INTVAL (operands[1]) & 31;
3136   operands[4] = GEN_INT (32 - start - size);
3137   operands[1] = GEN_INT (start + size - 1);
3138   return \"rlwimi %0,%3,%h4,%h2,%h1\";
3140   [(set_attr "type" "insert")])
3142 (define_insn "*insvsi_internal1"
3143   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3144                          (match_operand:SI 1 "const_int_operand" "i")
3145                          (match_operand:SI 2 "const_int_operand" "i"))
3146         (rotate:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3147                    (match_operand:SI 4 "const_int_operand" "i")))]
3148   "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3149   "*
3151   int shift = INTVAL (operands[4]) & 31;
3152   int start = INTVAL (operands[2]) & 31;
3153   int size = INTVAL (operands[1]) & 31;
3155   operands[4] = GEN_INT (shift - start - size);
3156   operands[1] = GEN_INT (start + size - 1);
3157   return \"rlwimi %0,%3,%h4,%h2,%h1\";
3159   [(set_attr "type" "insert")])
3161 (define_insn "*insvsi_internal2"
3162   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3163                          (match_operand:SI 1 "const_int_operand" "i")
3164                          (match_operand:SI 2 "const_int_operand" "i"))
3165         (ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3166                      (match_operand:SI 4 "const_int_operand" "i")))]
3167   "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3168   "*
3170   int shift = INTVAL (operands[4]) & 31;
3171   int start = INTVAL (operands[2]) & 31;
3172   int size = INTVAL (operands[1]) & 31;
3174   operands[4] = GEN_INT (32 - shift - start - size);
3175   operands[1] = GEN_INT (start + size - 1);
3176   return \"rlwimi %0,%3,%h4,%h2,%h1\";
3178   [(set_attr "type" "insert")])
3180 (define_insn "*insvsi_internal3"
3181   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3182                          (match_operand:SI 1 "const_int_operand" "i")
3183                          (match_operand:SI 2 "const_int_operand" "i"))
3184         (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3185                      (match_operand:SI 4 "const_int_operand" "i")))]
3186   "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3187   "*
3189   int shift = INTVAL (operands[4]) & 31;
3190   int start = INTVAL (operands[2]) & 31;
3191   int size = INTVAL (operands[1]) & 31;
3193   operands[4] = GEN_INT (32 - shift - start - size);
3194   operands[1] = GEN_INT (start + size - 1);
3195   return \"rlwimi %0,%3,%h4,%h2,%h1\";
3197   [(set_attr "type" "insert")])
3199 (define_insn "*insvsi_internal4"
3200   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3201                          (match_operand:SI 1 "const_int_operand" "i")
3202                          (match_operand:SI 2 "const_int_operand" "i"))
3203         (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3204                          (match_operand:SI 4 "const_int_operand" "i")
3205                          (match_operand:SI 5 "const_int_operand" "i")))]
3206   "INTVAL (operands[4]) >= INTVAL (operands[1])"
3207   "*
3209   int extract_start = INTVAL (operands[5]) & 31;
3210   int extract_size = INTVAL (operands[4]) & 31;
3211   int insert_start = INTVAL (operands[2]) & 31;
3212   int insert_size = INTVAL (operands[1]) & 31;
3214 /* Align extract field with insert field */
3215   operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size);
3216   operands[1] = GEN_INT (insert_start + insert_size - 1);
3217   return \"rlwimi %0,%3,%h5,%h2,%h1\";
3219   [(set_attr "type" "insert")])
3221 ;; combine patterns for rlwimi
3222 (define_insn "*insvsi_internal5"
3223   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3224         (ior:SI (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
3225                         (match_operand:SI 1 "mask_operand" "i"))
3226                 (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3227                                      (match_operand:SI 2 "const_int_operand" "i"))
3228                         (match_operand:SI 5 "mask_operand" "i"))))]
3229   "INTVAL(operands[1]) == ~INTVAL(operands[5])"
3230   "*
3232  int me = extract_ME(operands[5]);
3233  int mb = extract_MB(operands[5]);
3234  operands[4] = GEN_INT(32 - INTVAL(operands[2]));
3235  operands[2] = GEN_INT(mb);
3236  operands[1] = GEN_INT(me);
3237  return \"rlwimi %0,%3,%h4,%h2,%h1\";
3239   [(set_attr "type" "insert")])
3241 (define_insn "*insvsi_internal6"
3242   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3243         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3244                                      (match_operand:SI 2 "const_int_operand" "i"))
3245                         (match_operand:SI 5 "mask_operand" "i"))
3246                 (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
3247                         (match_operand:SI 1 "mask_operand" "i"))))]
3248   "INTVAL(operands[1]) == ~INTVAL(operands[5])"
3249   "*
3251  int me = extract_ME(operands[5]);
3252  int mb = extract_MB(operands[5]);
3253  operands[4] = GEN_INT(32 - INTVAL(operands[2]));
3254  operands[2] = GEN_INT(mb);
3255  operands[1] = GEN_INT(me);
3256  return \"rlwimi %0,%3,%h4,%h2,%h1\";
3258   [(set_attr "type" "insert")])
3260 (define_insn "insvdi_internal"
3261   [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3262                          (match_operand:SI 1 "const_int_operand" "i")
3263                          (match_operand:SI 2 "const_int_operand" "i"))
3264         (match_operand:DI 3 "gpc_reg_operand" "r"))]
3265   "TARGET_POWERPC64"
3266   "*
3268   int start = INTVAL (operands[2]) & 63;
3269   int size = INTVAL (operands[1]) & 63;
3271   operands[1] = GEN_INT (64 - start - size);
3272   return \"rldimi %0,%3,%H1,%H2\";
3274   [(set_attr "type" "insert")
3275    (set_attr "size" "64")])
3277 (define_insn "*insvdi_internal2"
3278   [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3279                          (match_operand:SI 1 "const_int_operand" "i")
3280                          (match_operand:SI 2 "const_int_operand" "i"))
3281         (ashiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3282                      (match_operand:SI 4 "const_int_operand" "i")))]
3283   "TARGET_POWERPC64
3284    && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
3285   "*
3287   int shift = INTVAL (operands[4]) & 63;
3288   int start = (INTVAL (operands[2]) & 63) - 32;
3289   int size = INTVAL (operands[1]) & 63;
3291   operands[4] = GEN_INT (64 - shift - start - size);
3292   operands[2] = GEN_INT (start);
3293   operands[1] = GEN_INT (start + size - 1);
3294   return \"rlwimi %0,%3,%h4,%h2,%h1\";
3297 (define_insn "*insvdi_internal3"
3298   [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3299                          (match_operand:SI 1 "const_int_operand" "i")
3300                          (match_operand:SI 2 "const_int_operand" "i"))
3301         (lshiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3302                      (match_operand:SI 4 "const_int_operand" "i")))]
3303   "TARGET_POWERPC64
3304    && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
3305   "*
3307   int shift = INTVAL (operands[4]) & 63;
3308   int start = (INTVAL (operands[2]) & 63) - 32;
3309   int size = INTVAL (operands[1]) & 63;
3311   operands[4] = GEN_INT (64 - shift - start - size);
3312   operands[2] = GEN_INT (start);
3313   operands[1] = GEN_INT (start + size - 1);
3314   return \"rlwimi %0,%3,%h4,%h2,%h1\";
3317 (define_expand "extzv"
3318   [(set (match_operand 0 "gpc_reg_operand" "")
3319         (zero_extract (match_operand 1 "gpc_reg_operand" "")
3320                        (match_operand:SI 2 "const_int_operand" "")
3321                        (match_operand:SI 3 "const_int_operand" "")))]
3322   ""
3323   "
3325   /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
3326      the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
3327      compiler if the address of the structure is taken later.  */
3328   if (GET_CODE (operands[0]) == SUBREG
3329       && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
3330     FAIL;
3332   if (TARGET_POWERPC64 && GET_MODE (operands[1]) == DImode)
3333     emit_insn (gen_extzvdi_internal (operands[0], operands[1], operands[2],
3334                                      operands[3]));
3335   else
3336     emit_insn (gen_extzvsi_internal (operands[0], operands[1], operands[2],
3337                                      operands[3]));
3338   DONE;
3341 (define_insn "extzvsi_internal"
3342   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3343         (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3344                          (match_operand:SI 2 "const_int_operand" "i")
3345                          (match_operand:SI 3 "const_int_operand" "i")))]
3346   ""
3347   "*
3349   int start = INTVAL (operands[3]) & 31;
3350   int size = INTVAL (operands[2]) & 31;
3352   if (start + size >= 32)
3353     operands[3] = const0_rtx;
3354   else
3355     operands[3] = GEN_INT (start + size);
3356   return \"rlwinm %0,%1,%3,%s2,31\";
3358   [(set_attr "type" "shift")])
3360 (define_insn "*extzvsi_internal1"
3361   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3362         (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3363                          (match_operand:SI 2 "const_int_operand" "i,i")
3364                          (match_operand:SI 3 "const_int_operand" "i,i"))
3365                     (const_int 0)))
3366    (clobber (match_scratch:SI 4 "=r,r"))]
3367   ""
3368   "*
3370   int start = INTVAL (operands[3]) & 31;
3371   int size = INTVAL (operands[2]) & 31;
3373   /* Force split for non-cc0 compare.  */
3374   if (which_alternative == 1)
3375      return \"#\";
3377   /* If the bit-field being tested fits in the upper or lower half of a
3378      word, it is possible to use andiu. or andil. to test it.  This is
3379      useful because the condition register set-use delay is smaller for
3380      andi[ul]. than for rlinm.  This doesn't work when the starting bit
3381      position is 0 because the LT and GT bits may be set wrong.  */
3383   if ((start > 0 && start + size <= 16) || start >= 16)
3384     {
3385       operands[3] = GEN_INT (((1 << (16 - (start & 15)))
3386                               - (1 << (16 - (start & 15) - size))));
3387       if (start < 16)
3388         return \"andis. %4,%1,%3\";
3389       else
3390         return \"andi. %4,%1,%3\";
3391     }
3393   if (start + size >= 32)
3394     operands[3] = const0_rtx;
3395   else
3396     operands[3] = GEN_INT (start + size);
3397   return \"rlwinm. %4,%1,%3,%s2,31\";
3399   [(set_attr "type" "shift")
3400    (set_attr "dot" "yes")
3401    (set_attr "length" "4,8")])
3403 (define_split
3404   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
3405         (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
3406                          (match_operand:SI 2 "const_int_operand" "")
3407                          (match_operand:SI 3 "const_int_operand" ""))
3408                     (const_int 0)))
3409    (clobber (match_scratch:SI 4 ""))]
3410   "reload_completed"
3411   [(set (match_dup 4)
3412         (zero_extract:SI (match_dup 1) (match_dup 2)
3413                          (match_dup 3)))
3414    (set (match_dup 0)
3415         (compare:CC (match_dup 4)
3416                     (const_int 0)))]
3417   "")
3419 (define_insn "*extzvsi_internal2"
3420   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3421         (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3422                          (match_operand:SI 2 "const_int_operand" "i,i")
3423                          (match_operand:SI 3 "const_int_operand" "i,i"))
3424                     (const_int 0)))
3425    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3426         (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
3427   ""
3428   "*
3430   int start = INTVAL (operands[3]) & 31;
3431   int size = INTVAL (operands[2]) & 31;
3433   /* Force split for non-cc0 compare.  */
3434   if (which_alternative == 1)
3435      return \"#\";
3437   /* Since we are using the output value, we can't ignore any need for
3438      a shift.  The bit-field must end at the LSB.  */
3439   if (start >= 16 && start + size == 32)
3440     {
3441       operands[3] = GEN_INT ((1 << size) - 1);
3442       return \"andi. %0,%1,%3\";
3443     }
3445   if (start + size >= 32)
3446     operands[3] = const0_rtx;
3447   else
3448     operands[3] = GEN_INT (start + size);
3449   return \"rlwinm. %0,%1,%3,%s2,31\";
3451   [(set_attr "type" "shift")
3452    (set_attr "dot" "yes")
3453    (set_attr "length" "4,8")])
3455 (define_split
3456   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
3457         (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
3458                          (match_operand:SI 2 "const_int_operand" "")
3459                          (match_operand:SI 3 "const_int_operand" ""))
3460                     (const_int 0)))
3461    (set (match_operand:SI 0 "gpc_reg_operand" "")
3462         (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
3463   "reload_completed"
3464   [(set (match_dup 0)
3465         (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))
3466    (set (match_dup 4)
3467         (compare:CC (match_dup 0)
3468                     (const_int 0)))]
3469   "")
3471 (define_insn "extzvdi_internal"
3472   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3473         (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3474                          (match_operand:SI 2 "const_int_operand" "i")
3475                          (match_operand:SI 3 "const_int_operand" "i")))]
3476   "TARGET_POWERPC64"
3477   "*
3479   int start = INTVAL (operands[3]) & 63;
3480   int size = INTVAL (operands[2]) & 63;
3482   if (start + size >= 64)
3483     operands[3] = const0_rtx;
3484   else
3485     operands[3] = GEN_INT (start + size);
3486   operands[2] = GEN_INT (64 - size);
3487   return \"rldicl %0,%1,%3,%2\";
3489   [(set_attr "type" "shift")])
3491 (define_insn "*extzvdi_internal1"
3492   [(set (match_operand:CC 0 "gpc_reg_operand" "=x")
3493         (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3494                          (match_operand:SI 2 "const_int_operand" "i")
3495                          (match_operand:SI 3 "const_int_operand" "i"))
3496                     (const_int 0)))
3497    (clobber (match_scratch:DI 4 "=r"))]
3498   "TARGET_64BIT && rs6000_gen_cell_microcode"
3499   "*
3501   int start = INTVAL (operands[3]) & 63;
3502   int size = INTVAL (operands[2]) & 63;
3504   if (start + size >= 64)
3505     operands[3] = const0_rtx;
3506   else
3507     operands[3] = GEN_INT (start + size);
3508   operands[2] = GEN_INT (64 - size);
3509   return \"rldicl. %4,%1,%3,%2\";
3511   [(set_attr "type" "shift")
3512    (set_attr "dot" "yes")])
3514 (define_insn "*extzvdi_internal2"
3515   [(set (match_operand:CC 4 "gpc_reg_operand" "=x")
3516         (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3517                          (match_operand:SI 2 "const_int_operand" "i")
3518                          (match_operand:SI 3 "const_int_operand" "i"))
3519                     (const_int 0)))
3520    (set (match_operand:DI 0 "gpc_reg_operand" "=r")
3521         (zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
3522   "TARGET_64BIT && rs6000_gen_cell_microcode"
3523   "*
3525   int start = INTVAL (operands[3]) & 63;
3526   int size = INTVAL (operands[2]) & 63;
3528   if (start + size >= 64)
3529     operands[3] = const0_rtx;
3530   else
3531     operands[3] = GEN_INT (start + size);
3532   operands[2] = GEN_INT (64 - size);
3533   return \"rldicl. %0,%1,%3,%2\";
3535   [(set_attr "type" "shift")
3536    (set_attr "dot" "yes")])
3539 (define_insn "rotl<mode>3"
3540   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3541         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3542                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3543   ""
3544   "rotl<wd>%I2 %0,%1,%<hH>2"
3545   [(set_attr "type" "shift")
3546    (set_attr "maybe_var_shift" "yes")])
3548 (define_insn "*rotlsi3_64"
3549   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3550         (zero_extend:DI
3551             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3552                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3553   "TARGET_POWERPC64"
3554   "rotlw%I2 %0,%1,%h2"
3555   [(set_attr "type" "shift")
3556    (set_attr "maybe_var_shift" "yes")])
3558 (define_insn_and_split "*rotl<mode>3_dot"
3559   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3560         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3561                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3562                     (const_int 0)))
3563    (clobber (match_scratch:GPR 0 "=r,r"))]
3564   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3565   "@
3566    rotl<wd>%I2. %0,%1,%<hH>2
3567    #"
3568   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3569   [(set (match_dup 0)
3570         (rotate:GPR (match_dup 1)
3571                     (match_dup 2)))
3572    (set (match_dup 3)
3573         (compare:CC (match_dup 0)
3574                     (const_int 0)))]
3575   ""
3576   [(set_attr "type" "shift")
3577    (set_attr "maybe_var_shift" "yes")
3578    (set_attr "dot" "yes")
3579    (set_attr "length" "4,8")])
3581 (define_insn_and_split "*rotl<mode>3_dot2"
3582   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3583         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3584                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3585                     (const_int 0)))
3586    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3587         (rotate:GPR (match_dup 1)
3588                     (match_dup 2)))]
3589   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3590   "@
3591    rotl<wd>%I2. %0,%1,%<hH>2
3592    #"
3593   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3594   [(set (match_dup 0)
3595         (rotate:GPR (match_dup 1)
3596                     (match_dup 2)))
3597    (set (match_dup 3)
3598         (compare:CC (match_dup 0)
3599                     (const_int 0)))]
3600   ""
3601   [(set_attr "type" "shift")
3602    (set_attr "maybe_var_shift" "yes")
3603    (set_attr "dot" "yes")
3604    (set_attr "length" "4,8")])
3607 (define_insn "*rotlsi3_internal4"
3608   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3609         (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3610                            (match_operand:SI 2 "reg_or_cint_operand" "rn"))
3611                 (match_operand:SI 3 "mask_operand" "n")))]
3612   ""
3613   "rlw%I2nm %0,%1,%h2,%m3,%M3"
3614   [(set_attr "type" "shift")
3615    (set_attr "maybe_var_shift" "yes")])
3617 (define_insn "*rotlsi3_internal5"
3618   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3619         (compare:CC (and:SI
3620                      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3621                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3622                      (match_operand:SI 3 "mask_operand" "n,n"))
3623                     (const_int 0)))
3624    (clobber (match_scratch:SI 4 "=r,r"))]
3625   ""
3626   "@
3627    rlw%I2nm. %4,%1,%h2,%m3,%M3
3628    #"
3629   [(set_attr "type" "shift")
3630    (set_attr "maybe_var_shift" "yes")
3631    (set_attr "dot" "yes")
3632    (set_attr "length" "4,8")])
3634 (define_split
3635   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
3636         (compare:CC (and:SI
3637                      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3638                                 (match_operand:SI 2 "reg_or_cint_operand" ""))
3639                      (match_operand:SI 3 "mask_operand" ""))
3640                     (const_int 0)))
3641    (clobber (match_scratch:SI 4 ""))]
3642   "reload_completed"
3643   [(set (match_dup 4)
3644         (and:SI (rotate:SI (match_dup 1)
3645                                 (match_dup 2))
3646                      (match_dup 3)))
3647    (set (match_dup 0)
3648         (compare:CC (match_dup 4)
3649                     (const_int 0)))]
3650   "")
3652 (define_insn "*rotlsi3_internal6"
3653   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3654         (compare:CC (and:SI
3655                      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3656                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3657                      (match_operand:SI 3 "mask_operand" "n,n"))
3658                     (const_int 0)))
3659    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3660         (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3661   ""
3662   "@
3663    rlw%I2nm. %0,%1,%h2,%m3,%M3
3664    #"
3665   [(set_attr "type" "shift")
3666    (set_attr "maybe_var_shift" "yes")
3667    (set_attr "dot" "yes")
3668    (set_attr "length" "4,8")])
3670 (define_split
3671   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
3672         (compare:CC (and:SI
3673                      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3674                                 (match_operand:SI 2 "reg_or_cint_operand" ""))
3675                      (match_operand:SI 3 "mask_operand" ""))
3676                     (const_int 0)))
3677    (set (match_operand:SI 0 "gpc_reg_operand" "")
3678         (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3679   "reload_completed"
3680   [(set (match_dup 0)
3681         (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3682    (set (match_dup 4)
3683         (compare:CC (match_dup 0)
3684                     (const_int 0)))]
3685   "")
3687 (define_insn "*rotlsi3_internal7le"
3688   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3689         (zero_extend:SI
3690          (subreg:QI
3691           (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3692                      (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
3693   "!BYTES_BIG_ENDIAN"
3694   "rlw%I2nm %0,%1,%h2,0xff"
3695   [(set (attr "cell_micro")
3696      (if_then_else (match_operand:SI 2 "const_int_operand" "")
3697         (const_string "not")
3698         (const_string "always")))
3699    (set_attr "type" "shift")])
3701 (define_insn "*rotlsi3_internal7be"
3702   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3703         (zero_extend:SI
3704          (subreg:QI
3705           (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3706                      (match_operand:SI 2 "reg_or_cint_operand" "ri")) 3)))]
3707   "BYTES_BIG_ENDIAN"
3708   "rlw%I2nm %0,%1,%h2,0xff"
3709   [(set (attr "cell_micro")
3710      (if_then_else (match_operand:SI 2 "const_int_operand" "")
3711         (const_string "not")
3712         (const_string "always")))
3713    (set_attr "type" "shift")])
3715 (define_insn "*rotlsi3_internal8le"
3716   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3717         (compare:CC (zero_extend:SI
3718                      (subreg:QI
3719                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3720                                  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
3721                     (const_int 0)))
3722    (clobber (match_scratch:SI 3 "=r,r"))]
3723   "!BYTES_BIG_ENDIAN"
3724   "@
3725    rlw%I2nm. %3,%1,%h2,0xff
3726    #"
3727   [(set_attr "type" "shift")
3728    (set_attr "maybe_var_shift" "yes")
3729    (set_attr "dot" "yes")
3730    (set_attr "length" "4,8")])
3732 (define_insn "*rotlsi3_internal8be"
3733   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3734         (compare:CC (zero_extend:SI
3735                      (subreg:QI
3736                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3737                                  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3))
3738                     (const_int 0)))
3739    (clobber (match_scratch:SI 3 "=r,r"))]
3740   "BYTES_BIG_ENDIAN"
3741   "@
3742    rlw%I2nm. %3,%1,%h2,0xff
3743    #"
3744   [(set_attr "type" "shift")
3745    (set_attr "maybe_var_shift" "yes")
3746    (set_attr "dot" "yes")
3747    (set_attr "length" "4,8")])
3749 (define_split
3750   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
3751         (compare:CC (zero_extend:SI
3752                      (subreg:QI
3753                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3754                                  (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
3755                     (const_int 0)))
3756    (clobber (match_scratch:SI 3 ""))]
3757   "!BYTES_BIG_ENDIAN && reload_completed"
3758   [(set (match_dup 3)
3759         (zero_extend:SI (subreg:QI
3760                       (rotate:SI (match_dup 1)
3761                                  (match_dup 2)) 0)))
3762    (set (match_dup 0)
3763         (compare:CC (match_dup 3)
3764                     (const_int 0)))]
3765   "")
3767 (define_split
3768   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
3769         (compare:CC (zero_extend:SI
3770                      (subreg:QI
3771                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3772                                  (match_operand:SI 2 "reg_or_cint_operand" "")) 3))
3773                     (const_int 0)))
3774    (clobber (match_scratch:SI 3 ""))]
3775   "BYTES_BIG_ENDIAN && reload_completed"
3776   [(set (match_dup 3)
3777         (zero_extend:SI (subreg:QI
3778                       (rotate:SI (match_dup 1)
3779                                  (match_dup 2)) 3)))
3780    (set (match_dup 0)
3781         (compare:CC (match_dup 3)
3782                     (const_int 0)))]
3783   "")
3785 (define_insn "*rotlsi3_internal9le"
3786   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3787         (compare:CC (zero_extend:SI
3788                      (subreg:QI
3789                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3790                                  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
3791                     (const_int 0)))
3792    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3793         (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
3794   "!BYTES_BIG_ENDIAN"
3795   "@
3796    rlw%I2nm. %0,%1,%h2,0xff
3797    #"
3798   [(set_attr "type" "shift")
3799    (set_attr "maybe_var_shift" "yes")
3800    (set_attr "dot" "yes")
3801    (set_attr "length" "4,8")])
3803 (define_insn "*rotlsi3_internal9be"
3804   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3805         (compare:CC (zero_extend:SI
3806                      (subreg:QI
3807                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3808                                  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3))
3809                     (const_int 0)))
3810    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3811         (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))]
3812   "BYTES_BIG_ENDIAN"
3813   "@
3814    rlw%I2nm. %0,%1,%h2,0xff
3815    #"
3816   [(set_attr "type" "shift")
3817    (set_attr "maybe_var_shift" "yes")
3818    (set_attr "dot" "yes")
3819    (set_attr "length" "4,8")])
3821 (define_split
3822   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
3823         (compare:CC (zero_extend:SI
3824                      (subreg:QI
3825                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3826                                  (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
3827                     (const_int 0)))
3828    (set (match_operand:SI 0 "gpc_reg_operand" "")
3829         (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
3830   "!BYTES_BIG_ENDIAN && reload_completed"
3831   [(set (match_dup 0)
3832         (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
3833    (set (match_dup 3)
3834         (compare:CC (match_dup 0)
3835                     (const_int 0)))]
3836   "")
3838 (define_split
3839   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
3840         (compare:CC (zero_extend:SI
3841                      (subreg:QI
3842                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3843                                  (match_operand:SI 2 "reg_or_cint_operand" "")) 3))
3844                     (const_int 0)))
3845    (set (match_operand:SI 0 "gpc_reg_operand" "")
3846         (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))]
3847   "BYTES_BIG_ENDIAN && reload_completed"
3848   [(set (match_dup 0)
3849         (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))
3850    (set (match_dup 3)
3851         (compare:CC (match_dup 0)
3852                     (const_int 0)))]
3853   "")
3855 (define_insn "*rotlsi3_internal10le"
3856   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3857         (zero_extend:SI
3858          (subreg:HI
3859           (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3860                      (match_operand:SI 2 "reg_or_cint_operand" "rn")) 0)))]
3861   "!BYTES_BIG_ENDIAN"
3862   "rlw%I2nm %0,%1,%h2,0xffff"
3863   [(set_attr "type" "shift")
3864    (set_attr "maybe_var_shift" "yes")])
3866 (define_insn "*rotlsi3_internal10be"
3867   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3868         (zero_extend:SI
3869          (subreg:HI
3870           (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3871                      (match_operand:SI 2 "reg_or_cint_operand" "rn")) 2)))]
3872   "BYTES_BIG_ENDIAN"
3873   "rlw%I2nm %0,%1,%h2,0xffff"
3874   [(set_attr "type" "shift")
3875    (set_attr "maybe_var_shift" "yes")])
3877 (define_insn "*rotlsi3_internal11le"
3878   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3879         (compare:CC (zero_extend:SI
3880                      (subreg:HI
3881                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3882                                  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
3883                     (const_int 0)))
3884    (clobber (match_scratch:SI 3 "=r,r"))]
3885   "!BYTES_BIG_ENDIAN"
3886   "@
3887    rlw%I2nm. %3,%1,%h2,0xffff
3888    #"
3889   [(set_attr "type" "shift")
3890    (set_attr "maybe_var_shift" "yes")
3891    (set_attr "dot" "yes")
3892    (set_attr "length" "4,8")])
3894 (define_insn "*rotlsi3_internal11be"
3895   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
3896         (compare:CC (zero_extend:SI
3897                      (subreg:HI
3898                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3899                                  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 2))
3900                     (const_int 0)))
3901    (clobber (match_scratch:SI 3 "=r,r"))]
3902   "BYTES_BIG_ENDIAN"
3903   "@
3904    rlw%I2nm. %3,%1,%h2,0xffff
3905    #"
3906   [(set_attr "type" "shift")
3907    (set_attr "maybe_var_shift" "yes")
3908    (set_attr "dot" "yes")
3909    (set_attr "length" "4,8")])
3911 (define_split
3912   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
3913         (compare:CC (zero_extend:SI
3914                      (subreg:HI
3915                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3916                                  (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
3917                     (const_int 0)))
3918    (clobber (match_scratch:SI 3 ""))]
3919   "!BYTES_BIG_ENDIAN && reload_completed"
3920   [(set (match_dup 3)
3921         (zero_extend:SI (subreg:HI
3922                       (rotate:SI (match_dup 1)
3923                                  (match_dup 2)) 0)))
3924    (set (match_dup 0)
3925         (compare:CC (match_dup 3)
3926                     (const_int 0)))]
3927   "")
3929 (define_split
3930   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
3931         (compare:CC (zero_extend:SI
3932                      (subreg:HI
3933                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3934                                  (match_operand:SI 2 "reg_or_cint_operand" "")) 2))
3935                     (const_int 0)))
3936    (clobber (match_scratch:SI 3 ""))]
3937   "BYTES_BIG_ENDIAN && reload_completed"
3938   [(set (match_dup 3)
3939         (zero_extend:SI (subreg:HI
3940                       (rotate:SI (match_dup 1)
3941                                  (match_dup 2)) 2)))
3942    (set (match_dup 0)
3943         (compare:CC (match_dup 3)
3944                     (const_int 0)))]
3945   "")
3947 (define_insn "*rotlsi3_internal12le"
3948   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3949         (compare:CC (zero_extend:SI
3950                      (subreg:HI
3951                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3952                                  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0))
3953                     (const_int 0)))
3954    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3955         (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
3956   "!BYTES_BIG_ENDIAN"
3957   "@
3958    rlw%I2nm. %0,%1,%h2,0xffff
3959    #"
3960   [(set_attr "type" "shift")
3961    (set_attr "maybe_var_shift" "yes")
3962    (set_attr "dot" "yes")
3963    (set_attr "length" "4,8")])
3965 (define_insn "*rotlsi3_internal12be"
3966   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3967         (compare:CC (zero_extend:SI
3968                      (subreg:HI
3969                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3970                                  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 2))
3971                     (const_int 0)))
3972    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3973         (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))]
3974   "BYTES_BIG_ENDIAN"
3975   "@
3976    rlw%I2nm. %0,%1,%h2,0xffff
3977    #"
3978   [(set_attr "type" "shift")
3979    (set_attr "maybe_var_shift" "yes")
3980    (set_attr "dot" "yes")
3981    (set_attr "length" "4,8")])
3983 (define_split
3984   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
3985         (compare:CC (zero_extend:SI
3986                      (subreg:HI
3987                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
3988                                  (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
3989                     (const_int 0)))
3990    (set (match_operand:SI 0 "gpc_reg_operand" "")
3991         (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
3992   "!BYTES_BIG_ENDIAN && reload_completed"
3993   [(set (match_dup 0)
3994         (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
3995    (set (match_dup 3)
3996         (compare:CC (match_dup 0)
3997                     (const_int 0)))]
3998   "")
4000 (define_split
4001   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4002         (compare:CC (zero_extend:SI
4003                      (subreg:HI
4004                       (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
4005                                  (match_operand:SI 2 "reg_or_cint_operand" "")) 2))
4006                     (const_int 0)))
4007    (set (match_operand:SI 0 "gpc_reg_operand" "")
4008         (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))]
4009   "BYTES_BIG_ENDIAN && reload_completed"
4010   [(set (match_dup 0)
4011         (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))
4012    (set (match_dup 3)
4013         (compare:CC (match_dup 0)
4014                     (const_int 0)))]
4015   "")
4018 (define_insn "ashl<mode>3"
4019   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4020         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4021                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4022   ""
4023   "sl<wd>%I2 %0,%1,%<hH>2"
4024   [(set_attr "type" "shift")
4025    (set_attr "maybe_var_shift" "yes")])
4027 (define_insn "*ashlsi3_64"
4028   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4029         (zero_extend:DI
4030             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4031                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4032   "TARGET_POWERPC64"
4033   "slw%I2 %0,%1,%h2"
4034   [(set_attr "type" "shift")
4035    (set_attr "maybe_var_shift" "yes")])
4037 (define_insn_and_split "*ashl<mode>3_dot"
4038   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4039         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4040                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4041                     (const_int 0)))
4042    (clobber (match_scratch:GPR 0 "=r,r"))]
4043   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4044   "@
4045    sl<wd>%I2. %0,%1,%<hH>2
4046    #"
4047   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4048   [(set (match_dup 0)
4049         (ashift:GPR (match_dup 1)
4050                     (match_dup 2)))
4051    (set (match_dup 3)
4052         (compare:CC (match_dup 0)
4053                     (const_int 0)))]
4054   ""
4055   [(set_attr "type" "shift")
4056    (set_attr "maybe_var_shift" "yes")
4057    (set_attr "dot" "yes")
4058    (set_attr "length" "4,8")])
4060 (define_insn_and_split "*ashl<mode>3_dot2"
4061   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4062         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4063                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4064                     (const_int 0)))
4065    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4066         (ashift:GPR (match_dup 1)
4067                     (match_dup 2)))]
4068   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4069   "@
4070    sl<wd>%I2. %0,%1,%<hH>2
4071    #"
4072   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4073   [(set (match_dup 0)
4074         (ashift:GPR (match_dup 1)
4075                     (match_dup 2)))
4076    (set (match_dup 3)
4077         (compare:CC (match_dup 0)
4078                     (const_int 0)))]
4079   ""
4080   [(set_attr "type" "shift")
4081    (set_attr "maybe_var_shift" "yes")
4082    (set_attr "dot" "yes")
4083    (set_attr "length" "4,8")])
4086 (define_insn "rlwinm"
4087   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4088         (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4089                            (match_operand:SI 2 "const_int_operand" "i"))
4090                 (match_operand:SI 3 "mask_operand" "n")))]
4091   "includes_lshift_p (operands[2], operands[3])"
4092   "rlwinm %0,%1,%h2,%m3,%M3"
4093   [(set_attr "type" "shift")])
4095 (define_insn ""
4096   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4097         (compare:CC
4098          (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4099                             (match_operand:SI 2 "const_int_operand" "i,i"))
4100                  (match_operand:SI 3 "mask_operand" "n,n"))
4101          (const_int 0)))
4102    (clobber (match_scratch:SI 4 "=r,r"))]
4103   "includes_lshift_p (operands[2], operands[3])"
4104   "@
4105    rlwinm. %4,%1,%h2,%m3,%M3
4106    #"
4107   [(set_attr "type" "shift")
4108    (set_attr "dot" "yes")
4109    (set_attr "length" "4,8")])
4111 (define_split
4112   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4113         (compare:CC
4114          (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
4115                             (match_operand:SI 2 "const_int_operand" ""))
4116                  (match_operand:SI 3 "mask_operand" ""))
4117          (const_int 0)))
4118    (clobber (match_scratch:SI 4 ""))]
4119   "includes_lshift_p (operands[2], operands[3]) && reload_completed"
4120   [(set (match_dup 4)
4121         (and:SI (ashift:SI (match_dup 1) (match_dup 2))
4122                  (match_dup 3)))
4123    (set (match_dup 0)
4124         (compare:CC (match_dup 4)
4125                     (const_int 0)))]
4126   "")
4128 (define_insn ""
4129   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4130         (compare:CC
4131          (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4132                             (match_operand:SI 2 "const_int_operand" "i,i"))
4133                  (match_operand:SI 3 "mask_operand" "n,n"))
4134          (const_int 0)))
4135    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4136         (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4137   "includes_lshift_p (operands[2], operands[3])"
4138   "@
4139    rlwinm. %0,%1,%h2,%m3,%M3
4140    #"
4141   [(set_attr "type" "shift")
4142    (set_attr "dot" "yes")
4143    (set_attr "length" "4,8")])
4145 (define_split
4146   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
4147         (compare:CC
4148          (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
4149                             (match_operand:SI 2 "const_int_operand" ""))
4150                  (match_operand:SI 3 "mask_operand" ""))
4151          (const_int 0)))
4152    (set (match_operand:SI 0 "gpc_reg_operand" "")
4153         (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4154   "includes_lshift_p (operands[2], operands[3]) && reload_completed"
4155   [(set (match_dup 0)
4156         (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4157    (set (match_dup 4)
4158         (compare:CC (match_dup 0)
4159                     (const_int 0)))]
4160   "")
4163 (define_insn "lshr<mode>3"
4164   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4165         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4166                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4167   ""
4168   "sr<wd>%I2 %0,%1,%<hH>2"
4169   [(set_attr "type" "shift")
4170    (set_attr "maybe_var_shift" "yes")])
4172 (define_insn "*lshrsi3_64"
4173   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4174         (zero_extend:DI
4175             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4176                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4177   "TARGET_POWERPC64"
4178   "srw%I2 %0,%1,%h2"
4179   [(set_attr "type" "shift")
4180    (set_attr "maybe_var_shift" "yes")])
4182 (define_insn_and_split "*lshr<mode>3_dot"
4183   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4184         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4185                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4186                     (const_int 0)))
4187    (clobber (match_scratch:GPR 0 "=r,r"))]
4188   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4189   "@
4190    sr<wd>%I2. %0,%1,%<hH>2
4191    #"
4192   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4193   [(set (match_dup 0)
4194         (lshiftrt:GPR (match_dup 1)
4195                       (match_dup 2)))
4196    (set (match_dup 3)
4197         (compare:CC (match_dup 0)
4198                     (const_int 0)))]
4199   ""
4200   [(set_attr "type" "shift")
4201    (set_attr "maybe_var_shift" "yes")
4202    (set_attr "dot" "yes")
4203    (set_attr "length" "4,8")])
4205 (define_insn_and_split "*lshr<mode>3_dot2"
4206   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4207         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4208                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4209                     (const_int 0)))
4210    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4211         (lshiftrt:GPR (match_dup 1)
4212                       (match_dup 2)))]
4213   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4214   "@
4215    sr<wd>%I2. %0,%1,%<hH>2
4216    #"
4217   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4218   [(set (match_dup 0)
4219         (lshiftrt:GPR (match_dup 1)
4220                       (match_dup 2)))
4221    (set (match_dup 3)
4222         (compare:CC (match_dup 0)
4223                     (const_int 0)))]
4224   ""
4225   [(set_attr "type" "shift")
4226    (set_attr "maybe_var_shift" "yes")
4227    (set_attr "dot" "yes")
4228    (set_attr "length" "4,8")])
4231 (define_insn ""
4232   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4233         (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4234                              (match_operand:SI 2 "const_int_operand" "i"))
4235                 (match_operand:SI 3 "mask_operand" "n")))]
4236   "includes_rshift_p (operands[2], operands[3])"
4237   "rlwinm %0,%1,%s2,%m3,%M3"
4238   [(set_attr "type" "shift")])
4240 (define_insn ""
4241   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4242         (compare:CC
4243          (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4244                               (match_operand:SI 2 "const_int_operand" "i,i"))
4245                  (match_operand:SI 3 "mask_operand" "n,n"))
4246          (const_int 0)))
4247    (clobber (match_scratch:SI 4 "=r,r"))]
4248   "includes_rshift_p (operands[2], operands[3])"
4249   "@
4250    rlwinm. %4,%1,%s2,%m3,%M3
4251    #"
4252   [(set_attr "type" "shift")
4253    (set_attr "dot" "yes")
4254    (set_attr "length" "4,8")])
4256 (define_split
4257   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4258         (compare:CC
4259          (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4260                               (match_operand:SI 2 "const_int_operand" ""))
4261                  (match_operand:SI 3 "mask_operand" ""))
4262          (const_int 0)))
4263    (clobber (match_scratch:SI 4 ""))]
4264   "includes_rshift_p (operands[2], operands[3]) && reload_completed"
4265   [(set (match_dup 4)
4266         (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
4267                  (match_dup 3)))
4268    (set (match_dup 0)
4269         (compare:CC (match_dup 4)
4270                     (const_int 0)))]
4271   "")
4273 (define_insn ""
4274   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4275         (compare:CC
4276          (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4277                               (match_operand:SI 2 "const_int_operand" "i,i"))
4278                  (match_operand:SI 3 "mask_operand" "n,n"))
4279          (const_int 0)))
4280    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4281         (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4282   "includes_rshift_p (operands[2], operands[3])"
4283   "@
4284    rlwinm. %0,%1,%s2,%m3,%M3
4285    #"
4286   [(set_attr "type" "shift")
4287    (set_attr "dot" "yes")
4288    (set_attr "length" "4,8")])
4290 (define_split
4291   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
4292         (compare:CC
4293          (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4294                               (match_operand:SI 2 "const_int_operand" ""))
4295                  (match_operand:SI 3 "mask_operand" ""))
4296          (const_int 0)))
4297    (set (match_operand:SI 0 "gpc_reg_operand" "")
4298         (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4299   "includes_rshift_p (operands[2], operands[3]) && reload_completed"
4300   [(set (match_dup 0)
4301         (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
4302    (set (match_dup 4)
4303         (compare:CC (match_dup 0)
4304                     (const_int 0)))]
4305   "")
4307 (define_insn "*lshiftrt_internal1le"
4308   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4309         (zero_extend:SI
4310          (subreg:QI
4311           (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4312                        (match_operand:SI 2 "const_int_operand" "i")) 0)))]
4313   "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4314   "rlwinm %0,%1,%s2,0xff"
4315   [(set_attr "type" "shift")])
4317 (define_insn "*lshiftrt_internal1be"
4318   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4319         (zero_extend:SI
4320          (subreg:QI
4321           (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4322                        (match_operand:SI 2 "const_int_operand" "i")) 3)))]
4323   "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4324   "rlwinm %0,%1,%s2,0xff"
4325   [(set_attr "type" "shift")])
4327 (define_insn "*lshiftrt_internal2le"
4328   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4329         (compare:CC
4330          (zero_extend:SI
4331           (subreg:QI
4332            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4333                         (match_operand:SI 2 "const_int_operand" "i,i")) 0))
4334          (const_int 0)))
4335    (clobber (match_scratch:SI 3 "=r,r"))]
4336   "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4337   "@
4338    rlwinm. %3,%1,%s2,0xff
4339    #"
4340   [(set_attr "type" "shift")
4341    (set_attr "dot" "yes")
4342    (set_attr "length" "4,8")])
4344 (define_insn "*lshiftrt_internal2be"
4345   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4346         (compare:CC
4347          (zero_extend:SI
4348           (subreg:QI
4349            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4350                         (match_operand:SI 2 "const_int_operand" "i,i")) 3))
4351          (const_int 0)))
4352    (clobber (match_scratch:SI 3 "=r,r"))]
4353   "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4354   "@
4355    rlwinm. %3,%1,%s2,0xff
4356    #"
4357   [(set_attr "type" "shift")
4358    (set_attr "dot" "yes")
4359    (set_attr "length" "4,8")])
4361 (define_split
4362   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4363         (compare:CC
4364          (zero_extend:SI
4365           (subreg:QI
4366            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4367                         (match_operand:SI 2 "const_int_operand" "")) 0))
4368          (const_int 0)))
4369    (clobber (match_scratch:SI 3 ""))]
4370   "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
4371   [(set (match_dup 3)
4372         (zero_extend:SI (subreg:QI
4373            (lshiftrt:SI (match_dup 1)
4374                         (match_dup 2)) 0)))
4375    (set (match_dup 0)
4376         (compare:CC (match_dup 3)
4377                     (const_int 0)))]
4378   "")
4380 (define_split
4381   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4382         (compare:CC
4383          (zero_extend:SI
4384           (subreg:QI
4385            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4386                         (match_operand:SI 2 "const_int_operand" "")) 3))
4387          (const_int 0)))
4388    (clobber (match_scratch:SI 3 ""))]
4389   "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
4390   [(set (match_dup 3)
4391         (zero_extend:SI (subreg:QI
4392            (lshiftrt:SI (match_dup 1)
4393                         (match_dup 2)) 3)))
4394    (set (match_dup 0)
4395         (compare:CC (match_dup 3)
4396                     (const_int 0)))]
4397   "")
4399 (define_insn "*lshiftrt_internal3le"
4400   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4401         (compare:CC
4402          (zero_extend:SI
4403           (subreg:QI
4404            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4405                         (match_operand:SI 2 "const_int_operand" "i,i")) 0))
4406          (const_int 0)))
4407    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4408         (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
4409   "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4410   "@
4411    rlwinm. %0,%1,%s2,0xff
4412    #"
4413   [(set_attr "type" "shift")
4414    (set_attr "dot" "yes")
4415    (set_attr "length" "4,8")])
4417 (define_insn "*lshiftrt_internal3be"
4418   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4419         (compare:CC
4420          (zero_extend:SI
4421           (subreg:QI
4422            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4423                         (match_operand:SI 2 "const_int_operand" "i,i")) 3))
4424          (const_int 0)))
4425    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4426         (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))]
4427   "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
4428   "@
4429    rlwinm. %0,%1,%s2,0xff
4430    #"
4431   [(set_attr "type" "shift")
4432    (set_attr "dot" "yes")
4433    (set_attr "length" "4,8")])
4435 (define_split
4436   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4437         (compare:CC
4438          (zero_extend:SI
4439           (subreg:QI
4440            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4441                         (match_operand:SI 2 "const_int_operand" "")) 0))
4442          (const_int 0)))
4443    (set (match_operand:SI 0 "gpc_reg_operand" "")
4444         (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
4445   "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
4446   [(set (match_dup 0)
4447         (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
4448    (set (match_dup 3)
4449         (compare:CC (match_dup 0)
4450                     (const_int 0)))]
4451   "")
4453 (define_split
4454   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4455         (compare:CC
4456          (zero_extend:SI
4457           (subreg:QI
4458            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4459                         (match_operand:SI 2 "const_int_operand" "")) 3))
4460          (const_int 0)))
4461    (set (match_operand:SI 0 "gpc_reg_operand" "")
4462         (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))]
4463   "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
4464   [(set (match_dup 0)
4465         (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))
4466    (set (match_dup 3)
4467         (compare:CC (match_dup 0)
4468                     (const_int 0)))]
4469   "")
4471 (define_insn "*lshiftrt_internal4le"
4472   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4473         (zero_extend:SI
4474          (subreg:HI
4475           (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4476                        (match_operand:SI 2 "const_int_operand" "i")) 0)))]
4477   "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4478   "rlwinm %0,%1,%s2,0xffff"
4479   [(set_attr "type" "shift")])
4481 (define_insn "*lshiftrt_internal4be"
4482   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4483         (zero_extend:SI
4484          (subreg:HI
4485           (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4486                        (match_operand:SI 2 "const_int_operand" "i")) 2)))]
4487   "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4488   "rlwinm %0,%1,%s2,0xffff"
4489   [(set_attr "type" "shift")])
4491 (define_insn "*lshiftrt_internal5le"
4492   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4493         (compare:CC
4494          (zero_extend:SI
4495           (subreg:HI
4496            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4497                         (match_operand:SI 2 "const_int_operand" "i,i")) 0))
4498          (const_int 0)))
4499    (clobber (match_scratch:SI 3 "=r,r"))]
4500   "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4501   "@
4502    rlwinm. %3,%1,%s2,0xffff
4503    #"
4504   [(set_attr "type" "shift")
4505    (set_attr "dot" "yes")
4506    (set_attr "length" "4,8")])
4508 (define_insn "*lshiftrt_internal5be"
4509   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
4510         (compare:CC
4511          (zero_extend:SI
4512           (subreg:HI
4513            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4514                         (match_operand:SI 2 "const_int_operand" "i,i")) 2))
4515          (const_int 0)))
4516    (clobber (match_scratch:SI 3 "=r,r"))]
4517   "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4518   "@
4519    rlwinm. %3,%1,%s2,0xffff
4520    #"
4521   [(set_attr "type" "shift")
4522    (set_attr "dot" "yes")
4523    (set_attr "length" "4,8")])
4525 (define_split
4526   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4527         (compare:CC
4528          (zero_extend:SI
4529           (subreg:HI
4530            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4531                         (match_operand:SI 2 "const_int_operand" "")) 0))
4532          (const_int 0)))
4533    (clobber (match_scratch:SI 3 ""))]
4534   "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
4535   [(set (match_dup 3)
4536         (zero_extend:SI (subreg:HI
4537            (lshiftrt:SI (match_dup 1)
4538                         (match_dup 2)) 0)))
4539    (set (match_dup 0)
4540         (compare:CC (match_dup 3)
4541                     (const_int 0)))]
4542   "")
4544 (define_split
4545   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
4546         (compare:CC
4547          (zero_extend:SI
4548           (subreg:HI
4549            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4550                         (match_operand:SI 2 "const_int_operand" "")) 2))
4551          (const_int 0)))
4552    (clobber (match_scratch:SI 3 ""))]
4553   "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
4554   [(set (match_dup 3)
4555         (zero_extend:SI (subreg:HI
4556            (lshiftrt:SI (match_dup 1)
4557                         (match_dup 2)) 2)))
4558    (set (match_dup 0)
4559         (compare:CC (match_dup 3)
4560                     (const_int 0)))]
4561   "")
4563 (define_insn "*lshiftrt_internal5le"
4564   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4565         (compare:CC
4566          (zero_extend:SI
4567           (subreg:HI
4568            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4569                         (match_operand:SI 2 "const_int_operand" "i,i")) 0))
4570          (const_int 0)))
4571    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4572         (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
4573   "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4574   "@
4575    rlwinm. %0,%1,%s2,0xffff
4576    #"
4577   [(set_attr "type" "shift")
4578    (set_attr "dot" "yes")
4579    (set_attr "length" "4,8")])
4581 (define_insn "*lshiftrt_internal5be"
4582   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4583         (compare:CC
4584          (zero_extend:SI
4585           (subreg:HI
4586            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4587                         (match_operand:SI 2 "const_int_operand" "i,i")) 2))
4588          (const_int 0)))
4589    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4590         (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))]
4591   "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
4592   "@
4593    rlwinm. %0,%1,%s2,0xffff
4594    #"
4595   [(set_attr "type" "shift")
4596    (set_attr "dot" "yes")
4597    (set_attr "length" "4,8")])
4599 (define_split
4600   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4601         (compare:CC
4602          (zero_extend:SI
4603           (subreg:HI
4604            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4605                         (match_operand:SI 2 "const_int_operand" "")) 0))
4606          (const_int 0)))
4607    (set (match_operand:SI 0 "gpc_reg_operand" "")
4608         (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
4609   "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
4610   [(set (match_dup 0)
4611         (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
4612    (set (match_dup 3)
4613         (compare:CC (match_dup 0)
4614                     (const_int 0)))]
4615   "")
4617 (define_split
4618   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
4619         (compare:CC
4620          (zero_extend:SI
4621           (subreg:HI
4622            (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
4623                         (match_operand:SI 2 "const_int_operand" "")) 2))
4624          (const_int 0)))
4625    (set (match_operand:SI 0 "gpc_reg_operand" "")
4626         (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))]
4627   "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
4628   [(set (match_dup 0)
4629         (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))
4630    (set (match_dup 3)
4631         (compare:CC (match_dup 0)
4632                     (const_int 0)))]
4633   "")
4636 (define_expand "ashr<mode>3"
4637   [(parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4638                    (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
4639                                  (match_operand:SI 2 "reg_or_cint_operand" "")))
4640               (clobber (reg:GPR CA_REGNO))])]
4641   ""
4643   /* The generic code does not generate optimal code for the low word
4644      (it should be a rlwimi and a rot).  Until we have target code to
4645      solve this generically, keep this expander.  */
4647   if (<MODE>mode == DImode && !TARGET_POWERPC64)
4648     {
4649       if (CONST_INT_P (operands[2]))
4650         {
4651           emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2]));
4652           DONE;
4653         }
4654       else
4655         FAIL;
4656     }
4659 (define_insn "*ashr<mode>3"
4660   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4661         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4662                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4663    (clobber (reg:GPR CA_REGNO))]
4664   ""
4665   "sra<wd>%I2 %0,%1,%<hH>2"
4666   [(set_attr "type" "shift")
4667    (set_attr "maybe_var_shift" "yes")])
4669 (define_insn "*ashrsi3_64"
4670   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4671         (sign_extend:DI
4672             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4673                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4674    (clobber (reg:SI CA_REGNO))]
4675   "TARGET_POWERPC64"
4676   "sraw%I2 %0,%1,%h2"
4677   [(set_attr "type" "shift")
4678    (set_attr "maybe_var_shift" "yes")])
4680 (define_insn_and_split "*ashr<mode>3_dot"
4681   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4682         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4683                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4684                     (const_int 0)))
4685    (clobber (match_scratch:GPR 0 "=r,r"))
4686    (clobber (reg:GPR CA_REGNO))]
4687   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4688   "@
4689    sra<wd>%I2. %0,%1,%<hH>2
4690    #"
4691   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4692   [(parallel [(set (match_dup 0)
4693                    (ashiftrt:GPR (match_dup 1)
4694                                  (match_dup 2)))
4695               (clobber (reg:GPR CA_REGNO))])
4696    (set (match_dup 3)
4697         (compare:CC (match_dup 0)
4698                     (const_int 0)))]
4699   ""
4700   [(set_attr "type" "shift")
4701    (set_attr "maybe_var_shift" "yes")
4702    (set_attr "dot" "yes")
4703    (set_attr "length" "4,8")])
4705 (define_insn_and_split "*ashr<mode>3_dot2"
4706   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4707         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4708                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4709                     (const_int 0)))
4710    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4711         (ashiftrt:GPR (match_dup 1)
4712                       (match_dup 2)))
4713    (clobber (reg:GPR CA_REGNO))]
4714   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4715   "@
4716    sra<wd>%I2. %0,%1,%<hH>2
4717    #"
4718   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4719   [(parallel [(set (match_dup 0)
4720                    (ashiftrt:GPR (match_dup 1)
4721                                  (match_dup 2)))
4722               (clobber (reg:GPR CA_REGNO))])
4723    (set (match_dup 3)
4724         (compare:CC (match_dup 0)
4725                     (const_int 0)))]
4726   ""
4727   [(set_attr "type" "shift")
4728    (set_attr "maybe_var_shift" "yes")
4729    (set_attr "dot" "yes")
4730    (set_attr "length" "4,8")])
4732 ;; Builtins to replace a division to generate FRE reciprocal estimate
4733 ;; instructions and the necessary fixup instructions
4734 (define_expand "recip<mode>3"
4735   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4736    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4737    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4738   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4740    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4741    DONE;
4744 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4745 ;; hardware division.  This is only done before register allocation and with
4746 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4747 (define_split
4748   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4749         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4750                     (match_operand 2 "gpc_reg_operand" "")))]
4751   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4752    && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4753    && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4754   [(const_int 0)]
4756   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4757   DONE;
4760 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4761 ;; appropriate fixup.
4762 (define_expand "rsqrt<mode>2"
4763   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4764    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4765   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4767   rs6000_emit_swrsqrt (operands[0], operands[1]);
4768   DONE;
4771 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4772 ;; modes here, and also add in conditional vsx/power8-vector support to access
4773 ;; values in the traditional Altivec registers if the appropriate
4774 ;; -mupper-regs-{df,sf} option is enabled.
4776 (define_expand "abs<mode>2"
4777   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4778         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4779   "TARGET_<MODE>_INSN"
4780   "")
4782 (define_insn "*abs<mode>2_fpr"
4783   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4784         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4785   "TARGET_<MODE>_FPR"
4786   "@
4787    fabs %0,%1
4788    xsabsdp %x0,%x1"
4789   [(set_attr "type" "fp")
4790    (set_attr "fp_type" "fp_addsub_<Fs>")])
4792 (define_insn "*nabs<mode>2_fpr"
4793   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4794         (neg:SFDF
4795          (abs:SFDF
4796           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4797   "TARGET_<MODE>_FPR"
4798   "@
4799    fnabs %0,%1
4800    xsnabsdp %x0,%x1"
4801   [(set_attr "type" "fp")
4802    (set_attr "fp_type" "fp_addsub_<Fs>")])
4804 (define_expand "neg<mode>2"
4805   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4806         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4807   "TARGET_<MODE>_INSN"
4808   "")
4810 (define_insn "*neg<mode>2_fpr"
4811   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4812         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4813   "TARGET_<MODE>_FPR"
4814   "@
4815    fneg %0,%1
4816    xsnegdp %x0,%x1"
4817   [(set_attr "type" "fp")
4818    (set_attr "fp_type" "fp_addsub_<Fs>")])
4820 (define_expand "add<mode>3"
4821   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4822         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4823                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4824   "TARGET_<MODE>_INSN"
4825   "")
4827 (define_insn "*add<mode>3_fpr"
4828   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4829         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4830                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4831   "TARGET_<MODE>_FPR"
4832   "@
4833    fadd<Ftrad> %0,%1,%2
4834    xsadd<Fvsx> %x0,%x1,%x2"
4835   [(set_attr "type" "fp")
4836    (set_attr "fp_type" "fp_addsub_<Fs>")])
4838 (define_expand "sub<mode>3"
4839   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4840         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4841                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4842   "TARGET_<MODE>_INSN"
4843   "")
4845 (define_insn "*sub<mode>3_fpr"
4846   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4847         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4848                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4849   "TARGET_<MODE>_FPR"
4850   "@
4851    fsub<Ftrad> %0,%1,%2
4852    xssub<Fvsx> %x0,%x1,%x2"
4853   [(set_attr "type" "fp")
4854    (set_attr "fp_type" "fp_addsub_<Fs>")])
4856 (define_expand "mul<mode>3"
4857   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4858         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4859                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4860   "TARGET_<MODE>_INSN"
4861   "")
4863 (define_insn "*mul<mode>3_fpr"
4864   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4865         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4866                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4867   "TARGET_<MODE>_FPR"
4868   "@
4869    fmul<Ftrad> %0,%1,%2
4870    xsmul<Fvsx> %x0,%x1,%x2"
4871   [(set_attr "type" "dmul")
4872    (set_attr "fp_type" "fp_mul_<Fs>")])
4874 (define_expand "div<mode>3"
4875   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4876         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4877                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4878   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4879   "")
4881 (define_insn "*div<mode>3_fpr"
4882   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4883         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4884                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4885   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4886   "@
4887    fdiv<Ftrad> %0,%1,%2
4888    xsdiv<Fvsx> %x0,%x1,%x2"
4889   [(set_attr "type" "<Fs>div")
4890    (set_attr "fp_type" "fp_div_<Fs>")])
4892 (define_insn "sqrt<mode>2"
4893   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4894         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4895   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4896    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4897   "@
4898    fsqrt<Ftrad> %0,%1
4899    xssqrt<Fvsx> %x0,%x1"
4900   [(set_attr "type" "<Fs>sqrt")
4901    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4903 ;; Floating point reciprocal approximation
4904 (define_insn "fre<Fs>"
4905   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4906         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
4907                      UNSPEC_FRES))]
4908   "TARGET_<FFRE>"
4909   "@
4910    fre<Ftrad> %0,%1
4911    xsre<Fvsx> %x0,%x1"
4912   [(set_attr "type" "fp")])
4914 (define_insn "*rsqrt<mode>2"
4915   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4916         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
4917                      UNSPEC_RSQRT))]
4918   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4919   "@
4920    frsqrte<Ftrad> %0,%1
4921    xsrsqrte<Fvsx> %x0,%x1"
4922   [(set_attr "type" "fp")])
4924 ;; Floating point comparisons
4925 (define_insn "*cmp<mode>_fpr"
4926   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4927         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4928                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4929   "TARGET_<MODE>_FPR"
4930   "@
4931    fcmpu %0,%1,%2
4932    xscmpudp %0,%x1,%x2"
4933   [(set_attr "type" "fpcompare")])
4935 ;; Floating point conversions
4936 (define_expand "extendsfdf2"
4937   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4938         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4939   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4940   "")
4942 (define_insn_and_split "*extendsfdf2_fpr"
4943   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wv")
4944         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z")))]
4945   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4946   "@
4947    #
4948    fmr %0,%1
4949    lfs%U1%X1 %0,%1
4950    #
4951    xxlor %x0,%x1,%x1
4952    lxsspx %x0,%y1"
4953   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4954   [(const_int 0)]
4956   emit_note (NOTE_INSN_DELETED);
4957   DONE;
4959   [(set_attr "type" "fp,fp,fpload,fp,vecsimple,fpload")])
4961 (define_expand "truncdfsf2"
4962   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4963         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4964   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4965   "")
4967 (define_insn "*truncdfsf2_fpr"
4968   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4969         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d")))]
4970   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4971   "frsp %0,%1"
4972   [(set_attr "type" "fp")])
4974 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4975 ;; builtins.c and optabs.c that are not correct for IBM long double
4976 ;; when little-endian.
4977 (define_expand "signbittf2"
4978   [(set (match_dup 2)
4979         (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
4980    (set (match_dup 3)
4981         (subreg:DI (match_dup 2) 0))
4982    (set (match_dup 4)
4983         (match_dup 5))
4984    (set (match_operand:SI 0 "gpc_reg_operand" "")
4985         (match_dup 6))]
4986   "!TARGET_IEEEQUAD
4987    && TARGET_HARD_FLOAT
4988    && (TARGET_FPRS || TARGET_E500_DOUBLE)
4989    && TARGET_LONG_DOUBLE_128"
4991   operands[2] = gen_reg_rtx (DFmode);
4992   operands[3] = gen_reg_rtx (DImode);
4993   if (TARGET_POWERPC64)
4994     {
4995       operands[4] = gen_reg_rtx (DImode);
4996       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4997       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4998                                     WORDS_BIG_ENDIAN ? 4 : 0);
4999     }
5000   else
5001     {
5002       operands[4] = gen_reg_rtx (SImode);
5003       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
5004                                     WORDS_BIG_ENDIAN ? 0 : 4);
5005       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
5006     }
5009 (define_expand "copysign<mode>3"
5010   [(set (match_dup 3)
5011         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
5012    (set (match_dup 4)
5013         (neg:SFDF (abs:SFDF (match_dup 1))))
5014    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
5015         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
5016                                (match_dup 5))
5017                          (match_dup 3)
5018                          (match_dup 4)))]
5019   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
5020    && ((TARGET_PPC_GFXOPT
5021         && !HONOR_NANS (<MODE>mode)
5022         && !HONOR_SIGNED_ZEROS (<MODE>mode))
5023        || TARGET_CMPB
5024        || VECTOR_UNIT_VSX_P (<MODE>mode))"
5026   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5027     {
5028       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5029                                              operands[2]));
5030       DONE;
5031     }
5033    operands[3] = gen_reg_rtx (<MODE>mode);
5034    operands[4] = gen_reg_rtx (<MODE>mode);
5035    operands[5] = CONST0_RTX (<MODE>mode);
5036   })
5038 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5039 ;; compiler from optimizing -0.0
5040 (define_insn "copysign<mode>3_fcpsgn"
5041   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5042         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5043                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5044                      UNSPEC_COPYSIGN))]
5045   "TARGET_<MODE>_FPR && TARGET_CMPB"
5046   "@
5047    fcpsgn %0,%2,%1
5048    xscpsgn<Fvsx> %x0,%x2,%x1"
5049   [(set_attr "type" "fp")])
5051 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5052 ;; fsel instruction and some auxiliary computations.  Then we just have a
5053 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5054 ;; combine.
5055 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5056 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5057 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
5058 ;; define_splits to make them if made by combine.  On VSX machines we have the
5059 ;; min/max instructions.
5061 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5062 ;; to allow either DF/SF to use only traditional registers.
5064 (define_expand "smax<mode>3"
5065   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5066         (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
5067                                (match_operand:SFDF 2 "gpc_reg_operand" ""))
5068                            (match_dup 1)
5069                            (match_dup 2)))]
5070   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
5072   rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
5073   DONE;
5076 (define_insn "*smax<mode>3_vsx"
5077   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5078         (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
5079                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
5080   "TARGET_<MODE>_FPR && TARGET_VSX"
5081   "xsmaxdp %x0,%x1,%x2"
5082   [(set_attr "type" "fp")])
5084 (define_expand "smin<mode>3"
5085   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5086         (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
5087                                (match_operand:SFDF 2 "gpc_reg_operand" ""))
5088                            (match_dup 2)
5089                            (match_dup 1)))]
5090   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
5092   rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
5093   DONE;
5096 (define_insn "*smin<mode>3_vsx"
5097   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5098         (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
5099                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
5100   "TARGET_<MODE>_FPR && TARGET_VSX"
5101   "xsmindp %x0,%x1,%x2"
5102   [(set_attr "type" "fp")])
5104 (define_split
5105   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5106         (match_operator:SFDF 3 "min_max_operator"
5107          [(match_operand:SFDF 1 "gpc_reg_operand" "")
5108           (match_operand:SFDF 2 "gpc_reg_operand" "")]))]
5109   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math
5110    && !TARGET_VSX"
5111   [(const_int 0)]
5113   rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1],
5114                       operands[2]);
5115   DONE;
5118 (define_split
5119   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5120         (match_operator:SF 3 "min_max_operator"
5121          [(match_operand:SF 1 "gpc_reg_operand" "")
5122           (match_operand:SF 2 "gpc_reg_operand" "")]))]
5123   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
5124    && TARGET_SINGLE_FLOAT && !flag_trapping_math"
5125   [(const_int 0)]
5126   "
5127 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
5128                       operands[1], operands[2]);
5129   DONE;
5132 (define_expand "mov<mode>cc"
5133    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
5134          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
5135                            (match_operand:GPR 2 "gpc_reg_operand" "")
5136                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
5137   "TARGET_ISEL<sel>"
5138   "
5140   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5141     DONE;
5142   else
5143     FAIL;
5146 ;; We use the BASE_REGS for the isel input operands because, if rA is
5147 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
5148 ;; because we may switch the operands and rB may end up being rA.
5150 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
5151 ;; leave out the mode in operand 4 and use one pattern, but reload can
5152 ;; change the mode underneath our feet and then gets confused trying
5153 ;; to reload the value.
5154 (define_insn "isel_signed_<mode>"
5155   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5156         (if_then_else:GPR
5157          (match_operator 1 "scc_comparison_operator"
5158                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
5159                           (const_int 0)])
5160          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
5161          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5162   "TARGET_ISEL<sel>"
5163   "*
5164 { return output_isel (operands); }"
5165   [(set_attr "type" "isel")
5166    (set_attr "length" "4")])
5168 (define_insn "isel_unsigned_<mode>"
5169   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5170         (if_then_else:GPR
5171          (match_operator 1 "scc_comparison_operator"
5172                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5173                           (const_int 0)])
5174          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
5175          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5176   "TARGET_ISEL<sel>"
5177   "*
5178 { return output_isel (operands); }"
5179   [(set_attr "type" "isel")
5180    (set_attr "length" "4")])
5182 ;; These patterns can be useful for combine; they let combine know that
5183 ;; isel can handle reversed comparisons so long as the operands are
5184 ;; registers.
5186 (define_insn "*isel_reversed_signed_<mode>"
5187   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5188         (if_then_else:GPR
5189          (match_operator 1 "scc_rev_comparison_operator"
5190                          [(match_operand:CC 4 "cc_reg_operand" "y")
5191                           (const_int 0)])
5192          (match_operand:GPR 2 "gpc_reg_operand" "b")
5193          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
5194   "TARGET_ISEL<sel>"
5195   "*
5196 { return output_isel (operands); }"
5197   [(set_attr "type" "isel")
5198    (set_attr "length" "4")])
5200 (define_insn "*isel_reversed_unsigned_<mode>"
5201   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5202         (if_then_else:GPR
5203          (match_operator 1 "scc_rev_comparison_operator"
5204                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
5205                           (const_int 0)])
5206          (match_operand:GPR 2 "gpc_reg_operand" "b")
5207          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
5208   "TARGET_ISEL<sel>"
5209   "*
5210 { return output_isel (operands); }"
5211   [(set_attr "type" "isel")
5212    (set_attr "length" "4")])
5214 (define_expand "movsfcc"
5215    [(set (match_operand:SF 0 "gpc_reg_operand" "")
5216          (if_then_else:SF (match_operand 1 "comparison_operator" "")
5217                           (match_operand:SF 2 "gpc_reg_operand" "")
5218                           (match_operand:SF 3 "gpc_reg_operand" "")))]
5219   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
5220   "
5222   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5223     DONE;
5224   else
5225     FAIL;
5228 (define_insn "*fselsfsf4"
5229   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5230         (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
5231                              (match_operand:SF 4 "zero_fp_constant" "F"))
5232                          (match_operand:SF 2 "gpc_reg_operand" "f")
5233                          (match_operand:SF 3 "gpc_reg_operand" "f")))]
5234   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
5235   "fsel %0,%1,%2,%3"
5236   [(set_attr "type" "fp")])
5238 (define_insn "*fseldfsf4"
5239   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5240         (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
5241                              (match_operand:DF 4 "zero_fp_constant" "F"))
5242                          (match_operand:SF 2 "gpc_reg_operand" "f")
5243                          (match_operand:SF 3 "gpc_reg_operand" "f")))]
5244   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
5245   "fsel %0,%1,%2,%3"
5246   [(set_attr "type" "fp")])
5248 ;; The conditional move instructions allow us to perform max and min
5249 ;; operations even when
5251 (define_split
5252   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5253         (match_operator:DF 3 "min_max_operator"
5254          [(match_operand:DF 1 "gpc_reg_operand" "")
5255           (match_operand:DF 2 "gpc_reg_operand" "")]))]
5256   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
5257    && !flag_trapping_math"
5258   [(const_int 0)]
5259   "
5260 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
5261                       operands[1], operands[2]);
5262   DONE;
5265 (define_expand "movdfcc"
5266    [(set (match_operand:DF 0 "gpc_reg_operand" "")
5267          (if_then_else:DF (match_operand 1 "comparison_operator" "")
5268                           (match_operand:DF 2 "gpc_reg_operand" "")
5269                           (match_operand:DF 3 "gpc_reg_operand" "")))]
5270   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5271   "
5273   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5274     DONE;
5275   else
5276     FAIL;
5279 (define_insn "*fseldfdf4"
5280   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5281         (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
5282                              (match_operand:DF 4 "zero_fp_constant" "F"))
5283                          (match_operand:DF 2 "gpc_reg_operand" "d")
5284                          (match_operand:DF 3 "gpc_reg_operand" "d")))]
5285   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5286   "fsel %0,%1,%2,%3"
5287   [(set_attr "type" "fp")])
5289 (define_insn "*fselsfdf4"
5290   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5291         (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
5292                              (match_operand:SF 4 "zero_fp_constant" "F"))
5293                          (match_operand:DF 2 "gpc_reg_operand" "d")
5294                          (match_operand:DF 3 "gpc_reg_operand" "d")))]
5295   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
5296   "fsel %0,%1,%2,%3"
5297   [(set_attr "type" "fp")])
5299 ;; Conversions to and from floating-point.
5301 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5302 ; don't want to support putting SImode in FPR registers.
5303 (define_insn "lfiwax"
5304   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
5305         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
5306                    UNSPEC_LFIWAX))]
5307   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5308   "@
5309    lfiwax %0,%y1
5310    lxsiwax %x0,%y1
5311    mtvsrwa %x0,%1"
5312   [(set_attr "type" "fpload,fpload,mffgpr")])
5314 ; This split must be run before register allocation because it allocates the
5315 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5316 ; it earlier to allow for the combiner to merge insns together where it might
5317 ; not be needed and also in case the insns are deleted as dead code.
5319 (define_insn_and_split "floatsi<mode>2_lfiwax"
5320   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5321         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5322    (clobber (match_scratch:DI 2 "=d"))]
5323   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5324    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5325   "#"
5326   ""
5327   [(pc)]
5328   "
5330   rtx dest = operands[0];
5331   rtx src = operands[1];
5332   rtx tmp;
5334   if (!MEM_P (src) && TARGET_POWERPC64
5335       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5336     tmp = convert_to_mode (DImode, src, false);
5337   else
5338     {
5339       tmp = operands[2];
5340       if (GET_CODE (tmp) == SCRATCH)
5341         tmp = gen_reg_rtx (DImode);
5342       if (MEM_P (src))
5343         {
5344           src = rs6000_address_for_fpconvert (src);
5345           emit_insn (gen_lfiwax (tmp, src));
5346         }
5347       else
5348         {
5349           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5350           emit_move_insn (stack, src);
5351           emit_insn (gen_lfiwax (tmp, stack));
5352         }
5353     }
5354   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5355   DONE;
5357   [(set_attr "length" "12")
5358    (set_attr "type" "fpload")])
5360 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5361   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<rreg2>")
5362         (float:SFDF
5363          (sign_extend:DI
5364           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5365    (clobber (match_scratch:DI 2 "=0,d"))]
5366   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5367    && <SI_CONVERT_FP>"
5368   "#"
5369   ""
5370   [(pc)]
5371   "
5373   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5374   if (GET_CODE (operands[2]) == SCRATCH)
5375     operands[2] = gen_reg_rtx (DImode);
5376   emit_insn (gen_lfiwax (operands[2], operands[1]));
5377   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5378   DONE;
5380   [(set_attr "length" "8")
5381    (set_attr "type" "fpload")])
5383 (define_insn "lfiwzx"
5384   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
5385         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
5386                    UNSPEC_LFIWZX))]
5387   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5388   "@
5389    lfiwzx %0,%y1
5390    lxsiwzx %x0,%y1
5391    mtvsrwz %x0,%1"
5392   [(set_attr "type" "fpload,fpload,mftgpr")])
5394 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5395   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5396         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5397    (clobber (match_scratch:DI 2 "=d"))]
5398   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5399    && <SI_CONVERT_FP>"
5400   "#"
5401   ""
5402   [(pc)]
5403   "
5405   rtx dest = operands[0];
5406   rtx src = operands[1];
5407   rtx tmp;
5409   if (!MEM_P (src) && TARGET_POWERPC64
5410       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5411     tmp = convert_to_mode (DImode, src, true);
5412   else
5413     {
5414       tmp = operands[2];
5415       if (GET_CODE (tmp) == SCRATCH)
5416         tmp = gen_reg_rtx (DImode);
5417       if (MEM_P (src))
5418         {
5419           src = rs6000_address_for_fpconvert (src);
5420           emit_insn (gen_lfiwzx (tmp, src));
5421         }
5422       else
5423         {
5424           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5425           emit_move_insn (stack, src);
5426           emit_insn (gen_lfiwzx (tmp, stack));
5427         }
5428     }
5429   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5430   DONE;
5432   [(set_attr "length" "12")
5433    (set_attr "type" "fpload")])
5435 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5436   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<rreg2>")
5437         (unsigned_float:SFDF
5438          (zero_extend:DI
5439           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5440    (clobber (match_scratch:DI 2 "=0,d"))]
5441   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5442    && <SI_CONVERT_FP>"
5443   "#"
5444   ""
5445   [(pc)]
5446   "
5448   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5449   if (GET_CODE (operands[2]) == SCRATCH)
5450     operands[2] = gen_reg_rtx (DImode);
5451   emit_insn (gen_lfiwzx (operands[2], operands[1]));
5452   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5453   DONE;
5455   [(set_attr "length" "8")
5456    (set_attr "type" "fpload")])
5458 ; For each of these conversions, there is a define_expand, a define_insn
5459 ; with a '#' template, and a define_split (with C code).  The idea is
5460 ; to allow constant folding with the template of the define_insn,
5461 ; then to have the insns split later (between sched1 and final).
5463 (define_expand "floatsidf2"
5464   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5465                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5466               (use (match_dup 2))
5467               (use (match_dup 3))
5468               (clobber (match_dup 4))
5469               (clobber (match_dup 5))
5470               (clobber (match_dup 6))])]
5471   "TARGET_HARD_FLOAT 
5472    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5473   "
5475   if (TARGET_E500_DOUBLE)
5476     {
5477       if (!REG_P (operands[1]))
5478         operands[1] = force_reg (SImode, operands[1]);
5479       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5480       DONE;
5481     }
5482   else if (TARGET_LFIWAX && TARGET_FCFID)
5483     {
5484       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5485       DONE;
5486     }
5487   else if (TARGET_FCFID)
5488     {
5489       rtx dreg = operands[1];
5490       if (!REG_P (dreg))
5491         dreg = force_reg (SImode, dreg);
5492       dreg = convert_to_mode (DImode, dreg, false);
5493       emit_insn (gen_floatdidf2 (operands[0], dreg));
5494       DONE;
5495     }
5497   if (!REG_P (operands[1]))
5498     operands[1] = force_reg (SImode, operands[1]);
5499   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5500   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5501   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5502   operands[5] = gen_reg_rtx (DFmode);
5503   operands[6] = gen_reg_rtx (SImode);
5506 (define_insn_and_split "*floatsidf2_internal"
5507   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5508         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5509    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5510    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5511    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5512    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5513    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5514   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5515   "#"
5516   ""
5517   [(pc)]
5518   "
5520   rtx lowword, highword;
5521   gcc_assert (MEM_P (operands[4]));
5522   highword = adjust_address (operands[4], SImode, 0);
5523   lowword = adjust_address (operands[4], SImode, 4);
5524   if (! WORDS_BIG_ENDIAN)
5525     {
5526       rtx tmp;
5527       tmp = highword; highword = lowword; lowword = tmp;
5528     }
5530   emit_insn (gen_xorsi3 (operands[6], operands[1],
5531                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5532   emit_move_insn (lowword, operands[6]);
5533   emit_move_insn (highword, operands[2]);
5534   emit_move_insn (operands[5], operands[4]);
5535   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5536   DONE;
5538   [(set_attr "length" "24")
5539    (set_attr "type" "fp")])
5541 ;; If we don't have a direct conversion to single precision, don't enable this
5542 ;; conversion for 32-bit without fast math, because we don't have the insn to
5543 ;; generate the fixup swizzle to avoid double rounding problems.
5544 (define_expand "floatunssisf2"
5545   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5546         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5547   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5548    && (!TARGET_FPRS
5549        || (TARGET_FPRS
5550            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5551                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5552                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5553   "
5555   if (!TARGET_FPRS)
5556     {
5557       if (!REG_P (operands[1]))
5558         operands[1] = force_reg (SImode, operands[1]);
5559     }
5560   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5561     {
5562       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5563       DONE;
5564     }
5565   else
5566     {
5567       rtx dreg = operands[1];
5568       if (!REG_P (dreg))
5569         dreg = force_reg (SImode, dreg);
5570       dreg = convert_to_mode (DImode, dreg, true);
5571       emit_insn (gen_floatdisf2 (operands[0], dreg));
5572       DONE;
5573     }
5576 (define_expand "floatunssidf2"
5577   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5578                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5579               (use (match_dup 2))
5580               (use (match_dup 3))
5581               (clobber (match_dup 4))
5582               (clobber (match_dup 5))])]
5583   "TARGET_HARD_FLOAT
5584    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5585   "
5587   if (TARGET_E500_DOUBLE)
5588     {
5589       if (!REG_P (operands[1]))
5590         operands[1] = force_reg (SImode, operands[1]);
5591       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5592       DONE;
5593     }
5594   else if (TARGET_LFIWZX && TARGET_FCFID)
5595     {
5596       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5597       DONE;
5598     }
5599   else if (TARGET_FCFID)
5600     {
5601       rtx dreg = operands[1];
5602       if (!REG_P (dreg))
5603         dreg = force_reg (SImode, dreg);
5604       dreg = convert_to_mode (DImode, dreg, true);
5605       emit_insn (gen_floatdidf2 (operands[0], dreg));
5606       DONE;
5607     }
5609   if (!REG_P (operands[1]))
5610     operands[1] = force_reg (SImode, operands[1]);
5611   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5612   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5613   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5614   operands[5] = gen_reg_rtx (DFmode);
5617 (define_insn_and_split "*floatunssidf2_internal"
5618   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5619         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5620    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5621    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5622    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5623    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5624   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5625    && !(TARGET_FCFID && TARGET_POWERPC64)"
5626   "#"
5627   ""
5628   [(pc)]
5629   "
5631   rtx lowword, highword;
5632   gcc_assert (MEM_P (operands[4]));
5633   highword = adjust_address (operands[4], SImode, 0);
5634   lowword = adjust_address (operands[4], SImode, 4);
5635   if (! WORDS_BIG_ENDIAN)
5636     {
5637       rtx tmp;
5638       tmp = highword; highword = lowword; lowword = tmp;
5639     }
5641   emit_move_insn (lowword, operands[1]);
5642   emit_move_insn (highword, operands[2]);
5643   emit_move_insn (operands[5], operands[4]);
5644   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5645   DONE;
5647   [(set_attr "length" "20")
5648    (set_attr "type" "fp")])
5650 (define_expand "fix_trunc<mode>si2"
5651   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5652         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5653   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5654   "
5656   if (!<E500_CONVERT>)
5657     {
5658       rtx tmp, stack;
5660       if (TARGET_STFIWX)
5661         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5662       else
5663         {
5664           tmp = gen_reg_rtx (DImode);
5665           stack = rs6000_allocate_stack_temp (DImode, true, false);
5666           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5667                                                       tmp, stack));
5668         }
5669       DONE;
5670     }
5673 ; Like the convert to float patterns, this insn must be split before
5674 ; register allocation so that it can allocate the memory slot if it
5675 ; needed
5676 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5677   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5678         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5679    (clobber (match_scratch:DI 2 "=d"))]
5680   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5681    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5682    && TARGET_STFIWX && can_create_pseudo_p ()"
5683   "#"
5684   ""
5685   [(pc)]
5687   rtx dest = operands[0];
5688   rtx src = operands[1];
5689   rtx tmp = operands[2];
5691   if (GET_CODE (tmp) == SCRATCH)
5692     tmp = gen_reg_rtx (DImode);
5694   emit_insn (gen_fctiwz_<mode> (tmp, src));
5695   if (MEM_P (dest))
5696     {
5697       dest = rs6000_address_for_fpconvert (dest);
5698       emit_insn (gen_stfiwx (dest, tmp));
5699       DONE;
5700     }
5701   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5702     {
5703       dest = gen_lowpart (DImode, dest);
5704       emit_move_insn (dest, tmp);
5705       DONE;
5706     }
5707   else
5708     {
5709       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5710       emit_insn (gen_stfiwx (stack, tmp));
5711       emit_move_insn (dest, stack);
5712       DONE;
5713     }
5715   [(set_attr "length" "12")
5716    (set_attr "type" "fp")])
5718 (define_insn_and_split "fix_trunc<mode>si2_internal"
5719   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5720         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5721    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5722    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5723   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5724   "#"
5725   ""
5726   [(pc)]
5727   "
5729   rtx lowword;
5730   gcc_assert (MEM_P (operands[3]));
5731   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5733   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5734   emit_move_insn (operands[3], operands[2]);
5735   emit_move_insn (operands[0], lowword);
5736   DONE;
5738   [(set_attr "length" "16")
5739    (set_attr "type" "fp")])
5741 (define_expand "fix_trunc<mode>di2"
5742   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5743         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5744   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5745    && TARGET_FCFID"
5746   "")
5748 (define_insn "*fix_trunc<mode>di2_fctidz"
5749   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5750         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))]
5751   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5752     && TARGET_FCFID && !VECTOR_UNIT_VSX_P (<MODE>mode)"
5753   "fctidz %0,%1"
5754   [(set_attr "type" "fp")])
5756 (define_expand "fixuns_trunc<mode>si2"
5757   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5758         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5759   "TARGET_HARD_FLOAT
5760    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5761        || <E500_CONVERT>)"
5762   "
5764   if (!<E500_CONVERT>)
5765     {
5766       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5767       DONE;
5768     }
5771 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5772   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5773         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5774    (clobber (match_scratch:DI 2 "=d"))]
5775   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5776    && TARGET_STFIWX && can_create_pseudo_p ()"
5777   "#"
5778   ""
5779   [(pc)]
5781   rtx dest = operands[0];
5782   rtx src = operands[1];
5783   rtx tmp = operands[2];
5785   if (GET_CODE (tmp) == SCRATCH)
5786     tmp = gen_reg_rtx (DImode);
5788   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5789   if (MEM_P (dest))
5790     {
5791       dest = rs6000_address_for_fpconvert (dest);
5792       emit_insn (gen_stfiwx (dest, tmp));
5793       DONE;
5794     }
5795   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5796     {
5797       dest = gen_lowpart (DImode, dest);
5798       emit_move_insn (dest, tmp);
5799       DONE;
5800     }
5801   else
5802     {
5803       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5804       emit_insn (gen_stfiwx (stack, tmp));
5805       emit_move_insn (dest, stack);
5806       DONE;
5807     }
5809   [(set_attr "length" "12")
5810    (set_attr "type" "fp")])
5812 (define_expand "fixuns_trunc<mode>di2"
5813   [(set (match_operand:DI 0 "register_operand" "")
5814         (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5815   "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5816   "")
5818 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5819   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5820         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))]
5821   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5822     && TARGET_FCTIDUZ && !VECTOR_UNIT_VSX_P (<MODE>mode)"
5823   "fctiduz %0,%1"
5824   [(set_attr "type" "fp")])
5826 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5827 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5828 ; because the first makes it clear that operand 0 is not live
5829 ; before the instruction.
5830 (define_insn "fctiwz_<mode>"
5831   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5832         (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))]
5833                    UNSPEC_FCTIWZ))]
5834   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5835   "fctiwz %0,%1"
5836   [(set_attr "type" "fp")])
5838 (define_insn "fctiwuz_<mode>"
5839   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5840         (unspec:DI [(unsigned_fix:SI
5841                      (match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>"))]
5842                    UNSPEC_FCTIWUZ))]
5843   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5844   "fctiwuz %0,%1"
5845   [(set_attr "type" "fp")])
5847 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5848 ;; since the friz instruction does not truncate the value if the floating
5849 ;; point value is < LONG_MIN or > LONG_MAX.
5850 (define_insn "*friz"
5851   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5852         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d"))))]
5853   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5854    && !VECTOR_UNIT_VSX_P (DFmode) && flag_unsafe_math_optimizations
5855    && !flag_trapping_math && TARGET_FRIZ"
5856   "friz %0,%1"
5857   [(set_attr "type" "fp")])
5859 ;; Since FCTIWZ doesn't sign extend the upper bits, we have to do a store and a
5860 ;; load to properly sign extend the value, but at least doing a store, load
5861 ;; into a GPR to sign extend, a store from the GPR and a load back into the FPR
5862 ;; if we have 32-bit memory ops
5863 (define_insn_and_split "*round32<mode>2_fprs"
5864   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5865         (float:SFDF
5866          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5867    (clobber (match_scratch:DI 2 "=d"))
5868    (clobber (match_scratch:DI 3 "=d"))]
5869   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5870    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5871    && can_create_pseudo_p ()"
5872   "#"
5873   ""
5874   [(pc)]
5876   rtx dest = operands[0];
5877   rtx src = operands[1];
5878   rtx tmp1 = operands[2];
5879   rtx tmp2 = operands[3];
5880   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5882   if (GET_CODE (tmp1) == SCRATCH)
5883     tmp1 = gen_reg_rtx (DImode);
5884   if (GET_CODE (tmp2) == SCRATCH)
5885     tmp2 = gen_reg_rtx (DImode);
5887   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5888   emit_insn (gen_stfiwx (stack, tmp1));
5889   emit_insn (gen_lfiwax (tmp2, stack));
5890   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5891   DONE;
5893   [(set_attr "type" "fpload")
5894    (set_attr "length" "16")])
5896 (define_insn_and_split "*roundu32<mode>2_fprs"
5897   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5898         (unsigned_float:SFDF
5899          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5900    (clobber (match_scratch:DI 2 "=d"))
5901    (clobber (match_scratch:DI 3 "=d"))]
5902   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5903    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU
5904    && can_create_pseudo_p ()"
5905   "#"
5906   ""
5907   [(pc)]
5909   rtx dest = operands[0];
5910   rtx src = operands[1];
5911   rtx tmp1 = operands[2];
5912   rtx tmp2 = operands[3];
5913   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5915   if (GET_CODE (tmp1) == SCRATCH)
5916     tmp1 = gen_reg_rtx (DImode);
5917   if (GET_CODE (tmp2) == SCRATCH)
5918     tmp2 = gen_reg_rtx (DImode);
5920   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5921   emit_insn (gen_stfiwx (stack, tmp1));
5922   emit_insn (gen_lfiwzx (tmp2, stack));
5923   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5924   DONE;
5926   [(set_attr "type" "fpload")
5927    (set_attr "length" "16")])
5929 ;; No VSX equivalent to fctid
5930 (define_insn "lrint<mode>di2"
5931   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5932         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5933                    UNSPEC_FCTID))]
5934   "TARGET_<MODE>_FPR && TARGET_FPRND"
5935   "fctid %0,%1"
5936   [(set_attr "type" "fp")])
5938 (define_insn "btrunc<mode>2"
5939   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5940         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5941                      UNSPEC_FRIZ))]
5942   "TARGET_<MODE>_FPR && TARGET_FPRND"
5943   "@
5944    friz %0,%1
5945    xsrdpiz %x0,%x1"
5946   [(set_attr "type" "fp")
5947    (set_attr "fp_type" "fp_addsub_<Fs>")])
5949 (define_insn "ceil<mode>2"
5950   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5951         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5952                      UNSPEC_FRIP))]
5953   "TARGET_<MODE>_FPR && TARGET_FPRND"
5954   "@
5955    frip %0,%1
5956    xsrdpip %x0,%x1"
5957   [(set_attr "type" "fp")
5958    (set_attr "fp_type" "fp_addsub_<Fs>")])
5960 (define_insn "floor<mode>2"
5961   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5962         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5963                      UNSPEC_FRIM))]
5964   "TARGET_<MODE>_FPR && TARGET_FPRND"
5965   "@
5966    frim %0,%1
5967    xsrdpim %x0,%x1"
5968   [(set_attr "type" "fp")
5969    (set_attr "fp_type" "fp_addsub_<Fs>")])
5971 ;; No VSX equivalent to frin
5972 (define_insn "round<mode>2"
5973   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5974         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5975                      UNSPEC_FRIN))]
5976   "TARGET_<MODE>_FPR && TARGET_FPRND"
5977   "frin %0,%1"
5978   [(set_attr "type" "fp")
5979    (set_attr "fp_type" "fp_addsub_<Fs>")])
5981 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5982 (define_insn "stfiwx"
5983   [(set (match_operand:SI 0 "memory_operand" "=Z")
5984         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
5985                    UNSPEC_STFIWX))]
5986   "TARGET_PPC_GFXOPT"
5987   "stfiwx %1,%y0"
5988   [(set_attr "type" "fpstore")])
5990 ;; If we don't have a direct conversion to single precision, don't enable this
5991 ;; conversion for 32-bit without fast math, because we don't have the insn to
5992 ;; generate the fixup swizzle to avoid double rounding problems.
5993 (define_expand "floatsisf2"
5994   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5995         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5996   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5997    && (!TARGET_FPRS
5998        || (TARGET_FPRS
5999            && ((TARGET_FCFIDS && TARGET_LFIWAX)
6000                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6001                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
6002   "
6004   if (!TARGET_FPRS)
6005     {
6006       if (!REG_P (operands[1]))
6007         operands[1] = force_reg (SImode, operands[1]);
6008     }
6009   else if (TARGET_FCFIDS && TARGET_LFIWAX)
6010     {
6011       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6012       DONE;
6013     }
6014   else if (TARGET_FCFID && TARGET_LFIWAX)
6015     {
6016       rtx dfreg = gen_reg_rtx (DFmode);
6017       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6018       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6019       DONE;
6020     }
6021   else
6022     {
6023       rtx dreg = operands[1];
6024       if (!REG_P (dreg))
6025         dreg = force_reg (SImode, dreg);
6026       dreg = convert_to_mode (DImode, dreg, false);
6027       emit_insn (gen_floatdisf2 (operands[0], dreg));
6028       DONE;
6029     }
6032 (define_expand "floatdidf2"
6033   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6034         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6035   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6036   "")
6038 (define_insn "*floatdidf2_fpr"
6039   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6040         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d")))]
6041   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
6042    && !VECTOR_UNIT_VSX_P (DFmode)"
6043   "fcfid %0,%1"
6044   [(set_attr "type" "fp")])
6046 ; Allow the combiner to merge source memory operands to the conversion so that
6047 ; the optimizer/register allocator doesn't try to load the value too early in a
6048 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6049 ; hit.  We will split after reload to avoid the trip through the GPRs
6051 (define_insn_and_split "*floatdidf2_mem"
6052   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6053         (float:DF (match_operand:DI 1 "memory_operand" "m")))
6054    (clobber (match_scratch:DI 2 "=d"))]
6055   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6056   "#"
6057   "&& reload_completed"
6058   [(set (match_dup 2) (match_dup 1))
6059    (set (match_dup 0) (float:DF (match_dup 2)))]
6060   ""
6061   [(set_attr "length" "8")
6062    (set_attr "type" "fpload")])
6064 (define_expand "floatunsdidf2"
6065   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6066         (unsigned_float:DF
6067          (match_operand:DI 1 "gpc_reg_operand" "")))]
6068   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6069   "")
6071 (define_insn "*floatunsdidf2_fcfidu"
6072   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6073         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d")))]
6074   "TARGET_HARD_FLOAT && TARGET_FCFIDU && !VECTOR_UNIT_VSX_P (DFmode)"
6075   "fcfidu %0,%1"
6076   [(set_attr "type" "fp")
6077    (set_attr "length" "4")])
6079 (define_insn_and_split "*floatunsdidf2_mem"
6080   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6081         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m")))
6082    (clobber (match_scratch:DI 2 "=d"))]
6083   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6084   "#"
6085   "&& reload_completed"
6086   [(set (match_dup 2) (match_dup 1))
6087    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6088   ""
6089   [(set_attr "length" "8")
6090    (set_attr "type" "fpload")])
6092 (define_expand "floatdisf2"
6093   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6094         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6095   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6096    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6097   "
6099   if (!TARGET_FCFIDS)
6100     {
6101       rtx val = operands[1];
6102       if (!flag_unsafe_math_optimizations)
6103         {
6104           rtx label = gen_label_rtx ();
6105           val = gen_reg_rtx (DImode);
6106           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6107           emit_label (label);
6108         }
6109       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6110       DONE;
6111     }
6114 (define_insn "floatdisf2_fcfids"
6115   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6116         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))]
6117   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6118    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6119   "fcfids %0,%1"
6120   [(set_attr "type" "fp")])
6122 (define_insn_and_split "*floatdisf2_mem"
6123   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6124         (float:SF (match_operand:DI 1 "memory_operand" "m")))
6125    (clobber (match_scratch:DI 2 "=f"))]
6126   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6127    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6128   "#"
6129   "&& reload_completed"
6130   [(pc)]
6131   "
6133   emit_move_insn (operands[2], operands[1]);
6134   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6135   DONE;
6137   [(set_attr "length" "8")])
6139 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6140 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6141 ;; from double rounding.
6142 ;; Instead of creating a new cpu type for two FP operations, just use fp
6143 (define_insn_and_split "floatdisf2_internal1"
6144   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6145         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6146    (clobber (match_scratch:DF 2 "=d"))]
6147   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
6148   "#"
6149   "&& reload_completed"
6150   [(set (match_dup 2)
6151         (float:DF (match_dup 1)))
6152    (set (match_dup 0)
6153         (float_truncate:SF (match_dup 2)))]
6154   ""
6155   [(set_attr "length" "8")
6156    (set_attr "type" "fp")])
6158 ;; Twiddles bits to avoid double rounding.
6159 ;; Bits that might be truncated when converting to DFmode are replaced
6160 ;; by a bit that won't be lost at that stage, but is below the SFmode
6161 ;; rounding position.
6162 (define_expand "floatdisf2_internal2"
6163   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6164                                               (const_int 53)))
6165               (clobber (reg:DI CA_REGNO))])
6166    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6167                                            (const_int 2047)))
6168    (set (match_dup 3) (plus:DI (match_dup 3)
6169                                (const_int 1)))
6170    (set (match_dup 0) (plus:DI (match_dup 0)
6171                                (const_int 2047)))
6172    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6173                                      (const_int 2)))
6174    (set (match_dup 0) (ior:DI (match_dup 0)
6175                               (match_dup 1)))
6176    (set (match_dup 0) (and:DI (match_dup 0)
6177                               (const_int -2048)))
6178    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6179                            (label_ref (match_operand:DI 2 "" ""))
6180                            (pc)))
6181    (set (match_dup 0) (match_dup 1))]
6182   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
6183   "
6185   operands[3] = gen_reg_rtx (DImode);
6186   operands[4] = gen_reg_rtx (CCUNSmode);
6189 (define_expand "floatunsdisf2"
6190   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6191         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6192   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6193    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6194   "")
6196 (define_insn "floatunsdisf2_fcfidus"
6197   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6198         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))]
6199   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6200    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6201   "fcfidus %0,%1"
6202   [(set_attr "type" "fp")])
6204 (define_insn_and_split "*floatunsdisf2_mem"
6205   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6206         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m")))
6207    (clobber (match_scratch:DI 2 "=f"))]
6208   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6209    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6210   "#"
6211   "&& reload_completed"
6212   [(pc)]
6213   "
6215   emit_move_insn (operands[2], operands[1]);
6216   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6217   DONE;
6219   [(set_attr "length" "8")
6220    (set_attr "type" "fpload")])
6222 ;; Define the TImode operations that can be done in a small number
6223 ;; of instructions.  The & constraints are to prevent the register
6224 ;; allocator from allocating registers that overlap with the inputs
6225 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6226 ;; also allow for the output being the same as one of the inputs.
6228 (define_insn "addti3"
6229   [(set (match_operand:TI 0 "gpc_reg_operand" "=&r,&r,r,r")
6230         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "%r,r,0,0")
6231                  (match_operand:TI 2 "reg_or_short_operand" "r,I,r,I")))]
6232   "TARGET_64BIT"
6234   if (WORDS_BIG_ENDIAN)
6235     return (GET_CODE (operands[2])) != CONST_INT
6236             ? \"addc %L0,%L1,%L2\;adde %0,%1,%2\"
6237             : \"addic %L0,%L1,%2\;add%G2e %0,%1\";
6238   else
6239     return (GET_CODE (operands[2])) != CONST_INT
6240             ? \"addc %0,%1,%2\;adde %L0,%L1,%L2\"
6241             : \"addic %0,%1,%2\;add%G2e %L0,%L1\";
6243   [(set_attr "type" "two")
6244    (set_attr "length" "8")])
6246 (define_insn "subti3"
6247   [(set (match_operand:TI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
6248         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "r,I,0,r,I")
6249                   (match_operand:TI 2 "gpc_reg_operand" "r,r,r,0,0")))]
6250   "TARGET_64BIT"
6252   if (WORDS_BIG_ENDIAN)
6253     return (GET_CODE (operands[1]) != CONST_INT)
6254             ? \"subfc %L0,%L2,%L1\;subfe %0,%2,%1\"
6255             : \"subfic %L0,%L2,%1\;subf%G1e %0,%2\";
6256   else
6257     return (GET_CODE (operands[1]) != CONST_INT)
6258             ? \"subfc %0,%2,%1\;subfe %L0,%L2,%L1\"
6259             : \"subfic %0,%2,%1\;subf%G1e %L0,%L2\";
6261   [(set_attr "type" "two")
6262    (set_attr "length" "8")])
6265 ;; Define the DImode operations that can be done in a small number
6266 ;; of instructions.  The & constraints are to prevent the register
6267 ;; allocator from allocating registers that overlap with the inputs
6268 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6269 ;; also allow for the output being the same as one of the inputs.
6271 (define_insn "*adddi3_noppc64"
6272   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
6273         (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
6274                  (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
6275   "! TARGET_POWERPC64"
6276   "*
6278   if (WORDS_BIG_ENDIAN)
6279     return (GET_CODE (operands[2])) != CONST_INT
6280             ? \"addc %L0,%L1,%L2\;adde %0,%1,%2\"
6281             : \"addic %L0,%L1,%2\;add%G2e %0,%1\";
6282   else
6283     return (GET_CODE (operands[2])) != CONST_INT
6284             ? \"addc %0,%1,%2\;adde %L0,%L1,%L2\"
6285             : \"addic %0,%1,%2\;add%G2e %L0,%L1\";
6287   [(set_attr "type" "two")
6288    (set_attr "length" "8")])
6290 (define_insn "*subdi3_noppc64"
6291   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
6292         (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I")
6293                   (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))]
6294   "! TARGET_POWERPC64"
6295   "*
6297   if (WORDS_BIG_ENDIAN)
6298     return (GET_CODE (operands[1]) != CONST_INT)
6299             ? \"subfc %L0,%L2,%L1\;subfe %0,%2,%1\"
6300             : \"subfic %L0,%L2,%1\;subf%G1e %0,%2\";
6301   else
6302     return (GET_CODE (operands[1]) != CONST_INT)
6303             ? \"subfc %0,%2,%1\;subfe %L0,%L2,%L1\"
6304             : \"subfic %0,%2,%1\;subf%G1e %L0,%L2\";
6306   [(set_attr "type" "two")
6307    (set_attr "length" "8")])
6309 (define_insn "*negdi2_noppc64"
6310   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
6311         (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))]
6312   "! TARGET_POWERPC64"
6313   "*
6315   return (WORDS_BIG_ENDIAN)
6316     ? \"subfic %L0,%L1,0\;subfze %0,%1\"
6317     : \"subfic %0,%1,0\;subfze %L0,%L1\";
6319   [(set_attr "type" "two")
6320    (set_attr "length" "8")])
6323 ;; Shift by a variable amount is too complex to be worth open-coding.  We
6324 ;; just handle shifts by constants.
6325 (define_insn "ashrdi3_no_power"
6326   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
6327         (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6328                      (match_operand:SI 2 "const_int_operand" "M,i")))
6329    (clobber (reg:SI CA_REGNO))]
6330   "!TARGET_POWERPC64"
6332   switch (which_alternative)
6333     {
6334     default:
6335       gcc_unreachable ();
6336     case 0:
6337       if (WORDS_BIG_ENDIAN)
6338         return \"srawi %0,%1,31\;srawi %L0,%1,%h2\";
6339       else
6340         return \"srawi %L0,%L1,31\;srawi %0,%L1,%h2\";
6341     case 1:
6342       if (WORDS_BIG_ENDIAN)
6343         return \"srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2\";
6344       else
6345         return \"srwi %0,%1,%h2\;insrwi %0,%L1,%h2,0\;srawi %L0,%L1,%h2\";
6346     }
6348   [(set_attr "type" "two,three")
6349    (set_attr "length" "8,12")])
6351 (define_insn "*ashrdisi3_noppc64be"
6352   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6353         (subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6354                                 (const_int 32)) 4))]
6355   "TARGET_32BIT && !TARGET_POWERPC64 && WORDS_BIG_ENDIAN"
6356   "*
6358   if (REGNO (operands[0]) == REGNO (operands[1]))
6359     return \"\";
6360   else
6361     return \"mr %0,%1\";
6363    [(set_attr "length" "4")])
6366 ;; PowerPC64 DImode operations.
6368 (define_insn "*rotldi3_internal4"
6369   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6370         (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6371                            (match_operand:DI 2 "reg_or_cint_operand" "rn"))
6372                 (match_operand:DI 3 "mask64_operand" "n")))]
6373   "TARGET_POWERPC64"
6374   "rld%I2c%B3 %0,%1,%H2,%S3"
6375   [(set_attr "type" "shift")
6376    (set_attr "maybe_var_shift" "yes")])
6378 (define_insn "*rotldi3_internal5"
6379   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6380         (compare:CC (and:DI
6381                      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6382                                 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn"))
6383                      (match_operand:DI 3 "mask64_operand" "n,n"))
6384                     (const_int 0)))
6385    (clobber (match_scratch:DI 4 "=r,r"))]
6386   "TARGET_64BIT"
6387   "@
6388    rld%I2c%B3. %4,%1,%H2,%S3
6389    #"
6390   [(set_attr "type" "shift")
6391    (set_attr "maybe_var_shift" "yes")
6392    (set_attr "dot" "yes")
6393    (set_attr "length" "4,8")])
6395 (define_split
6396   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6397         (compare:CC (and:DI
6398                      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6399                                 (match_operand:DI 2 "reg_or_cint_operand" ""))
6400                      (match_operand:DI 3 "mask64_operand" ""))
6401                     (const_int 0)))
6402    (clobber (match_scratch:DI 4 ""))]
6403   "TARGET_POWERPC64 && reload_completed"
6404   [(set (match_dup 4)
6405         (and:DI (rotate:DI (match_dup 1)
6406                                 (match_dup 2))
6407                      (match_dup 3)))
6408    (set (match_dup 0)
6409         (compare:CC (match_dup 4)
6410                     (const_int 0)))]
6411   "")
6413 (define_insn "*rotldi3_internal6"
6414   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
6415         (compare:CC (and:DI
6416                      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6417                                 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn"))
6418                      (match_operand:DI 3 "mask64_operand" "n,n"))
6419                     (const_int 0)))
6420    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6421         (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
6422   "TARGET_64BIT"
6423   "@
6424    rld%I2c%B3. %0,%1,%H2,%S3
6425    #"
6426   [(set_attr "type" "shift")
6427    (set_attr "maybe_var_shift" "yes")
6428    (set_attr "dot" "yes")
6429    (set_attr "length" "4,8")])
6431 (define_split
6432   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
6433         (compare:CC (and:DI
6434                      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6435                                 (match_operand:DI 2 "reg_or_cint_operand" ""))
6436                      (match_operand:DI 3 "mask64_operand" ""))
6437                     (const_int 0)))
6438    (set (match_operand:DI 0 "gpc_reg_operand" "")
6439         (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
6440   "TARGET_POWERPC64 && reload_completed"
6441   [(set (match_dup 0)
6442         (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
6443    (set (match_dup 4)
6444         (compare:CC (match_dup 0)
6445                     (const_int 0)))]
6446   "")
6448 (define_insn "*rotldi3_internal7le"
6449   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6450         (zero_extend:DI
6451          (subreg:QI
6452           (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6453                      (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))]
6454   "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
6455   "rld%I2cl %0,%1,%H2,56"
6456   [(set_attr "type" "shift")
6457    (set_attr "maybe_var_shift" "yes")])
6459 (define_insn "*rotldi3_internal7be"
6460   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6461         (zero_extend:DI
6462          (subreg:QI
6463           (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6464                      (match_operand:DI 2 "reg_or_cint_operand" "rn")) 7)))]
6465   "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
6466   "rld%I2cl %0,%1,%H2,56"
6467   [(set_attr "type" "shift")
6468    (set_attr "maybe_var_shift" "yes")])
6470 (define_insn "*rotldi3_internal8le"
6471   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6472         (compare:CC (zero_extend:DI
6473                      (subreg:QI
6474                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6475                                  (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6476                     (const_int 0)))
6477    (clobber (match_scratch:DI 3 "=r,r"))]
6478   "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6479   "@
6480    rld%I2cl. %3,%1,%H2,56
6481    #"
6482   [(set_attr "type" "shift")
6483    (set_attr "maybe_var_shift" "yes")
6484    (set_attr "dot" "yes")
6485    (set_attr "length" "4,8")])
6487 (define_insn "*rotldi3_internal8be"
6488   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6489         (compare:CC (zero_extend:DI
6490                      (subreg:QI
6491                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6492                                  (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 7))
6493                     (const_int 0)))
6494    (clobber (match_scratch:DI 3 "=r,r"))]
6495   "TARGET_64BIT && BYTES_BIG_ENDIAN"
6496   "@
6497    rld%I2cl. %3,%1,%H2,56
6498    #"
6499   [(set_attr "type" "shift")
6500    (set_attr "maybe_var_shift" "yes")
6501    (set_attr "dot" "yes")
6502    (set_attr "length" "4,8")])
6504 (define_split
6505   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6506         (compare:CC (zero_extend:DI
6507                      (subreg:QI
6508                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6509                                  (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6510                     (const_int 0)))
6511    (clobber (match_scratch:DI 3 ""))]
6512   "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6513   [(set (match_dup 3)
6514         (zero_extend:DI (subreg:QI
6515                       (rotate:DI (match_dup 1)
6516                                  (match_dup 2)) 0)))
6517    (set (match_dup 0)
6518         (compare:CC (match_dup 3)
6519                     (const_int 0)))]
6520   "")
6522 (define_split
6523   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6524         (compare:CC (zero_extend:DI
6525                      (subreg:QI
6526                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6527                                  (match_operand:DI 2 "reg_or_cint_operand" "")) 7))
6528                     (const_int 0)))
6529    (clobber (match_scratch:DI 3 ""))]
6530   "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6531   [(set (match_dup 3)
6532         (zero_extend:DI (subreg:QI
6533                       (rotate:DI (match_dup 1)
6534                                  (match_dup 2)) 7)))
6535    (set (match_dup 0)
6536         (compare:CC (match_dup 3)
6537                     (const_int 0)))]
6538   "")
6540 (define_insn "*rotldi3_internal9le"
6541   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6542         (compare:CC (zero_extend:DI
6543                      (subreg:QI
6544                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6545                                  (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6546                     (const_int 0)))
6547    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6548         (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6549   "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6550   "@
6551    rld%I2cl. %0,%1,%H2,56
6552    #"
6553   [(set_attr "type" "shift")
6554    (set_attr "maybe_var_shift" "yes")
6555    (set_attr "dot" "yes")
6556    (set_attr "length" "4,8")])
6558 (define_insn "*rotldi3_internal9be"
6559   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6560         (compare:CC (zero_extend:DI
6561                      (subreg:QI
6562                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6563                                  (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 7))
6564                     (const_int 0)))
6565    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6566         (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))]
6567   "TARGET_64BIT && BYTES_BIG_ENDIAN"
6568   "@
6569    rld%I2cl. %0,%1,%H2,56
6570    #"
6571   [(set_attr "type" "shift")
6572    (set_attr "maybe_var_shift" "yes")
6573    (set_attr "dot" "yes")
6574    (set_attr "length" "4,8")])
6576 (define_split
6577   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6578         (compare:CC (zero_extend:DI
6579                      (subreg:QI
6580                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6581                                  (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6582                     (const_int 0)))
6583    (set (match_operand:DI 0 "gpc_reg_operand" "")
6584         (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6585   "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6586   [(set (match_dup 0)
6587         (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
6588    (set (match_dup 3)
6589         (compare:CC (match_dup 0)
6590                     (const_int 0)))]
6591   "")
6593 (define_split
6594   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6595         (compare:CC (zero_extend:DI
6596                      (subreg:QI
6597                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6598                                  (match_operand:DI 2 "reg_or_cint_operand" "")) 7))
6599                     (const_int 0)))
6600    (set (match_operand:DI 0 "gpc_reg_operand" "")
6601         (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))]
6602   "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6603   [(set (match_dup 0)
6604         (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))
6605    (set (match_dup 3)
6606         (compare:CC (match_dup 0)
6607                     (const_int 0)))]
6608   "")
6610 (define_insn "*rotldi3_internal10le"
6611   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6612         (zero_extend:DI
6613          (subreg:HI
6614           (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6615                      (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))]
6616   "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
6617   "rld%I2cl %0,%1,%H2,48"
6618   [(set_attr "type" "shift")
6619    (set_attr "maybe_var_shift" "yes")])
6621 (define_insn "*rotldi3_internal10be"
6622   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6623         (zero_extend:DI
6624          (subreg:HI
6625           (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6626                      (match_operand:DI 2 "reg_or_cint_operand" "rn")) 6)))]
6627   "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
6628   "rld%I2cl %0,%1,%H2,48"
6629   [(set_attr "type" "shift")
6630    (set_attr "maybe_var_shift" "yes")])
6632 (define_insn "*rotldi3_internal11le"
6633   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6634         (compare:CC (zero_extend:DI
6635                      (subreg:HI
6636                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6637                                  (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6638                     (const_int 0)))
6639    (clobber (match_scratch:DI 3 "=r,r"))]
6640   "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6641   "@
6642    rld%I2cl. %3,%1,%H2,48
6643    #"
6644   [(set_attr "type" "shift")
6645    (set_attr "maybe_var_shift" "yes")
6646    (set_attr "dot" "yes")
6647    (set_attr "length" "4,8")])
6649 (define_insn "*rotldi3_internal11be"
6650   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6651         (compare:CC (zero_extend:DI
6652                      (subreg:HI
6653                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6654                                  (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 6))
6655                     (const_int 0)))
6656    (clobber (match_scratch:DI 3 "=r,r"))]
6657   "TARGET_64BIT && BYTES_BIG_ENDIAN"
6658   "@
6659    rld%I2cl. %3,%1,%H2,48
6660    #"
6661   [(set_attr "type" "shift")
6662    (set_attr "maybe_var_shift" "yes")
6663    (set_attr "dot" "yes")
6664    (set_attr "length" "4,8")])
6666 (define_split
6667   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6668         (compare:CC (zero_extend:DI
6669                      (subreg:HI
6670                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6671                                  (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6672                     (const_int 0)))
6673    (clobber (match_scratch:DI 3 ""))]
6674   "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6675   [(set (match_dup 3)
6676         (zero_extend:DI (subreg:HI
6677                       (rotate:DI (match_dup 1)
6678                                  (match_dup 2)) 0)))
6679    (set (match_dup 0)
6680         (compare:CC (match_dup 3)
6681                     (const_int 0)))]
6682   "")
6684 (define_split
6685   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6686         (compare:CC (zero_extend:DI
6687                      (subreg:HI
6688                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6689                                  (match_operand:DI 2 "reg_or_cint_operand" "")) 6))
6690                     (const_int 0)))
6691    (clobber (match_scratch:DI 3 ""))]
6692   "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6693   [(set (match_dup 3)
6694         (zero_extend:DI (subreg:HI
6695                       (rotate:DI (match_dup 1)
6696                                  (match_dup 2)) 6)))
6697    (set (match_dup 0)
6698         (compare:CC (match_dup 3)
6699                     (const_int 0)))]
6700   "")
6702 (define_insn "*rotldi3_internal12le"
6703   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6704         (compare:CC (zero_extend:DI
6705                      (subreg:HI
6706                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6707                                  (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6708                     (const_int 0)))
6709    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6710         (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6711   "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6712   "@
6713    rld%I2cl. %0,%1,%H2,48
6714    #"
6715   [(set_attr "type" "shift")
6716    (set_attr "maybe_var_shift" "yes")
6717    (set_attr "dot" "yes")
6718    (set_attr "length" "4,8")])
6720 (define_insn "*rotldi3_internal12be"
6721   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6722         (compare:CC (zero_extend:DI
6723                      (subreg:HI
6724                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6725                                  (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 6))
6726                     (const_int 0)))
6727    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6728         (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))]
6729   "TARGET_64BIT && BYTES_BIG_ENDIAN"
6730   "@
6731    rld%I2cl. %0,%1,%H2,48
6732    #"
6733   [(set_attr "type" "shift")
6734    (set_attr "maybe_var_shift" "yes")
6735    (set_attr "dot" "yes")
6736    (set_attr "length" "4,8")])
6738 (define_split
6739   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6740         (compare:CC (zero_extend:DI
6741                      (subreg:HI
6742                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6743                                  (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6744                     (const_int 0)))
6745    (set (match_operand:DI 0 "gpc_reg_operand" "")
6746         (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6747   "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6748   [(set (match_dup 0)
6749         (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
6750    (set (match_dup 3)
6751         (compare:CC (match_dup 0)
6752                     (const_int 0)))]
6753   "")
6755 (define_split
6756   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6757         (compare:CC (zero_extend:DI
6758                      (subreg:HI
6759                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6760                                  (match_operand:DI 2 "reg_or_cint_operand" "")) 6))
6761                     (const_int 0)))
6762    (set (match_operand:DI 0 "gpc_reg_operand" "")
6763         (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))]
6764   "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6765   [(set (match_dup 0)
6766         (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))
6767    (set (match_dup 3)
6768         (compare:CC (match_dup 0)
6769                     (const_int 0)))]
6770   "")
6772 (define_insn "*rotldi3_internal13le"
6773   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6774         (zero_extend:DI
6775          (subreg:SI
6776           (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6777                      (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))]
6778   "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
6779   "rld%I2cl %0,%1,%H2,32"
6780   [(set_attr "type" "shift")
6781    (set_attr "maybe_var_shift" "yes")])
6783 (define_insn "*rotldi3_internal13be"
6784   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6785         (zero_extend:DI
6786          (subreg:SI
6787           (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6788                      (match_operand:DI 2 "reg_or_cint_operand" "rn")) 4)))]
6789   "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
6790   "rld%I2cl %0,%1,%H2,32"
6791   [(set_attr "type" "shift")
6792    (set_attr "maybe_var_shift" "yes")])
6794 (define_insn "*rotldi3_internal14le"
6795   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6796         (compare:CC (zero_extend:DI
6797                      (subreg:SI
6798                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6799                                  (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6800                     (const_int 0)))
6801    (clobber (match_scratch:DI 3 "=r,r"))]
6802   "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6803   "@
6804    rld%I2cl. %3,%1,%H2,32
6805    #"
6806   [(set_attr "type" "shift")
6807    (set_attr "maybe_var_shift" "yes")
6808    (set_attr "dot" "yes")
6809    (set_attr "length" "4,8")])
6811 (define_insn "*rotldi3_internal14be"
6812   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6813         (compare:CC (zero_extend:DI
6814                      (subreg:SI
6815                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6816                                  (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 4))
6817                     (const_int 0)))
6818    (clobber (match_scratch:DI 3 "=r,r"))]
6819   "TARGET_64BIT && BYTES_BIG_ENDIAN"
6820   "@
6821    rld%I2cl. %3,%1,%H2,32
6822    #"
6823   [(set_attr "type" "shift")
6824    (set_attr "maybe_var_shift" "yes")
6825    (set_attr "dot" "yes")
6826    (set_attr "length" "4,8")])
6828 (define_split
6829   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6830         (compare:CC (zero_extend:DI
6831                      (subreg:SI
6832                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6833                                  (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6834                     (const_int 0)))
6835    (clobber (match_scratch:DI 3 ""))]
6836   "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6837   [(set (match_dup 3)
6838         (zero_extend:DI (subreg:SI
6839                       (rotate:DI (match_dup 1)
6840                                  (match_dup 2)) 0)))
6841    (set (match_dup 0)
6842         (compare:CC (match_dup 3)
6843                     (const_int 0)))]
6844   "")
6846 (define_split
6847   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6848         (compare:CC (zero_extend:DI
6849                      (subreg:SI
6850                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6851                                  (match_operand:DI 2 "reg_or_cint_operand" "")) 4))
6852                     (const_int 0)))
6853    (clobber (match_scratch:DI 3 ""))]
6854   "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6855   [(set (match_dup 3)
6856         (zero_extend:DI (subreg:SI
6857                       (rotate:DI (match_dup 1)
6858                                  (match_dup 2)) 4)))
6859    (set (match_dup 0)
6860         (compare:CC (match_dup 3)
6861                     (const_int 0)))]
6862   "")
6864 (define_insn "*rotldi3_internal15le"
6865   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6866         (compare:CC (zero_extend:DI
6867                      (subreg:SI
6868                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6869                                  (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0))
6870                     (const_int 0)))
6871    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6872         (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6873   "TARGET_64BIT && !BYTES_BIG_ENDIAN"
6874   "@
6875    rld%I2cl. %0,%1,%H2,32
6876    #"
6877   [(set_attr "type" "shift")
6878    (set_attr "maybe_var_shift" "yes")
6879    (set_attr "dot" "yes")
6880    (set_attr "length" "4,8")])
6882 (define_insn "*rotldi3_internal15be"
6883   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6884         (compare:CC (zero_extend:DI
6885                      (subreg:SI
6886                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6887                                  (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 4))
6888                     (const_int 0)))
6889    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6890         (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))]
6891   "TARGET_64BIT && BYTES_BIG_ENDIAN"
6892   "@
6893    rld%I2cl. %0,%1,%H2,32
6894    #"
6895   [(set_attr "type" "shift")
6896    (set_attr "maybe_var_shift" "yes")
6897    (set_attr "dot" "yes")
6898    (set_attr "length" "4,8")])
6900 (define_split
6901   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6902         (compare:CC (zero_extend:DI
6903                      (subreg:SI
6904                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6905                                  (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
6906                     (const_int 0)))
6907    (set (match_operand:DI 0 "gpc_reg_operand" "")
6908         (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6909   "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
6910   [(set (match_dup 0)
6911         (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
6912    (set (match_dup 3)
6913         (compare:CC (match_dup 0)
6914                     (const_int 0)))]
6915   "")
6917 (define_split
6918   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
6919         (compare:CC (zero_extend:DI
6920                      (subreg:SI
6921                       (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
6922                                  (match_operand:DI 2 "reg_or_cint_operand" "")) 4))
6923                     (const_int 0)))
6924    (set (match_operand:DI 0 "gpc_reg_operand" "")
6925         (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))]
6926   "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
6927   [(set (match_dup 0)
6928         (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))
6929    (set (match_dup 3)
6930         (compare:CC (match_dup 0)
6931                     (const_int 0)))]
6932   "")
6934 (define_insn "*ashldi3_internal4"
6935   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6936         (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6937                            (match_operand:SI 2 "const_int_operand" "i"))
6938                 (match_operand:DI 3 "const_int_operand" "n")))]
6939   "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
6940   "rldic %0,%1,%H2,%W3"
6941   [(set_attr "type" "shift")])
6943 (define_insn "ashldi3_internal5"
6944   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6945         (compare:CC
6946          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6947                             (match_operand:SI 2 "const_int_operand" "i,i"))
6948                  (match_operand:DI 3 "const_int_operand" "n,n"))
6949          (const_int 0)))
6950    (clobber (match_scratch:DI 4 "=r,r"))]
6951   "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
6952   "@
6953    rldic. %4,%1,%H2,%W3
6954    #"
6955   [(set_attr "type" "shift")
6956    (set_attr "dot" "yes")
6957    (set_attr "length" "4,8")])
6959 (define_split
6960   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
6961         (compare:CC
6962          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
6963                             (match_operand:SI 2 "const_int_operand" ""))
6964                  (match_operand:DI 3 "const_int_operand" ""))
6965          (const_int 0)))
6966    (clobber (match_scratch:DI 4 ""))]
6967   "TARGET_POWERPC64 && reload_completed
6968    && includes_rldic_lshift_p (operands[2], operands[3])"
6969   [(set (match_dup 4)
6970         (and:DI (ashift:DI (match_dup 1) (match_dup 2))
6971                 (match_dup 3)))
6972    (set (match_dup 0)
6973         (compare:CC (match_dup 4)
6974                     (const_int 0)))]
6975   "")
6977 (define_insn "*ashldi3_internal6"
6978   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
6979         (compare:CC
6980          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6981                             (match_operand:SI 2 "const_int_operand" "i,i"))
6982                     (match_operand:DI 3 "const_int_operand" "n,n"))
6983          (const_int 0)))
6984    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6985         (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
6986   "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
6987   "@
6988    rldic. %0,%1,%H2,%W3
6989    #"
6990   [(set_attr "type" "shift")
6991    (set_attr "dot" "yes")
6992    (set_attr "length" "4,8")])
6994 (define_split
6995   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
6996         (compare:CC
6997          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
6998                             (match_operand:SI 2 "const_int_operand" ""))
6999                  (match_operand:DI 3 "const_int_operand" ""))
7000          (const_int 0)))
7001    (set (match_operand:DI 0 "gpc_reg_operand" "")
7002         (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7003   "TARGET_POWERPC64 && reload_completed
7004    && includes_rldic_lshift_p (operands[2], operands[3])"
7005   [(set (match_dup 0)
7006         (and:DI (ashift:DI (match_dup 1) (match_dup 2))
7007                 (match_dup 3)))
7008    (set (match_dup 4)
7009         (compare:CC (match_dup 0)
7010                     (const_int 0)))]
7011   "")
7013 (define_insn "*ashldi3_internal7"
7014   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
7015         (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
7016                            (match_operand:SI 2 "const_int_operand" "i"))
7017                 (match_operand:DI 3 "mask64_operand" "n")))]
7018   "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
7019   "rldicr %0,%1,%H2,%S3"
7020   [(set_attr "type" "shift")])
7022 (define_insn "ashldi3_internal8"
7023   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
7024         (compare:CC
7025          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7026                             (match_operand:SI 2 "const_int_operand" "i,i"))
7027                  (match_operand:DI 3 "mask64_operand" "n,n"))
7028          (const_int 0)))
7029    (clobber (match_scratch:DI 4 "=r,r"))]
7030   "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
7031   "@
7032    rldicr. %4,%1,%H2,%S3
7033    #"
7034   [(set_attr "type" "shift")
7035    (set_attr "dot" "yes")
7036    (set_attr "length" "4,8")])
7038 (define_split
7039   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
7040         (compare:CC
7041          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
7042                             (match_operand:SI 2 "const_int_operand" ""))
7043                  (match_operand:DI 3 "mask64_operand" ""))
7044          (const_int 0)))
7045    (clobber (match_scratch:DI 4 ""))]
7046   "TARGET_POWERPC64 && reload_completed
7047    && includes_rldicr_lshift_p (operands[2], operands[3])"
7048   [(set (match_dup 4)
7049         (and:DI (ashift:DI (match_dup 1) (match_dup 2))
7050                 (match_dup 3)))
7051    (set (match_dup 0)
7052         (compare:CC (match_dup 4)
7053                     (const_int 0)))]
7054   "")
7056 (define_insn "*ashldi3_internal9"
7057   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
7058         (compare:CC
7059          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
7060                             (match_operand:SI 2 "const_int_operand" "i,i"))
7061                     (match_operand:DI 3 "mask64_operand" "n,n"))
7062          (const_int 0)))
7063    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
7064         (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7065   "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
7066   "@
7067    rldicr. %0,%1,%H2,%S3
7068    #"
7069   [(set_attr "type" "shift")
7070    (set_attr "dot" "yes")
7071    (set_attr "length" "4,8")])
7073 (define_split
7074   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
7075         (compare:CC
7076          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
7077                             (match_operand:SI 2 "const_int_operand" ""))
7078                  (match_operand:DI 3 "mask64_operand" ""))
7079          (const_int 0)))
7080    (set (match_operand:DI 0 "gpc_reg_operand" "")
7081         (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7082   "TARGET_POWERPC64 && reload_completed
7083    && includes_rldicr_lshift_p (operands[2], operands[3])"
7084   [(set (match_dup 0)
7085         (and:DI (ashift:DI (match_dup 1) (match_dup 2))
7086                 (match_dup 3)))
7087    (set (match_dup 4)
7088         (compare:CC (match_dup 0)
7089                     (const_int 0)))]
7090   "")
7093 (define_insn_and_split "*anddi3_2rld"
7094   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
7095         (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
7096                 (match_operand:DI 2 "and_2rld_operand" "n")))]
7097   "TARGET_POWERPC64"
7098   "#"
7099   ""
7100   [(set (match_dup 0)
7101         (and:DI (rotate:DI (match_dup 1)
7102                            (match_dup 4))
7103                 (match_dup 5)))
7104    (set (match_dup 0)
7105         (and:DI (rotate:DI (match_dup 0)
7106                            (match_dup 6))
7107                 (match_dup 7)))]
7109   build_mask64_2_operands (operands[2], &operands[4]);
7111   [(set_attr "length" "8")])
7113 (define_insn_and_split "*anddi3_2rld_dot"
7114   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
7115         (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
7116                             (match_operand:DI 2 "and_2rld_operand" "n,n"))
7117                     (const_int 0)))
7118    (clobber (match_scratch:DI 0 "=r,r"))]
7119   "TARGET_64BIT && rs6000_gen_cell_microcode"
7120   "@
7121    #
7122    #"
7123   "&& reload_completed"
7124   [(set (match_dup 0)
7125         (and:DI (rotate:DI (match_dup 1)
7126                            (match_dup 4))
7127                 (match_dup 5)))
7128    (parallel [(set (match_dup 3)
7129                    (compare:CC (and:DI (rotate:DI (match_dup 0)
7130                                                   (match_dup 6))
7131                                        (match_dup 7))
7132                                (const_int 0)))
7133               (clobber (match_dup 0))])]
7135   build_mask64_2_operands (operands[2], &operands[4]);
7137   [(set_attr "type" "compare")
7138    (set_attr "dot" "yes")
7139    (set_attr "length" "8,12")])
7141 (define_insn_and_split "*anddi3_2rld_dot2"
7142   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
7143         (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
7144                             (match_operand:DI 2 "and_2rld_operand" "n,n"))
7145                     (const_int 0)))
7146    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
7147         (and:DI (match_dup 1)
7148                 (match_dup 2)))]
7149   "TARGET_64BIT && rs6000_gen_cell_microcode"
7150   "@
7151    #
7152    #"
7153   "&& reload_completed"
7154   [(set (match_dup 0)
7155         (and:DI (rotate:DI (match_dup 1)
7156                            (match_dup 4))
7157                 (match_dup 5)))
7158    (parallel [(set (match_dup 3)
7159                    (compare:CC (and:DI (rotate:DI (match_dup 0)
7160                                                   (match_dup 6))
7161                                        (match_dup 7))
7162                                (const_int 0)))
7163               (set (match_dup 0)
7164                    (and:DI (rotate:DI (match_dup 0)
7165                                       (match_dup 6))
7166                            (match_dup 7)))])]
7168   build_mask64_2_operands (operands[2], &operands[4]);
7170   [(set_attr "type" "compare")
7171    (set_attr "dot" "yes")
7172    (set_attr "length" "8,12")])
7174 ;; 128-bit logical operations expanders
7176 (define_expand "and<mode>3"
7177   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7178         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
7179                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
7180   ""
7181   "")
7183 (define_expand "ior<mode>3"
7184   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7185         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
7186                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
7187   ""
7188   "")
7190 (define_expand "xor<mode>3"
7191   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7192         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
7193                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
7194   ""
7195   "")
7197 (define_expand "one_cmpl<mode>2"
7198   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7199         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
7200   ""
7201   "")
7203 (define_expand "nor<mode>3"
7204   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7205         (and:BOOL_128
7206          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
7207          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
7208   ""
7209   "")
7211 (define_expand "andc<mode>3"
7212   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7213         (and:BOOL_128
7214          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
7215          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
7216   ""
7217   "")
7219 ;; Power8 vector logical instructions.
7220 (define_expand "eqv<mode>3"
7221   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7222         (not:BOOL_128
7223          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
7224                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
7225   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7226   "")
7228 ;; Rewrite nand into canonical form
7229 (define_expand "nand<mode>3"
7230   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7231         (ior:BOOL_128
7232          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
7233          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
7234   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7235   "")
7237 ;; The canonical form is to have the negated element first, so we need to
7238 ;; reverse arguments.
7239 (define_expand "orc<mode>3"
7240   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
7241         (ior:BOOL_128
7242          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
7243          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
7244   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7245   "")
7247 ;; 128-bit logical operations insns and split operations
7248 (define_insn_and_split "*and<mode>3_internal"
7249   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7250         (and:BOOL_128
7251          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7252          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
7253   ""
7255   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7256     return "xxland %x0,%x1,%x2";
7258   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7259     return "vand %0,%1,%2";
7261   return "#";
7263   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7264   [(const_int 0)]
7266   rs6000_split_logical (operands, AND, false, false, false);
7267   DONE;
7269   [(set (attr "type")
7270       (if_then_else
7271         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7272         (const_string "vecsimple")
7273         (const_string "integer")))
7274    (set (attr "length")
7275       (if_then_else
7276         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7277         (const_string "4")
7278         (if_then_else
7279          (match_test "TARGET_POWERPC64")
7280          (const_string "8")
7281          (const_string "16"))))])
7283 ;; 128-bit IOR/XOR
7284 (define_insn_and_split "*bool<mode>3_internal"
7285   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7286         (match_operator:BOOL_128 3 "boolean_or_operator"
7287          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7288           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
7289   ""
7291   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7292     return "xxl%q3 %x0,%x1,%x2";
7294   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7295     return "v%q3 %0,%1,%2";
7297   return "#";
7299   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7300   [(const_int 0)]
7302   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
7303   DONE;
7305   [(set (attr "type")
7306       (if_then_else
7307         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7308         (const_string "vecsimple")
7309         (const_string "integer")))
7310    (set (attr "length")
7311       (if_then_else
7312         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7313         (const_string "4")
7314         (if_then_else
7315          (match_test "TARGET_POWERPC64")
7316          (const_string "8")
7317          (const_string "16"))))])
7319 ;; 128-bit ANDC/ORC
7320 (define_insn_and_split "*boolc<mode>3_internal1"
7321   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7322         (match_operator:BOOL_128 3 "boolean_operator"
7323          [(not:BOOL_128
7324            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP1>"))
7325           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
7326   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7328   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7329     return "xxl%q3 %x0,%x1,%x2";
7331   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7332     return "v%q3 %0,%1,%2";
7334   return "#";
7336   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7337    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7338   [(const_int 0)]
7340   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false);
7341   DONE;
7343   [(set (attr "type")
7344       (if_then_else
7345         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7346         (const_string "vecsimple")
7347         (const_string "integer")))
7348    (set (attr "length")
7349       (if_then_else
7350         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7351         (const_string "4")
7352         (if_then_else
7353          (match_test "TARGET_POWERPC64")
7354          (const_string "8")
7355          (const_string "16"))))])
7357 (define_insn_and_split "*boolc<mode>3_internal2"
7358   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7359         (match_operator:TI2 3 "boolean_operator"
7360          [(not:TI2
7361            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
7362           (match_operand:TI2 2 "int_reg_operand" "r,r,0")]))]
7363   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7364   "#"
7365   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7366   [(const_int 0)]
7368   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false);
7369   DONE;
7371   [(set_attr "type" "integer")
7372    (set (attr "length")
7373         (if_then_else
7374          (match_test "TARGET_POWERPC64")
7375          (const_string "8")
7376          (const_string "16")))])
7378 ;; 128-bit NAND/NOR
7379 (define_insn_and_split "*boolcc<mode>3_internal1"
7380   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7381         (match_operator:BOOL_128 3 "boolean_operator"
7382          [(not:BOOL_128
7383            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
7384           (not:BOOL_128
7385            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
7386   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7388   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7389     return "xxl%q3 %x0,%x1,%x2";
7391   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7392     return "v%q3 %0,%1,%2";
7394   return "#";
7396   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7397    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7398   [(const_int 0)]
7400   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7401   DONE;
7403   [(set (attr "type")
7404       (if_then_else
7405         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7406         (const_string "vecsimple")
7407         (const_string "integer")))
7408    (set (attr "length")
7409       (if_then_else
7410         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7411         (const_string "4")
7412         (if_then_else
7413          (match_test "TARGET_POWERPC64")
7414          (const_string "8")
7415          (const_string "16"))))])
7417 (define_insn_and_split "*boolcc<mode>3_internal2"
7418   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7419         (match_operator:TI2 3 "boolean_operator"
7420          [(not:TI2
7421            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
7422           (not:TI2
7423            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
7424   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7425   "#"
7426   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7427   [(const_int 0)]
7429   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7430   DONE;
7432   [(set_attr "type" "integer")
7433    (set (attr "length")
7434         (if_then_else
7435          (match_test "TARGET_POWERPC64")
7436          (const_string "8")
7437          (const_string "16")))])
7440 ;; 128-bit EQV
7441 (define_insn_and_split "*eqv<mode>3_internal1"
7442   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7443         (not:BOOL_128
7444          (xor:BOOL_128
7445           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
7446           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
7447   "TARGET_P8_VECTOR"
7449   if (vsx_register_operand (operands[0], <MODE>mode))
7450     return "xxleqv %x0,%x1,%x2";
7452   return "#";
7454   "TARGET_P8_VECTOR && reload_completed
7455    && int_reg_operand (operands[0], <MODE>mode)"
7456   [(const_int 0)]
7458   rs6000_split_logical (operands, XOR, true, false, false);
7459   DONE;
7461   [(set (attr "type")
7462       (if_then_else
7463         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7464         (const_string "vecsimple")
7465         (const_string "integer")))
7466    (set (attr "length")
7467       (if_then_else
7468         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7469         (const_string "4")
7470         (if_then_else
7471          (match_test "TARGET_POWERPC64")
7472          (const_string "8")
7473          (const_string "16"))))])
7475 (define_insn_and_split "*eqv<mode>3_internal2"
7476   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7477         (not:TI2
7478          (xor:TI2
7479           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
7480           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
7481   "!TARGET_P8_VECTOR"
7482   "#"
7483   "reload_completed && !TARGET_P8_VECTOR"
7484   [(const_int 0)]
7486   rs6000_split_logical (operands, XOR, true, false, false);
7487   DONE;
7489   [(set_attr "type" "integer")
7490    (set (attr "length")
7491         (if_then_else
7492          (match_test "TARGET_POWERPC64")
7493          (const_string "8")
7494          (const_string "16")))])
7496 ;; 128-bit one's complement
7497 (define_insn_and_split "*one_cmpl<mode>3_internal"
7498   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7499         (not:BOOL_128
7500           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
7501   ""
7503   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7504     return "xxlnor %x0,%x1,%x1";
7506   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7507     return "vnor %0,%1,%1";
7509   return "#";
7511   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7512   [(const_int 0)]
7514   rs6000_split_logical (operands, NOT, false, false, false);
7515   DONE;
7517   [(set (attr "type")
7518       (if_then_else
7519         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7520         (const_string "vecsimple")
7521         (const_string "integer")))
7522    (set (attr "length")
7523       (if_then_else
7524         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7525         (const_string "4")
7526         (if_then_else
7527          (match_test "TARGET_POWERPC64")
7528          (const_string "8")
7529          (const_string "16"))))])
7532 ;; Now define ways of moving data around.
7534 ;; Set up a register with a value from the GOT table
7536 (define_expand "movsi_got"
7537   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7538         (unspec:SI [(match_operand:SI 1 "got_operand" "")
7539                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
7540   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7541   "
7543   if (GET_CODE (operands[1]) == CONST)
7544     {
7545       rtx offset = const0_rtx;
7546       HOST_WIDE_INT value;
7548       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
7549       value = INTVAL (offset);
7550       if (value != 0)
7551         {
7552           rtx tmp = (!can_create_pseudo_p ()
7553                      ? operands[0]
7554                      : gen_reg_rtx (Pmode));
7555           emit_insn (gen_movsi_got (tmp, operands[1]));
7556           emit_insn (gen_addsi3 (operands[0], tmp, offset));
7557           DONE;
7558         }
7559     }
7561   operands[2] = rs6000_got_register (operands[1]);
7564 (define_insn "*movsi_got_internal"
7565   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7566         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7567                     (match_operand:SI 2 "gpc_reg_operand" "b")]
7568                    UNSPEC_MOVSI_GOT))]
7569   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7570   "lwz %0,%a1@got(%2)"
7571   [(set_attr "type" "load")])
7573 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
7574 ;; didn't get allocated to a hard register.
7575 (define_split
7576   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7577         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7578                     (match_operand:SI 2 "memory_operand" "")]
7579                    UNSPEC_MOVSI_GOT))]
7580   "DEFAULT_ABI == ABI_V4
7581     && flag_pic == 1
7582     && (reload_in_progress || reload_completed)"
7583   [(set (match_dup 0) (match_dup 2))
7584    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
7585                                  UNSPEC_MOVSI_GOT))]
7586   "")
7588 ;; For SI, we special-case integers that can't be loaded in one insn.  We
7589 ;; do the load 16-bits at a time.  We could do this by loading from memory,
7590 ;; and this is even supposed to be faster, but it is simpler not to get
7591 ;; integers in the TOC.
7592 (define_insn "movsi_low"
7593   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7594         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
7595                            (match_operand 2 "" ""))))]
7596   "TARGET_MACHO && ! TARGET_64BIT"
7597   "lwz %0,lo16(%2)(%1)"
7598   [(set_attr "type" "load")
7599    (set_attr "length" "4")])
7601 (define_insn "*movsi_internal1"
7602   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
7603         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
7604   "!TARGET_SINGLE_FPU &&
7605    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
7606   "@
7607    mr %0,%1
7608    la %0,%a1
7609    lwz%U1%X1 %0,%1
7610    stw%U0%X0 %1,%0
7611    li %0,%1
7612    lis %0,%v1
7613    #
7614    mf%1 %0
7615    mt%0 %1
7616    mt%0 %1
7617    nop"
7618   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
7619    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
7621 (define_insn "*movsi_internal1_single"
7622   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
7623         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
7624   "TARGET_SINGLE_FPU &&
7625    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
7626   "@
7627    mr %0,%1
7628    la %0,%a1
7629    lwz%U1%X1 %0,%1
7630    stw%U0%X0 %1,%0
7631    li %0,%1
7632    lis %0,%v1
7633    #
7634    mf%1 %0
7635    mt%0 %1
7636    mt%0 %1
7637    nop
7638    stfs%U0%X0 %1,%0
7639    lfs%U1%X1 %0,%1"
7640   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
7641    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
7643 ;; Split a load of a large constant into the appropriate two-insn
7644 ;; sequence.
7646 (define_split
7647   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7648         (match_operand:SI 1 "const_int_operand" ""))]
7649   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7650    && (INTVAL (operands[1]) & 0xffff) != 0"
7651   [(set (match_dup 0)
7652         (match_dup 2))
7653    (set (match_dup 0)
7654         (ior:SI (match_dup 0)
7655                 (match_dup 3)))]
7656   "
7658   if (rs6000_emit_set_const (operands[0], operands[1]))
7659     DONE;
7660   else
7661     FAIL;
7664 (define_insn "*mov<mode>_internal2"
7665   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7666         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7667                     (const_int 0)))
7668    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7669   ""
7670   "@
7671    cmp<wd>i %2,%0,0
7672    mr. %0,%1
7673    #"
7674   [(set_attr "type" "cmp,logical,cmp")
7675    (set_attr "dot" "yes")
7676    (set_attr "length" "4,4,8")])
7678 (define_split
7679   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
7680         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
7681                     (const_int 0)))
7682    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
7683   "reload_completed"
7684   [(set (match_dup 0) (match_dup 1))
7685    (set (match_dup 2)
7686         (compare:CC (match_dup 0)
7687                     (const_int 0)))]
7688   "")
7690 (define_insn "*movhi_internal"
7691   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
7692         (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
7693   "gpc_reg_operand (operands[0], HImode)
7694    || gpc_reg_operand (operands[1], HImode)"
7695   "@
7696    mr %0,%1
7697    lhz%U1%X1 %0,%1
7698    sth%U0%X0 %1,%0
7699    li %0,%w1
7700    mf%1 %0
7701    mt%0 %1
7702    nop"
7703   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
7705 (define_expand "mov<mode>"
7706   [(set (match_operand:INT 0 "general_operand" "")
7707         (match_operand:INT 1 "any_operand" ""))]
7708   ""
7709   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7711 (define_insn "*movqi_internal"
7712   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
7713         (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
7714   "gpc_reg_operand (operands[0], QImode)
7715    || gpc_reg_operand (operands[1], QImode)"
7716   "@
7717    mr %0,%1
7718    lbz%U1%X1 %0,%1
7719    stb%U0%X0 %1,%0
7720    li %0,%1
7721    mf%1 %0
7722    mt%0 %1
7723    nop"
7724   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
7726 ;; Here is how to move condition codes around.  When we store CC data in
7727 ;; an integer register or memory, we store just the high-order 4 bits.
7728 ;; This lets us not shift in the most common case of CR0.
7729 (define_expand "movcc"
7730   [(set (match_operand:CC 0 "nonimmediate_operand" "")
7731         (match_operand:CC 1 "nonimmediate_operand" ""))]
7732   ""
7733   "")
7735 (define_insn "*movcc_internal1"
7736   [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
7737         (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
7738   "register_operand (operands[0], CCmode)
7739    || register_operand (operands[1], CCmode)"
7740   "@
7741    mcrf %0,%1
7742    mtcrf 128,%1
7743    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7744    crxor %0,%0,%0
7745    mfcr %0%Q1
7746    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7747    mr %0,%1
7748    li %0,%1
7749    mf%1 %0
7750    mt%0 %1
7751    lwz%U1%X1 %0,%1
7752    stw%U0%X0 %1,%0"
7753   [(set (attr "type")
7754      (cond [(eq_attr "alternative" "0,3")
7755                 (const_string "cr_logical")
7756             (eq_attr "alternative" "1,2")
7757                 (const_string "mtcr")
7758             (eq_attr "alternative" "6,7")
7759                 (const_string "integer")
7760             (eq_attr "alternative" "8")
7761                 (const_string "mfjmpr")
7762             (eq_attr "alternative" "9")
7763                 (const_string "mtjmpr")
7764             (eq_attr "alternative" "10")
7765                 (const_string "load")
7766             (eq_attr "alternative" "11")
7767                 (const_string "store")
7768             (match_test "TARGET_MFCRF")
7769                 (const_string "mfcrf")
7770            ]
7771         (const_string "mfcr")))
7772    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7774 ;; For floating-point, we normally deal with the floating-point registers
7775 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7776 ;; can produce floating-point values in fixed-point registers.  Unless the
7777 ;; value is a simple constant or already in memory, we deal with this by
7778 ;; allocating memory and copying the value explicitly via that memory location.
7780 ;; Move 32-bit binary/decimal floating point
7781 (define_expand "mov<mode>"
7782   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7783         (match_operand:FMOVE32 1 "any_operand" ""))]
7784   "<fmove_ok>"
7785   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7787 (define_split
7788   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7789         (match_operand:FMOVE32 1 "const_double_operand" ""))]
7790   "reload_completed
7791    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7792        || (GET_CODE (operands[0]) == SUBREG
7793            && GET_CODE (SUBREG_REG (operands[0])) == REG
7794            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7795   [(set (match_dup 2) (match_dup 3))]
7796   "
7798   long l;
7799   REAL_VALUE_TYPE rv;
7801   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
7802   <real_value_to_target> (rv, l);
7804   if (! TARGET_POWERPC64)
7805     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7806   else
7807     operands[2] = gen_lowpart (SImode, operands[0]);
7809   operands[3] = gen_int_mode (l, SImode);
7812 (define_insn "mov<mode>_hardfloat"
7813   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,wa,wa,<f32_lr>,<f32_sm>,wu,Z,?<f32_dm>,?r,*c*l,!r,*h,!r,!r")
7814         (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,wa,j,<f32_lm>,<f32_sr>,Z,wu,r,<f32_dm>,r,h,0,G,Fn"))]
7815   "(gpc_reg_operand (operands[0], <MODE>mode)
7816    || gpc_reg_operand (operands[1], <MODE>mode))
7817    && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
7818   "@
7819    mr %0,%1
7820    lwz%U1%X1 %0,%1
7821    stw%U0%X0 %1,%0
7822    fmr %0,%1
7823    xxlor %x0,%x1,%x1
7824    xxlxor %x0,%x0,%x0
7825    <f32_li>
7826    <f32_si>
7827    <f32_lv>
7828    <f32_sv>
7829    mtvsrwz %x0,%1
7830    mfvsrwz %0,%x1
7831    mt%0 %1
7832    mf%1 %0
7833    nop
7834    #
7835    #"
7836   [(set_attr "type" "*,load,store,fp,vecsimple,vecsimple,fpload,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*,*,*")
7837    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8")])
7839 (define_insn "*mov<mode>_softfloat"
7840   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7841         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7842   "(gpc_reg_operand (operands[0], <MODE>mode)
7843    || gpc_reg_operand (operands[1], <MODE>mode))
7844    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
7845   "@
7846    mr %0,%1
7847    mt%0 %1
7848    mf%1 %0
7849    lwz%U1%X1 %0,%1
7850    stw%U0%X0 %1,%0
7851    li %0,%1
7852    lis %0,%v1
7853    #
7854    #
7855    nop"
7856   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7857    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7860 ;; Move 64-bit binary/decimal floating point
7861 (define_expand "mov<mode>"
7862   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7863         (match_operand:FMOVE64 1 "any_operand" ""))]
7864   ""
7865   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7867 (define_split
7868   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7869         (match_operand:FMOVE64 1 "const_int_operand" ""))]
7870   "! TARGET_POWERPC64 && reload_completed
7871    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7872        || (GET_CODE (operands[0]) == SUBREG
7873            && GET_CODE (SUBREG_REG (operands[0])) == REG
7874            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7875   [(set (match_dup 2) (match_dup 4))
7876    (set (match_dup 3) (match_dup 1))]
7877   "
7879   int endian = (WORDS_BIG_ENDIAN == 0);
7880   HOST_WIDE_INT value = INTVAL (operands[1]);
7882   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7883   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7884   operands[4] = GEN_INT (value >> 32);
7885   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7888 (define_split
7889   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7890         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7891   "! TARGET_POWERPC64 && reload_completed
7892    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7893        || (GET_CODE (operands[0]) == SUBREG
7894            && GET_CODE (SUBREG_REG (operands[0])) == REG
7895            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7896   [(set (match_dup 2) (match_dup 4))
7897    (set (match_dup 3) (match_dup 5))]
7898   "
7900   int endian = (WORDS_BIG_ENDIAN == 0);
7901   long l[2];
7902   REAL_VALUE_TYPE rv;
7904   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
7905   <real_value_to_target> (rv, l);
7907   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7908   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7909   operands[4] = gen_int_mode (l[endian], SImode);
7910   operands[5] = gen_int_mode (l[1 - endian], SImode);
7913 (define_split
7914   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7915         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7916   "TARGET_POWERPC64 && reload_completed
7917    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7918        || (GET_CODE (operands[0]) == SUBREG
7919            && GET_CODE (SUBREG_REG (operands[0])) == REG
7920            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7921   [(set (match_dup 2) (match_dup 3))]
7922   "
7924   int endian = (WORDS_BIG_ENDIAN == 0);
7925   long l[2];
7926   REAL_VALUE_TYPE rv;
7927   HOST_WIDE_INT val;
7929   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
7930   <real_value_to_target> (rv, l);
7932   operands[2] = gen_lowpart (DImode, operands[0]);
7933   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7934   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7935          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7937   operands[3] = gen_int_mode (val, DImode);
7940 ;; Don't have reload use general registers to load a constant.  It is
7941 ;; less efficient than loading the constant into an FP register, since
7942 ;; it will probably be used there.
7944 ;; The move constraints are ordered to prefer floating point registers before
7945 ;; general purpose registers to avoid doing a store and a load to get the value
7946 ;; into a floating point register when it is needed for a floating point
7947 ;; operation.  Prefer traditional floating point registers over VSX registers,
7948 ;; since the D-form version of the memory instructions does not need a GPR for
7949 ;; reloading.
7951 (define_insn "*mov<mode>_hardfloat32"
7952   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,wv,Z,wa,wa,Y,r,!r,!r,!r,!r")
7953         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,wv,wa,j,r,Y,r,G,H,F"))]
7954   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7955    && (gpc_reg_operand (operands[0], <MODE>mode)
7956        || gpc_reg_operand (operands[1], <MODE>mode))"
7957   "@
7958    stfd%U0%X0 %1,%0
7959    lfd%U1%X1 %0,%1
7960    fmr %0,%1
7961    lxsd%U1x %x0,%y1
7962    stxsd%U0x %x1,%y0
7963    xxlor %x0,%x1,%x1
7964    xxlxor %x0,%x0,%x0
7965    #
7966    #
7967    #
7968    #
7969    #
7970    #"
7971   [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,store,load,two,fp,fp,*")
7972    (set_attr "length" "4,4,4,4,4,4,4,8,8,8,8,12,16")])
7974 (define_insn "*mov<mode>_softfloat32"
7975   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7976         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7977   "! TARGET_POWERPC64 
7978    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
7979        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
7980        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
7981    && (gpc_reg_operand (operands[0], <MODE>mode)
7982        || gpc_reg_operand (operands[1], <MODE>mode))"
7983   "#"
7984   [(set_attr "type" "store,load,two,*,*,*")
7985    (set_attr "length" "8,8,8,8,12,16")])
7987 ; ld/std require word-aligned displacements -> 'Y' constraint.
7988 ; List Y->r and r->Y before r->r for reload.
7989 (define_insn "*mov<mode>_hardfloat64"
7990   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,wv,Z,wa,wa,Y,r,!r,*c*l,!r,*h,!r,!r,!r,r,wg,r,wk")
7991         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,wv,wa,j,r,Y,r,r,h,0,G,H,F,wg,r,wk,r"))]
7992   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7993    && (gpc_reg_operand (operands[0], <MODE>mode)
7994        || gpc_reg_operand (operands[1], <MODE>mode))"
7995   "@
7996    stfd%U0%X0 %1,%0
7997    lfd%U1%X1 %0,%1
7998    fmr %0,%1
7999    lxsd%U1x %x0,%y1
8000    stxsd%U0x %x1,%y0
8001    xxlor %x0,%x1,%x1
8002    xxlxor %x0,%x0,%x0
8003    std%U0%X0 %1,%0
8004    ld%U1%X1 %0,%1
8005    mr %0,%1
8006    mt%0 %1
8007    mf%1 %0
8008    nop
8009    #
8010    #
8011    #
8012    mftgpr %0,%1
8013    mffgpr %0,%1
8014    mfvsrd %0,%x1
8015    mtvsrd %x0,%1"
8016   [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,store,load,*,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr,mftgpr,mffgpr")
8017    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16,4,4,4,4")])
8019 (define_insn "*mov<mode>_softfloat64"
8020   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
8021         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
8022   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
8023    && (gpc_reg_operand (operands[0], <MODE>mode)
8024        || gpc_reg_operand (operands[1], <MODE>mode))"
8025   "@
8026    std%U0%X0 %1,%0
8027    ld%U1%X1 %0,%1
8028    mr %0,%1
8029    mt%0 %1
8030    mf%1 %0
8031    #
8032    #
8033    #
8034    nop"
8035   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
8036    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
8038 (define_expand "mov<mode>"
8039   [(set (match_operand:FMOVE128 0 "general_operand" "")
8040         (match_operand:FMOVE128 1 "any_operand" ""))]
8041   ""
8042   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
8044 ;; It's important to list Y->r and r->Y before r->r because otherwise
8045 ;; reload, given m->r, will try to pick r->r and reload it, which
8046 ;; doesn't make progress.
8048 ;; We can't split little endian direct moves of TDmode, because the words are
8049 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
8050 ;; problematical.  Don't allow direct move for this case.
8052 (define_insn_and_split "*mov<mode>_64bit_dm"
8053   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,Y,r,r,r,wm")
8054         (match_operand:FMOVE128 1 "input_operand" "d,m,d,r,YGHF,r,wm,r"))]
8055   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
8056    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
8057    && (gpc_reg_operand (operands[0], <MODE>mode)
8058        || gpc_reg_operand (operands[1], <MODE>mode))"
8059   "#"
8060   "&& reload_completed"
8061   [(pc)]
8062 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8063   [(set_attr "length" "8,8,8,12,12,8,8,8")])
8065 (define_insn_and_split "*movtd_64bit_nodm"
8066   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
8067         (match_operand:TD 1 "input_operand" "d,m,d,r,YGHF,r"))]
8068   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
8069    && (gpc_reg_operand (operands[0], TDmode)
8070        || gpc_reg_operand (operands[1], TDmode))"
8071   "#"
8072   "&& reload_completed"
8073   [(pc)]
8074 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8075   [(set_attr "length" "8,8,8,12,12,8")])
8077 (define_insn_and_split "*mov<mode>_32bit"
8078   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
8079         (match_operand:FMOVE128 1 "input_operand" "d,m,d,r,YGHF,r"))]
8080   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
8081    && (gpc_reg_operand (operands[0], <MODE>mode)
8082        || gpc_reg_operand (operands[1], <MODE>mode))"
8083   "#"
8084   "&& reload_completed"
8085   [(pc)]
8086 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8087   [(set_attr "length" "8,8,8,20,20,16")])
8089 (define_insn_and_split "*mov<mode>_softfloat"
8090   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
8091         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
8092   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
8093    && (gpc_reg_operand (operands[0], <MODE>mode)
8094        || gpc_reg_operand (operands[1], <MODE>mode))"
8095   "#"
8096   "&& reload_completed"
8097   [(pc)]
8098 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8099   [(set_attr "length" "20,20,16")])
8101 (define_expand "extenddftf2"
8102   [(set (match_operand:TF 0 "nonimmediate_operand" "")
8103         (float_extend:TF (match_operand:DF 1 "input_operand" "")))]
8104   "!TARGET_IEEEQUAD
8105    && TARGET_HARD_FLOAT
8106    && (TARGET_FPRS || TARGET_E500_DOUBLE)
8107    && TARGET_LONG_DOUBLE_128"
8109   if (TARGET_E500_DOUBLE)
8110     emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
8111   else
8112     emit_insn (gen_extenddftf2_fprs (operands[0], operands[1]));
8113   DONE;
8116 (define_expand "extenddftf2_fprs"
8117   [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
8118                    (float_extend:TF (match_operand:DF 1 "input_operand" "")))
8119               (use (match_dup 2))])]
8120   "!TARGET_IEEEQUAD
8121    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
8122    && TARGET_LONG_DOUBLE_128"
8124   operands[2] = CONST0_RTX (DFmode);
8125   /* Generate GOT reference early for SVR4 PIC.  */
8126   if (DEFAULT_ABI == ABI_V4 && flag_pic)
8127     operands[2] = validize_mem (force_const_mem (DFmode, operands[2]));
8130 (define_insn_and_split "*extenddftf2_internal"
8131   [(set (match_operand:TF 0 "nonimmediate_operand" "=m,Y,d,&d,r")
8132        (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,rmGHF")))
8133    (use (match_operand:DF 2 "zero_reg_mem_operand" "d,r,m,d,n"))]
8134   "!TARGET_IEEEQUAD
8135    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
8136    && TARGET_LONG_DOUBLE_128"
8137   "#"
8138   "&& reload_completed"
8139   [(pc)]
8141   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8142   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8143   emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word),
8144                   operands[1]);
8145   emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word),
8146                   operands[2]);
8147   DONE;
8150 (define_expand "extendsftf2"
8151   [(set (match_operand:TF 0 "nonimmediate_operand" "")
8152         (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
8153   "!TARGET_IEEEQUAD
8154    && TARGET_HARD_FLOAT
8155    && (TARGET_FPRS || TARGET_E500_DOUBLE)
8156    && TARGET_LONG_DOUBLE_128"
8158   rtx tmp = gen_reg_rtx (DFmode);
8159   emit_insn (gen_extendsfdf2 (tmp, operands[1]));
8160   emit_insn (gen_extenddftf2 (operands[0], tmp));
8161   DONE;
8164 (define_expand "trunctfdf2"
8165   [(set (match_operand:DF 0 "gpc_reg_operand" "")
8166         (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))]
8167   "!TARGET_IEEEQUAD
8168    && TARGET_HARD_FLOAT
8169    && (TARGET_FPRS || TARGET_E500_DOUBLE)
8170    && TARGET_LONG_DOUBLE_128"
8171   "")
8173 (define_insn_and_split "trunctfdf2_internal1"
8174   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
8175         (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,d")))]
8176   "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
8177    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8178   "@
8179    #
8180    fmr %0,%1"
8181   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
8182   [(const_int 0)]
8184   emit_note (NOTE_INSN_DELETED);
8185   DONE;
8187   [(set_attr "type" "fp")])
8189 (define_insn "trunctfdf2_internal2"
8190   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8191         (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "d")))]
8192   "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
8193    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
8194    && TARGET_LONG_DOUBLE_128"
8195   "fadd %0,%1,%L1"
8196   [(set_attr "type" "fp")
8197    (set_attr "fp_type" "fp_addsub_d")])
8199 (define_expand "trunctfsf2"
8200   [(set (match_operand:SF 0 "gpc_reg_operand" "")
8201         (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "")))]
8202   "!TARGET_IEEEQUAD
8203    && TARGET_HARD_FLOAT
8204    && (TARGET_FPRS || TARGET_E500_DOUBLE)
8205    && TARGET_LONG_DOUBLE_128"
8207   if (TARGET_E500_DOUBLE)
8208     emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
8209   else
8210     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
8211   DONE;
8214 (define_insn_and_split "trunctfsf2_fprs"
8215   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
8216         (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "d")))
8217    (clobber (match_scratch:DF 2 "=d"))]
8218   "!TARGET_IEEEQUAD
8219    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
8220    && TARGET_LONG_DOUBLE_128"
8221   "#"
8222   "&& reload_completed"
8223   [(set (match_dup 2)
8224         (float_truncate:DF (match_dup 1)))
8225    (set (match_dup 0)
8226         (float_truncate:SF (match_dup 2)))]
8227   "")
8229 (define_expand "floatsitf2"
8230   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8231         (float:TF (match_operand:SI 1 "gpc_reg_operand" "")))]
8232   "!TARGET_IEEEQUAD
8233    && TARGET_HARD_FLOAT
8234    && (TARGET_FPRS || TARGET_E500_DOUBLE)
8235    && TARGET_LONG_DOUBLE_128"
8237   rtx tmp = gen_reg_rtx (DFmode);
8238   expand_float (tmp, operands[1], false);
8239   emit_insn (gen_extenddftf2 (operands[0], tmp));
8240   DONE;
8243 ; fadd, but rounding towards zero.
8244 ; This is probably not the optimal code sequence.
8245 (define_insn "fix_trunc_helper"
8246   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8247         (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "d")]
8248                    UNSPEC_FIX_TRUNC_TF))
8249    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8250   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
8251   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8252   [(set_attr "type" "fp")
8253    (set_attr "length" "20")])
8255 (define_expand "fix_trunctfsi2"
8256   [(set (match_operand:SI 0 "gpc_reg_operand" "")
8257         (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))]
8258   "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT
8259    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
8261   if (TARGET_E500_DOUBLE)
8262     emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
8263   else
8264     emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
8265   DONE;
8268 (define_expand "fix_trunctfsi2_fprs"
8269   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
8270                    (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))
8271               (clobber (match_dup 2))
8272               (clobber (match_dup 3))
8273               (clobber (match_dup 4))
8274               (clobber (match_dup 5))])]
8275   "!TARGET_IEEEQUAD
8276    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8278   operands[2] = gen_reg_rtx (DFmode);
8279   operands[3] = gen_reg_rtx (DFmode);
8280   operands[4] = gen_reg_rtx (DImode);
8281   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8284 (define_insn_and_split "*fix_trunctfsi2_internal"
8285   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8286         (fix:SI (match_operand:TF 1 "gpc_reg_operand" "d")))
8287    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8288    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8289    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8290    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8291   "!TARGET_IEEEQUAD
8292    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8293   "#"
8294   ""
8295   [(pc)]
8297   rtx lowword;
8298   emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
8300   gcc_assert (MEM_P (operands[5]));
8301   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8303   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8304   emit_move_insn (operands[5], operands[4]);
8305   emit_move_insn (operands[0], lowword);
8306   DONE;
8309 (define_expand "negtf2"
8310   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8311         (neg:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
8312   "!TARGET_IEEEQUAD
8313    && TARGET_HARD_FLOAT
8314    && (TARGET_FPRS || TARGET_E500_DOUBLE)
8315    && TARGET_LONG_DOUBLE_128"
8316   "")
8318 (define_insn "negtf2_internal"
8319   [(set (match_operand:TF 0 "gpc_reg_operand" "=d")
8320         (neg:TF (match_operand:TF 1 "gpc_reg_operand" "d")))]
8321   "!TARGET_IEEEQUAD
8322    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8323   "*
8325   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8326     return \"fneg %L0,%L1\;fneg %0,%1\";
8327   else
8328     return \"fneg %0,%1\;fneg %L0,%L1\";
8330   [(set_attr "type" "fp")
8331    (set_attr "length" "8")])
8333 (define_expand "abstf2"
8334   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8335         (abs:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
8336   "!TARGET_IEEEQUAD
8337    && TARGET_HARD_FLOAT
8338    && (TARGET_FPRS || TARGET_E500_DOUBLE)
8339    && TARGET_LONG_DOUBLE_128"
8340   "
8342   rtx label = gen_label_rtx ();
8343   if (TARGET_E500_DOUBLE)
8344     {
8345       if (flag_finite_math_only && !flag_trapping_math)
8346         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
8347       else
8348         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
8349     }
8350   else
8351     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8352   emit_label (label);
8353   DONE;
8356 (define_expand "abstf2_internal"
8357   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8358         (match_operand:TF 1 "gpc_reg_operand" ""))
8359    (set (match_dup 3) (match_dup 5))
8360    (set (match_dup 5) (abs:DF (match_dup 5)))
8361    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8362    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8363                            (label_ref (match_operand 2 "" ""))
8364                            (pc)))
8365    (set (match_dup 6) (neg:DF (match_dup 6)))]
8366   "!TARGET_IEEEQUAD
8367    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
8368    && TARGET_LONG_DOUBLE_128"
8369   "
8371   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8372   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8373   operands[3] = gen_reg_rtx (DFmode);
8374   operands[4] = gen_reg_rtx (CCFPmode);
8375   operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
8376   operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
8379 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8380 ;; must have 3 arguments, and scratch register constraint must be a single
8381 ;; constraint.
8383 ;; Reload patterns to support gpr load/store with misaligned mem.
8384 ;; and multiple gpr load/store at offset >= 0xfffc
8385 (define_expand "reload_<mode>_store"
8386   [(parallel [(match_operand 0 "memory_operand" "=m")
8387               (match_operand 1 "gpc_reg_operand" "r")
8388               (match_operand:GPR 2 "register_operand" "=&b")])]
8389   ""
8391   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8392   DONE;
8395 (define_expand "reload_<mode>_load"
8396   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8397               (match_operand 1 "memory_operand" "m")
8398               (match_operand:GPR 2 "register_operand" "=b")])]
8399   ""
8401   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8402   DONE;
8406 ;; Power8 merge instructions to allow direct move to/from floating point
8407 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8408 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8409 ;; value, since it is allocated in reload and not all of the flow information
8410 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8411 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8412 ;; schedule other instructions between the two instructions.  TFmode is
8413 ;; currently limited to traditional FPR registers.  If/when this is changed, we
8414 ;; will need to revist %L to make sure it works with VSX registers, or add an
8415 ;; %x version of %L.
8417 (define_insn "p8_fmrgow_<mode>"
8418   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8419         (unspec:FMOVE64X [(match_operand:TF 1 "register_operand" "d")]
8420                          UNSPEC_P8V_FMRGOW))]
8421   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8422   "fmrgow %0,%1,%L1"
8423   [(set_attr "type" "vecperm")])
8425 (define_insn "p8_mtvsrwz_1"
8426   [(set (match_operand:TF 0 "register_operand" "=d")
8427         (unspec:TF [(match_operand:SI 1 "register_operand" "r")]
8428                    UNSPEC_P8V_MTVSRWZ))]
8429   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8430   "mtvsrwz %x0,%1"
8431   [(set_attr "type" "mftgpr")])
8433 (define_insn "p8_mtvsrwz_2"
8434   [(set (match_operand:TF 0 "register_operand" "+d")
8435         (unspec:TF [(match_dup 0)
8436                     (match_operand:SI 1 "register_operand" "r")]
8437                    UNSPEC_P8V_MTVSRWZ))]
8438   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8439   "mtvsrwz %L0,%1"
8440   [(set_attr "type" "mftgpr")])
8442 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8443   [(set (match_operand:FMOVE64X 0 "register_operand" "=ws")
8444         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8445                          UNSPEC_P8V_RELOAD_FROM_GPR))
8446    (clobber (match_operand:TF 2 "register_operand" "=d"))]
8447   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8448   "#"
8449   "&& reload_completed"
8450   [(const_int 0)]
8452   rtx dest = operands[0];
8453   rtx src = operands[1];
8454   rtx tmp = operands[2];
8455   rtx gpr_hi_reg = gen_highpart (SImode, src);
8456   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8458   emit_insn (gen_p8_mtvsrwz_1 (tmp, gpr_hi_reg));
8459   emit_insn (gen_p8_mtvsrwz_2 (tmp, gpr_lo_reg));
8460   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp));
8461   DONE;
8463   [(set_attr "length" "12")
8464    (set_attr "type" "three")])
8466 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8467 (define_insn "p8_mtvsrd_1"
8468   [(set (match_operand:TF 0 "register_operand" "=ws")
8469         (unspec:TF [(match_operand:DI 1 "register_operand" "r")]
8470                    UNSPEC_P8V_MTVSRD))]
8471   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8472   "mtvsrd %0,%1"
8473   [(set_attr "type" "mftgpr")])
8475 (define_insn "p8_mtvsrd_2"
8476   [(set (match_operand:TF 0 "register_operand" "+ws")
8477         (unspec:TF [(match_dup 0)
8478                     (match_operand:DI 1 "register_operand" "r")]
8479                    UNSPEC_P8V_MTVSRD))]
8480   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8481   "mtvsrd %L0,%1"
8482   [(set_attr "type" "mftgpr")])
8484 (define_insn "p8_xxpermdi_<mode>"
8485   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8486         (unspec:FMOVE128_GPR [(match_operand:TF 1 "register_operand" "ws")]
8487                              UNSPEC_P8V_XXPERMDI))]
8488   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8489   "xxpermdi %x0,%1,%L1,0"
8490   [(set_attr "type" "vecperm")])
8492 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8493   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8494         (unspec:FMOVE128_GPR
8495          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8496          UNSPEC_P8V_RELOAD_FROM_GPR))
8497    (clobber (match_operand:TF 2 "register_operand" "=ws"))]
8498   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8499   "#"
8500   "&& reload_completed"
8501   [(const_int 0)]
8503   rtx dest = operands[0];
8504   rtx src = operands[1];
8505   rtx tmp = operands[2];
8506   rtx gpr_hi_reg = gen_highpart (DImode, src);
8507   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8509   emit_insn (gen_p8_mtvsrd_1 (tmp, gpr_hi_reg));
8510   emit_insn (gen_p8_mtvsrd_2 (tmp, gpr_lo_reg));
8511   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp));
8513   [(set_attr "length" "12")
8514    (set_attr "type" "three")])
8516 (define_split
8517   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8518         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8519   "reload_completed
8520    && (int_reg_operand (operands[0], <MODE>mode)
8521        || int_reg_operand (operands[1], <MODE>mode))"
8522   [(pc)]
8523 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8525 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8526 ;; type is stored internally as double precision in the VSX registers, we have
8527 ;; to convert it from the vector format.
8529 (define_insn_and_split "reload_vsx_from_gprsf"
8530   [(set (match_operand:SF 0 "register_operand" "=wa")
8531         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8532                    UNSPEC_P8V_RELOAD_FROM_GPR))
8533    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8534   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8535   "#"
8536   "&& reload_completed"
8537   [(const_int 0)]
8539   rtx op0 = operands[0];
8540   rtx op1 = operands[1];
8541   rtx op2 = operands[2];
8542   /* Also use the destination register to hold the unconverted DImode value.
8543      This is conceptually a separate value from OP0, so we use gen_rtx_REG
8544      rather than simplify_gen_subreg.  */
8545   rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
8546   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8548   /* Move SF value to upper 32-bits for xscvspdpn.  */
8549   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8550   emit_move_insn (op0_di, op2);
8551   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0_di));
8552   DONE;
8554   [(set_attr "length" "8")
8555    (set_attr "type" "two")])
8557 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8558 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8559 ;; and then doing a move of that.
8560 (define_insn "p8_mfvsrd_3_<mode>"
8561   [(set (match_operand:DF 0 "register_operand" "=r")
8562         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8563                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8564   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8565   "mfvsrd %0,%x1"
8566   [(set_attr "type" "mftgpr")])
8568 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8569   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8570         (unspec:FMOVE128_GPR
8571          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8572          UNSPEC_P8V_RELOAD_FROM_VSX))
8573    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8574   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8575   "#"
8576   "&& reload_completed"
8577   [(const_int 0)]
8579   rtx dest = operands[0];
8580   rtx src = operands[1];
8581   rtx tmp = operands[2];
8582   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8583   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8585   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8586   emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
8587   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8589   [(set_attr "length" "12")
8590    (set_attr "type" "three")])
8592 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8593 ;; type is stored internally as double precision, we have to convert it to the
8594 ;; vector format.
8596 (define_insn_and_split "reload_gpr_from_vsxsf"
8597   [(set (match_operand:SF 0 "register_operand" "=r")
8598         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8599                    UNSPEC_P8V_RELOAD_FROM_VSX))
8600    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8601   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8602   "#"
8603   "&& reload_completed"
8604   [(const_int 0)]
8606   rtx op0 = operands[0];
8607   rtx op1 = operands[1];
8608   rtx op2 = operands[2];
8609   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8611   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8612   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8613   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8614   DONE;
8616   [(set_attr "length" "12")
8617    (set_attr "type" "three")])
8619 (define_insn "p8_mfvsrd_4_disf"
8620   [(set (match_operand:DI 0 "register_operand" "=r")
8621         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8622                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8623   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8624   "mfvsrd %0,%x1"
8625   [(set_attr "type" "mftgpr")])
8628 ;; Next come the multi-word integer load and store and the load and store
8629 ;; multiple insns.
8631 ;; List r->r after r->Y, otherwise reload will try to reload a
8632 ;; non-offsettable address by using r->r which won't make progress.
8633 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8634 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8635 (define_insn "*movdi_internal32"
8636   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
8637         (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
8638   "! TARGET_POWERPC64
8639    && (gpc_reg_operand (operands[0], DImode)
8640        || gpc_reg_operand (operands[1], DImode))"
8641   "@
8642    #
8643    #
8644    #
8645    stfd%U0%X0 %1,%0
8646    lfd%U1%X1 %0,%1
8647    fmr %0,%1
8648    #"
8649   [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
8651 (define_split
8652   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8653         (match_operand:DI 1 "const_int_operand" ""))]
8654   "! TARGET_POWERPC64 && reload_completed
8655    && gpr_or_gpr_p (operands[0], operands[1])
8656    && !direct_move_p (operands[0], operands[1])"
8657   [(set (match_dup 2) (match_dup 4))
8658    (set (match_dup 3) (match_dup 1))]
8659   "
8661   HOST_WIDE_INT value = INTVAL (operands[1]);
8662   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8663                                        DImode);
8664   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8665                                        DImode);
8666   operands[4] = GEN_INT (value >> 32);
8667   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8670 (define_split
8671   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8672         (match_operand:DIFD 1 "input_operand" ""))]
8673   "reload_completed && !TARGET_POWERPC64
8674    && gpr_or_gpr_p (operands[0], operands[1])
8675    && !direct_move_p (operands[0], operands[1])"
8676   [(pc)]
8677 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8679 (define_insn "*movdi_internal64"
8680   [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi")
8681         (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))]
8682   "TARGET_POWERPC64
8683    && (gpc_reg_operand (operands[0], DImode)
8684        || gpc_reg_operand (operands[1], DImode))"
8685   "@
8686    std%U0%X0 %1,%0
8687    ld%U1%X1 %0,%1
8688    mr %0,%1
8689    li %0,%1
8690    lis %0,%v1
8691    #
8692    stfd%U0%X0 %1,%0
8693    lfd%U1%X1 %0,%1
8694    fmr %0,%1
8695    mf%1 %0
8696    mt%0 %1
8697    nop
8698    mftgpr %0,%1
8699    mffgpr %0,%1
8700    mfvsrd %0,%x1
8701    mtvsrd %x0,%1
8702    xxlxor %x0,%x0,%x0"
8703   [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
8704    (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
8706 ;; Generate all one-bits and clear left or right.
8707 ;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber.
8708 (define_split
8709   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8710         (match_operand:DI 1 "mask64_operand" ""))]
8711   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8712   [(set (match_dup 0) (const_int -1))
8713    (set (match_dup 0)
8714         (and:DI (rotate:DI (match_dup 0)
8715                            (const_int 0))
8716                 (match_dup 1)))]
8717   "")
8719 ;; Split a load of a large constant into the appropriate five-instruction
8720 ;; sequence.  Handle anything in a constant number of insns.
8721 ;; When non-easy constants can go in the TOC, this should use
8722 ;; easy_fp_constant predicate.
8723 (define_split
8724   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8725         (match_operand:DI 1 "const_int_operand" ""))]
8726   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8727   [(set (match_dup 0) (match_dup 2))
8728    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8729   "
8731   if (rs6000_emit_set_const (operands[0], operands[1]))
8732     DONE;
8733   else
8734     FAIL;
8737 (define_split
8738   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8739         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8740   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8741   [(set (match_dup 0) (match_dup 2))
8742    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8743   "
8745   if (rs6000_emit_set_const (operands[0], operands[1]))
8746     DONE;
8747   else
8748     FAIL;
8751 ;; TImode/PTImode is similar, except that we usually want to compute the
8752 ;; address into a register and use lsi/stsi (the exception is during reload).
8754 (define_insn "*mov<mode>_string"
8755   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8756         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8757   "! TARGET_POWERPC64
8758    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8759    && (gpc_reg_operand (operands[0], <MODE>mode)
8760        || gpc_reg_operand (operands[1], <MODE>mode))"
8761   "*
8763   switch (which_alternative)
8764     {
8765     default:
8766       gcc_unreachable ();
8767     case 0:
8768       if (TARGET_STRING)
8769         return \"stswi %1,%P0,16\";
8770     case 1:
8771       return \"#\";
8772     case 2:
8773       /* If the address is not used in the output, we can use lsi.  Otherwise,
8774          fall through to generating four loads.  */
8775       if (TARGET_STRING
8776           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8777         return \"lswi %0,%P1,16\";
8778       /* ... fall through ...  */
8779     case 3:
8780     case 4:
8781     case 5:
8782       return \"#\";
8783     }
8785   [(set_attr "type" "store,store,load,load,*,*")
8786    (set_attr "update" "yes")
8787    (set_attr "indexed" "yes")
8788    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8789                                           (const_string "always")
8790                                           (const_string "conditional")))])
8792 (define_insn "*mov<mode>_ppc64"
8793   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8794         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8795   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8796    && (gpc_reg_operand (operands[0], <MODE>mode)
8797        || gpc_reg_operand (operands[1], <MODE>mode)))"
8799   return rs6000_output_move_128bit (operands);
8801   [(set_attr "type" "store,store,load,load,*,*")
8802    (set_attr "length" "8")])
8804 (define_split
8805   [(set (match_operand:TI2 0 "int_reg_operand" "")
8806         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8807   "TARGET_POWERPC64
8808    && (VECTOR_MEM_NONE_P (<MODE>mode)
8809        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8810   [(set (match_dup 2) (match_dup 4))
8811    (set (match_dup 3) (match_dup 5))]
8812   "
8814   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8815                                        <MODE>mode);
8816   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8817                                        <MODE>mode);
8818   if (CONST_WIDE_INT_P (operands[1]))
8819     {
8820       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8821       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8822     }
8823   else if (CONST_INT_P (operands[1]))
8824     {
8825       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8826       operands[5] = operands[1];
8827     }
8828   else
8829     FAIL;
8832 (define_split
8833   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8834         (match_operand:TI2 1 "input_operand" ""))]
8835   "reload_completed
8836    && gpr_or_gpr_p (operands[0], operands[1])
8837    && !direct_move_p (operands[0], operands[1])
8838    && !quad_load_store_p (operands[0], operands[1])"
8839   [(pc)]
8840 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8842 (define_expand "load_multiple"
8843   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8844                           (match_operand:SI 1 "" ""))
8845                      (use (match_operand:SI 2 "" ""))])]
8846   "TARGET_STRING && !TARGET_POWERPC64"
8847   "
8849   int regno;
8850   int count;
8851   rtx op1;
8852   int i;
8854   /* Support only loading a constant number of fixed-point registers from
8855      memory and only bother with this if more than two; the machine
8856      doesn't support more than eight.  */
8857   if (GET_CODE (operands[2]) != CONST_INT
8858       || INTVAL (operands[2]) <= 2
8859       || INTVAL (operands[2]) > 8
8860       || GET_CODE (operands[1]) != MEM
8861       || GET_CODE (operands[0]) != REG
8862       || REGNO (operands[0]) >= 32)
8863     FAIL;
8865   count = INTVAL (operands[2]);
8866   regno = REGNO (operands[0]);
8868   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8869   op1 = replace_equiv_address (operands[1],
8870                                force_reg (SImode, XEXP (operands[1], 0)));
8872   for (i = 0; i < count; i++)
8873     XVECEXP (operands[3], 0, i)
8874       = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regno + i),
8875                      adjust_address_nv (op1, SImode, i * 4));
8878 (define_insn "*ldmsi8"
8879   [(match_parallel 0 "load_multiple_operation"
8880     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8881           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8882      (set (match_operand:SI 3 "gpc_reg_operand" "")
8883           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8884      (set (match_operand:SI 4 "gpc_reg_operand" "")
8885           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8886      (set (match_operand:SI 5 "gpc_reg_operand" "")
8887           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8888      (set (match_operand:SI 6 "gpc_reg_operand" "")
8889           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8890      (set (match_operand:SI 7 "gpc_reg_operand" "")
8891           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8892      (set (match_operand:SI 8 "gpc_reg_operand" "")
8893           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8894      (set (match_operand:SI 9 "gpc_reg_operand" "")
8895           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8896   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8897   "*
8898 { return rs6000_output_load_multiple (operands); }"
8899   [(set_attr "type" "load")
8900    (set_attr "update" "yes")
8901    (set_attr "indexed" "yes")
8902    (set_attr "length" "32")])
8904 (define_insn "*ldmsi7"
8905   [(match_parallel 0 "load_multiple_operation"
8906     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8907           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8908      (set (match_operand:SI 3 "gpc_reg_operand" "")
8909           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8910      (set (match_operand:SI 4 "gpc_reg_operand" "")
8911           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8912      (set (match_operand:SI 5 "gpc_reg_operand" "")
8913           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8914      (set (match_operand:SI 6 "gpc_reg_operand" "")
8915           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8916      (set (match_operand:SI 7 "gpc_reg_operand" "")
8917           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8918      (set (match_operand:SI 8 "gpc_reg_operand" "")
8919           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8920   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8921   "*
8922 { return rs6000_output_load_multiple (operands); }"
8923   [(set_attr "type" "load")
8924    (set_attr "update" "yes")
8925    (set_attr "indexed" "yes")
8926    (set_attr "length" "32")])
8928 (define_insn "*ldmsi6"
8929   [(match_parallel 0 "load_multiple_operation"
8930     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8931           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8932      (set (match_operand:SI 3 "gpc_reg_operand" "")
8933           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8934      (set (match_operand:SI 4 "gpc_reg_operand" "")
8935           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8936      (set (match_operand:SI 5 "gpc_reg_operand" "")
8937           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8938      (set (match_operand:SI 6 "gpc_reg_operand" "")
8939           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8940      (set (match_operand:SI 7 "gpc_reg_operand" "")
8941           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8942   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8943   "*
8944 { return rs6000_output_load_multiple (operands); }"
8945   [(set_attr "type" "load")
8946    (set_attr "update" "yes")
8947    (set_attr "indexed" "yes")
8948    (set_attr "length" "32")])
8950 (define_insn "*ldmsi5"
8951   [(match_parallel 0 "load_multiple_operation"
8952     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8953           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8954      (set (match_operand:SI 3 "gpc_reg_operand" "")
8955           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8956      (set (match_operand:SI 4 "gpc_reg_operand" "")
8957           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8958      (set (match_operand:SI 5 "gpc_reg_operand" "")
8959           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8960      (set (match_operand:SI 6 "gpc_reg_operand" "")
8961           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8962   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8963   "*
8964 { return rs6000_output_load_multiple (operands); }"
8965   [(set_attr "type" "load")
8966    (set_attr "update" "yes")
8967    (set_attr "indexed" "yes")
8968    (set_attr "length" "32")])
8970 (define_insn "*ldmsi4"
8971   [(match_parallel 0 "load_multiple_operation"
8972     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8973           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8974      (set (match_operand:SI 3 "gpc_reg_operand" "")
8975           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8976      (set (match_operand:SI 4 "gpc_reg_operand" "")
8977           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8978      (set (match_operand:SI 5 "gpc_reg_operand" "")
8979           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8980   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8981   "*
8982 { return rs6000_output_load_multiple (operands); }"
8983   [(set_attr "type" "load")
8984    (set_attr "update" "yes")
8985    (set_attr "indexed" "yes")
8986    (set_attr "length" "32")])
8988 (define_insn "*ldmsi3"
8989   [(match_parallel 0 "load_multiple_operation"
8990     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8991           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8992      (set (match_operand:SI 3 "gpc_reg_operand" "")
8993           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8994      (set (match_operand:SI 4 "gpc_reg_operand" "")
8995           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8996   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8997   "*
8998 { return rs6000_output_load_multiple (operands); }"
8999   [(set_attr "type" "load")
9000    (set_attr "update" "yes")
9001    (set_attr "indexed" "yes")
9002    (set_attr "length" "32")])
9004 (define_expand "store_multiple"
9005   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
9006                           (match_operand:SI 1 "" ""))
9007                      (clobber (scratch:SI))
9008                      (use (match_operand:SI 2 "" ""))])]
9009   "TARGET_STRING && !TARGET_POWERPC64"
9010   "
9012   int regno;
9013   int count;
9014   rtx to;
9015   rtx op0;
9016   int i;
9018   /* Support only storing a constant number of fixed-point registers to
9019      memory and only bother with this if more than two; the machine
9020      doesn't support more than eight.  */
9021   if (GET_CODE (operands[2]) != CONST_INT
9022       || INTVAL (operands[2]) <= 2
9023       || INTVAL (operands[2]) > 8
9024       || GET_CODE (operands[0]) != MEM
9025       || GET_CODE (operands[1]) != REG
9026       || REGNO (operands[1]) >= 32)
9027     FAIL;
9029   count = INTVAL (operands[2]);
9030   regno = REGNO (operands[1]);
9032   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
9033   to = force_reg (SImode, XEXP (operands[0], 0));
9034   op0 = replace_equiv_address (operands[0], to);
9036   XVECEXP (operands[3], 0, 0)
9037     = gen_rtx_SET (VOIDmode, adjust_address_nv (op0, SImode, 0), operands[1]);
9038   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
9039                                                  gen_rtx_SCRATCH (SImode));
9041   for (i = 1; i < count; i++)
9042     XVECEXP (operands[3], 0, i + 1)
9043       = gen_rtx_SET (VOIDmode,
9044                      adjust_address_nv (op0, SImode, i * 4),
9045                      gen_rtx_REG (SImode, regno + i));
9048 (define_insn "*stmsi8"
9049   [(match_parallel 0 "store_multiple_operation"
9050     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9051           (match_operand:SI 2 "gpc_reg_operand" "r"))
9052      (clobber (match_scratch:SI 3 "=X"))
9053      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9054           (match_operand:SI 4 "gpc_reg_operand" "r"))
9055      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9056           (match_operand:SI 5 "gpc_reg_operand" "r"))
9057      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9058           (match_operand:SI 6 "gpc_reg_operand" "r"))
9059      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9060           (match_operand:SI 7 "gpc_reg_operand" "r"))
9061      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9062           (match_operand:SI 8 "gpc_reg_operand" "r"))
9063      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9064           (match_operand:SI 9 "gpc_reg_operand" "r"))
9065      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9066           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9067   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9068   "stswi %2,%1,%O0"
9069   [(set_attr "type" "store")
9070    (set_attr "update" "yes")
9071    (set_attr "indexed" "yes")
9072    (set_attr "cell_micro" "always")])
9074 (define_insn "*stmsi7"
9075   [(match_parallel 0 "store_multiple_operation"
9076     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9077           (match_operand:SI 2 "gpc_reg_operand" "r"))
9078      (clobber (match_scratch:SI 3 "=X"))
9079      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9080           (match_operand:SI 4 "gpc_reg_operand" "r"))
9081      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9082           (match_operand:SI 5 "gpc_reg_operand" "r"))
9083      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9084           (match_operand:SI 6 "gpc_reg_operand" "r"))
9085      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9086           (match_operand:SI 7 "gpc_reg_operand" "r"))
9087      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9088           (match_operand:SI 8 "gpc_reg_operand" "r"))
9089      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9090           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9091   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9092   "stswi %2,%1,%O0"
9093   [(set_attr "type" "store")
9094    (set_attr "update" "yes")
9095    (set_attr "indexed" "yes")
9096    (set_attr "cell_micro" "always")])
9098 (define_insn "*stmsi6"
9099   [(match_parallel 0 "store_multiple_operation"
9100     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9101           (match_operand:SI 2 "gpc_reg_operand" "r"))
9102      (clobber (match_scratch:SI 3 "=X"))
9103      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9104           (match_operand:SI 4 "gpc_reg_operand" "r"))
9105      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9106           (match_operand:SI 5 "gpc_reg_operand" "r"))
9107      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9108           (match_operand:SI 6 "gpc_reg_operand" "r"))
9109      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9110           (match_operand:SI 7 "gpc_reg_operand" "r"))
9111      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9112           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9113   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9114   "stswi %2,%1,%O0"
9115   [(set_attr "type" "store")
9116    (set_attr "update" "yes")
9117    (set_attr "indexed" "yes")
9118    (set_attr "cell_micro" "always")])
9120 (define_insn "*stmsi5"
9121   [(match_parallel 0 "store_multiple_operation"
9122     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9123           (match_operand:SI 2 "gpc_reg_operand" "r"))
9124      (clobber (match_scratch:SI 3 "=X"))
9125      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9126           (match_operand:SI 4 "gpc_reg_operand" "r"))
9127      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9128           (match_operand:SI 5 "gpc_reg_operand" "r"))
9129      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9130           (match_operand:SI 6 "gpc_reg_operand" "r"))
9131      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9132           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9133   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9134   "stswi %2,%1,%O0"
9135   [(set_attr "type" "store")
9136    (set_attr "update" "yes")
9137    (set_attr "indexed" "yes")
9138    (set_attr "cell_micro" "always")])
9140 (define_insn "*stmsi4"
9141   [(match_parallel 0 "store_multiple_operation"
9142     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9143           (match_operand:SI 2 "gpc_reg_operand" "r"))
9144      (clobber (match_scratch:SI 3 "=X"))
9145      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9146           (match_operand:SI 4 "gpc_reg_operand" "r"))
9147      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9148           (match_operand:SI 5 "gpc_reg_operand" "r"))
9149      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9150           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9151   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9152   "stswi %2,%1,%O0"
9153   [(set_attr "type" "store")
9154    (set_attr "update" "yes")
9155    (set_attr "indexed" "yes")
9156    (set_attr "cell_micro" "always")])
9158 (define_insn "*stmsi3"
9159   [(match_parallel 0 "store_multiple_operation"
9160     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9161           (match_operand:SI 2 "gpc_reg_operand" "r"))
9162      (clobber (match_scratch:SI 3 "=X"))
9163      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9164           (match_operand:SI 4 "gpc_reg_operand" "r"))
9165      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9166           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9167   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9168   "stswi %2,%1,%O0"
9169   [(set_attr "type" "store")
9170    (set_attr "update" "yes")
9171    (set_attr "indexed" "yes")
9172    (set_attr "cell_micro" "always")])
9174 (define_expand "setmemsi"
9175   [(parallel [(set (match_operand:BLK 0 "" "")
9176                    (match_operand 2 "const_int_operand" ""))
9177               (use (match_operand:SI 1 "" ""))
9178               (use (match_operand:SI 3 "" ""))])]
9179   ""
9180   "
9182   /* If value to set is not zero, use the library routine.  */
9183   if (operands[2] != const0_rtx)
9184     FAIL;
9186   if (expand_block_clear (operands))
9187     DONE;
9188   else
9189     FAIL;
9192 ;; String/block move insn.
9193 ;; Argument 0 is the destination
9194 ;; Argument 1 is the source
9195 ;; Argument 2 is the length
9196 ;; Argument 3 is the alignment
9198 (define_expand "movmemsi"
9199   [(parallel [(set (match_operand:BLK 0 "" "")
9200                    (match_operand:BLK 1 "" ""))
9201               (use (match_operand:SI 2 "" ""))
9202               (use (match_operand:SI 3 "" ""))])]
9203   ""
9204   "
9206   if (expand_block_move (operands))
9207     DONE;
9208   else
9209     FAIL;
9212 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
9213 ;; register allocator doesn't have a clue about allocating 8 word registers.
9214 ;; rD/rS = r5 is preferred, efficient form.
9215 (define_expand "movmemsi_8reg"
9216   [(parallel [(set (match_operand 0 "" "")
9217                    (match_operand 1 "" ""))
9218               (use (match_operand 2 "" ""))
9219               (use (match_operand 3 "" ""))
9220               (clobber (reg:SI  5))
9221               (clobber (reg:SI  6))
9222               (clobber (reg:SI  7))
9223               (clobber (reg:SI  8))
9224               (clobber (reg:SI  9))
9225               (clobber (reg:SI 10))
9226               (clobber (reg:SI 11))
9227               (clobber (reg:SI 12))
9228               (clobber (match_scratch:SI 4 ""))])]
9229   "TARGET_STRING"
9230   "")
9232 (define_insn ""
9233   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9234         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9235    (use (match_operand:SI 2 "immediate_operand" "i"))
9236    (use (match_operand:SI 3 "immediate_operand" "i"))
9237    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9238    (clobber (reg:SI  6))
9239    (clobber (reg:SI  7))
9240    (clobber (reg:SI  8))
9241    (clobber (reg:SI  9))
9242    (clobber (reg:SI 10))
9243    (clobber (reg:SI 11))
9244    (clobber (reg:SI 12))
9245    (clobber (match_scratch:SI 5 "=X"))]
9246   "TARGET_STRING
9247    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9248        || INTVAL (operands[2]) == 0)
9249    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9250    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9251    && REGNO (operands[4]) == 5"
9252   "lswi %4,%1,%2\;stswi %4,%0,%2"
9253   [(set_attr "type" "store")
9254    (set_attr "update" "yes")
9255    (set_attr "indexed" "yes")
9256    (set_attr "cell_micro" "always")
9257    (set_attr "length" "8")])
9259 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
9260 ;; register allocator doesn't have a clue about allocating 6 word registers.
9261 ;; rD/rS = r5 is preferred, efficient form.
9262 (define_expand "movmemsi_6reg"
9263   [(parallel [(set (match_operand 0 "" "")
9264                    (match_operand 1 "" ""))
9265               (use (match_operand 2 "" ""))
9266               (use (match_operand 3 "" ""))
9267               (clobber (reg:SI  5))
9268               (clobber (reg:SI  6))
9269               (clobber (reg:SI  7))
9270               (clobber (reg:SI  8))
9271               (clobber (reg:SI  9))
9272               (clobber (reg:SI 10))
9273               (clobber (match_scratch:SI 4 ""))])]
9274   "TARGET_STRING"
9275   "")
9277 (define_insn ""
9278   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9279         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9280    (use (match_operand:SI 2 "immediate_operand" "i"))
9281    (use (match_operand:SI 3 "immediate_operand" "i"))
9282    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9283    (clobber (reg:SI  6))
9284    (clobber (reg:SI  7))
9285    (clobber (reg:SI  8))
9286    (clobber (reg:SI  9))
9287    (clobber (reg:SI 10))
9288    (clobber (match_scratch:SI 5 "=X"))]
9289   "TARGET_STRING
9290    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9291    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9292    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9293    && REGNO (operands[4]) == 5"
9294   "lswi %4,%1,%2\;stswi %4,%0,%2"
9295   [(set_attr "type" "store")
9296    (set_attr "update" "yes")
9297    (set_attr "indexed" "yes")
9298    (set_attr "cell_micro" "always")
9299    (set_attr "length" "8")])
9301 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9302 ;; problems with TImode.
9303 ;; rD/rS = r5 is preferred, efficient form.
9304 (define_expand "movmemsi_4reg"
9305   [(parallel [(set (match_operand 0 "" "")
9306                    (match_operand 1 "" ""))
9307               (use (match_operand 2 "" ""))
9308               (use (match_operand 3 "" ""))
9309               (clobber (reg:SI 5))
9310               (clobber (reg:SI 6))
9311               (clobber (reg:SI 7))
9312               (clobber (reg:SI 8))
9313               (clobber (match_scratch:SI 4 ""))])]
9314   "TARGET_STRING"
9315   "")
9317 (define_insn ""
9318   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9319         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9320    (use (match_operand:SI 2 "immediate_operand" "i"))
9321    (use (match_operand:SI 3 "immediate_operand" "i"))
9322    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9323    (clobber (reg:SI 6))
9324    (clobber (reg:SI 7))
9325    (clobber (reg:SI 8))
9326    (clobber (match_scratch:SI 5 "=X"))]
9327   "TARGET_STRING
9328    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9329    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9330    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9331    && REGNO (operands[4]) == 5"
9332   "lswi %4,%1,%2\;stswi %4,%0,%2"
9333   [(set_attr "type" "store")
9334    (set_attr "update" "yes")
9335    (set_attr "indexed" "yes")
9336    (set_attr "cell_micro" "always")
9337    (set_attr "length" "8")])
9339 ;; Move up to 8 bytes at a time.
9340 (define_expand "movmemsi_2reg"
9341   [(parallel [(set (match_operand 0 "" "")
9342                    (match_operand 1 "" ""))
9343               (use (match_operand 2 "" ""))
9344               (use (match_operand 3 "" ""))
9345               (clobber (match_scratch:DI 4 ""))
9346               (clobber (match_scratch:SI 5 ""))])]
9347   "TARGET_STRING && ! TARGET_POWERPC64"
9348   "")
9350 (define_insn ""
9351   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9352         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9353    (use (match_operand:SI 2 "immediate_operand" "i"))
9354    (use (match_operand:SI 3 "immediate_operand" "i"))
9355    (clobber (match_scratch:DI 4 "=&r"))
9356    (clobber (match_scratch:SI 5 "=X"))]
9357   "TARGET_STRING && ! TARGET_POWERPC64
9358    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9359   "lswi %4,%1,%2\;stswi %4,%0,%2"
9360   [(set_attr "type" "store")
9361    (set_attr "update" "yes")
9362    (set_attr "indexed" "yes")
9363    (set_attr "cell_micro" "always")
9364    (set_attr "length" "8")])
9366 ;; Move up to 4 bytes at a time.
9367 (define_expand "movmemsi_1reg"
9368   [(parallel [(set (match_operand 0 "" "")
9369                    (match_operand 1 "" ""))
9370               (use (match_operand 2 "" ""))
9371               (use (match_operand 3 "" ""))
9372               (clobber (match_scratch:SI 4 ""))
9373               (clobber (match_scratch:SI 5 ""))])]
9374   "TARGET_STRING"
9375   "")
9377 (define_insn ""
9378   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9379         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9380    (use (match_operand:SI 2 "immediate_operand" "i"))
9381    (use (match_operand:SI 3 "immediate_operand" "i"))
9382    (clobber (match_scratch:SI 4 "=&r"))
9383    (clobber (match_scratch:SI 5 "=X"))]
9384   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9385   "lswi %4,%1,%2\;stswi %4,%0,%2"
9386   [(set_attr "type" "store")
9387    (set_attr "update" "yes")
9388    (set_attr "indexed" "yes")
9389    (set_attr "cell_micro" "always")
9390    (set_attr "length" "8")])
9392 ;; Define insns that do load or store with update.  Some of these we can
9393 ;; get by using pre-decrement or pre-increment, but the hardware can also
9394 ;; do cases where the increment is not the size of the object.
9396 ;; In all these cases, we use operands 0 and 1 for the register being
9397 ;; incremented because those are the operands that local-alloc will
9398 ;; tie and these are the pair most likely to be tieable (and the ones
9399 ;; that will benefit the most).
9401 (define_insn "*movdi_update1"
9402   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9403         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9404                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9405    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9406         (plus:DI (match_dup 1) (match_dup 2)))]
9407   "TARGET_POWERPC64 && TARGET_UPDATE
9408    && (!avoiding_indexed_address_p (DImode)
9409        || !gpc_reg_operand (operands[2], DImode))"
9410   "@
9411    ldux %3,%0,%2
9412    ldu %3,%2(%0)"
9413   [(set_attr "type" "load")
9414    (set_attr "update" "yes")
9415    (set_attr "indexed" "yes,no")])
9417 (define_insn "movdi_<mode>_update"
9418   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9419                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9420         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9421    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9422         (plus:P (match_dup 1) (match_dup 2)))]
9423   "TARGET_POWERPC64 && TARGET_UPDATE
9424    && (!avoiding_indexed_address_p (Pmode)
9425        || !gpc_reg_operand (operands[2], Pmode)
9426        || (REG_P (operands[0])
9427            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9428   "@
9429    stdux %3,%0,%2
9430    stdu %3,%2(%0)"
9431   [(set_attr "type" "store")
9432    (set_attr "update" "yes")
9433    (set_attr "indexed" "yes,no")])
9435 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9436 ;; needed for stack allocation, even if the user passes -mno-update.
9437 (define_insn "movdi_<mode>_update_stack"
9438   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9439                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9440         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9441    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9442         (plus:P (match_dup 1) (match_dup 2)))]
9443   "TARGET_POWERPC64"
9444   "@
9445    stdux %3,%0,%2
9446    stdu %3,%2(%0)"
9447   [(set_attr "type" "store")
9448    (set_attr "update" "yes")
9449    (set_attr "indexed" "yes,no")])
9451 (define_insn "*movsi_update1"
9452   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9453         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9454                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9455    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9456         (plus:SI (match_dup 1) (match_dup 2)))]
9457   "TARGET_UPDATE
9458    && (!avoiding_indexed_address_p (SImode)
9459        || !gpc_reg_operand (operands[2], SImode))"
9460   "@
9461    lwzux %3,%0,%2
9462    lwzu %3,%2(%0)"
9463   [(set_attr "type" "load")
9464    (set_attr "update" "yes")
9465    (set_attr "indexed" "yes,no")])
9467 (define_insn "*movsi_update2"
9468   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9469         (sign_extend:DI
9470          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9471                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9472    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9473         (plus:DI (match_dup 1) (match_dup 2)))]
9474   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9475    && !avoiding_indexed_address_p (DImode)"
9476   "lwaux %3,%0,%2"
9477   [(set_attr "type" "load")
9478    (set_attr "sign_extend" "yes")
9479    (set_attr "update" "yes")
9480    (set_attr "indexed" "yes")])
9482 (define_insn "movsi_update"
9483   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9484                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9485         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9486    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9487         (plus:SI (match_dup 1) (match_dup 2)))]
9488   "TARGET_UPDATE
9489    && (!avoiding_indexed_address_p (SImode)
9490        || !gpc_reg_operand (operands[2], SImode)
9491        || (REG_P (operands[0])
9492            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9493   "@
9494    stwux %3,%0,%2
9495    stwu %3,%2(%0)"
9496   [(set_attr "type" "store")
9497    (set_attr "update" "yes")
9498    (set_attr "indexed" "yes,no")])
9500 ;; This is an unconditional pattern; needed for stack allocation, even
9501 ;; if the user passes -mno-update.
9502 (define_insn "movsi_update_stack"
9503   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9504                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9505         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9506    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9507         (plus:SI (match_dup 1) (match_dup 2)))]
9508   ""
9509   "@
9510    stwux %3,%0,%2
9511    stwu %3,%2(%0)"
9512   [(set_attr "type" "store")
9513    (set_attr "update" "yes")
9514    (set_attr "indexed" "yes,no")])
9516 (define_insn "*movhi_update1"
9517   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9518         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9519                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9520    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9521         (plus:SI (match_dup 1) (match_dup 2)))]
9522   "TARGET_UPDATE
9523    && (!avoiding_indexed_address_p (SImode)
9524        || !gpc_reg_operand (operands[2], SImode))"
9525   "@
9526    lhzux %3,%0,%2
9527    lhzu %3,%2(%0)"
9528   [(set_attr "type" "load")
9529    (set_attr "update" "yes")
9530    (set_attr "indexed" "yes,no")])
9532 (define_insn "*movhi_update2"
9533   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9534         (zero_extend:SI
9535          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9536                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9537    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9538         (plus:SI (match_dup 1) (match_dup 2)))]
9539   "TARGET_UPDATE
9540    && (!avoiding_indexed_address_p (SImode)
9541        || !gpc_reg_operand (operands[2], SImode))"
9542   "@
9543    lhzux %3,%0,%2
9544    lhzu %3,%2(%0)"
9545   [(set_attr "type" "load")
9546    (set_attr "update" "yes")
9547    (set_attr "indexed" "yes,no")])
9549 (define_insn "*movhi_update3"
9550   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9551         (sign_extend:SI
9552          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9553                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9554    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9555         (plus:SI (match_dup 1) (match_dup 2)))]
9556   "TARGET_UPDATE && rs6000_gen_cell_microcode
9557    && (!avoiding_indexed_address_p (SImode)
9558        || !gpc_reg_operand (operands[2], SImode))"
9559   "@
9560    lhaux %3,%0,%2
9561    lhau %3,%2(%0)"
9562   [(set_attr "type" "load")
9563    (set_attr "sign_extend" "yes")
9564    (set_attr "update" "yes")
9565    (set_attr "indexed" "yes,no")])
9567 (define_insn "*movhi_update4"
9568   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9569                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9570         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9571    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9572         (plus:SI (match_dup 1) (match_dup 2)))]
9573   "TARGET_UPDATE
9574    && (!avoiding_indexed_address_p (SImode)
9575        || !gpc_reg_operand (operands[2], SImode))"
9576   "@
9577    sthux %3,%0,%2
9578    sthu %3,%2(%0)"
9579   [(set_attr "type" "store")
9580    (set_attr "update" "yes")
9581    (set_attr "indexed" "yes,no")])
9583 (define_insn "*movqi_update1"
9584   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9585         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9586                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9587    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9588         (plus:SI (match_dup 1) (match_dup 2)))]
9589   "TARGET_UPDATE
9590    && (!avoiding_indexed_address_p (SImode)
9591        || !gpc_reg_operand (operands[2], SImode))"
9592   "@
9593    lbzux %3,%0,%2
9594    lbzu %3,%2(%0)"
9595   [(set_attr "type" "load")
9596    (set_attr "update" "yes")
9597    (set_attr "indexed" "yes,no")])
9599 (define_insn "*movqi_update2"
9600   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9601         (zero_extend:SI
9602          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9603                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9604    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9605         (plus:SI (match_dup 1) (match_dup 2)))]
9606   "TARGET_UPDATE
9607    && (!avoiding_indexed_address_p (SImode)
9608        || !gpc_reg_operand (operands[2], SImode))"
9609   "@
9610    lbzux %3,%0,%2
9611    lbzu %3,%2(%0)"
9612   [(set_attr "type" "load")
9613    (set_attr "update" "yes")
9614    (set_attr "indexed" "yes,no")])
9616 (define_insn "*movqi_update3"
9617   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9618                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9619         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9620    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9621         (plus:SI (match_dup 1) (match_dup 2)))]
9622   "TARGET_UPDATE
9623    && (!avoiding_indexed_address_p (SImode)
9624        || !gpc_reg_operand (operands[2], SImode))"
9625   "@
9626    stbux %3,%0,%2
9627    stbu %3,%2(%0)"
9628   [(set_attr "type" "store")
9629    (set_attr "update" "yes")
9630    (set_attr "indexed" "yes,no")])
9632 (define_insn "*movsf_update1"
9633   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9634         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9635                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9636    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9637         (plus:SI (match_dup 1) (match_dup 2)))]
9638   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9639    && (!avoiding_indexed_address_p (SImode)
9640        || !gpc_reg_operand (operands[2], SImode))"
9641   "@
9642    lfsux %3,%0,%2
9643    lfsu %3,%2(%0)"
9644   [(set_attr "type" "fpload")
9645    (set_attr "update" "yes")
9646    (set_attr "indexed" "yes,no")])
9648 (define_insn "*movsf_update2"
9649   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9650                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9651         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9652    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9653         (plus:SI (match_dup 1) (match_dup 2)))]
9654   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9655    && (!avoiding_indexed_address_p (SImode)
9656        || !gpc_reg_operand (operands[2], SImode))"
9657   "@
9658    stfsux %3,%0,%2
9659    stfsu %3,%2(%0)"
9660   [(set_attr "type" "fpstore")
9661    (set_attr "update" "yes")
9662    (set_attr "indexed" "yes,no")])
9664 (define_insn "*movsf_update3"
9665   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9666         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9667                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9668    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9669         (plus:SI (match_dup 1) (match_dup 2)))]
9670   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9671    && (!avoiding_indexed_address_p (SImode)
9672        || !gpc_reg_operand (operands[2], SImode))"
9673   "@
9674    lwzux %3,%0,%2
9675    lwzu %3,%2(%0)"
9676   [(set_attr "type" "load")
9677    (set_attr "update" "yes")
9678    (set_attr "indexed" "yes,no")])
9680 (define_insn "*movsf_update4"
9681   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9682                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9683         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9684    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9685         (plus:SI (match_dup 1) (match_dup 2)))]
9686   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9687    && (!avoiding_indexed_address_p (SImode)
9688        || !gpc_reg_operand (operands[2], SImode))"
9689   "@
9690    stwux %3,%0,%2
9691    stwu %3,%2(%0)"
9692   [(set_attr "type" "store")
9693    (set_attr "update" "yes")
9694    (set_attr "indexed" "yes,no")])
9696 (define_insn "*movdf_update1"
9697   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9698         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9699                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9700    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9701         (plus:SI (match_dup 1) (match_dup 2)))]
9702   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9703    && (!avoiding_indexed_address_p (SImode)
9704        || !gpc_reg_operand (operands[2], SImode))"
9705   "@
9706    lfdux %3,%0,%2
9707    lfdu %3,%2(%0)"
9708   [(set_attr "type" "fpload")
9709    (set_attr "update" "yes")
9710    (set_attr "indexed" "yes,no")])
9712 (define_insn "*movdf_update2"
9713   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9714                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9715         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9716    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9717         (plus:SI (match_dup 1) (match_dup 2)))]
9718   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9719    && (!avoiding_indexed_address_p (SImode)
9720        || !gpc_reg_operand (operands[2], SImode))"
9721   "@
9722    stfdux %3,%0,%2
9723    stfdu %3,%2(%0)"
9724   [(set_attr "type" "fpstore")
9725    (set_attr "update" "yes")
9726    (set_attr "indexed" "yes,no")])
9729 ;; After inserting conditional returns we can sometimes have
9730 ;; unnecessary register moves.  Unfortunately we cannot have a
9731 ;; modeless peephole here, because some single SImode sets have early
9732 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9733 ;; sequences, using get_attr_length here will smash the operands
9734 ;; array.  Neither is there an early_cobbler_p predicate.
9735 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9736 (define_peephole2
9737   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9738         (match_operand:DF 1 "any_operand" ""))
9739    (set (match_operand:DF 2 "gpc_reg_operand" "")
9740         (match_dup 0))]
9741   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9742    && peep2_reg_dead_p (2, operands[0])"
9743   [(set (match_dup 2) (match_dup 1))])
9745 (define_peephole2
9746   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9747         (match_operand:SF 1 "any_operand" ""))
9748    (set (match_operand:SF 2 "gpc_reg_operand" "")
9749         (match_dup 0))]
9750   "peep2_reg_dead_p (2, operands[0])"
9751   [(set (match_dup 2) (match_dup 1))])
9754 ;; TLS support.
9756 ;; Mode attributes for different ABIs.
9757 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9758 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9759 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9760 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9762 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9763   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9764         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9765               (match_operand 4 "" "g")))
9766    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9767                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9768                    UNSPEC_TLSGD)
9769    (clobber (reg:SI LR_REGNO))]
9770   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9772   if (TARGET_CMODEL != CMODEL_SMALL)
9773     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9774            "bl %z3\;nop";
9775   else
9776     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9778   "&& TARGET_TLS_MARKERS"
9779   [(set (match_dup 0)
9780         (unspec:TLSmode [(match_dup 1)
9781                          (match_dup 2)]
9782                         UNSPEC_TLSGD))
9783    (parallel [(set (match_dup 0)
9784                    (call (mem:TLSmode (match_dup 3))
9785                          (match_dup 4)))
9786               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9787               (clobber (reg:SI LR_REGNO))])]
9788   ""
9789   [(set_attr "type" "two")
9790    (set (attr "length")
9791      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9792                    (const_int 16)
9793                    (const_int 12)))])
9795 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9796   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9797         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9798               (match_operand 4 "" "g")))
9799    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9800                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9801                    UNSPEC_TLSGD)
9802    (clobber (reg:SI LR_REGNO))]
9803   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9805   if (flag_pic)
9806     {
9807       if (TARGET_SECURE_PLT && flag_pic == 2)
9808         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9809       else
9810         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9811     }
9812   else
9813     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9815   "&& TARGET_TLS_MARKERS"
9816   [(set (match_dup 0)
9817         (unspec:TLSmode [(match_dup 1)
9818                          (match_dup 2)]
9819                         UNSPEC_TLSGD))
9820    (parallel [(set (match_dup 0)
9821                    (call (mem:TLSmode (match_dup 3))
9822                          (match_dup 4)))
9823               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9824               (clobber (reg:SI LR_REGNO))])]
9825   ""
9826   [(set_attr "type" "two")
9827    (set_attr "length" "8")])
9829 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9830   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9831         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9832                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9833                         UNSPEC_TLSGD))]
9834   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9835   "addi %0,%1,%2@got@tlsgd"
9836   "&& TARGET_CMODEL != CMODEL_SMALL"
9837   [(set (match_dup 3)
9838         (high:TLSmode
9839             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9840    (set (match_dup 0)
9841         (lo_sum:TLSmode (match_dup 3)
9842             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9843   "
9845   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9847   [(set (attr "length")
9848      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9849                    (const_int 8)
9850                    (const_int 4)))])
9852 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9853   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9854      (high:TLSmode
9855        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9856                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9857                        UNSPEC_TLSGD)))]
9858   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9859   "addis %0,%1,%2@got@tlsgd@ha"
9860   [(set_attr "length" "4")])
9862 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9863   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9864      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9865        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9866                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9867                        UNSPEC_TLSGD)))]
9868   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9869   "addi %0,%1,%2@got@tlsgd@l"
9870   [(set_attr "length" "4")])
9872 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9873   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9874         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9875               (match_operand 2 "" "g")))
9876    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9877                    UNSPEC_TLSGD)
9878    (clobber (reg:SI LR_REGNO))]
9879   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9880    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9881   "bl %z1(%3@tlsgd)\;nop"
9882   [(set_attr "type" "branch")
9883    (set_attr "length" "8")])
9885 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9886   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9887         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9888               (match_operand 2 "" "g")))
9889    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9890                    UNSPEC_TLSGD)
9891    (clobber (reg:SI LR_REGNO))]
9892   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9894   if (flag_pic)
9895     {
9896       if (TARGET_SECURE_PLT && flag_pic == 2)
9897         return "bl %z1+32768(%3@tlsgd)@plt";
9898       return "bl %z1(%3@tlsgd)@plt";
9899     }
9900   return "bl %z1(%3@tlsgd)";
9902   [(set_attr "type" "branch")
9903    (set_attr "length" "4")])
9905 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9906   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9907         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9908               (match_operand 3 "" "g")))
9909    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9910                    UNSPEC_TLSLD)
9911    (clobber (reg:SI LR_REGNO))]
9912   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9914   if (TARGET_CMODEL != CMODEL_SMALL)
9915     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9916            "bl %z2\;nop";
9917   else
9918     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9920   "&& TARGET_TLS_MARKERS"
9921   [(set (match_dup 0)
9922         (unspec:TLSmode [(match_dup 1)]
9923                         UNSPEC_TLSLD))
9924    (parallel [(set (match_dup 0)
9925                    (call (mem:TLSmode (match_dup 2))
9926                          (match_dup 3)))
9927               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9928               (clobber (reg:SI LR_REGNO))])]
9929   ""
9930   [(set_attr "type" "two")
9931    (set (attr "length")
9932      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9933                    (const_int 16)
9934                    (const_int 12)))])
9936 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9937   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9938         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9939               (match_operand 3 "" "g")))
9940    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9941                    UNSPEC_TLSLD)
9942    (clobber (reg:SI LR_REGNO))]
9943   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9945   if (flag_pic)
9946     {
9947       if (TARGET_SECURE_PLT && flag_pic == 2)
9948         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9949       else
9950         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9951     }
9952   else
9953     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9955   "&& TARGET_TLS_MARKERS"
9956   [(set (match_dup 0)
9957         (unspec:TLSmode [(match_dup 1)]
9958                         UNSPEC_TLSLD))
9959    (parallel [(set (match_dup 0)
9960                    (call (mem:TLSmode (match_dup 2))
9961                          (match_dup 3)))
9962               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9963               (clobber (reg:SI LR_REGNO))])]
9964   ""
9965   [(set_attr "length" "8")])
9967 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9968   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9969         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9970                         UNSPEC_TLSLD))]
9971   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9972   "addi %0,%1,%&@got@tlsld"
9973   "&& TARGET_CMODEL != CMODEL_SMALL"
9974   [(set (match_dup 2)
9975         (high:TLSmode
9976             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9977    (set (match_dup 0)
9978         (lo_sum:TLSmode (match_dup 2)
9979             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9980   "
9982   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9984   [(set (attr "length")
9985      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9986                    (const_int 8)
9987                    (const_int 4)))])
9989 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9990   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9991      (high:TLSmode
9992        (unspec:TLSmode [(const_int 0)
9993                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9994                        UNSPEC_TLSLD)))]
9995   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9996   "addis %0,%1,%&@got@tlsld@ha"
9997   [(set_attr "length" "4")])
9999 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10000   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10001      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10002        (unspec:TLSmode [(const_int 0)
10003                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10004                        UNSPEC_TLSLD)))]
10005   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10006   "addi %0,%1,%&@got@tlsld@l"
10007   [(set_attr "length" "4")])
10009 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10010   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10011         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10012               (match_operand 2 "" "g")))
10013    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10014    (clobber (reg:SI LR_REGNO))]
10015   "HAVE_AS_TLS && TARGET_TLS_MARKERS
10016    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10017   "bl %z1(%&@tlsld)\;nop"
10018   [(set_attr "type" "branch")
10019    (set_attr "length" "8")])
10021 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10022   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10023         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10024               (match_operand 2 "" "g")))
10025    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10026    (clobber (reg:SI LR_REGNO))]
10027   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10029   if (flag_pic)
10030     {
10031       if (TARGET_SECURE_PLT && flag_pic == 2)
10032         return "bl %z1+32768(%&@tlsld)@plt";
10033       return "bl %z1(%&@tlsld)@plt";
10034     }
10035   return "bl %z1(%&@tlsld)";
10037   [(set_attr "type" "branch")
10038    (set_attr "length" "4")])
10040 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10041   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10042         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10043                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10044                         UNSPEC_TLSDTPREL))]
10045   "HAVE_AS_TLS"
10046   "addi %0,%1,%2@dtprel")
10048 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10049   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10050         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10051                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10052                         UNSPEC_TLSDTPRELHA))]
10053   "HAVE_AS_TLS"
10054   "addis %0,%1,%2@dtprel@ha")
10056 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10057   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10058         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10059                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10060                         UNSPEC_TLSDTPRELLO))]
10061   "HAVE_AS_TLS"
10062   "addi %0,%1,%2@dtprel@l")
10064 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10065   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10066         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10067                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10068                         UNSPEC_TLSGOTDTPREL))]
10069   "HAVE_AS_TLS"
10070   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10071   "&& TARGET_CMODEL != CMODEL_SMALL"
10072   [(set (match_dup 3)
10073         (high:TLSmode
10074             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10075    (set (match_dup 0)
10076         (lo_sum:TLSmode (match_dup 3)
10077             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10078   "
10080   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10082   [(set (attr "length")
10083      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10084                    (const_int 8)
10085                    (const_int 4)))])
10087 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10088   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10089      (high:TLSmode
10090        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10091                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10092                        UNSPEC_TLSGOTDTPREL)))]
10093   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10094   "addis %0,%1,%2@got@dtprel@ha"
10095   [(set_attr "length" "4")])
10097 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10098   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10099      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10100          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10101                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10102                          UNSPEC_TLSGOTDTPREL)))]
10103   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10104   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10105   [(set_attr "length" "4")])
10107 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10108   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10109         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10110                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10111                         UNSPEC_TLSTPREL))]
10112   "HAVE_AS_TLS"
10113   "addi %0,%1,%2@tprel")
10115 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10116   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10117         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10118                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10119                         UNSPEC_TLSTPRELHA))]
10120   "HAVE_AS_TLS"
10121   "addis %0,%1,%2@tprel@ha")
10123 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10124   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10125         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10126                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10127                         UNSPEC_TLSTPRELLO))]
10128   "HAVE_AS_TLS"
10129   "addi %0,%1,%2@tprel@l")
10131 ;; "b" output constraint here and on tls_tls input to support linker tls
10132 ;; optimization.  The linker may edit the instructions emitted by a
10133 ;; tls_got_tprel/tls_tls pair to addis,addi.
10134 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10135   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10136         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10137                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10138                         UNSPEC_TLSGOTTPREL))]
10139   "HAVE_AS_TLS"
10140   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10141   "&& TARGET_CMODEL != CMODEL_SMALL"
10142   [(set (match_dup 3)
10143         (high:TLSmode
10144             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10145    (set (match_dup 0)
10146         (lo_sum:TLSmode (match_dup 3)
10147             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10148   "
10150   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10152   [(set (attr "length")
10153      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10154                    (const_int 8)
10155                    (const_int 4)))])
10157 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10158   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10159      (high:TLSmode
10160        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10161                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10162                        UNSPEC_TLSGOTTPREL)))]
10163   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10164   "addis %0,%1,%2@got@tprel@ha"
10165   [(set_attr "length" "4")])
10167 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10168   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10169      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10170          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10171                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10172                          UNSPEC_TLSGOTTPREL)))]
10173   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10174   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10175   [(set_attr "length" "4")])
10177 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10178   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10179         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10180                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10181                         UNSPEC_TLSTLS))]
10182   "TARGET_ELF && HAVE_AS_TLS"
10183   "add %0,%1,%2@tls")
10185 (define_expand "tls_get_tpointer"
10186   [(set (match_operand:SI 0 "gpc_reg_operand" "")
10187         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10188   "TARGET_XCOFF && HAVE_AS_TLS"
10189   "
10191   emit_insn (gen_tls_get_tpointer_internal ());
10192   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10193   DONE;
10196 (define_insn "tls_get_tpointer_internal"
10197   [(set (reg:SI 3)
10198         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10199    (clobber (reg:SI LR_REGNO))]
10200   "TARGET_XCOFF && HAVE_AS_TLS"
10201   "bla __get_tpointer")
10203 (define_expand "tls_get_addr<mode>"
10204   [(set (match_operand:P 0 "gpc_reg_operand" "")
10205         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10206                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10207   "TARGET_XCOFF && HAVE_AS_TLS"
10208   "
10210   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10211   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10212   emit_insn (gen_tls_get_addr_internal<mode> ());
10213   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10214   DONE;
10217 (define_insn "tls_get_addr_internal<mode>"
10218   [(set (reg:P 3)
10219         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10220    (clobber (reg:P 0))
10221    (clobber (reg:P 4))
10222    (clobber (reg:P 5))
10223    (clobber (reg:P 11))
10224    (clobber (reg:CC CR0_REGNO))
10225    (clobber (reg:P LR_REGNO))]
10226   "TARGET_XCOFF && HAVE_AS_TLS"
10227   "bla __tls_get_addr")
10229 ;; Next come insns related to the calling sequence.
10231 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10232 ;; We move the back-chain and decrement the stack pointer.
10234 (define_expand "allocate_stack"
10235   [(set (match_operand 0 "gpc_reg_operand" "")
10236         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10237    (set (reg 1)
10238         (minus (reg 1) (match_dup 1)))]
10239   ""
10240   "
10241 { rtx chain = gen_reg_rtx (Pmode);
10242   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10243   rtx neg_op0;
10244   rtx insn, par, set, mem;
10246   emit_move_insn (chain, stack_bot);
10248   /* Check stack bounds if necessary.  */
10249   if (crtl->limit_stack)
10250     {
10251       rtx available;
10252       available = expand_binop (Pmode, sub_optab,
10253                                 stack_pointer_rtx, stack_limit_rtx,
10254                                 NULL_RTX, 1, OPTAB_WIDEN);
10255       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10256     }
10258   if (GET_CODE (operands[1]) != CONST_INT
10259       || INTVAL (operands[1]) < -32767
10260       || INTVAL (operands[1]) > 32768)
10261     {
10262       neg_op0 = gen_reg_rtx (Pmode);
10263       if (TARGET_32BIT)
10264         emit_insn (gen_negsi2 (neg_op0, operands[1]));
10265       else
10266         emit_insn (gen_negdi2 (neg_op0, operands[1]));
10267     }
10268   else
10269     neg_op0 = GEN_INT (- INTVAL (operands[1]));
10271   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10272                                        : gen_movdi_di_update_stack))
10273                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10274                          chain));
10275   /* Since we didn't use gen_frame_mem to generate the MEM, grab
10276      it now and set the alias set/attributes. The above gen_*_update
10277      calls will generate a PARALLEL with the MEM set being the first
10278      operation. */
10279   par = PATTERN (insn);
10280   gcc_assert (GET_CODE (par) == PARALLEL);
10281   set = XVECEXP (par, 0, 0);
10282   gcc_assert (GET_CODE (set) == SET);
10283   mem = SET_DEST (set);
10284   gcc_assert (MEM_P (mem));
10285   MEM_NOTRAP_P (mem) = 1;
10286   set_mem_alias_set (mem, get_frame_alias_set ());
10288   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10289   DONE;
10292 ;; These patterns say how to save and restore the stack pointer.  We need not
10293 ;; save the stack pointer at function level since we are careful to
10294 ;; preserve the backchain.  At block level, we have to restore the backchain
10295 ;; when we restore the stack pointer.
10297 ;; For nonlocal gotos, we must save both the stack pointer and its
10298 ;; backchain and restore both.  Note that in the nonlocal case, the
10299 ;; save area is a memory location.
10301 (define_expand "save_stack_function"
10302   [(match_operand 0 "any_operand" "")
10303    (match_operand 1 "any_operand" "")]
10304   ""
10305   "DONE;")
10307 (define_expand "restore_stack_function"
10308   [(match_operand 0 "any_operand" "")
10309    (match_operand 1 "any_operand" "")]
10310   ""
10311   "DONE;")
10313 ;; Adjust stack pointer (op0) to a new value (op1).
10314 ;; First copy old stack backchain to new location, and ensure that the
10315 ;; scheduler won't reorder the sp assignment before the backchain write.
10316 (define_expand "restore_stack_block"
10317   [(set (match_dup 2) (match_dup 3))
10318    (set (match_dup 4) (match_dup 2))
10319    (match_dup 5)
10320    (set (match_operand 0 "register_operand" "")
10321         (match_operand 1 "register_operand" ""))]
10322   ""
10323   "
10325   rtvec p;
10327   operands[1] = force_reg (Pmode, operands[1]);
10328   operands[2] = gen_reg_rtx (Pmode);
10329   operands[3] = gen_frame_mem (Pmode, operands[0]);
10330   operands[4] = gen_frame_mem (Pmode, operands[1]);
10331   p = rtvec_alloc (1);
10332   RTVEC_ELT (p, 0) = gen_rtx_SET (VOIDmode,
10333                                   gen_frame_mem (BLKmode, operands[0]),
10334                                   const0_rtx);
10335   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10338 (define_expand "save_stack_nonlocal"
10339   [(set (match_dup 3) (match_dup 4))
10340    (set (match_operand 0 "memory_operand" "") (match_dup 3))
10341    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10342   ""
10343   "
10345   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10347   /* Copy the backchain to the first word, sp to the second.  */
10348   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10349   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10350   operands[3] = gen_reg_rtx (Pmode);
10351   operands[4] = gen_frame_mem (Pmode, operands[1]);
10354 (define_expand "restore_stack_nonlocal"
10355   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10356    (set (match_dup 3) (match_dup 4))
10357    (set (match_dup 5) (match_dup 2))
10358    (match_dup 6)
10359    (set (match_operand 0 "register_operand" "") (match_dup 3))]
10360   ""
10361   "
10363   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10364   rtvec p;
10366   /* Restore the backchain from the first word, sp from the second.  */
10367   operands[2] = gen_reg_rtx (Pmode);
10368   operands[3] = gen_reg_rtx (Pmode);
10369   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10370   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10371   operands[5] = gen_frame_mem (Pmode, operands[3]);
10372   p = rtvec_alloc (1);
10373   RTVEC_ELT (p, 0) = gen_rtx_SET (VOIDmode,
10374                                   gen_frame_mem (BLKmode, operands[0]),
10375                                   const0_rtx);
10376   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10379 ;; TOC register handling.
10381 ;; Code to initialize the TOC register...
10383 (define_insn "load_toc_aix_si"
10384   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10385                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10386               (use (reg:SI 2))])]
10387   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10388   "*
10390   char buf[30];
10391   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10392   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10393   operands[2] = gen_rtx_REG (Pmode, 2);
10394   return \"lwz %0,%1(%2)\";
10396   [(set_attr "type" "load")
10397    (set_attr "update" "no")
10398    (set_attr "indexed" "no")])
10400 (define_insn "load_toc_aix_di"
10401   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10402                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10403               (use (reg:DI 2))])]
10404   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10405   "*
10407   char buf[30];
10408 #ifdef TARGET_RELOCATABLE
10409   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10410                                !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
10411 #else
10412   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10413 #endif
10414   if (TARGET_ELF)
10415     strcat (buf, \"@toc\");
10416   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10417   operands[2] = gen_rtx_REG (Pmode, 2);
10418   return \"ld %0,%1(%2)\";
10420   [(set_attr "type" "load")
10421    (set_attr "update" "no")
10422    (set_attr "indexed" "no")])
10424 (define_insn "load_toc_v4_pic_si"
10425   [(set (reg:SI LR_REGNO)
10426         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10427   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10428   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10429   [(set_attr "type" "branch")
10430    (set_attr "length" "4")])
10432 (define_expand "load_toc_v4_PIC_1"
10433   [(parallel [(set (reg:SI LR_REGNO)
10434                    (match_operand:SI 0 "immediate_operand" "s"))
10435               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10436   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10437    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10438   "")
10440 (define_insn "load_toc_v4_PIC_1_normal"
10441   [(set (reg:SI LR_REGNO)
10442         (match_operand:SI 0 "immediate_operand" "s"))
10443    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10444   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10445    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10446   "bcl 20,31,%0\\n%0:"
10447   [(set_attr "type" "branch")
10448    (set_attr "length" "4")])
10450 (define_insn "load_toc_v4_PIC_1_476"
10451   [(set (reg:SI LR_REGNO)
10452         (match_operand:SI 0 "immediate_operand" "s"))
10453    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10454   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10455    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10456   "*
10458   char name[32];
10459   static char templ[32];
10461   get_ppc476_thunk_name (name);
10462   sprintf (templ, \"bl %s\\n%%0:\", name);
10463   return templ;
10465   [(set_attr "type" "branch")
10466    (set_attr "length" "4")])
10468 (define_expand "load_toc_v4_PIC_1b"
10469   [(parallel [(set (reg:SI LR_REGNO)
10470                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10471                                (label_ref (match_operand 1 "" ""))]
10472                            UNSPEC_TOCPTR))
10473               (match_dup 1)])]
10474   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10475   "")
10477 (define_insn "load_toc_v4_PIC_1b_normal"
10478   [(set (reg:SI LR_REGNO)
10479         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10480                     (label_ref (match_operand 1 "" ""))]
10481                 UNSPEC_TOCPTR))
10482    (match_dup 1)]
10483   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10484   "bcl 20,31,$+8\;.long %0-$"
10485   [(set_attr "type" "branch")
10486    (set_attr "length" "8")])
10488 (define_insn "load_toc_v4_PIC_1b_476"
10489   [(set (reg:SI LR_REGNO)
10490         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10491                     (label_ref (match_operand 1 "" ""))]
10492                 UNSPEC_TOCPTR))
10493    (match_dup 1)]
10494   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10495   "*
10497   char name[32];
10498   static char templ[32];
10500   get_ppc476_thunk_name (name);
10501   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10502   return templ;
10504   [(set_attr "type" "branch")
10505    (set_attr "length" "16")])
10507 (define_insn "load_toc_v4_PIC_2"
10508   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10509         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10510                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10511                              (match_operand:SI 3 "immediate_operand" "s")))))]
10512   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10513   "lwz %0,%2-%3(%1)"
10514   [(set_attr "type" "load")])
10516 (define_insn "load_toc_v4_PIC_3b"
10517   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10518         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10519                  (high:SI
10520                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10521                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10522   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10523   "addis %0,%1,%2-%3@ha")
10525 (define_insn "load_toc_v4_PIC_3c"
10526   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10527         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10528                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10529                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10530   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10531   "addi %0,%1,%2-%3@l")
10533 ;; If the TOC is shared over a translation unit, as happens with all
10534 ;; the kinds of PIC that we support, we need to restore the TOC
10535 ;; pointer only when jumping over units of translation.
10536 ;; On Darwin, we need to reload the picbase.
10538 (define_expand "builtin_setjmp_receiver"
10539   [(use (label_ref (match_operand 0 "" "")))]
10540   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10541    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10542    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10543   "
10545 #if TARGET_MACHO
10546   if (DEFAULT_ABI == ABI_DARWIN)
10547     {
10548       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10549       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10550       rtx tmplabrtx;
10551       char tmplab[20];
10553       crtl->uses_pic_offset_table = 1;
10554       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10555                                   CODE_LABEL_NUMBER (operands[0]));
10556       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10558       emit_insn (gen_load_macho_picbase (tmplabrtx));
10559       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10560       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10561     }
10562   else
10563 #endif
10564     rs6000_emit_load_toc_table (FALSE);
10565   DONE;
10568 ;; Largetoc support
10569 (define_insn "*largetoc_high"
10570   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10571         (high:DI
10572           (unspec [(match_operand:DI 1 "" "")
10573                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10574                   UNSPEC_TOCREL)))]
10575    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10576    "addis %0,%2,%1@toc@ha")
10578 (define_insn "*largetoc_high_aix<mode>"
10579   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10580         (high:P
10581           (unspec [(match_operand:P 1 "" "")
10582                    (match_operand:P 2 "gpc_reg_operand" "b")]
10583                   UNSPEC_TOCREL)))]
10584    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10585    "addis %0,%1@u(%2)")
10587 (define_insn "*largetoc_high_plus"
10588   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10589         (high:DI
10590           (plus:DI
10591             (unspec [(match_operand:DI 1 "" "")
10592                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10593                     UNSPEC_TOCREL)
10594             (match_operand:DI 3 "add_cint_operand" "n"))))]
10595    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10596    "addis %0,%2,%1+%3@toc@ha")
10598 (define_insn "*largetoc_high_plus_aix<mode>"
10599   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10600         (high:P
10601           (plus:P
10602             (unspec [(match_operand:P 1 "" "")
10603                      (match_operand:P 2 "gpc_reg_operand" "b")]
10604                     UNSPEC_TOCREL)
10605             (match_operand:P 3 "add_cint_operand" "n"))))]
10606    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10607    "addis %0,%1+%3@u(%2)")
10609 (define_insn "*largetoc_low"
10610   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
10611         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,!*r")
10612                    (match_operand:DI 2 "" "")))]
10613    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10614    "@
10615     addi %0,%1,%2@l
10616     addic %0,%1,%2@l")
10618 (define_insn "*largetoc_low_aix<mode>"
10619   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10620         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10621                    (match_operand:P 2 "" "")))]
10622    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10623    "la %0,%2@l(%1)")
10625 (define_insn_and_split "*tocref<mode>"
10626   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10627         (match_operand:P 1 "small_toc_ref" "R"))]
10628    "TARGET_TOC"
10629    "la %0,%a1"
10630    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10631   [(set (match_dup 0) (high:P (match_dup 1)))
10632    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10634 ;; Elf specific ways of loading addresses for non-PIC code.
10635 ;; The output of this could be r0, but we make a very strong
10636 ;; preference for a base register because it will usually
10637 ;; be needed there.
10638 (define_insn "elf_high"
10639   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10640         (high:SI (match_operand 1 "" "")))]
10641   "TARGET_ELF && ! TARGET_64BIT"
10642   "lis %0,%1@ha")
10644 (define_insn "elf_low"
10645   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
10646         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r")
10647                    (match_operand 2 "" "")))]
10648    "TARGET_ELF && ! TARGET_64BIT"
10649    "@
10650     la %0,%2@l(%1)
10651     addic %0,%1,%K2")
10653 ;; Call and call_value insns
10654 (define_expand "call"
10655   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10656                     (match_operand 1 "" ""))
10657               (use (match_operand 2 "" ""))
10658               (clobber (reg:SI LR_REGNO))])]
10659   ""
10660   "
10662 #if TARGET_MACHO
10663   if (MACHOPIC_INDIRECT)
10664     operands[0] = machopic_indirect_call_target (operands[0]);
10665 #endif
10667   gcc_assert (GET_CODE (operands[0]) == MEM);
10668   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10670   operands[0] = XEXP (operands[0], 0);
10672   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10673     {
10674       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10675       DONE;
10676     }
10678   if (GET_CODE (operands[0]) != SYMBOL_REF
10679       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10680     {
10681       if (INTVAL (operands[2]) & CALL_LONG)
10682         operands[0] = rs6000_longcall_ref (operands[0]);
10684       switch (DEFAULT_ABI)
10685         {
10686         case ABI_V4:
10687         case ABI_DARWIN:
10688           operands[0] = force_reg (Pmode, operands[0]);
10689           break;
10691         default:
10692           gcc_unreachable ();
10693         }
10694     }
10697 (define_expand "call_value"
10698   [(parallel [(set (match_operand 0 "" "")
10699                    (call (mem:SI (match_operand 1 "address_operand" ""))
10700                          (match_operand 2 "" "")))
10701               (use (match_operand 3 "" ""))
10702               (clobber (reg:SI LR_REGNO))])]
10703   ""
10704   "
10706 #if TARGET_MACHO
10707   if (MACHOPIC_INDIRECT)
10708     operands[1] = machopic_indirect_call_target (operands[1]);
10709 #endif
10711   gcc_assert (GET_CODE (operands[1]) == MEM);
10712   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10714   operands[1] = XEXP (operands[1], 0);
10716   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10717     {
10718       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10719       DONE;
10720     }
10722   if (GET_CODE (operands[1]) != SYMBOL_REF
10723       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10724     {
10725       if (INTVAL (operands[3]) & CALL_LONG)
10726         operands[1] = rs6000_longcall_ref (operands[1]);
10728       switch (DEFAULT_ABI)
10729         {
10730         case ABI_V4:
10731         case ABI_DARWIN:
10732           operands[1] = force_reg (Pmode, operands[1]);
10733           break;
10735         default:
10736           gcc_unreachable ();
10737         }
10738     }
10741 ;; Call to function in current module.  No TOC pointer reload needed.
10742 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10743 ;; either the function was not prototyped, or it was prototyped as a
10744 ;; variable argument function.  It is > 0 if FP registers were passed
10745 ;; and < 0 if they were not.
10747 (define_insn "*call_local32"
10748   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10749          (match_operand 1 "" "g,g"))
10750    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10751    (clobber (reg:SI LR_REGNO))]
10752   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10753   "*
10755   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10756     output_asm_insn (\"crxor 6,6,6\", operands);
10758   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10759     output_asm_insn (\"creqv 6,6,6\", operands);
10761   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10763   [(set_attr "type" "branch")
10764    (set_attr "length" "4,8")])
10766 (define_insn "*call_local64"
10767   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10768          (match_operand 1 "" "g,g"))
10769    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10770    (clobber (reg:SI LR_REGNO))]
10771   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10772   "*
10774   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10775     output_asm_insn (\"crxor 6,6,6\", operands);
10777   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10778     output_asm_insn (\"creqv 6,6,6\", operands);
10780   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10782   [(set_attr "type" "branch")
10783    (set_attr "length" "4,8")])
10785 (define_insn "*call_value_local32"
10786   [(set (match_operand 0 "" "")
10787         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10788               (match_operand 2 "" "g,g")))
10789    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10790    (clobber (reg:SI LR_REGNO))]
10791   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10792   "*
10794   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10795     output_asm_insn (\"crxor 6,6,6\", operands);
10797   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10798     output_asm_insn (\"creqv 6,6,6\", operands);
10800   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10802   [(set_attr "type" "branch")
10803    (set_attr "length" "4,8")])
10806 (define_insn "*call_value_local64"
10807   [(set (match_operand 0 "" "")
10808         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10809               (match_operand 2 "" "g,g")))
10810    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10811    (clobber (reg:SI LR_REGNO))]
10812   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10813   "*
10815   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10816     output_asm_insn (\"crxor 6,6,6\", operands);
10818   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10819     output_asm_insn (\"creqv 6,6,6\", operands);
10821   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10823   [(set_attr "type" "branch")
10824    (set_attr "length" "4,8")])
10827 ;; A function pointer under System V is just a normal pointer
10828 ;; operands[0] is the function pointer
10829 ;; operands[1] is the stack size to clean up
10830 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10831 ;; which indicates how to set cr1
10833 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10834   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10835          (match_operand 1 "" "g,g,g,g"))
10836    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10837    (clobber (reg:SI LR_REGNO))]
10838   "DEFAULT_ABI == ABI_V4
10839    || DEFAULT_ABI == ABI_DARWIN"
10841   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10842     output_asm_insn ("crxor 6,6,6", operands);
10844   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10845     output_asm_insn ("creqv 6,6,6", operands);
10847   return "b%T0l";
10849   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10850    (set_attr "length" "4,4,8,8")])
10852 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10853   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10854          (match_operand 1 "" "g,g"))
10855    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10856    (clobber (reg:SI LR_REGNO))]
10857   "(DEFAULT_ABI == ABI_DARWIN
10858    || (DEFAULT_ABI == ABI_V4
10859        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10861   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10862     output_asm_insn ("crxor 6,6,6", operands);
10864   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10865     output_asm_insn ("creqv 6,6,6", operands);
10867 #if TARGET_MACHO
10868   return output_call(insn, operands, 0, 2);
10869 #else
10870   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10871     {
10872       gcc_assert (!TARGET_SECURE_PLT);
10873       return "bl %z0@plt";
10874     }
10875   else
10876     return "bl %z0";
10877 #endif
10879   "DEFAULT_ABI == ABI_V4
10880    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10881    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10882   [(parallel [(call (mem:SI (match_dup 0))
10883                     (match_dup 1))
10884               (use (match_dup 2))
10885               (use (match_dup 3))
10886               (clobber (reg:SI LR_REGNO))])]
10888   operands[3] = pic_offset_table_rtx;
10890   [(set_attr "type" "branch,branch")
10891    (set_attr "length" "4,8")])
10893 (define_insn "*call_nonlocal_sysv_secure<mode>"
10894   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10895          (match_operand 1 "" "g,g"))
10896    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10897    (use (match_operand:SI 3 "register_operand" "r,r"))
10898    (clobber (reg:SI LR_REGNO))]
10899   "(DEFAULT_ABI == ABI_V4
10900     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10901     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10903   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10904     output_asm_insn ("crxor 6,6,6", operands);
10906   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10907     output_asm_insn ("creqv 6,6,6", operands);
10909   if (flag_pic == 2)
10910     /* The magic 32768 offset here and in the other sysv call insns
10911        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10912        See sysv4.h:toc_section.  */
10913     return "bl %z0+32768@plt";
10914   else
10915     return "bl %z0@plt";
10917   [(set_attr "type" "branch,branch")
10918    (set_attr "length" "4,8")])
10920 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10921   [(set (match_operand 0 "" "")
10922         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10923               (match_operand 2 "" "g,g,g,g")))
10924    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10925    (clobber (reg:SI LR_REGNO))]
10926   "DEFAULT_ABI == ABI_V4
10927    || DEFAULT_ABI == ABI_DARWIN"
10929   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10930     output_asm_insn ("crxor 6,6,6", operands);
10932   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10933     output_asm_insn ("creqv 6,6,6", operands);
10935   return "b%T1l";
10937   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10938    (set_attr "length" "4,4,8,8")])
10940 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10941   [(set (match_operand 0 "" "")
10942         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10943               (match_operand 2 "" "g,g")))
10944    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10945    (clobber (reg:SI LR_REGNO))]
10946   "(DEFAULT_ABI == ABI_DARWIN
10947    || (DEFAULT_ABI == ABI_V4
10948        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10950   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10951     output_asm_insn ("crxor 6,6,6", operands);
10953   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10954     output_asm_insn ("creqv 6,6,6", operands);
10956 #if TARGET_MACHO
10957   return output_call(insn, operands, 1, 3);
10958 #else
10959   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10960     {
10961       gcc_assert (!TARGET_SECURE_PLT);
10962       return "bl %z1@plt";
10963     }
10964   else
10965     return "bl %z1";
10966 #endif
10968   "DEFAULT_ABI == ABI_V4
10969    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10970    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10971   [(parallel [(set (match_dup 0)
10972                    (call (mem:SI (match_dup 1))
10973                          (match_dup 2)))
10974               (use (match_dup 3))
10975               (use (match_dup 4))
10976               (clobber (reg:SI LR_REGNO))])]
10978   operands[4] = pic_offset_table_rtx;
10980   [(set_attr "type" "branch,branch")
10981    (set_attr "length" "4,8")])
10983 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10984   [(set (match_operand 0 "" "")
10985         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10986               (match_operand 2 "" "g,g")))
10987    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10988    (use (match_operand:SI 4 "register_operand" "r,r"))
10989    (clobber (reg:SI LR_REGNO))]
10990   "(DEFAULT_ABI == ABI_V4
10991     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10992     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10994   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10995     output_asm_insn ("crxor 6,6,6", operands);
10997   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10998     output_asm_insn ("creqv 6,6,6", operands);
11000   if (flag_pic == 2)
11001     return "bl %z1+32768@plt";
11002   else
11003     return "bl %z1@plt";
11005   [(set_attr "type" "branch,branch")
11006    (set_attr "length" "4,8")])
11009 ;; Call to AIX abi function in the same module.
11011 (define_insn "*call_local_aix<mode>"
11012   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11013          (match_operand 1 "" "g"))
11014    (clobber (reg:P LR_REGNO))]
11015   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11016   "bl %z0"
11017   [(set_attr "type" "branch")
11018    (set_attr "length" "4")])
11020 (define_insn "*call_value_local_aix<mode>"
11021   [(set (match_operand 0 "" "")
11022         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11023               (match_operand 2 "" "g")))
11024    (clobber (reg:P LR_REGNO))]
11025   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11026   "bl %z1"
11027   [(set_attr "type" "branch")
11028    (set_attr "length" "4")])
11030 ;; Call to AIX abi function which may be in another module.
11031 ;; Restore the TOC pointer (r2) after the call.
11033 (define_insn "*call_nonlocal_aix<mode>"
11034   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11035          (match_operand 1 "" "g"))
11036    (clobber (reg:P LR_REGNO))]
11037   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11038   "bl %z0\;nop"
11039   [(set_attr "type" "branch")
11040    (set_attr "length" "8")])
11042 (define_insn "*call_value_nonlocal_aix<mode>"
11043   [(set (match_operand 0 "" "")
11044         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11045               (match_operand 2 "" "g")))
11046    (clobber (reg:P LR_REGNO))]
11047   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11048   "bl %z1\;nop"
11049   [(set_attr "type" "branch")
11050    (set_attr "length" "8")])
11052 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11053 ;; Operand0 is the addresss of the function to call
11054 ;; Operand2 is the location in the function descriptor to load r2 from
11055 ;; Operand3 is the stack location to hold the current TOC pointer
11057 (define_insn "*call_indirect_aix<mode>"
11058   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11059          (match_operand 1 "" "g,g"))
11060    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11061    (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11062    (clobber (reg:P LR_REGNO))]
11063   "DEFAULT_ABI == ABI_AIX"
11064   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3"
11065   [(set_attr "type" "jmpreg")
11066    (set_attr "length" "12")])
11068 (define_insn "*call_value_indirect_aix<mode>"
11069   [(set (match_operand 0 "" "")
11070         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11071               (match_operand 2 "" "g,g")))
11072    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11073    (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>"))
11074    (clobber (reg:P LR_REGNO))]
11075   "DEFAULT_ABI == ABI_AIX"
11076   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4"
11077   [(set_attr "type" "jmpreg")
11078    (set_attr "length" "12")])
11080 ;; Call to indirect functions with the ELFv2 ABI.
11081 ;; Operand0 is the addresss of the function to call
11082 ;; Operand2 is the stack location to hold the current TOC pointer
11084 (define_insn "*call_indirect_elfv2<mode>"
11085   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11086          (match_operand 1 "" "g,g"))
11087    (set (reg:P TOC_REGNUM) (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11088    (clobber (reg:P LR_REGNO))]
11089   "DEFAULT_ABI == ABI_ELFv2"
11090   "b%T0l\;<ptrload> 2,%2"
11091   [(set_attr "type" "jmpreg")
11092    (set_attr "length" "8")])
11094 (define_insn "*call_value_indirect_elfv2<mode>"
11095   [(set (match_operand 0 "" "")
11096         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11097               (match_operand 2 "" "g,g")))
11098    (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11099    (clobber (reg:P LR_REGNO))]
11100   "DEFAULT_ABI == ABI_ELFv2"
11101   "b%T1l\;<ptrload> 2,%3"
11102   [(set_attr "type" "jmpreg")
11103    (set_attr "length" "8")])
11106 ;; Call subroutine returning any type.
11107 (define_expand "untyped_call"
11108   [(parallel [(call (match_operand 0 "" "")
11109                     (const_int 0))
11110               (match_operand 1 "" "")
11111               (match_operand 2 "" "")])]
11112   ""
11113   "
11115   int i;
11117   emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx));
11119   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11120     {
11121       rtx set = XVECEXP (operands[2], 0, i);
11122       emit_move_insn (SET_DEST (set), SET_SRC (set));
11123     }
11125   /* The optimizer does not know that the call sets the function value
11126      registers we stored in the result block.  We avoid problems by
11127      claiming that all hard registers are used and clobbered at this
11128      point.  */
11129   emit_insn (gen_blockage ());
11131   DONE;
11134 ;; sibling call patterns
11135 (define_expand "sibcall"
11136   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11137                     (match_operand 1 "" ""))
11138               (use (match_operand 2 "" ""))
11139               (use (reg:SI LR_REGNO))
11140               (simple_return)])]
11141   ""
11142   "
11144 #if TARGET_MACHO
11145   if (MACHOPIC_INDIRECT)
11146     operands[0] = machopic_indirect_call_target (operands[0]);
11147 #endif
11149   gcc_assert (GET_CODE (operands[0]) == MEM);
11150   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11152   operands[0] = XEXP (operands[0], 0);
11154   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11155     {
11156       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11157       DONE;
11158     }
11161 (define_expand "sibcall_value"
11162   [(parallel [(set (match_operand 0 "register_operand" "")
11163                 (call (mem:SI (match_operand 1 "address_operand" ""))
11164                       (match_operand 2 "" "")))
11165               (use (match_operand 3 "" ""))
11166               (use (reg:SI LR_REGNO))
11167               (simple_return)])]
11168   ""
11169   "
11171 #if TARGET_MACHO
11172   if (MACHOPIC_INDIRECT)
11173     operands[1] = machopic_indirect_call_target (operands[1]);
11174 #endif
11176   gcc_assert (GET_CODE (operands[1]) == MEM);
11177   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11179   operands[1] = XEXP (operands[1], 0);
11181   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11182     {
11183       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11184       DONE;
11185     }
11188 ;; this and similar patterns must be marked as using LR, otherwise
11189 ;; dataflow will try to delete the store into it.  This is true
11190 ;; even when the actual reg to jump to is in CTR, when LR was
11191 ;; saved and restored around the PIC-setting BCL.
11192 (define_insn "*sibcall_local32"
11193   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11194          (match_operand 1 "" "g,g"))
11195    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11196    (use (reg:SI LR_REGNO))
11197    (simple_return)]
11198   "(INTVAL (operands[2]) & CALL_LONG) == 0"
11199   "*
11201   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11202     output_asm_insn (\"crxor 6,6,6\", operands);
11204   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11205     output_asm_insn (\"creqv 6,6,6\", operands);
11207   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11209   [(set_attr "type" "branch")
11210    (set_attr "length" "4,8")])
11212 (define_insn "*sibcall_local64"
11213   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11214          (match_operand 1 "" "g,g"))
11215    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11216    (use (reg:SI LR_REGNO))
11217    (simple_return)]
11218   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11219   "*
11221   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11222     output_asm_insn (\"crxor 6,6,6\", operands);
11224   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11225     output_asm_insn (\"creqv 6,6,6\", operands);
11227   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11229   [(set_attr "type" "branch")
11230    (set_attr "length" "4,8")])
11232 (define_insn "*sibcall_value_local32"
11233   [(set (match_operand 0 "" "")
11234         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11235               (match_operand 2 "" "g,g")))
11236    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11237    (use (reg:SI LR_REGNO))
11238    (simple_return)]
11239   "(INTVAL (operands[3]) & CALL_LONG) == 0"
11240   "*
11242   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11243     output_asm_insn (\"crxor 6,6,6\", operands);
11245   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11246     output_asm_insn (\"creqv 6,6,6\", operands);
11248   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11250   [(set_attr "type" "branch")
11251    (set_attr "length" "4,8")])
11253 (define_insn "*sibcall_value_local64"
11254   [(set (match_operand 0 "" "")
11255         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11256               (match_operand 2 "" "g,g")))
11257    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11258    (use (reg:SI LR_REGNO))
11259    (simple_return)]
11260   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11261   "*
11263   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11264     output_asm_insn (\"crxor 6,6,6\", operands);
11266   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11267     output_asm_insn (\"creqv 6,6,6\", operands);
11269   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11271   [(set_attr "type" "branch")
11272    (set_attr "length" "4,8")])
11274 (define_insn "*sibcall_nonlocal_sysv<mode>"
11275   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11276          (match_operand 1 "" ""))
11277    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11278    (use (reg:SI LR_REGNO))
11279    (simple_return)]
11280   "(DEFAULT_ABI == ABI_DARWIN
11281     || DEFAULT_ABI == ABI_V4)
11282    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11283   "*
11285   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11286     output_asm_insn (\"crxor 6,6,6\", operands);
11288   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11289     output_asm_insn (\"creqv 6,6,6\", operands);
11291   if (which_alternative >= 2)
11292     return \"b%T0\";
11293   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11294     {
11295       gcc_assert (!TARGET_SECURE_PLT);
11296       return \"b %z0@plt\";
11297     }
11298   else
11299     return \"b %z0\";
11301   [(set_attr "type" "branch")
11302    (set_attr "length" "4,8,4,8")])
11304 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11305   [(set (match_operand 0 "" "")
11306         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11307               (match_operand 2 "" "")))
11308    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11309    (use (reg:SI LR_REGNO))
11310    (simple_return)]
11311   "(DEFAULT_ABI == ABI_DARWIN
11312     || DEFAULT_ABI == ABI_V4)
11313    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11314   "*
11316   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11317     output_asm_insn (\"crxor 6,6,6\", operands);
11319   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11320     output_asm_insn (\"creqv 6,6,6\", operands);
11322   if (which_alternative >= 2)
11323     return \"b%T1\";
11324   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11325     {
11326       gcc_assert (!TARGET_SECURE_PLT);
11327       return \"b %z1@plt\";
11328     }
11329   else
11330     return \"b %z1\";
11332   [(set_attr "type" "branch")
11333    (set_attr "length" "4,8,4,8")])
11335 ;; AIX ABI sibling call patterns.
11337 (define_insn "*sibcall_aix<mode>"
11338   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11339          (match_operand 1 "" "g,g"))
11340    (simple_return)]
11341   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11342   "@
11343    b %z0
11344    b%T0"
11345   [(set_attr "type" "branch")
11346    (set_attr "length" "4")])
11348 (define_insn "*sibcall_value_aix<mode>"
11349   [(set (match_operand 0 "" "")
11350         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11351               (match_operand 2 "" "g,g")))
11352    (simple_return)]
11353   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11354   "@
11355    b %z1
11356    b%T1"
11357   [(set_attr "type" "branch")
11358    (set_attr "length" "4")])
11360 (define_expand "sibcall_epilogue"
11361   [(use (const_int 0))]
11362   ""
11364   if (!TARGET_SCHED_PROLOG)
11365     emit_insn (gen_blockage ());
11366   rs6000_emit_epilogue (TRUE);
11367   DONE;
11370 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11371 ;; all of memory.  This blocks insns from being moved across this point.
11373 (define_insn "blockage"
11374   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11375   ""
11376   "")
11378 (define_expand "probe_stack"
11379   [(set (match_operand 0 "memory_operand" "=m")
11380         (unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
11381   ""
11383   if (TARGET_64BIT)
11384     emit_insn (gen_probe_stack_di (operands[0]));
11385   else
11386     emit_insn (gen_probe_stack_si (operands[0]));
11387   DONE;
11390 (define_insn "probe_stack_<mode>"
11391   [(set (match_operand:P 0 "memory_operand" "=m")
11392         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11393   ""
11395   operands[1] = gen_rtx_REG (Pmode, 0);
11396   return "st<wd>%U0%X0 %1,%0";
11398   [(set_attr "type" "store")
11399    (set (attr "update")
11400         (if_then_else (match_operand 0 "update_address_mem")
11401                       (const_string "yes")
11402                       (const_string "no")))
11403    (set (attr "indexed")
11404         (if_then_else (match_operand 0 "indexed_address_mem")
11405                       (const_string "yes")
11406                       (const_string "no")))
11407    (set_attr "length" "4")])
11409 (define_insn "probe_stack_range<P:mode>"
11410   [(set (match_operand:P 0 "register_operand" "=r")
11411         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11412                             (match_operand:P 2 "register_operand" "r")]
11413                            UNSPECV_PROBE_STACK_RANGE))]
11414   ""
11415   "* return output_probe_stack_range (operands[0], operands[2]);"
11416   [(set_attr "type" "three")])
11418 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11419 ;; signed & unsigned, and one type of branch.
11421 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11422 ;; insns, and branches.
11424 (define_expand "cbranch<mode>4"
11425   [(use (match_operator 0 "rs6000_cbranch_operator"
11426          [(match_operand:GPR 1 "gpc_reg_operand" "")
11427           (match_operand:GPR 2 "reg_or_short_operand" "")]))
11428    (use (match_operand 3 ""))]
11429   ""
11430   "
11432   /* Take care of the possibility that operands[2] might be negative but
11433      this might be a logical operation.  That insn doesn't exist.  */
11434   if (GET_CODE (operands[2]) == CONST_INT
11435       && INTVAL (operands[2]) < 0)
11436     {
11437       operands[2] = force_reg (<MODE>mode, operands[2]);
11438       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11439                                     GET_MODE (operands[0]),
11440                                     operands[1], operands[2]);
11441    }
11443   rs6000_emit_cbranch (<MODE>mode, operands);
11444   DONE;
11447 (define_expand "cbranch<mode>4"
11448   [(use (match_operator 0 "rs6000_cbranch_operator"
11449          [(match_operand:FP 1 "gpc_reg_operand" "")
11450           (match_operand:FP 2 "gpc_reg_operand" "")]))
11451    (use (match_operand 3 ""))]
11452   ""
11453   "
11455   rs6000_emit_cbranch (<MODE>mode, operands);
11456   DONE;
11459 (define_expand "cstore<mode>4"
11460   [(use (match_operator 1 "rs6000_cbranch_operator"
11461          [(match_operand:GPR 2 "gpc_reg_operand" "")
11462           (match_operand:GPR 3 "reg_or_short_operand" "")]))
11463    (clobber (match_operand:SI 0 "register_operand"))]
11464   ""
11465   "
11467   /* Take care of the possibility that operands[3] might be negative but
11468      this might be a logical operation.  That insn doesn't exist.  */
11469   if (GET_CODE (operands[3]) == CONST_INT
11470       && INTVAL (operands[3]) < 0)
11471     {
11472       operands[3] = force_reg (<MODE>mode, operands[3]);
11473       operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
11474                                     GET_MODE (operands[1]),
11475                                     operands[2], operands[3]);
11476     }
11478   /* For SNE, we would prefer that the xor/abs sequence be used for integers.
11479      For SEQ, likewise, except that comparisons with zero should be done
11480      with an scc insns.  However, due to the order that combine see the
11481      resulting insns, we must, in fact, allow SEQ for integers.  Fail in
11482      the cases we don't want to handle or are best handled by portable
11483      code.  */
11484   if (GET_CODE (operands[1]) == NE)
11485     FAIL;
11486   if ((GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE
11487        || GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
11488       && operands[3] == const0_rtx)
11489     FAIL;
11490   rs6000_emit_sCOND (<MODE>mode, operands);
11491   DONE;
11494 (define_expand "cstore<mode>4"
11495   [(use (match_operator 1 "rs6000_cbranch_operator"
11496          [(match_operand:FP 2 "gpc_reg_operand" "")
11497           (match_operand:FP 3 "gpc_reg_operand" "")]))
11498    (clobber (match_operand:SI 0 "register_operand"))]
11499   ""
11500   "
11502   rs6000_emit_sCOND (<MODE>mode, operands);
11503   DONE;
11507 (define_expand "stack_protect_set"
11508   [(match_operand 0 "memory_operand" "")
11509    (match_operand 1 "memory_operand" "")]
11510   ""
11512 #ifdef TARGET_THREAD_SSP_OFFSET
11513   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11514   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11515   operands[1] = gen_rtx_MEM (Pmode, addr);
11516 #endif
11517   if (TARGET_64BIT)
11518     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11519   else
11520     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11521   DONE;
11524 (define_insn "stack_protect_setsi"
11525   [(set (match_operand:SI 0 "memory_operand" "=m")
11526         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11527    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11528   "TARGET_32BIT"
11529   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11530   [(set_attr "type" "three")
11531    (set_attr "length" "12")])
11533 (define_insn "stack_protect_setdi"
11534   [(set (match_operand:DI 0 "memory_operand" "=Y")
11535         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11536    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11537   "TARGET_64BIT"
11538   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11539   [(set_attr "type" "three")
11540    (set_attr "length" "12")])
11542 (define_expand "stack_protect_test"
11543   [(match_operand 0 "memory_operand" "")
11544    (match_operand 1 "memory_operand" "")
11545    (match_operand 2 "" "")]
11546   ""
11548   rtx test, op0, op1;
11549 #ifdef TARGET_THREAD_SSP_OFFSET
11550   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11551   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11552   operands[1] = gen_rtx_MEM (Pmode, addr);
11553 #endif
11554   op0 = operands[0];
11555   op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11556   test = gen_rtx_EQ (VOIDmode, op0, op1);
11557   emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11558   DONE;
11561 (define_insn "stack_protect_testsi"
11562   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11563         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11564                       (match_operand:SI 2 "memory_operand" "m,m")]
11565                      UNSPEC_SP_TEST))
11566    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11567    (clobber (match_scratch:SI 3 "=&r,&r"))]
11568   "TARGET_32BIT"
11569   "@
11570    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11571    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11572   [(set_attr "length" "16,20")])
11574 (define_insn "stack_protect_testdi"
11575   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11576         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11577                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11578                      UNSPEC_SP_TEST))
11579    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11580    (clobber (match_scratch:DI 3 "=&r,&r"))]
11581   "TARGET_64BIT"
11582   "@
11583    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11584    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11585   [(set_attr "length" "16,20")])
11588 ;; Here are the actual compare insns.
11589 (define_insn "*cmp<mode>_internal1"
11590   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11591         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11592                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11593   ""
11594   "cmp<wd>%I2 %0,%1,%2"
11595   [(set_attr "type" "cmp")])
11597 ;; If we are comparing a register for equality with a large constant,
11598 ;; we can do this with an XOR followed by a compare.  But this is profitable
11599 ;; only if the large constant is only used for the comparison (and in this
11600 ;; case we already have a register to reuse as scratch).
11602 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11603 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11605 (define_peephole2
11606   [(set (match_operand:SI 0 "register_operand")
11607         (match_operand:SI 1 "logical_const_operand" ""))
11608    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11609                        [(match_dup 0)
11610                         (match_operand:SI 2 "logical_const_operand" "")]))
11611    (set (match_operand:CC 4 "cc_reg_operand" "")
11612         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11613                     (match_dup 0)))
11614    (set (pc)
11615         (if_then_else (match_operator 6 "equality_operator"
11616                        [(match_dup 4) (const_int 0)])
11617                       (match_operand 7 "" "")
11618                       (match_operand 8 "" "")))]
11619   "peep2_reg_dead_p (3, operands[0])
11620    && peep2_reg_dead_p (4, operands[4])"
11621  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11622   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11623   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11626   /* Get the constant we are comparing against, and see what it looks like
11627      when sign-extended from 16 to 32 bits.  Then see what constant we could
11628      XOR with SEXTC to get the sign-extended value.  */
11629   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11630                                               SImode,
11631                                               operands[1], operands[2]);
11632   HOST_WIDE_INT c = INTVAL (cnst);
11633   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11634   HOST_WIDE_INT xorv = c ^ sextc;
11636   operands[9] = GEN_INT (xorv);
11637   operands[10] = GEN_INT (sextc);
11640 (define_insn "*cmpsi_internal2"
11641   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11642         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11643                        (match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
11644   ""
11645   "cmplw%I2 %0,%1,%b2"
11646   [(set_attr "type" "cmp")])
11648 (define_insn "*cmpdi_internal2"
11649   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11650         (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
11651                        (match_operand:DI 2 "reg_or_u_short_operand" "rK")))]
11652   ""
11653   "cmpld%I2 %0,%1,%b2"
11654   [(set_attr "type" "cmp")])
11656 ;; The following two insns don't exist as single insns, but if we provide
11657 ;; them, we can swap an add and compare, which will enable us to overlap more
11658 ;; of the required delay between a compare and branch.  We generate code for
11659 ;; them by splitting.
11661 (define_insn ""
11662   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11663         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11664                     (match_operand:SI 2 "short_cint_operand" "i")))
11665    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11666         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11667   ""
11668   "#"
11669   [(set_attr "length" "8")])
11671 (define_insn ""
11672   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11673         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11674                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11675    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11676         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11677   ""
11678   "#"
11679   [(set_attr "length" "8")])
11681 (define_split
11682   [(set (match_operand:CC 3 "cc_reg_operand" "")
11683         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11684                     (match_operand:SI 2 "short_cint_operand" "")))
11685    (set (match_operand:SI 0 "gpc_reg_operand" "")
11686         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11687   ""
11688   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11689    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11691 (define_split
11692   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11693         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11694                        (match_operand:SI 2 "u_short_cint_operand" "")))
11695    (set (match_operand:SI 0 "gpc_reg_operand" "")
11696         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11697   ""
11698   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11699    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11701 ;; Only need to compare second words if first words equal
11702 (define_insn "*cmptf_internal1"
11703   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11704         (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
11705                       (match_operand:TF 2 "gpc_reg_operand" "d")))]
11706   "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
11707    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11708   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11709   [(set_attr "type" "fpcompare")
11710    (set_attr "length" "12")])
11712 (define_insn_and_split "*cmptf_internal2"
11713   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11714         (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
11715                       (match_operand:TF 2 "gpc_reg_operand" "d")))
11716     (clobber (match_scratch:DF 3 "=d"))
11717     (clobber (match_scratch:DF 4 "=d"))
11718     (clobber (match_scratch:DF 5 "=d"))
11719     (clobber (match_scratch:DF 6 "=d"))
11720     (clobber (match_scratch:DF 7 "=d"))
11721     (clobber (match_scratch:DF 8 "=d"))
11722     (clobber (match_scratch:DF 9 "=d"))
11723     (clobber (match_scratch:DF 10 "=d"))
11724     (clobber (match_scratch:GPR 11 "=b"))]
11725   "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
11726    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11727   "#"
11728   "&& reload_completed"
11729   [(set (match_dup 3) (match_dup 14))
11730    (set (match_dup 4) (match_dup 15))
11731    (set (match_dup 9) (abs:DF (match_dup 5)))
11732    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11733    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11734                            (label_ref (match_dup 12))
11735                            (pc)))
11736    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11737    (set (pc) (label_ref (match_dup 13)))
11738    (match_dup 12)
11739    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11740    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11741    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11742    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11743    (match_dup 13)]
11745   REAL_VALUE_TYPE rv;
11746   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11747   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11749   operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word);
11750   operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word);
11751   operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word);
11752   operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word);
11753   operands[12] = gen_label_rtx ();
11754   operands[13] = gen_label_rtx ();
11755   real_inf (&rv);
11756   operands[14] = force_const_mem (DFmode,
11757                                   CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode));
11758   operands[15] = force_const_mem (DFmode,
11759                                   CONST_DOUBLE_FROM_REAL_VALUE (dconst0,
11760                                                                 DFmode));
11761   if (TARGET_TOC)
11762     {
11763       rtx tocref;
11764       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11765       operands[14] = gen_const_mem (DFmode, tocref);
11766       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11767       operands[15] = gen_const_mem (DFmode, tocref);
11768       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11769       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11770     }
11773 ;; Now we have the scc insns.  We can do some combinations because of the
11774 ;; way the machine works.
11776 ;; Note that this is probably faster if we can put an insn between the
11777 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11778 ;; cases the insns below which don't use an intermediate CR field will
11779 ;; be used instead.
11780 (define_insn ""
11781   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11782         (match_operator:SI 1 "scc_comparison_operator"
11783                            [(match_operand 2 "cc_reg_operand" "y")
11784                             (const_int 0)]))]
11785   ""
11786   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11787   [(set (attr "type")
11788      (cond [(match_test "TARGET_MFCRF")
11789                 (const_string "mfcrf")
11790            ]
11791         (const_string "mfcr")))
11792    (set_attr "length" "8")])
11794 ;; Same as above, but get the GT bit.
11795 (define_insn "move_from_CR_gt_bit"
11796   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11797         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11798   "TARGET_HARD_FLOAT && !TARGET_FPRS"
11799   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11800   [(set_attr "type" "mfcr")
11801    (set_attr "length" "8")])
11803 ;; Same as above, but get the OV/ORDERED bit.
11804 (define_insn "move_from_CR_ov_bit"
11805   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11806         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11807                    UNSPEC_MV_CR_OV))]
11808   "TARGET_ISEL"
11809   "mfcr %0\;rlwinm %0,%0,%t1,1"
11810   [(set_attr "type" "mfcr")
11811    (set_attr "length" "8")])
11813 (define_insn ""
11814   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11815         (match_operator:DI 1 "scc_comparison_operator"
11816                            [(match_operand 2 "cc_reg_operand" "y")
11817                             (const_int 0)]))]
11818   "TARGET_POWERPC64"
11819   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11820   [(set (attr "type")
11821      (cond [(match_test "TARGET_MFCRF")
11822                 (const_string "mfcrf")
11823            ]
11824         (const_string "mfcr")))
11825    (set_attr "length" "8")])
11827 (define_insn ""
11828   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11829         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11830                                        [(match_operand 2 "cc_reg_operand" "y,y")
11831                                         (const_int 0)])
11832                     (const_int 0)))
11833    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11834         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11835   "TARGET_32BIT"
11836   "@
11837    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11838    #"
11839   [(set_attr "type" "shift")
11840    (set_attr "dot" "yes")
11841    (set_attr "length" "8,16")])
11843 (define_split
11844   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11845         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11846                                        [(match_operand 2 "cc_reg_operand" "")
11847                                         (const_int 0)])
11848                     (const_int 0)))
11849    (set (match_operand:SI 3 "gpc_reg_operand" "")
11850         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11851   "TARGET_32BIT && reload_completed"
11852   [(set (match_dup 3)
11853         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11854    (set (match_dup 0)
11855         (compare:CC (match_dup 3)
11856                     (const_int 0)))]
11857   "")
11859 (define_insn ""
11860   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11861         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11862                                       [(match_operand 2 "cc_reg_operand" "y")
11863                                        (const_int 0)])
11864                    (match_operand:SI 3 "const_int_operand" "n")))]
11865   ""
11866   "*
11868   int is_bit = ccr_bit (operands[1], 1);
11869   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11870   int count;
11872   if (is_bit >= put_bit)
11873     count = is_bit - put_bit;
11874   else
11875     count = 32 - (put_bit - is_bit);
11877   operands[4] = GEN_INT (count);
11878   operands[5] = GEN_INT (put_bit);
11880   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11882   [(set (attr "type")
11883      (cond [(match_test "TARGET_MFCRF")
11884                 (const_string "mfcrf")
11885            ]
11886         (const_string "mfcr")))
11887    (set_attr "length" "8")])
11889 (define_insn ""
11890   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11891         (compare:CC
11892          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11893                                        [(match_operand 2 "cc_reg_operand" "y,y")
11894                                         (const_int 0)])
11895                     (match_operand:SI 3 "const_int_operand" "n,n"))
11896          (const_int 0)))
11897    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11898         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11899                    (match_dup 3)))]
11900   ""
11901   "*
11903   int is_bit = ccr_bit (operands[1], 1);
11904   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11905   int count;
11907   /* Force split for non-cc0 compare.  */
11908   if (which_alternative == 1)
11909      return \"#\";
11911   if (is_bit >= put_bit)
11912     count = is_bit - put_bit;
11913   else
11914     count = 32 - (put_bit - is_bit);
11916   operands[5] = GEN_INT (count);
11917   operands[6] = GEN_INT (put_bit);
11919   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11921   [(set_attr "type" "shift")
11922    (set_attr "dot" "yes")
11923    (set_attr "length" "8,16")])
11925 (define_split
11926   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11927         (compare:CC
11928          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11929                                        [(match_operand 2 "cc_reg_operand" "")
11930                                         (const_int 0)])
11931                     (match_operand:SI 3 "const_int_operand" ""))
11932          (const_int 0)))
11933    (set (match_operand:SI 4 "gpc_reg_operand" "")
11934         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11935                    (match_dup 3)))]
11936   "reload_completed"
11937   [(set (match_dup 4)
11938         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11939                    (match_dup 3)))
11940    (set (match_dup 0)
11941         (compare:CC (match_dup 4)
11942                     (const_int 0)))]
11943   "")
11945 ;; There is a 3 cycle delay between consecutive mfcr instructions
11946 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
11948 (define_peephole
11949   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11950         (match_operator:SI 1 "scc_comparison_operator"
11951                            [(match_operand 2 "cc_reg_operand" "y")
11952                             (const_int 0)]))
11953    (set (match_operand:SI 3 "gpc_reg_operand" "=r")
11954         (match_operator:SI 4 "scc_comparison_operator"
11955                            [(match_operand 5 "cc_reg_operand" "y")
11956                             (const_int 0)]))]
11957   "REGNO (operands[2]) != REGNO (operands[5])"
11958   "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11959   [(set_attr "type" "mfcr")
11960    (set_attr "length" "12")])
11962 (define_peephole
11963   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11964         (match_operator:DI 1 "scc_comparison_operator"
11965                            [(match_operand 2 "cc_reg_operand" "y")
11966                             (const_int 0)]))
11967    (set (match_operand:DI 3 "gpc_reg_operand" "=r")
11968         (match_operator:DI 4 "scc_comparison_operator"
11969                            [(match_operand 5 "cc_reg_operand" "y")
11970                             (const_int 0)]))]
11971   "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
11972   "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11973   [(set_attr "type" "mfcr")
11974    (set_attr "length" "12")])
11976 ;; There are some scc insns that can be done directly, without a compare.
11977 ;; These are faster because they don't involve the communications between
11978 ;; the FXU and branch units.   In fact, we will be replacing all of the
11979 ;; integer scc insns here or in the portable methods in emit_store_flag.
11981 ;; Also support (neg (scc ..)) since that construct is used to replace
11982 ;; branches, (plus (scc ..) ..) since that construct is common and
11983 ;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
11984 ;; cases where it is no more expensive than (neg (scc ..)).
11986 ;; Have reload force a constant into a register for the simple insns that
11987 ;; otherwise won't accept constants.  We do this because it is faster than
11988 ;; the cmp/mfcr sequence we would otherwise generate.
11990 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11991                               (DI "rKJI")])
11993 (define_insn_and_split "*eq<mode>"
11994   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11995         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11996                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))]
11997   ""
11998   "#"
11999   ""
12000   [(set (match_dup 0)
12001         (clz:GPR (match_dup 3)))
12002    (set (match_dup 0)
12003         (lshiftrt:GPR (match_dup 0) (match_dup 4)))]
12004   {
12005     if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)
12006       {
12007         /* Use output operand as intermediate.  */
12008         operands[3] = operands[0];
12010         if (logical_operand (operands[2], <MODE>mode))
12011           emit_insn (gen_rtx_SET (VOIDmode, operands[3],
12012                                   gen_rtx_XOR (<MODE>mode,
12013                                                operands[1], operands[2])));
12014         else
12015           emit_insn (gen_rtx_SET (VOIDmode, operands[3],
12016                                   gen_rtx_PLUS (<MODE>mode, operands[1],
12017                                                 negate_rtx (<MODE>mode,
12018                                                             operands[2]))));
12019       }
12020     else
12021       operands[3] = operands[1];
12023     operands[4] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12024   })
12026 (define_insn_and_split "*eq<mode>_compare"
12027   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
12028         (compare:CC
12029          (eq:P (match_operand:P 1 "gpc_reg_operand" "=r")
12030                (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12031          (const_int 0)))
12032    (set (match_operand:P 0 "gpc_reg_operand" "=r")
12033         (eq:P (match_dup 1) (match_dup 2)))]
12034   "optimize_size"
12035   "#"
12036   "optimize_size"
12037   [(set (match_dup 0)
12038         (clz:P (match_dup 4)))
12039    (parallel [(set (match_dup 3)
12040                    (compare:CC (lshiftrt:P (match_dup 0) (match_dup 5))
12041                                (const_int 0)))
12042               (set (match_dup 0)
12043                    (lshiftrt:P (match_dup 0) (match_dup 5)))])]
12044   {
12045     if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)
12046       {
12047         /* Use output operand as intermediate.  */
12048         operands[4] = operands[0];
12050         if (logical_operand (operands[2], <MODE>mode))
12051           emit_insn (gen_rtx_SET (VOIDmode, operands[4],
12052                                   gen_rtx_XOR (<MODE>mode,
12053                                                operands[1], operands[2])));
12054         else
12055           emit_insn (gen_rtx_SET (VOIDmode, operands[4],
12056                                   gen_rtx_PLUS (<MODE>mode, operands[1],
12057                                                 negate_rtx (<MODE>mode,
12058                                                             operands[2]))));
12059       }
12060     else
12061       operands[4] = operands[1];
12063     operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12064   })
12066 ;; We have insns of the form shown by the first define_insn below.  If
12067 ;; there is something inside the comparison operation, we must split it.
12068 (define_split
12069   [(set (match_operand:SI 0 "gpc_reg_operand" "")
12070         (plus:SI (match_operator 1 "comparison_operator"
12071                                  [(match_operand:SI 2 "" "")
12072                                   (match_operand:SI 3
12073                                                     "reg_or_cint_operand" "")])
12074                  (match_operand:SI 4 "gpc_reg_operand" "")))
12075    (clobber (match_operand:SI 5 "register_operand" ""))]
12076   "! gpc_reg_operand (operands[2], SImode)"
12077   [(set (match_dup 5) (match_dup 2))
12078    (set (match_dup 0) (plus:SI (match_op_dup 1 [(match_dup 5) (match_dup 3)])
12079                                (match_dup 4)))])
12081 (define_insn "*plus_eqsi"
12082   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r")
12083         (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
12084                         (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I"))
12085                  (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))]
12086   "TARGET_32BIT"
12087   "@
12088    xor %0,%1,%2\;subfic %0,%0,0\;addze %0,%3
12089    subfic %0,%1,0\;addze %0,%3
12090    xori %0,%1,%b2\;subfic %0,%0,0\;addze %0,%3
12091    xoris %0,%1,%u2\;subfic %0,%0,0\;addze %0,%3
12092    subfic %0,%1,%2\;subfic %0,%0,0\;addze %0,%3"
12093   [(set_attr "type" "three,two,three,three,three")
12094    (set_attr "length" "12,8,12,12,12")])
12096 (define_insn "*compare_plus_eqsi"
12097   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y")
12098         (compare:CC
12099          (plus:SI
12100           (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
12101                  (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I,r,O,K,L,I"))
12102           (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r"))
12103          (const_int 0)))
12104    (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))]
12105   "TARGET_32BIT && optimize_size"
12106   "@
12107    xor %4,%1,%2\;subfic %4,%4,0\;addze. %4,%3
12108    subfic %4,%1,0\;addze. %4,%3
12109    xori %4,%1,%b2\;subfic %4,%4,0\;addze. %4,%3
12110    xoris %4,%1,%u2\;subfic %4,%4,0\;addze. %4,%3
12111    subfic %4,%1,%2\;subfic %4,%4,0\;addze. %4,%3
12112    #
12113    #
12114    #
12115    #
12116    #"
12117   [(set_attr "type" "compare")
12118    (set_attr "length" "12,8,12,12,12,16,12,16,16,16")])
12120 (define_split
12121   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12122         (compare:CC
12123          (plus:SI
12124           (eq:SI (match_operand:SI 1 "gpc_reg_operand" "")
12125                  (match_operand:SI 2 "scc_eq_operand" ""))
12126           (match_operand:SI 3 "gpc_reg_operand" ""))
12127          (const_int 0)))
12128    (clobber (match_scratch:SI 4 ""))]
12129   "TARGET_32BIT && optimize_size && reload_completed"
12130   [(set (match_dup 4)
12131         (plus:SI (eq:SI (match_dup 1)
12132                  (match_dup 2))
12133           (match_dup 3)))
12134    (set (match_dup 0)
12135         (compare:CC (match_dup 4)
12136                     (const_int 0)))]
12137   "")
12139 (define_insn "*plus_eqsi_compare"
12140   [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y")
12141         (compare:CC
12142          (plus:SI
12143           (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
12144                  (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I,r,O,K,L,I"))
12145           (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r"))
12146          (const_int 0)))
12147    (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r")
12148         (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12149   "TARGET_32BIT && optimize_size"
12150   "@
12151    xor %0,%1,%2\;subfic %0,%0,0\;addze. %0,%3
12152    subfic %0,%1,0\;addze. %0,%3
12153    xori %0,%1,%b2\;subfic %0,%0,0\;addze. %0,%3
12154    xoris %0,%1,%u2\;subfic %0,%0,0\;addze. %0,%3
12155    subfic %0,%1,%2\;subfic %0,%0,0\;addze. %0,%3
12156    #
12157    #
12158    #
12159    #
12160    #"
12161   [(set_attr "type" "compare")
12162    (set_attr "length" "12,8,12,12,12,16,12,16,16,16")])
12164 (define_split
12165   [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
12166         (compare:CC
12167          (plus:SI
12168           (eq:SI (match_operand:SI 1 "gpc_reg_operand" "")
12169                  (match_operand:SI 2 "scc_eq_operand" ""))
12170           (match_operand:SI 3 "gpc_reg_operand" ""))
12171          (const_int 0)))
12172    (set (match_operand:SI 0 "gpc_reg_operand" "")
12173         (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12174   "TARGET_32BIT && optimize_size && reload_completed"
12175   [(set (match_dup 0)
12176         (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
12177    (set (match_dup 4)
12178         (compare:CC (match_dup 0)
12179                     (const_int 0)))]
12180   "")
12182 (define_insn "*neg_eq0<mode>"
12183   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12184         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12185                      (const_int 0))))]
12186   ""
12187   "addic %0,%1,-1\;subfe %0,%0,%0"
12188   [(set_attr "type" "two")
12189    (set_attr "length" "8")])
12191 (define_insn_and_split "*neg_eq<mode>"
12192   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12193         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "%r")
12194                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))]
12195   ""
12196   "#"
12197   ""
12198   [(set (match_dup 0) (neg:P (eq:P (match_dup 3) (const_int 0))))]
12199   {
12200     if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)
12201       {
12202         /* Use output operand as intermediate.  */
12203         operands[3] = operands[0];
12205         if (logical_operand (operands[2], <MODE>mode))
12206           emit_insn (gen_rtx_SET (VOIDmode, operands[3],
12207                                   gen_rtx_XOR (<MODE>mode,
12208                                                operands[1], operands[2])));
12209         else
12210           emit_insn (gen_rtx_SET (VOIDmode, operands[3],
12211                                   gen_rtx_PLUS (<MODE>mode, operands[1],
12212                                                 negate_rtx (<MODE>mode,
12213                                                             operands[2]))));
12214       }
12215     else
12216       operands[3] = operands[1];
12217   })
12219 (define_insn "*ne0_<mode>"
12220   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12221         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12222               (const_int 0)))
12223    (clobber (match_scratch:P 2 "=&r"))]
12224   "!(TARGET_32BIT && TARGET_ISEL)"
12225   "addic %2,%1,-1\;subfe %0,%2,%1"
12226   [(set_attr "type" "two")
12227    (set_attr "length" "8")])
12229 (define_insn "*plus_ne0_<mode>"
12230   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12231         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12232                       (const_int 0))
12233                 (match_operand:P 2 "gpc_reg_operand" "r")))
12234    (clobber (match_scratch:P 3 "=&r"))]
12235   ""
12236   "addic %3,%1,-1\;addze %0,%2"
12237   [(set_attr "type" "two")
12238    (set_attr "length" "8")])
12240 (define_insn "*compare_plus_ne0_<mode>"
12241   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12242         (compare:CC (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12243                                   (const_int 0))
12244                             (match_operand:P 2 "gpc_reg_operand" "r,r"))
12245                     (const_int 0)))
12246    (clobber (match_scratch:P 3 "=&r,&r"))
12247    (clobber (match_scratch:P 4 "=X,&r"))]
12248   ""
12249   "@
12250    addic %3,%1,-1\;addze. %3,%2
12251    #"
12252   [(set_attr "type" "compare")
12253    (set_attr "length" "8,12")])
12255 (define_split
12256   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12257         (compare:CC (ne:P (match_operand:SI 1 "gpc_reg_operand" "")
12258                           (const_int 0))
12259                     (neg:P (match_operand:P 2 "gpc_reg_operand" ""))))
12260    (clobber (match_scratch:P 3 ""))
12261    (clobber (match_scratch:P 4 ""))]
12262   "reload_completed"
12263   [(parallel [(set (match_dup 3)
12264                    (plus:P (ne:P (match_dup 1)
12265                                  (const_int 0))
12266                            (match_dup 2)))
12267               (clobber (match_dup 4))])
12268    (set (match_dup 0)
12269         (compare:CC (match_dup 3)
12270                     (const_int 0)))]
12271   "")
12273 ; For combine.
12274 (define_insn "*compare_plus_ne0_<mode>_1"
12275   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
12276         (compare:CCEQ (ne:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12277                             (const_int 0))
12278                       (neg:P (match_operand:P 2 "gpc_reg_operand" "r,r"))))
12279    (clobber (match_scratch:P 3 "=&r,&r"))
12280    (clobber (match_scratch:P 4 "=X,&r"))]
12281   ""
12282   "@
12283    addic %3,%1,-1\;addze. %3,%2
12284    #"
12285   [(set_attr "type" "compare")
12286    (set_attr "length" "8,12")])
12288 (define_split
12289   [(set (match_operand:CCEQ 0 "cc_reg_not_micro_cr0_operand" "")
12290         (compare:CCEQ (ne:P (match_operand:SI 1 "gpc_reg_operand" "")
12291                             (const_int 0))
12292                       (neg:P (match_operand:P 2 "gpc_reg_operand" ""))))
12293    (clobber (match_scratch:P 3 ""))
12294    (clobber (match_scratch:P 4 ""))]
12295   "reload_completed"
12296   [(parallel [(set (match_dup 3)
12297                    (plus:P (ne:P (match_dup 1)
12298                                  (const_int 0))
12299                            (match_dup 2)))
12300               (clobber (match_dup 4))])
12301    (set (match_dup 0)
12302         (compare:CC (match_dup 3)
12303                     (const_int 0)))]
12304   "")
12306 (define_insn "*plus_ne0_<mode>_compare"
12307   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
12308         (compare:CC
12309          (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12310                        (const_int 0))
12311                  (match_operand:P 2 "gpc_reg_operand" "r,r"))
12312          (const_int 0)))
12313    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12314         (plus:P (ne:P (match_dup 1)
12315                       (const_int 0))
12316                 (match_dup 2)))
12317    (clobber (match_scratch:P 3 "=&r,&r"))]
12318   ""
12319   "@
12320    addic %3,%1,-1\;addze. %0,%2
12321    #"
12322   [(set_attr "type" "compare")
12323    (set_attr "length" "8,12")])
12325 (define_split
12326   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
12327         (compare:CC
12328          (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "")
12329                        (const_int 0))
12330                  (match_operand:P 2 "gpc_reg_operand" ""))
12331          (const_int 0)))
12332    (set (match_operand:P 0 "gpc_reg_operand" "")
12333         (plus:P (ne:P (match_dup 1)
12334                       (const_int 0))
12335                 (match_dup 2)))
12336    (clobber (match_scratch:P 3 ""))]
12337   "reload_completed"
12338   [(parallel [(set (match_dup 0)
12339                    (plus:P (ne:P (match_dup 1)
12340                                  (const_int 0))
12341                            (match_dup 2)))
12342               (clobber (match_dup 3))])
12343    (set (match_dup 4)
12344         (compare:CC (match_dup 0)
12345                     (const_int 0)))]
12346   "")
12348 (define_insn "*leu<mode>"
12349   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12350         (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
12351                (match_operand:P 2 "reg_or_short_operand" "rI")))]
12352   ""
12353   "subf%I2c %0,%1,%2\;li %0,0\;adde %0,%0,%0"
12354   [(set_attr "type" "three")
12355    (set_attr "length" "12")])
12357 (define_insn "*leu<mode>_compare"
12358   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
12359         (compare:CC
12360          (leu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12361                 (match_operand:P 2 "reg_or_short_operand" "rI,rI"))
12362          (const_int 0)))
12363    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12364         (leu:P (match_dup 1) (match_dup 2)))]
12365   ""
12366   "@
12367    subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0
12368    #"
12369   [(set_attr "type" "compare")
12370    (set_attr "length" "12,16")])
12372 (define_split
12373   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
12374         (compare:CC
12375          (leu:P (match_operand:P 1 "gpc_reg_operand" "")
12376                 (match_operand:P 2 "reg_or_short_operand" ""))
12377          (const_int 0)))
12378    (set (match_operand:P 0 "gpc_reg_operand" "")
12379         (leu:P (match_dup 1) (match_dup 2)))]
12380   "reload_completed"
12381   [(set (match_dup 0)
12382         (leu:P (match_dup 1) (match_dup 2)))
12383    (set (match_dup 3)
12384         (compare:CC (match_dup 0)
12385                     (const_int 0)))]
12386   "")
12388 (define_insn "*plus_leu<mode>"
12389   [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
12390         (plus:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
12391                        (match_operand:P 2 "reg_or_short_operand" "rI"))
12392                 (match_operand:P 3 "gpc_reg_operand" "r")))]
12393   ""
12394   "subf%I2c %0,%1,%2\;addze %0,%3"
12395   [(set_attr "type" "two")
12396    (set_attr "length" "8")])
12398 (define_insn ""
12399   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12400         (compare:CC
12401          (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12402                           (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
12403                   (match_operand:SI 3 "gpc_reg_operand" "r,r"))
12404          (const_int 0)))
12405    (clobber (match_scratch:SI 4 "=&r,&r"))]
12406   "TARGET_32BIT"
12407   "@
12408    subf%I2c %4,%1,%2\;addze. %4,%3
12409    #"
12410   [(set_attr "type" "compare")
12411    (set_attr "length" "8,12")])
12413 (define_split
12414   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12415         (compare:CC
12416          (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12417                           (match_operand:SI 2 "reg_or_short_operand" ""))
12418                   (match_operand:SI 3 "gpc_reg_operand" ""))
12419          (const_int 0)))
12420    (clobber (match_scratch:SI 4 ""))]
12421   "TARGET_32BIT && reload_completed"
12422   [(set (match_dup 4)
12423         (plus:SI (leu:SI (match_dup 1) (match_dup 2))
12424                   (match_dup 3)))
12425    (set (match_dup 0)
12426         (compare:CC (match_dup 4)
12427                     (const_int 0)))]
12428   "")
12430 (define_insn ""
12431   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
12432         (compare:CC
12433          (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12434                           (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
12435                   (match_operand:SI 3 "gpc_reg_operand" "r,r"))
12436          (const_int 0)))
12437    (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
12438         (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12439   "TARGET_32BIT"
12440   "@
12441    subf%I2c %0,%1,%2\;addze. %0,%3
12442    #"
12443   [(set_attr "type" "compare")
12444    (set_attr "length" "8,12")])
12446 (define_split
12447   [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
12448         (compare:CC
12449          (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12450                           (match_operand:SI 2 "reg_or_short_operand" ""))
12451                   (match_operand:SI 3 "gpc_reg_operand" ""))
12452          (const_int 0)))
12453    (set (match_operand:SI 0 "gpc_reg_operand" "")
12454         (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12455   "TARGET_32BIT && reload_completed"
12456   [(set (match_dup 0)
12457         (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
12458    (set (match_dup 4)
12459         (compare:CC (match_dup 0)
12460                     (const_int 0)))]
12461   "")
12463 (define_insn "*neg_leu<mode>"
12464   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12465         (neg:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
12466                       (match_operand:P 2 "reg_or_short_operand" "rI"))))]
12467   ""
12468   "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;nand %0,%0,%0"
12469    [(set_attr "type" "three")
12470     (set_attr "length" "12")])
12472 (define_insn "*and_neg_leu<mode>"
12473   [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
12474         (and:P (neg:P
12475                  (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
12476                         (match_operand:P 2 "reg_or_short_operand" "rI")))
12477                 (match_operand:P 3 "gpc_reg_operand" "r")))]
12478   ""
12479   "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;andc %0,%3,%0"
12480   [(set_attr "type" "three")
12481    (set_attr "length" "12")])
12483 (define_insn ""
12484   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12485         (compare:CC
12486          (and:SI (neg:SI
12487                   (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12488                           (match_operand:SI 2 "reg_or_short_operand" "rI,rI")))
12489                  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
12490          (const_int 0)))
12491    (clobber (match_scratch:SI 4 "=&r,&r"))]
12492   "TARGET_32BIT"
12493   "@
12494    subf%I2c %4,%1,%2\;subfe %4,%4,%4\;andc. %4,%3,%4
12495    #"
12496   [(set_attr "type" "compare")
12497    (set_attr "length" "12,16")])
12499 (define_split
12500   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12501         (compare:CC
12502          (and:SI (neg:SI
12503                   (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12504                           (match_operand:SI 2 "reg_or_short_operand" "")))
12505                  (match_operand:SI 3 "gpc_reg_operand" ""))
12506          (const_int 0)))
12507    (clobber (match_scratch:SI 4 ""))]
12508   "TARGET_32BIT && reload_completed"
12509   [(set (match_dup 4)
12510         (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2)))
12511                 (match_dup 3)))
12512    (set (match_dup 0)
12513         (compare:CC (match_dup 4)
12514                     (const_int 0)))]
12515   "")
12517 (define_insn ""
12518   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
12519         (compare:CC
12520          (and:SI (neg:SI
12521                   (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12522                           (match_operand:SI 2 "reg_or_short_operand" "rI,rI")))
12523                  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
12524          (const_int 0)))
12525    (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
12526         (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
12527   "TARGET_32BIT"
12528   "@
12529    subf%I2c %0,%1,%2\;subfe %0,%0,%0\;andc. %0,%3,%0
12530    #"
12531   [(set_attr "type" "compare")
12532    (set_attr "length" "12,16")])
12534 (define_split
12535   [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
12536         (compare:CC
12537          (and:SI (neg:SI
12538                   (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12539                           (match_operand:SI 2 "reg_or_short_operand" "")))
12540                  (match_operand:SI 3 "gpc_reg_operand" ""))
12541          (const_int 0)))
12542    (set (match_operand:SI 0 "gpc_reg_operand" "")
12543         (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
12544   "TARGET_32BIT && reload_completed"
12545   [(set (match_dup 0)
12546         (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2)))
12547                 (match_dup 3)))
12548    (set (match_dup 4)
12549         (compare:CC (match_dup 0)
12550                     (const_int 0)))]
12551   "")
12553 (define_insn_and_split "*ltu<mode>"
12554   [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12555         (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12556                (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))]
12557   ""
12558   "#"
12559   ""
12560   [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12561    (set (match_dup 0) (neg:P (match_dup 0)))]
12562   "")
12564 (define_insn_and_split "*ltu<mode>_compare"
12565   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
12566         (compare:CC
12567          (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
12568                 (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P"))
12569          (const_int 0)))
12570    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r")
12571         (ltu:P (match_dup 1) (match_dup 2)))]
12572   ""
12573   "#"
12574   ""
12575   [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12576    (parallel [(set (match_dup 3)
12577                    (compare:CC (neg:P (match_dup 0)) (const_int 0)))
12578               (set (match_dup 0) (neg:P (match_dup 0)))])]
12579   "")
12581 (define_insn_and_split "*plus_ltu<mode>"
12582   [(set (match_operand:P 0 "gpc_reg_operand" "=&r,r")
12583         (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12584                        (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))
12585                 (match_operand:P 3 "gpc_reg_operand" "r,r")))]
12586   ""
12587   "#"
12588   "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
12589   [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12590    (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))]
12591   "")
12593 (define_insn_and_split "*plus_ltu<mode>_1"
12594   [(set (match_operand:P 0 "gpc_reg_operand" "=&r,r")
12595         (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12596                        (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))
12597                 (match_operand:P 3 "short_cint_operand" "I,I")))]
12598   ""
12599   "#"
12600   "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
12601   [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12602    (parallel [(set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))
12603               (clobber (reg:P CA_REGNO))])]
12604   "")
12606 (define_insn_and_split "*plus_ltu<mode>_compare"
12607   [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
12608         (compare:CC
12609          (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
12610                         (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P"))
12611                  (match_operand:P 3 "gpc_reg_operand" "r,r,r,r"))
12612          (const_int 0)))
12613    (set (match_operand:P 0 "gpc_reg_operand" "=&r,&r,&r,&r")
12614         (plus:P (ltu:P (match_dup 1) (match_dup 2)) (match_dup 3)))]
12615   ""
12616   "#"
12617   "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
12618   [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12619    (parallel [(set (match_dup 4)
12620                    (compare:CC (minus:P (match_dup 3) (match_dup 0))
12621                                (const_int 0)))
12622               (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))])]
12623   "")
12625 (define_insn "*neg_ltu<mode>"
12626   [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12627         (neg:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12628                       (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))))]
12629   ""
12630   "@
12631    subfc %0,%2,%1\;subfe %0,%0,%0
12632    addic %0,%1,%n2\;subfe %0,%0,%0"
12633   [(set_attr "type" "two")
12634    (set_attr "length" "8")])
12636 (define_insn "*geu<mode>"
12637   [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12638         (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12639                (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))]
12640   ""
12641   "@
12642    subfc %0,%2,%1\;li %0,0\;adde %0,%0,%0
12643    addic %0,%1,%n2\;li %0,0\;adde %0,%0,%0"
12644   [(set_attr "type" "three")
12645    (set_attr "length" "12")])
12647 (define_insn "*geu<mode>_compare"
12648   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
12649         (compare:CC
12650          (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
12651                 (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P"))
12652          (const_int 0)))
12653    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r")
12654         (geu:P (match_dup 1) (match_dup 2)))]
12655   ""
12656   "@
12657    subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0
12658    addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0
12659    #
12660    #"
12661   [(set_attr "type" "compare")
12662    (set_attr "length" "12,12,16,16")])
12664 (define_split
12665   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
12666         (compare:CC
12667          (geu:P (match_operand:P 1 "gpc_reg_operand" "")
12668                 (match_operand:P 2 "reg_or_neg_short_operand" ""))
12669          (const_int 0)))
12670    (set (match_operand:P 0 "gpc_reg_operand" "")
12671         (geu:P (match_dup 1) (match_dup 2)))]
12672   "reload_completed"
12673   [(set (match_dup 0)
12674         (geu:P (match_dup 1) (match_dup 2)))
12675    (set (match_dup 3)
12676         (compare:CC (match_dup 0)
12677                     (const_int 0)))]
12678   "")
12680 (define_insn "*plus_geu<mode>"
12681   [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r")
12682         (plus:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12683                        (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))
12684                 (match_operand:P 3 "gpc_reg_operand" "r,r")))]
12685   ""
12686   "@
12687    subfc %0,%2,%1\;addze %0,%3
12688    addic %0,%1,%n2\;addze %0,%3"
12689   [(set_attr "type" "two")
12690    (set_attr "length" "8")])
12692 (define_insn ""
12693   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
12694         (compare:CC
12695          (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
12696                           (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
12697                   (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
12698          (const_int 0)))
12699    (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
12700   "TARGET_32BIT"
12701   "@
12702    subfc %4,%2,%1\;addze. %4,%3
12703    addic %4,%1,%n2\;addze. %4,%3
12704    #
12705    #"
12706   [(set_attr "type" "compare")
12707    (set_attr "length" "8,8,12,12")])
12709 (define_split
12710   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12711         (compare:CC
12712          (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12713                           (match_operand:SI 2 "reg_or_neg_short_operand" ""))
12714                   (match_operand:SI 3 "gpc_reg_operand" ""))
12715          (const_int 0)))
12716    (clobber (match_scratch:SI 4 ""))]
12717   "TARGET_32BIT && reload_completed"
12718   [(set (match_dup 4)
12719         (plus:SI (geu:SI (match_dup 1) (match_dup 2))
12720                   (match_dup 3)))
12721    (set (match_dup 0)
12722         (compare:CC (match_dup 4)
12723                     (const_int 0)))]
12724   "")
12726 (define_insn ""
12727   [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
12728         (compare:CC
12729          (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
12730                           (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
12731                   (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
12732          (const_int 0)))
12733    (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
12734         (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12735   "TARGET_32BIT"
12736   "@
12737    subfc %0,%2,%1\;addze. %0,%3
12738    addic %0,%1,%n2\;addze. %0,%3
12739    #
12740    #"
12741   [(set_attr "type" "compare")
12742    (set_attr "length" "8,8,12,12")])
12744 (define_split
12745   [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
12746         (compare:CC
12747          (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12748                           (match_operand:SI 2 "reg_or_neg_short_operand" ""))
12749                   (match_operand:SI 3 "gpc_reg_operand" ""))
12750          (const_int 0)))
12751    (set (match_operand:SI 0 "gpc_reg_operand" "")
12752         (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12753   "TARGET_32BIT && reload_completed"
12754   [(set (match_dup 0)
12755         (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
12756    (set (match_dup 4)
12757         (compare:CC (match_dup 0)
12758                     (const_int 0)))]
12759   "")
12761 (define_insn "*neg_geu<mode>"
12762   [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12763         (neg:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12764                       (match_operand:P 2 "reg_or_short_operand" "r,I"))))]
12765   ""
12766   "@
12767    subfc %0,%2,%1\;subfe %0,%0,%0\;nand %0,%0,%0
12768    subfic %0,%1,-1\;add%I2c %0,%0,%2\;subfe %0,%0,%0"
12769   [(set_attr "type" "three")
12770    (set_attr "length" "12")])
12772 (define_insn "*and_neg_geu<mode>"
12773   [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r")
12774         (and:P (neg:P
12775                  (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12776                         (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))
12777                 (match_operand:P 3 "gpc_reg_operand" "r,r")))]
12778   ""
12779   "@
12780    subfc %0,%2,%1\;subfe %0,%0,%0\;andc %0,%3,%0
12781    addic %0,%1,%n2\;subfe %0,%0,%0\;andc %0,%3,%0"
12782   [(set_attr "type" "three")
12783    (set_attr "length" "12")])
12785 (define_insn ""
12786   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
12787         (compare:CC
12788          (and:SI (neg:SI
12789                   (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
12790                           (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")))
12791                  (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
12792          (const_int 0)))
12793    (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
12794   "TARGET_32BIT"
12795   "@
12796    subfc %4,%2,%1\;subfe %4,%4,%4\;andc. %4,%3,%4
12797    addic %4,%1,%n2\;subfe %4,%4,%4\;andc. %4,%3,%4
12798    #
12799    #"
12800   [(set_attr "type" "compare")
12801    (set_attr "length" "12,12,16,16")])
12803 (define_split
12804   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12805         (compare:CC
12806          (and:SI (neg:SI
12807                   (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12808                           (match_operand:SI 2 "reg_or_neg_short_operand" "")))
12809                  (match_operand:SI 3 "gpc_reg_operand" ""))
12810          (const_int 0)))
12811    (clobber (match_scratch:SI 4 ""))]
12812   "TARGET_32BIT && reload_completed"
12813   [(set (match_dup 4)
12814         (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2)))
12815                 (match_dup 3)))
12816    (set (match_dup 0)
12817         (compare:CC (match_dup 4)
12818                     (const_int 0)))]
12819   "")
12821 (define_insn ""
12822   [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
12823         (compare:CC
12824          (and:SI (neg:SI
12825                   (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
12826                           (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")))
12827                  (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
12828          (const_int 0)))
12829    (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
12830         (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
12831   "TARGET_32BIT"
12832   "@
12833    subfc %0,%2,%1\;subfe %0,%0,%0\;andc. %0,%3,%0
12834    addic %0,%1,%n2\;subfe %0,%0,%0\;andc. %0,%3,%0
12835    #
12836    #"
12837   [(set_attr "type" "compare")
12838    (set_attr "length" "12,12,16,16")])
12840 (define_split
12841   [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
12842         (compare:CC
12843          (and:SI (neg:SI
12844                   (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
12845                           (match_operand:SI 2 "reg_or_neg_short_operand" "")))
12846                  (match_operand:SI 3 "gpc_reg_operand" ""))
12847          (const_int 0)))
12848    (set (match_operand:SI 0 "gpc_reg_operand" "")
12849         (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
12850   "TARGET_32BIT && reload_completed"
12851   [(set (match_dup 0)
12852         (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
12853    (set (match_dup 4)
12854         (compare:CC (match_dup 0)
12855                     (const_int 0)))]
12856   "")
12858 (define_insn "*plus_gt0<mode>"
12859   [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
12860         (plus:P (gt:P (match_operand:P 1 "gpc_reg_operand" "r")
12861                       (const_int 0))
12862                  (match_operand:P 2 "gpc_reg_operand" "r")))]
12863   ""
12864   "addc %0,%1,%1\;subfe %0,%1,%0\;addze %0,%2"
12865   [(set_attr "type" "three")
12866    (set_attr "length" "12")])
12868 (define_insn ""
12869   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12870         (compare:CC
12871          (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12872                          (const_int 0))
12873                   (match_operand:SI 2 "gpc_reg_operand" "r,r"))
12874          (const_int 0)))
12875    (clobber (match_scratch:SI 3 "=&r,&r"))]
12876   "TARGET_32BIT"
12877   "@
12878    addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2
12879    #"
12880   [(set_attr "type" "compare")
12881    (set_attr "length" "12,16")])
12883 (define_split
12884   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12885         (compare:CC
12886          (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
12887                          (const_int 0))
12888                   (match_operand:SI 2 "gpc_reg_operand" ""))
12889          (const_int 0)))
12890    (clobber (match_scratch:SI 3 ""))]
12891   "TARGET_32BIT && reload_completed"
12892   [(set (match_dup 3)
12893         (plus:SI (gt:SI (match_dup 1) (const_int 0))
12894                   (match_dup 2)))
12895    (set (match_dup 0)
12896         (compare:CC (match_dup 3)
12897                     (const_int 0)))]
12898   "")
12900 (define_insn ""
12901   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12902         (compare:CC
12903          (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
12904                          (const_int 0))
12905                   (match_operand:DI 2 "gpc_reg_operand" "r,r"))
12906          (const_int 0)))
12907    (clobber (match_scratch:DI 3 "=&r,&r"))]
12908   "TARGET_64BIT"
12909   "@
12910    addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2
12911    #"
12912   [(set_attr "type" "compare")
12913    (set_attr "length" "12,16")])
12915 (define_split
12916   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12917         (compare:CC
12918          (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "")
12919                          (const_int 0))
12920                   (match_operand:DI 2 "gpc_reg_operand" ""))
12921          (const_int 0)))
12922    (clobber (match_scratch:DI 3 ""))]
12923   "TARGET_64BIT && reload_completed"
12924   [(set (match_dup 3)
12925         (plus:DI (gt:DI (match_dup 1) (const_int 0))
12926                  (match_dup 2)))
12927    (set (match_dup 0)
12928         (compare:CC (match_dup 3)
12929                     (const_int 0)))]
12930   "")
12932 (define_insn ""
12933   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
12934         (compare:CC
12935          (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12936                          (const_int 0))
12937                   (match_operand:SI 2 "gpc_reg_operand" "r,r"))
12938          (const_int 0)))
12939    (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
12940         (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))]
12941   "TARGET_32BIT"
12942   "@
12943    addc %0,%1,%1\;subfe %0,%1,%0\;addze. %0,%2
12944    #"
12945   [(set_attr "type" "compare")
12946    (set_attr "length" "12,16")])
12948 (define_split
12949   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
12950         (compare:CC
12951          (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
12952                          (const_int 0))
12953                   (match_operand:SI 2 "gpc_reg_operand" ""))
12954          (const_int 0)))
12955    (set (match_operand:SI 0 "gpc_reg_operand" "")
12956         (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))]
12957   "TARGET_32BIT && reload_completed"
12958   [(set (match_dup 0)
12959         (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
12960    (set (match_dup 3)
12961         (compare:CC (match_dup 0)
12962                     (const_int 0)))]
12963   "")
12965 (define_insn ""
12966   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
12967         (compare:CC
12968          (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
12969                          (const_int 0))
12970                   (match_operand:DI 2 "gpc_reg_operand" "r,r"))
12971          (const_int 0)))
12972    (set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
12973         (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))]
12974   "TARGET_64BIT"
12975   "@
12976    addc %0,%1,%1\;subfe %0,%1,%0\;addze. %0,%2
12977    #"
12978   [(set_attr "type" "compare")
12979    (set_attr "length" "12,16")])
12981 (define_split
12982   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
12983         (compare:CC
12984          (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "")
12985                          (const_int 0))
12986                   (match_operand:DI 2 "gpc_reg_operand" ""))
12987          (const_int 0)))
12988    (set (match_operand:DI 0 "gpc_reg_operand" "")
12989         (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))]
12990   "TARGET_64BIT && reload_completed"
12991   [(set (match_dup 0)
12992         (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))
12993    (set (match_dup 3)
12994         (compare:CC (match_dup 0)
12995                     (const_int 0)))]
12996   "")
12998 (define_insn_and_split "*gtu<mode>"
12999   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13000         (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
13001                (match_operand:P 2 "reg_or_short_operand" "rI")))]
13002   ""
13003   "#"
13004   ""
13005   [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13006    (set (match_dup 0) (neg:P (match_dup 0)))]
13007   "")
13009 (define_insn_and_split "*gtu<mode>_compare"
13010   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
13011         (compare:CC
13012          (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
13013                  (match_operand:P 2 "reg_or_short_operand" "rI,rI"))
13014          (const_int 0)))
13015    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
13016         (gtu:P (match_dup 1) (match_dup 2)))]
13017   ""
13018   "#"
13019   ""
13020   [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13021    (parallel [(set (match_dup 3)
13022                    (compare:CC (neg:P (match_dup 0)) (const_int 0)))
13023               (set (match_dup 0) (neg:P (match_dup 0)))])]
13024   "")
13026 (define_insn_and_split "*plus_gtu<mode>"
13027   [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
13028         (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
13029                        (match_operand:P 2 "reg_or_short_operand" "rI"))
13030                 (match_operand:P 3 "gpc_reg_operand" "r")))]
13031   ""
13032   "#"
13033   "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
13034   [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13035    (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))]
13036   "")
13038 (define_insn_and_split "*plus_gtu<mode>_1"
13039   [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
13040         (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
13041                        (match_operand:P 2 "reg_or_short_operand" "rI"))
13042                 (match_operand:P 3 "short_cint_operand" "I")))]
13043   ""
13044   "#"
13045   "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
13046   [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13047    (parallel [(set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))
13048               (clobber (reg:P CA_REGNO))])]
13049   "")
13051 (define_insn_and_split "*plus_gtu<mode>_compare"
13052   [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
13053         (compare:CC
13054          (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
13055                         (match_operand:P 2 "reg_or_short_operand" "I,r,I,r"))
13056                  (match_operand:P 3 "gpc_reg_operand" "r,r,r,r"))
13057          (const_int 0)))
13058    (set (match_operand:P 0 "gpc_reg_operand" "=&r,&r,&r,&r")
13059         (plus:P (gtu:P (match_dup 1) (match_dup 2)) (match_dup 3)))]
13060   ""
13061   "#"
13062   "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
13063   [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13064    (parallel [(set (match_dup 4)
13065                    (compare:CC (minus:P (match_dup 3) (match_dup 0))
13066                                (const_int 0)))
13067               (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))])]
13068   "")
13070 (define_insn "*neg_gtu<mode>"
13071   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13072         (neg:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
13073                       (match_operand:P 2 "reg_or_short_operand" "rI"))))]
13074   ""
13075   "subf%I2c %0,%1,%2\;subfe %0,%0,%0"
13076   [(set_attr "type" "two")
13077    (set_attr "length" "8")])
13080 ;; Define both directions of branch and return.  If we need a reload
13081 ;; register, we'd rather use CR0 since it is much easier to copy a
13082 ;; register CC value to there.
13084 (define_insn ""
13085   [(set (pc)
13086         (if_then_else (match_operator 1 "branch_comparison_operator"
13087                                       [(match_operand 2
13088                                                       "cc_reg_operand" "y")
13089                                        (const_int 0)])
13090                       (label_ref (match_operand 0 "" ""))
13091                       (pc)))]
13092   ""
13093   "*
13095   return output_cbranch (operands[1], \"%l0\", 0, insn);
13097   [(set_attr "type" "branch")])
13099 (define_insn ""
13100   [(set (pc)
13101         (if_then_else (match_operator 0 "branch_comparison_operator"
13102                                       [(match_operand 1
13103                                                       "cc_reg_operand" "y")
13104                                        (const_int 0)])
13105                       (any_return)
13106                       (pc)))]
13107   "<return_pred>"
13108   "*
13110   return output_cbranch (operands[0], NULL, 0, insn);
13112   [(set_attr "type" "jmpreg")
13113    (set_attr "length" "4")])
13115 (define_insn ""
13116   [(set (pc)
13117         (if_then_else (match_operator 1 "branch_comparison_operator"
13118                                       [(match_operand 2
13119                                                       "cc_reg_operand" "y")
13120                                        (const_int 0)])
13121                       (pc)
13122                       (label_ref (match_operand 0 "" ""))))]
13123   ""
13124   "*
13126   return output_cbranch (operands[1], \"%l0\", 1, insn);
13128   [(set_attr "type" "branch")])
13130 (define_insn ""
13131   [(set (pc)
13132         (if_then_else (match_operator 0 "branch_comparison_operator"
13133                                       [(match_operand 1
13134                                                       "cc_reg_operand" "y")
13135                                        (const_int 0)])
13136                       (pc)
13137                       (any_return)))]
13138   "<return_pred>"
13139   "*
13141   return output_cbranch (operands[0], NULL, 1, insn);
13143   [(set_attr "type" "jmpreg")
13144    (set_attr "length" "4")])
13146 ;; Logic on condition register values.
13148 ; This pattern matches things like
13149 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
13150 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
13151 ;                                  (const_int 1)))
13152 ; which are generated by the branch logic.
13153 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
13155 (define_insn "*cceq_ior_compare"
13156   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13157         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
13158                         [(match_operator:SI 2
13159                                       "branch_positive_comparison_operator"
13160                                       [(match_operand 3
13161                                                       "cc_reg_operand" "y,y")
13162                                        (const_int 0)])
13163                          (match_operator:SI 4
13164                                       "branch_positive_comparison_operator"
13165                                       [(match_operand 5
13166                                                       "cc_reg_operand" "0,y")
13167                                        (const_int 0)])])
13168                       (const_int 1)))]
13169   ""
13170   "cr%q1 %E0,%j2,%j4"
13171   [(set_attr "type" "cr_logical,delayed_cr")])
13173 ; Why is the constant -1 here, but 1 in the previous pattern?
13174 ; Because ~1 has all but the low bit set.
13175 (define_insn ""
13176   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13177         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
13178                         [(not:SI (match_operator:SI 2
13179                                       "branch_positive_comparison_operator"
13180                                       [(match_operand 3
13181                                                       "cc_reg_operand" "y,y")
13182                                        (const_int 0)]))
13183                          (match_operator:SI 4
13184                                 "branch_positive_comparison_operator"
13185                                 [(match_operand 5
13186                                                 "cc_reg_operand" "0,y")
13187                                  (const_int 0)])])
13188                       (const_int -1)))]
13189   ""
13190   "cr%q1 %E0,%j2,%j4"
13191   [(set_attr "type" "cr_logical,delayed_cr")])
13193 (define_insn "*cceq_rev_compare"
13194   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13195         (compare:CCEQ (match_operator:SI 1
13196                                       "branch_positive_comparison_operator"
13197                                       [(match_operand 2
13198                                                       "cc_reg_operand" "0,y")
13199                                        (const_int 0)])
13200                       (const_int 0)))]
13201   ""
13202   "crnot %E0,%j1"
13203   [(set_attr "type" "cr_logical,delayed_cr")])
13205 ;; If we are comparing the result of two comparisons, this can be done
13206 ;; using creqv or crxor.
13208 (define_insn_and_split ""
13209   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
13210         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
13211                               [(match_operand 2 "cc_reg_operand" "y")
13212                                (const_int 0)])
13213                       (match_operator 3 "branch_comparison_operator"
13214                               [(match_operand 4 "cc_reg_operand" "y")
13215                                (const_int 0)])))]
13216   ""
13217   "#"
13218   ""
13219   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
13220                                     (match_dup 5)))]
13221   "
13223   int positive_1, positive_2;
13225   positive_1 = branch_positive_comparison_operator (operands[1],
13226                                                     GET_MODE (operands[1]));
13227   positive_2 = branch_positive_comparison_operator (operands[3],
13228                                                     GET_MODE (operands[3]));
13230   if (! positive_1)
13231     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
13232                                                             GET_CODE (operands[1])),
13233                                   SImode,
13234                                   operands[2], const0_rtx);
13235   else if (GET_MODE (operands[1]) != SImode)
13236     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
13237                                   operands[2], const0_rtx);
13239   if (! positive_2)
13240     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
13241                                                             GET_CODE (operands[3])),
13242                                   SImode,
13243                                   operands[4], const0_rtx);
13244   else if (GET_MODE (operands[3]) != SImode)
13245     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
13246                                   operands[4], const0_rtx);
13248   if (positive_1 == positive_2)
13249     {
13250       operands[1] = gen_rtx_NOT (SImode, operands[1]);
13251       operands[5] = constm1_rtx;
13252     }
13253   else
13254     {
13255       operands[5] = const1_rtx;
13256     }
13259 ;; Unconditional branch and return.
13261 (define_insn "jump"
13262   [(set (pc)
13263         (label_ref (match_operand 0 "" "")))]
13264   ""
13265   "b %l0"
13266   [(set_attr "type" "branch")])
13268 (define_insn "<return_str>return"
13269   [(any_return)]
13270   "<return_pred>"
13271   "blr"
13272   [(set_attr "type" "jmpreg")])
13274 (define_expand "indirect_jump"
13275   [(set (pc) (match_operand 0 "register_operand" ""))])
13277 (define_insn "*indirect_jump<mode>"
13278   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
13279   ""
13280   "@
13281    bctr
13282    blr"
13283   [(set_attr "type" "jmpreg")])
13285 ;; Table jump for switch statements:
13286 (define_expand "tablejump"
13287   [(use (match_operand 0 "" ""))
13288    (use (label_ref (match_operand 1 "" "")))]
13289   ""
13290   "
13292   if (TARGET_32BIT)
13293     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
13294   else
13295     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
13296   DONE;
13299 (define_expand "tablejumpsi"
13300   [(set (match_dup 3)
13301         (plus:SI (match_operand:SI 0 "" "")
13302                  (match_dup 2)))
13303    (parallel [(set (pc) (match_dup 3))
13304               (use (label_ref (match_operand 1 "" "")))])]
13305   "TARGET_32BIT"
13306   "
13307 { operands[0] = force_reg (SImode, operands[0]);
13308   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
13309   operands[3] = gen_reg_rtx (SImode);
13312 (define_expand "tablejumpdi"
13313   [(set (match_dup 4)
13314         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
13315    (set (match_dup 3)
13316         (plus:DI (match_dup 4)
13317                  (match_dup 2)))
13318    (parallel [(set (pc) (match_dup 3))
13319               (use (label_ref (match_operand 1 "" "")))])]
13320   "TARGET_64BIT"
13321   "
13322 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
13323   operands[3] = gen_reg_rtx (DImode);
13324   operands[4] = gen_reg_rtx (DImode);
13327 (define_insn "*tablejump<mode>_internal1"
13328   [(set (pc)
13329         (match_operand:P 0 "register_operand" "c,*l"))
13330    (use (label_ref (match_operand 1 "" "")))]
13331   ""
13332   "@
13333    bctr
13334    blr"
13335   [(set_attr "type" "jmpreg")])
13337 (define_insn "nop"
13338   [(const_int 0)]
13339   ""
13340   "nop")
13342 (define_insn "group_ending_nop"
13343   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
13344   ""
13345   "*
13347   if (rs6000_cpu_attr == CPU_POWER6)
13348     return \"ori 1,1,0\";
13349   return \"ori 2,2,0\";
13352 ;; Define the subtract-one-and-jump insns, starting with the template
13353 ;; so loop.c knows what to generate.
13355 (define_expand "doloop_end"
13356   [(use (match_operand 0 "" ""))        ; loop pseudo
13357    (use (match_operand 1 "" ""))]       ; label
13358   ""
13359   "
13361   if (TARGET_64BIT)
13362     {
13363       if (GET_MODE (operands[0]) != DImode)
13364         FAIL;
13365       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
13366     }
13367   else
13368     {
13369       if (GET_MODE (operands[0]) != SImode)
13370         FAIL;
13371       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
13372     }
13373   DONE;
13376 (define_expand "ctr<mode>"
13377   [(parallel [(set (pc)
13378                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
13379                                      (const_int 1))
13380                                  (label_ref (match_operand 1 "" ""))
13381                                  (pc)))
13382               (set (match_dup 0)
13383                    (plus:P (match_dup 0)
13384                             (const_int -1)))
13385               (clobber (match_scratch:CC 2 ""))
13386               (clobber (match_scratch:P 3 ""))])]
13387   ""
13388   "")
13390 ;; We need to be able to do this for any operand, including MEM, or we
13391 ;; will cause reload to blow up since we don't allow output reloads on
13392 ;; JUMP_INSNs.
13393 ;; For the length attribute to be calculated correctly, the
13394 ;; label MUST be operand 0.
13396 (define_insn "*ctr<mode>_internal1"
13397   [(set (pc)
13398         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*r,*r,*r")
13399                           (const_int 1))
13400                       (label_ref (match_operand 0 "" ""))
13401                       (pc)))
13402    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
13403         (plus:P (match_dup 1)
13404                  (const_int -1)))
13405    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13406    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13407   ""
13408   "*
13410   if (which_alternative != 0)
13411     return \"#\";
13412   else if (get_attr_length (insn) == 4)
13413     return \"bdnz %l0\";
13414   else
13415     return \"bdz $+8\;b %l0\";
13417   [(set_attr "type" "branch")
13418    (set_attr "length" "*,12,16,16")])
13420 (define_insn "*ctr<mode>_internal2"
13421   [(set (pc)
13422         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*r,*r,*r")
13423                           (const_int 1))
13424                       (pc)
13425                       (label_ref (match_operand 0 "" ""))))
13426    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
13427         (plus:P (match_dup 1)
13428                  (const_int -1)))
13429    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13430    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13431   ""
13432   "*
13434   if (which_alternative != 0)
13435     return \"#\";
13436   else if (get_attr_length (insn) == 4)
13437     return \"bdz %l0\";
13438   else
13439     return \"bdnz $+8\;b %l0\";
13441   [(set_attr "type" "branch")
13442    (set_attr "length" "*,12,16,16")])
13444 ;; Similar but use EQ
13446 (define_insn "*ctr<mode>_internal5"
13447   [(set (pc)
13448         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*r,*r,*r")
13449                           (const_int 1))
13450                       (label_ref (match_operand 0 "" ""))
13451                       (pc)))
13452    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
13453         (plus:P (match_dup 1)
13454                  (const_int -1)))
13455    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13456    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13457   ""
13458   "*
13460   if (which_alternative != 0)
13461     return \"#\";
13462   else if (get_attr_length (insn) == 4)
13463     return \"bdz %l0\";
13464   else
13465     return \"bdnz $+8\;b %l0\";
13467   [(set_attr "type" "branch")
13468    (set_attr "length" "*,12,16,16")])
13470 (define_insn "*ctr<mode>_internal6"
13471   [(set (pc)
13472         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*r,*r,*r")
13473                           (const_int 1))
13474                       (pc)
13475                       (label_ref (match_operand 0 "" ""))))
13476    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
13477         (plus:P (match_dup 1)
13478                  (const_int -1)))
13479    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13480    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13481   ""
13482   "*
13484   if (which_alternative != 0)
13485     return \"#\";
13486   else if (get_attr_length (insn) == 4)
13487     return \"bdnz %l0\";
13488   else
13489     return \"bdz $+8\;b %l0\";
13491   [(set_attr "type" "branch")
13492    (set_attr "length" "*,12,16,16")])
13494 ;; Now the splitters if we could not allocate the CTR register
13496 (define_split
13497   [(set (pc)
13498         (if_then_else (match_operator 2 "comparison_operator"
13499                                       [(match_operand:P 1 "gpc_reg_operand" "")
13500                                        (const_int 1)])
13501                       (match_operand 5 "" "")
13502                       (match_operand 6 "" "")))
13503    (set (match_operand:P 0 "gpc_reg_operand" "")
13504         (plus:P (match_dup 1) (const_int -1)))
13505    (clobber (match_scratch:CC 3 ""))
13506    (clobber (match_scratch:P 4 ""))]
13507   "reload_completed"
13508   [(parallel [(set (match_dup 3)
13509                    (compare:CC (plus:P (match_dup 1)
13510                                         (const_int -1))
13511                                (const_int 0)))
13512               (set (match_dup 0)
13513                    (plus:P (match_dup 1)
13514                             (const_int -1)))])
13515    (set (pc) (if_then_else (match_dup 7)
13516                            (match_dup 5)
13517                            (match_dup 6)))]
13518   "
13519 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13520                                 operands[3], const0_rtx); }")
13522 (define_split
13523   [(set (pc)
13524         (if_then_else (match_operator 2 "comparison_operator"
13525                                       [(match_operand:P 1 "gpc_reg_operand" "")
13526                                        (const_int 1)])
13527                       (match_operand 5 "" "")
13528                       (match_operand 6 "" "")))
13529    (set (match_operand:P 0 "nonimmediate_operand" "")
13530         (plus:P (match_dup 1) (const_int -1)))
13531    (clobber (match_scratch:CC 3 ""))
13532    (clobber (match_scratch:P 4 ""))]
13533   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
13534   [(parallel [(set (match_dup 3)
13535                    (compare:CC (plus:P (match_dup 1)
13536                                         (const_int -1))
13537                                (const_int 0)))
13538               (set (match_dup 4)
13539                    (plus:P (match_dup 1)
13540                             (const_int -1)))])
13541    (set (match_dup 0)
13542         (match_dup 4))
13543    (set (pc) (if_then_else (match_dup 7)
13544                            (match_dup 5)
13545                            (match_dup 6)))]
13546   "
13547 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13548                                 operands[3], const0_rtx); }")
13550 (define_insn "trap"
13551   [(trap_if (const_int 1) (const_int 0))]
13552   ""
13553   "trap"
13554   [(set_attr "type" "trap")])
13556 (define_expand "ctrap<mode>4"
13557   [(trap_if (match_operator 0 "ordered_comparison_operator"
13558                             [(match_operand:GPR 1 "register_operand")
13559                              (match_operand:GPR 2 "reg_or_short_operand")])
13560             (match_operand 3 "zero_constant" ""))]
13561   ""
13562   "")
13564 (define_insn ""
13565   [(trap_if (match_operator 0 "ordered_comparison_operator"
13566                             [(match_operand:GPR 1 "register_operand" "r")
13567                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13568             (const_int 0))]
13569   ""
13570   "t<wd>%V0%I2 %1,%2"
13571   [(set_attr "type" "trap")])
13573 ;; Insns related to generating the function prologue and epilogue.
13575 (define_expand "prologue"
13576   [(use (const_int 0))]
13577   ""
13579   rs6000_emit_prologue ();
13580   if (!TARGET_SCHED_PROLOG)
13581     emit_insn (gen_blockage ());
13582   DONE;
13585 (define_insn "*movesi_from_cr_one"
13586   [(match_parallel 0 "mfcr_operation"
13587                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13588                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13589                                      (match_operand 3 "immediate_operand" "n")]
13590                           UNSPEC_MOVESI_FROM_CR))])]
13591   "TARGET_MFCRF"
13592   "*
13594   int mask = 0;
13595   int i;
13596   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13597   {
13598     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13599     operands[4] = GEN_INT (mask);
13600     output_asm_insn (\"mfcr %1,%4\", operands);
13601   }
13602   return \"\";
13604   [(set_attr "type" "mfcrf")])
13606 (define_insn "movesi_from_cr"
13607   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13608         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
13609                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13610                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
13611                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
13612                    UNSPEC_MOVESI_FROM_CR))]
13613   ""
13614   "mfcr %0"
13615   [(set_attr "type" "mfcr")])
13617 (define_insn "*crsave"
13618   [(match_parallel 0 "crsave_operation"
13619                    [(set (match_operand:SI 1 "memory_operand" "=m")
13620                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13621   ""
13622   "stw %2,%1"
13623   [(set_attr "type" "store")])
13625 (define_insn "*stmw"
13626   [(match_parallel 0 "stmw_operation"
13627                    [(set (match_operand:SI 1 "memory_operand" "=m")
13628                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13629   "TARGET_MULTIPLE"
13630   "stmw %2,%1"
13631   [(set_attr "type" "store")
13632    (set_attr "update" "yes")
13633    (set_attr "indexed" "yes")])
13635 ; The following comment applies to:
13636 ;     save_gpregs_*
13637 ;     save_fpregs_*
13638 ;     restore_gpregs*
13639 ;     return_and_restore_gpregs*
13640 ;     return_and_restore_fpregs*
13641 ;     return_and_restore_fpregs_aix*
13643 ; The out-of-line save / restore functions expects one input argument.
13644 ; Since those are not standard call_insn's, we must avoid using
13645 ; MATCH_OPERAND for that argument. That way the register rename
13646 ; optimization will not try to rename this register.
13647 ; Each pattern is repeated for each possible register number used in 
13648 ; various ABIs (r11, r1, and for some functions r12)
13650 (define_insn "*save_gpregs_<mode>_r11"
13651   [(match_parallel 0 "any_parallel_operand"
13652                    [(clobber (reg:P 65))
13653                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13654                     (use (reg:P 11))
13655                     (set (match_operand:P 2 "memory_operand" "=m")
13656                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13657   ""
13658   "bl %1"
13659   [(set_attr "type" "branch")
13660    (set_attr "length" "4")])
13662 (define_insn "*save_gpregs_<mode>_r12"
13663   [(match_parallel 0 "any_parallel_operand"
13664                    [(clobber (reg:P 65))
13665                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13666                     (use (reg:P 12))
13667                     (set (match_operand:P 2 "memory_operand" "=m")
13668                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13669   ""
13670   "bl %1"
13671   [(set_attr "type" "branch")
13672    (set_attr "length" "4")])
13674 (define_insn "*save_gpregs_<mode>_r1"
13675   [(match_parallel 0 "any_parallel_operand"
13676                    [(clobber (reg:P 65))
13677                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13678                     (use (reg:P 1))
13679                     (set (match_operand:P 2 "memory_operand" "=m")
13680                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13681   ""
13682   "bl %1"
13683   [(set_attr "type" "branch")
13684    (set_attr "length" "4")])
13686 (define_insn "*save_fpregs_<mode>_r11"
13687   [(match_parallel 0 "any_parallel_operand"
13688                    [(clobber (reg:P 65))
13689                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13690                     (use (reg:P 11))
13691                     (set (match_operand:DF 2 "memory_operand" "=m")
13692                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13693   ""
13694   "bl %1"
13695   [(set_attr "type" "branch")
13696    (set_attr "length" "4")])
13698 (define_insn "*save_fpregs_<mode>_r12"
13699   [(match_parallel 0 "any_parallel_operand"
13700                    [(clobber (reg:P 65))
13701                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13702                     (use (reg:P 12))
13703                     (set (match_operand:DF 2 "memory_operand" "=m")
13704                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13705   ""
13706   "bl %1"
13707   [(set_attr "type" "branch")
13708    (set_attr "length" "4")])
13710 (define_insn "*save_fpregs_<mode>_r1"
13711   [(match_parallel 0 "any_parallel_operand"
13712                    [(clobber (reg:P 65))
13713                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13714                     (use (reg:P 1))
13715                     (set (match_operand:DF 2 "memory_operand" "=m")
13716                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13717   ""
13718   "bl %1"
13719   [(set_attr "type" "branch")
13720    (set_attr "length" "4")])
13722 ; This is to explain that changes to the stack pointer should
13723 ; not be moved over loads from or stores to stack memory.
13724 (define_insn "stack_tie"
13725   [(match_parallel 0 "tie_operand"
13726                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13727   ""
13728   ""
13729   [(set_attr "length" "0")])
13731 (define_expand "epilogue"
13732   [(use (const_int 0))]
13733   ""
13735   if (!TARGET_SCHED_PROLOG)
13736     emit_insn (gen_blockage ());
13737   rs6000_emit_epilogue (FALSE);
13738   DONE;
13741 ; On some processors, doing the mtcrf one CC register at a time is
13742 ; faster (like on the 604e).  On others, doing them all at once is
13743 ; faster; for instance, on the 601 and 750.
13745 (define_expand "movsi_to_cr_one"
13746   [(set (match_operand:CC 0 "cc_reg_operand" "")
13747         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13748                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13749   ""
13750   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13752 (define_insn "*movsi_to_cr"
13753   [(match_parallel 0 "mtcrf_operation"
13754                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13755                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13756                                      (match_operand 3 "immediate_operand" "n")]
13757                                     UNSPEC_MOVESI_TO_CR))])]
13758  ""
13759  "*
13761   int mask = 0;
13762   int i;
13763   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13764     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13765   operands[4] = GEN_INT (mask);
13766   return \"mtcrf %4,%2\";
13768   [(set_attr "type" "mtcr")])
13770 (define_insn "*mtcrfsi"
13771   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13772         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13773                     (match_operand 2 "immediate_operand" "n")]
13774                    UNSPEC_MOVESI_TO_CR))]
13775   "GET_CODE (operands[0]) == REG
13776    && CR_REGNO_P (REGNO (operands[0]))
13777    && GET_CODE (operands[2]) == CONST_INT
13778    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13779   "mtcrf %R0,%1"
13780   [(set_attr "type" "mtcr")])
13782 ; The load-multiple instructions have similar properties.
13783 ; Note that "load_multiple" is a name known to the machine-independent
13784 ; code that actually corresponds to the PowerPC load-string.
13786 (define_insn "*lmw"
13787   [(match_parallel 0 "lmw_operation"
13788                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13789                          (match_operand:SI 2 "memory_operand" "m"))])]
13790   "TARGET_MULTIPLE"
13791   "lmw %1,%2"
13792   [(set_attr "type" "load")
13793    (set_attr "update" "yes")
13794    (set_attr "indexed" "yes")
13795    (set_attr "cell_micro" "always")])
13797 (define_insn "*return_internal_<mode>"
13798   [(simple_return)
13799    (use (match_operand:P 0 "register_operand" "lc"))]
13800   ""
13801   "b%T0"
13802   [(set_attr "type" "jmpreg")])
13804 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13805 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13807 ; The following comment applies to:
13808 ;     save_gpregs_*
13809 ;     save_fpregs_*
13810 ;     restore_gpregs*
13811 ;     return_and_restore_gpregs*
13812 ;     return_and_restore_fpregs*
13813 ;     return_and_restore_fpregs_aix*
13815 ; The out-of-line save / restore functions expects one input argument.
13816 ; Since those are not standard call_insn's, we must avoid using
13817 ; MATCH_OPERAND for that argument. That way the register rename
13818 ; optimization will not try to rename this register.
13819 ; Each pattern is repeated for each possible register number used in 
13820 ; various ABIs (r11, r1, and for some functions r12)
13822 (define_insn "*restore_gpregs_<mode>_r11"
13823  [(match_parallel 0 "any_parallel_operand"
13824                   [(clobber (match_operand:P 1 "register_operand" "=l"))
13825                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
13826                    (use (reg:P 11))
13827                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
13828                         (match_operand:P 4 "memory_operand" "m"))])]
13829  ""
13830  "bl %2"
13831  [(set_attr "type" "branch")
13832   (set_attr "length" "4")])
13834 (define_insn "*restore_gpregs_<mode>_r12"
13835  [(match_parallel 0 "any_parallel_operand"
13836                   [(clobber (match_operand:P 1 "register_operand" "=l"))
13837                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
13838                    (use (reg:P 12))
13839                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
13840                         (match_operand:P 4 "memory_operand" "m"))])]
13841  ""
13842  "bl %2"
13843  [(set_attr "type" "branch")
13844   (set_attr "length" "4")])
13846 (define_insn "*restore_gpregs_<mode>_r1"
13847  [(match_parallel 0 "any_parallel_operand"
13848                   [(clobber (match_operand:P 1 "register_operand" "=l"))
13849                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
13850                    (use (reg:P 1))
13851                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
13852                         (match_operand:P 4 "memory_operand" "m"))])]
13853  ""
13854  "bl %2"
13855  [(set_attr "type" "branch")
13856   (set_attr "length" "4")])
13858 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13859  [(match_parallel 0 "any_parallel_operand"
13860                   [(return)
13861                    (clobber (match_operand:P 1 "register_operand" "=l"))
13862                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
13863                    (use (reg:P 11))
13864                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
13865                         (match_operand:P 4 "memory_operand" "m"))])]
13866  ""
13867  "b %2"
13868  [(set_attr "type" "branch")
13869   (set_attr "length" "4")])
13871 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13872  [(match_parallel 0 "any_parallel_operand"
13873                   [(return)
13874                    (clobber (match_operand:P 1 "register_operand" "=l"))
13875                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
13876                    (use (reg:P 12))
13877                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
13878                         (match_operand:P 4 "memory_operand" "m"))])]
13879  ""
13880  "b %2"
13881  [(set_attr "type" "branch")
13882   (set_attr "length" "4")])
13884 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13885  [(match_parallel 0 "any_parallel_operand"
13886                   [(return)
13887                    (clobber (match_operand:P 1 "register_operand" "=l"))
13888                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
13889                    (use (reg:P 1))
13890                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
13891                         (match_operand:P 4 "memory_operand" "m"))])]
13892  ""
13893  "b %2"
13894  [(set_attr "type" "branch")
13895   (set_attr "length" "4")])
13897 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13898  [(match_parallel 0 "any_parallel_operand"
13899                   [(return)
13900                    (clobber (match_operand:P 1 "register_operand" "=l"))
13901                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
13902                    (use (reg:P 11))
13903                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
13904                         (match_operand:DF 4 "memory_operand" "m"))])]
13905  ""
13906  "b %2"
13907  [(set_attr "type" "branch")
13908   (set_attr "length" "4")])
13910 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13911  [(match_parallel 0 "any_parallel_operand"
13912                   [(return)
13913                    (clobber (match_operand:P 1 "register_operand" "=l"))
13914                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
13915                    (use (reg:P 12))
13916                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
13917                         (match_operand:DF 4 "memory_operand" "m"))])]
13918  ""
13919  "b %2"
13920  [(set_attr "type" "branch")
13921   (set_attr "length" "4")])
13923 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13924  [(match_parallel 0 "any_parallel_operand"
13925                   [(return)
13926                    (clobber (match_operand:P 1 "register_operand" "=l"))
13927                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
13928                    (use (reg:P 1))
13929                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
13930                         (match_operand:DF 4 "memory_operand" "m"))])]
13931  ""
13932  "b %2"
13933  [(set_attr "type" "branch")
13934   (set_attr "length" "4")])
13936 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13937  [(match_parallel 0 "any_parallel_operand"
13938                   [(return)
13939                    (use (match_operand:P 1 "register_operand" "l"))
13940                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
13941                    (use (reg:P 11))
13942                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
13943                         (match_operand:DF 4 "memory_operand" "m"))])]
13944  ""
13945  "b %2"
13946  [(set_attr "type" "branch")
13947   (set_attr "length" "4")])
13949 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13950  [(match_parallel 0 "any_parallel_operand"
13951                   [(return)
13952                    (use (match_operand:P 1 "register_operand" "l"))
13953                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
13954                    (use (reg:P 1))
13955                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
13956                         (match_operand:DF 4 "memory_operand" "m"))])]
13957  ""
13958  "b %2"
13959  [(set_attr "type" "branch")
13960   (set_attr "length" "4")])
13962 ; This is used in compiling the unwind routines.
13963 (define_expand "eh_return"
13964   [(use (match_operand 0 "general_operand" ""))]
13965   ""
13966   "
13968   if (TARGET_32BIT)
13969     emit_insn (gen_eh_set_lr_si (operands[0]));
13970   else
13971     emit_insn (gen_eh_set_lr_di (operands[0]));
13972   DONE;
13975 ; We can't expand this before we know where the link register is stored.
13976 (define_insn "eh_set_lr_<mode>"
13977   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13978                     UNSPECV_EH_RR)
13979    (clobber (match_scratch:P 1 "=&b"))]
13980   ""
13981   "#")
13983 (define_split
13984   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13985    (clobber (match_scratch 1 ""))]
13986   "reload_completed"
13987   [(const_int 0)]
13988   "
13990   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13991   DONE;
13994 (define_insn "prefetch"
13995   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13996              (match_operand:SI 1 "const_int_operand" "n")
13997              (match_operand:SI 2 "const_int_operand" "n"))]
13998   ""
13999   "*
14001   if (GET_CODE (operands[0]) == REG)
14002     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
14003   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
14005   [(set_attr "type" "load")])
14007 (define_insn "bpermd_<mode>"
14008   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
14009         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
14010                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
14011   "TARGET_POPCNTD"
14012   "bpermd %0,%1,%2"
14013   [(set_attr "type" "popcnt")])
14016 ;; Builtin fma support.  Handle 
14017 ;; Note that the conditions for expansion are in the FMA_F iterator.
14019 (define_expand "fma<mode>4"
14020   [(set (match_operand:FMA_F 0 "register_operand" "")
14021         (fma:FMA_F
14022           (match_operand:FMA_F 1 "register_operand" "")
14023           (match_operand:FMA_F 2 "register_operand" "")
14024           (match_operand:FMA_F 3 "register_operand" "")))]
14025   ""
14026   "")
14028 (define_insn "*fma<mode>4_fpr"
14029   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
14030         (fma:SFDF
14031           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>,<Fv>")
14032           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
14033           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))]
14034   "TARGET_<MODE>_FPR"
14035   "@
14036    fmadd<Ftrad> %0,%1,%2,%3
14037    xsmadda<Fvsx> %x0,%x1,%x2
14038    xsmaddm<Fvsx> %x0,%x1,%x3"
14039   [(set_attr "type" "fp")
14040    (set_attr "fp_type" "fp_maddsub_<Fs>")])
14042 ; Altivec only has fma and nfms.
14043 (define_expand "fms<mode>4"
14044   [(set (match_operand:FMA_F 0 "register_operand" "")
14045         (fma:FMA_F
14046           (match_operand:FMA_F 1 "register_operand" "")
14047           (match_operand:FMA_F 2 "register_operand" "")
14048           (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
14049   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14050   "")
14052 (define_insn "*fms<mode>4_fpr"
14053   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
14054         (fma:SFDF
14055          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
14056          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
14057          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
14058   "TARGET_<MODE>_FPR"
14059   "@
14060    fmsub<Ftrad> %0,%1,%2,%3
14061    xsmsuba<Fvsx> %x0,%x1,%x2
14062    xsmsubm<Fvsx> %x0,%x1,%x3"
14063   [(set_attr "type" "fp")
14064    (set_attr "fp_type" "fp_maddsub_<Fs>")])
14066 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
14067 (define_expand "fnma<mode>4"
14068   [(set (match_operand:FMA_F 0 "register_operand" "")
14069         (neg:FMA_F
14070           (fma:FMA_F
14071             (match_operand:FMA_F 1 "register_operand" "")
14072             (match_operand:FMA_F 2 "register_operand" "")
14073             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
14074   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
14075   "")
14077 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
14078 (define_expand "fnms<mode>4"
14079   [(set (match_operand:FMA_F 0 "register_operand" "")
14080         (neg:FMA_F
14081           (fma:FMA_F
14082             (match_operand:FMA_F 1 "register_operand" "")
14083             (match_operand:FMA_F 2 "register_operand" "")
14084             (match_operand:FMA_F 3 "register_operand" ""))))]
14085   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14086   "")
14088 ; Not an official optab name, but used from builtins.
14089 (define_expand "nfma<mode>4"
14090   [(set (match_operand:FMA_F 0 "register_operand" "")
14091         (neg:FMA_F
14092           (fma:FMA_F
14093             (match_operand:FMA_F 1 "register_operand" "")
14094             (match_operand:FMA_F 2 "register_operand" "")
14095             (match_operand:FMA_F 3 "register_operand" ""))))]
14096   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14097   "")
14099 (define_insn "*nfma<mode>4_fpr"
14100   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
14101         (neg:SFDF
14102          (fma:SFDF
14103           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
14104           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
14105           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
14106   "TARGET_<MODE>_FPR"
14107   "@
14108    fnmadd<Ftrad> %0,%1,%2,%3
14109    xsnmadda<Fvsx> %x0,%x1,%x2
14110    xsnmaddm<Fvsx> %x0,%x1,%x3"
14111   [(set_attr "type" "fp")
14112    (set_attr "fp_type" "fp_maddsub_<Fs>")])
14114 ; Not an official optab name, but used from builtins.
14115 (define_expand "nfms<mode>4"
14116   [(set (match_operand:FMA_F 0 "register_operand" "")
14117         (neg:FMA_F
14118           (fma:FMA_F
14119             (match_operand:FMA_F 1 "register_operand" "")
14120             (match_operand:FMA_F 2 "register_operand" "")
14121             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
14122   ""
14123   "")
14125 (define_insn "*nfmssf4_fpr"
14126   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
14127         (neg:SFDF
14128          (fma:SFDF
14129           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
14130           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
14131           (neg:SFDF
14132            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))))]
14133   "TARGET_<MODE>_FPR"
14134   "@
14135    fnmsub<Ftrad> %0,%1,%2,%3
14136    xsnmsuba<Fvsx> %x0,%x1,%x2
14137    xsnmsubm<Fvsx> %x0,%x1,%x3"
14138   [(set_attr "type" "fp")
14139    (set_attr "fp_type" "fp_maddsub_<Fs>")])
14142 (define_expand "rs6000_get_timebase"
14143   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
14144   ""
14146   if (TARGET_POWERPC64)
14147     emit_insn (gen_rs6000_mftb_di (operands[0]));
14148   else
14149     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
14150   DONE;
14153 (define_insn "rs6000_get_timebase_ppc32"
14154   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
14155         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
14156    (clobber (match_scratch:SI 1 "=r"))
14157    (clobber (match_scratch:CC 2 "=y"))]
14158   "!TARGET_POWERPC64"
14160   if (WORDS_BIG_ENDIAN)
14161     if (TARGET_MFCRF)
14162       {
14163         return "mfspr %0,269\;"
14164                "mfspr %L0,268\;"
14165                "mfspr %1,269\;"
14166                "cmpw %2,%0,%1\;"
14167                "bne- %2,$-16";
14168       }
14169     else
14170       {
14171         return "mftbu %0\;"
14172                "mftb %L0\;"
14173                "mftbu %1\;"
14174                "cmpw %2,%0,%1\;"
14175                "bne- %2,$-16";
14176       }
14177   else
14178     if (TARGET_MFCRF)
14179       {
14180         return "mfspr %L0,269\;"
14181                "mfspr %0,268\;"
14182                "mfspr %1,269\;"
14183                "cmpw %2,%L0,%1\;"
14184                "bne- %2,$-16";
14185       }
14186     else
14187       {
14188         return "mftbu %L0\;"
14189                "mftb %0\;"
14190                "mftbu %1\;"
14191                "cmpw %2,%L0,%1\;"
14192                "bne- %2,$-16";
14193       }
14195   [(set_attr "length" "20")])
14197 (define_insn "rs6000_mftb_<mode>"
14198   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
14199         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
14200   ""
14202   if (TARGET_MFCRF)
14203     return "mfspr %0,268";
14204   else
14205     return "mftb %0";
14209 (define_insn "rs6000_mffs"
14210   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
14211         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
14212   "TARGET_HARD_FLOAT && TARGET_FPRS"
14213   "mffs %0")
14215 (define_insn "rs6000_mtfsf"
14216   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
14217                      (match_operand:DF 1 "gpc_reg_operand" "d")]
14218                     UNSPECV_MTFSF)]
14219   "TARGET_HARD_FLOAT && TARGET_FPRS"
14220   "mtfsf %0,%1")
14223 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
14224 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
14225 ;; register that is being loaded.  The fused ops must be physically adjacent.
14227 ;; Find cases where the addis that feeds into a load instruction is either used
14228 ;; once or is the same as the target register, and replace it with the fusion
14229 ;; insn
14231 (define_peephole2
14232   [(set (match_operand:P 0 "base_reg_operand" "")
14233         (match_operand:P 1 "fusion_gpr_addis" ""))
14234    (set (match_operand:INT1 2 "base_reg_operand" "")
14235         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
14236   "TARGET_P8_FUSION
14237    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
14238                          operands[3])"
14239   [(const_int 0)]
14241   expand_fusion_gpr_load (operands);
14242   DONE;
14245 ;; Fusion insn, created by the define_peephole2 above (and eventually by
14246 ;; reload)
14248 (define_insn "fusion_gpr_load_<mode>"
14249   [(set (match_operand:INT1 0 "base_reg_operand" "=&b")
14250         (unspec:INT1 [(match_operand:INT1 1 "fusion_gpr_mem_combo" "")]
14251                      UNSPEC_FUSION_GPR))]
14252   "TARGET_P8_FUSION"
14254   return emit_fusion_gpr_load (operands[0], operands[1]);
14256   [(set_attr "type" "load")
14257    (set_attr "length" "8")])
14260 ;; Miscellaneous ISA 2.06 (power7) instructions
14261 (define_insn "addg6s"
14262   [(set (match_operand:SI 0 "register_operand" "=r")
14263         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14264                     (match_operand:SI 2 "register_operand" "r")]
14265                    UNSPEC_ADDG6S))]
14266   "TARGET_POPCNTD"
14267   "addg6s %0,%1,%2"
14268   [(set_attr "type" "integer")
14269    (set_attr "length" "4")])
14271 (define_insn "cdtbcd"
14272   [(set (match_operand:SI 0 "register_operand" "=r")
14273         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14274                    UNSPEC_CDTBCD))]
14275   "TARGET_POPCNTD"
14276   "cdtbcd %0,%1"
14277   [(set_attr "type" "integer")
14278    (set_attr "length" "4")])
14280 (define_insn "cbcdtd"
14281   [(set (match_operand:SI 0 "register_operand" "=r")
14282         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14283                    UNSPEC_CBCDTD))]
14284   "TARGET_POPCNTD"
14285   "cbcdtd %0,%1"
14286   [(set_attr "type" "integer")
14287    (set_attr "length" "4")])
14289 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14290                                         UNSPEC_DIVEO
14291                                         UNSPEC_DIVEU
14292                                         UNSPEC_DIVEUO])
14294 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
14295                              (UNSPEC_DIVEO      "eo")
14296                              (UNSPEC_DIVEU      "eu")
14297                              (UNSPEC_DIVEUO     "euo")])
14299 (define_insn "div<div_extend>_<mode>"
14300   [(set (match_operand:GPR 0 "register_operand" "=r")
14301         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14302                      (match_operand:GPR 2 "register_operand" "r")]
14303                     UNSPEC_DIV_EXTEND))]
14304   "TARGET_POPCNTD"
14305   "div<wd><div_extend> %0,%1,%2"
14306   [(set_attr "type" "div")
14307    (set_attr "size" "<bits>")])
14310 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14312 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14313 (define_mode_attr FP128_64 [(TF "DF") (TD "DI")])
14315 (define_expand "unpack<mode>"
14316   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14317         (unspec:<FP128_64>
14318          [(match_operand:FMOVE128 1 "register_operand" "")
14319           (match_operand:QI 2 "const_0_to_1_operand" "")]
14320          UNSPEC_UNPACK_128BIT))]
14321   ""
14322   "")
14324 (define_insn_and_split "unpack<mode>_dm"
14325   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14326         (unspec:<FP128_64>
14327          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14328           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14329          UNSPEC_UNPACK_128BIT))]
14330   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
14331   "#"
14332   "&& reload_completed"
14333   [(set (match_dup 0) (match_dup 3))]
14335   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14337   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14338     {
14339       emit_note (NOTE_INSN_DELETED);
14340       DONE;
14341     }
14343   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14345   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14346    (set_attr "length" "4")])
14348 (define_insn_and_split "unpack<mode>_nodm"
14349   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14350         (unspec:<FP128_64>
14351          [(match_operand:FMOVE128 1 "register_operand" "d,d")
14352           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14353          UNSPEC_UNPACK_128BIT))]
14354   "!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE"
14355   "#"
14356   "&& reload_completed"
14357   [(set (match_dup 0) (match_dup 3))]
14359   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14361   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14362     {
14363       emit_note (NOTE_INSN_DELETED);
14364       DONE;
14365     }
14367   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14369   [(set_attr "type" "fp,fpstore")
14370    (set_attr "length" "4")])
14372 (define_insn_and_split "pack<mode>"
14373   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14374         (unspec:FMOVE128
14375          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14376           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14377          UNSPEC_PACK_128BIT))]
14378   ""
14379   "@
14380    fmr %L0,%2
14381    #"
14382   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14383   [(set (match_dup 3) (match_dup 1))
14384    (set (match_dup 4) (match_dup 2))]
14386   unsigned dest_hi = REGNO (operands[0]);
14387   unsigned dest_lo = dest_hi + 1;
14389   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14390   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14392   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14393   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14395   [(set_attr "type" "fp,fp")
14396    (set_attr "length" "4,8")])
14398 (define_insn "unpackv1ti"
14399   [(set (match_operand:DI 0 "register_operand" "=d,d")
14400         (unspec:DI [(match_operand:V1TI 1 "register_operand" "0,wa")
14401                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14402          UNSPEC_UNPACK_128BIT))]
14403   "TARGET_VSX"
14405   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14406     return ASM_COMMENT_START " xxpermdi to same register";
14408   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14409   return "xxpermdi %x0,%x1,%x1,%3";
14411   [(set_attr "type" "vecperm")
14412    (set_attr "length" "4")])
14414 (define_insn "packv1ti"
14415   [(set (match_operand:V1TI 0 "register_operand" "=wa")
14416         (unspec:V1TI
14417          [(match_operand:DI 1 "register_operand" "d")
14418           (match_operand:DI 2 "register_operand" "d")]
14419          UNSPEC_PACK_128BIT))]
14420   "TARGET_VSX"
14421   "xxpermdi %x0,%x1,%x2,0"
14422   [(set_attr "type" "vecperm")
14423    (set_attr "length" "4")])
14427 (include "sync.md")
14428 (include "vector.md")
14429 (include "vsx.md")
14430 (include "altivec.md")
14431 (include "spe.md")
14432 (include "dfp.md")
14433 (include "paired.md")
14434 (include "crypto.md")
14435 (include "htm.md")