1fcd69e3d9cbfa3a02775fc06560f71d0ac0cc41
[platform/upstream/gcc.git] / gcc / config / rs6000 / rs6000.md
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2015 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4
5 ;; This file is part of GCC.
6
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.
11
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.
16
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/>.
20
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23 ;;
24 ;; REGNOS
25 ;;
26
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   ])
62
63 ;;
64 ;; UNSPEC usage
65 ;;
66
67 (define_c_enum "unspec"
68   [UNSPEC_FRSP                  ; frsp for POWER machines
69    UNSPEC_PROBE_STACK           ; probe stack memory reference
70    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
71    UNSPEC_TOC                   ; address of the TOC (more-or-less)
72    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
73    UNSPEC_MOVSI_GOT
74    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
75    UNSPEC_FCTIWZ
76    UNSPEC_FRIM
77    UNSPEC_FRIN
78    UNSPEC_FRIP
79    UNSPEC_FRIZ
80    UNSPEC_LD_MPIC               ; load_macho_picbase
81    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
82    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
83    UNSPEC_TLSGD
84    UNSPEC_TLSLD
85    UNSPEC_MOVESI_FROM_CR
86    UNSPEC_MOVESI_TO_CR
87    UNSPEC_TLSDTPREL
88    UNSPEC_TLSDTPRELHA
89    UNSPEC_TLSDTPRELLO
90    UNSPEC_TLSGOTDTPREL
91    UNSPEC_TLSTPREL
92    UNSPEC_TLSTPRELHA
93    UNSPEC_TLSTPRELLO
94    UNSPEC_TLSGOTTPREL
95    UNSPEC_TLSTLS
96    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
97    UNSPEC_MV_CR_GT              ; move_from_CR_gt_bit
98    UNSPEC_STFIWX
99    UNSPEC_POPCNTB
100    UNSPEC_FRES
101    UNSPEC_SP_SET
102    UNSPEC_SP_TEST
103    UNSPEC_SYNC
104    UNSPEC_LWSYNC
105    UNSPEC_SYNC_OP
106    UNSPEC_ATOMIC
107    UNSPEC_CMPXCHG
108    UNSPEC_XCHG
109    UNSPEC_AND
110    UNSPEC_DLMZB
111    UNSPEC_DLMZB_CR
112    UNSPEC_DLMZB_STRLEN
113    UNSPEC_RSQRT
114    UNSPEC_TOCREL
115    UNSPEC_MACHOPIC_OFFSET
116    UNSPEC_BPERM
117    UNSPEC_COPYSIGN
118    UNSPEC_PARITY
119    UNSPEC_FCTIW
120    UNSPEC_FCTID
121    UNSPEC_LFIWAX
122    UNSPEC_LFIWZX
123    UNSPEC_FCTIWUZ
124    UNSPEC_NOP
125    UNSPEC_GRP_END_NOP
126    UNSPEC_P8V_FMRGOW
127    UNSPEC_P8V_MTVSRWZ
128    UNSPEC_P8V_RELOAD_FROM_GPR
129    UNSPEC_P8V_MTVSRD
130    UNSPEC_P8V_XXPERMDI
131    UNSPEC_P8V_RELOAD_FROM_VSX
132    UNSPEC_ADDG6S
133    UNSPEC_CDTBCD
134    UNSPEC_CBCDTD
135    UNSPEC_DIVE
136    UNSPEC_DIVEO
137    UNSPEC_DIVEU
138    UNSPEC_DIVEUO
139    UNSPEC_UNPACK_128BIT
140    UNSPEC_PACK_128BIT
141    UNSPEC_LSQ
142    UNSPEC_FUSION_GPR
143   ])
144
145 ;;
146 ;; UNSPEC_VOLATILE usage
147 ;;
148
149 (define_c_enum "unspecv"
150   [UNSPECV_BLOCK
151    UNSPECV_LL                   ; load-locked
152    UNSPECV_SC                   ; store-conditional
153    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
154    UNSPECV_EH_RR                ; eh_reg_restore
155    UNSPECV_ISYNC                ; isync instruction
156    UNSPECV_MFTB                 ; move from time base
157    UNSPECV_NLGR                 ; non-local goto receiver
158    UNSPECV_MFFS                 ; Move from FPSCR
159    UNSPECV_MTFSF                ; Move to FPSCR Fields
160   ])
161
162 \f
163 ;; Define an insn type attribute.  This is used in function unit delay
164 ;; computations.
165 (define_attr "type"
166   "integer,two,three,
167    add,logical,shift,insert,
168    mul,halfmul,div,
169    exts,cntlz,popcnt,isel,
170    load,store,fpload,fpstore,vecload,vecstore,
171    cmp,
172    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
173    cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
174    fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
175    brinc,
176    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
177    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
178    htm"
179   (const_string "integer"))
180
181 ;; What data size does this instruction work on?
182 ;; This is used for insert, mul.
183 (define_attr "size" "8,16,32,64" (const_string "32"))
184
185 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
186 ;; This is used for add, logical, shift, exts, mul.
187 (define_attr "dot" "no,yes" (const_string "no"))
188
189 ;; Does this instruction sign-extend its result?
190 ;; This is used for load insns.
191 (define_attr "sign_extend" "no,yes" (const_string "no"))
192
193 ;; Does this instruction use indexed (that is, reg+reg) addressing?
194 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
195 ;; it is automatically set based on that.  If a load or store instruction
196 ;; has fewer than two operands it needs to set this attribute manually
197 ;; or the compiler will crash.
198 (define_attr "indexed" "no,yes"
199   (if_then_else (ior (match_operand 0 "indexed_address_mem")
200                      (match_operand 1 "indexed_address_mem"))
201                 (const_string "yes")
202                 (const_string "no")))
203
204 ;; Does this instruction use update addressing?
205 ;; This is used for load and store insns.  See the comments for "indexed".
206 (define_attr "update" "no,yes"
207   (if_then_else (ior (match_operand 0 "update_address_mem")
208                      (match_operand 1 "update_address_mem"))
209                 (const_string "yes")
210                 (const_string "no")))
211
212 ;; Is this instruction using operands[2] as shift amount, and can that be a
213 ;; register?
214 ;; This is used for shift insns.
215 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
216
217 ;; Is this instruction using a shift amount from a register?
218 ;; This is used for shift insns.
219 (define_attr "var_shift" "no,yes"
220   (if_then_else (and (eq_attr "type" "shift")
221                      (eq_attr "maybe_var_shift" "yes"))
222                 (if_then_else (match_operand 2 "gpc_reg_operand")
223                               (const_string "yes")
224                               (const_string "no"))
225                 (const_string "no")))
226
227 ;; Define floating point instruction sub-types for use with Xfpu.md
228 (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
230 ;; Length (in bytes).
231 ; '(pc)' in the following doesn't include the instruction itself; it is
232 ; calculated as if the instruction had zero size.
233 (define_attr "length" ""
234   (if_then_else (eq_attr "type" "branch")
235                 (if_then_else (and (ge (minus (match_dup 0) (pc))
236                                        (const_int -32768))
237                                    (lt (minus (match_dup 0) (pc))
238                                        (const_int 32764)))
239                               (const_int 4)
240                               (const_int 8))
241                 (const_int 4)))
242
243 ;; Processor type -- this attribute must exactly match the processor_type
244 ;; enumeration in rs6000-opts.h.
245 (define_attr "cpu"
246   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
247    ppc750,ppc7400,ppc7450,
248    ppc403,ppc405,ppc440,ppc476,
249    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
250    power4,power5,power6,power7,power8,
251    rs64a,mpccore,cell,ppca2,titan"
252   (const (symbol_ref "rs6000_cpu_attr")))
253
254
255 ;; If this instruction is microcoded on the CELL processor
256 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
257 (define_attr "cell_micro" "not,conditional,always"
258   (if_then_else (ior (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")))
266
267 (automata_option "ndfa")
268
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")
294
295 (include "predicates.md")
296 (include "constraints.md")
297
298 (include "darwin.md")
299
300 \f
301 ;; Mode iterators
302
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")])
306
307 ; Any supported integer mode.
308 (define_mode_iterator INT [QI HI SI DI TI PTI])
309
310 ; Any supported integer mode that fits in one register.
311 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
312
313 ; Everything we can extend QImode to.
314 (define_mode_iterator EXTQI [HI SI (DI "TARGET_POWERPC64")])
315
316 ; Everything we can extend HImode to.
317 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
318
319 ; Everything we can extend SImode to.
320 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
321
322 ; QImode or HImode for small atomic ops
323 (define_mode_iterator QHI [QI HI])
324
325 ; HImode or SImode for sign extended fusion ops
326 (define_mode_iterator HSI [HI SI])
327
328 ; SImode or DImode, even if DImode doesn't fit in GPRs.
329 (define_mode_iterator SDI [SI DI])
330
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")])
334
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])
338
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")])
351
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   ])
361
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")])
368
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  "")])
378
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 "")])
384
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")])
390
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")])
396
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")])
402
403 ; Definitions for 32-bit fpr direct move
404 ; At present, the decimal modes are not allowed in the traditional altivec
405 ; registers, so restrict the constraints to just the traditional FPRs.
406 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
407
408 ; Definitions for 32-bit VSX
409 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
410
411 ; Definitions for 32-bit use of altivec registers
412 (define_mode_attr f32_av  [(SF "wu") (SD "wn")])
413
414 ; Definitions for 64-bit VSX
415 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
416
417 ; Definitions for 64-bit direct move
418 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
419
420 ; Definitions for 64-bit use of altivec registers
421 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
422
423 ; These modes do not fit in integer registers in 32-bit mode.
424 ; but on e500v2, the gpr are 64 bit registers
425 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
426
427 ; Iterator for reciprocal estimate instructions
428 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
429
430 ; Iterator for just SF/DF
431 (define_mode_iterator SFDF [SF DF])
432
433 ; SF/DF suffix for traditional floating instructions
434 (define_mode_attr Ftrad         [(SF "s") (DF "")])
435
436 ; SF/DF suffix for VSX instructions
437 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
438
439 ; SF/DF constraint for arithmetic on traditional floating point registers
440 (define_mode_attr Ff            [(SF "f") (DF "d")])
441
442 ; SF/DF constraint for arithmetic on VSX registers
443 (define_mode_attr Fv            [(SF "wy") (DF "ws")])
444
445 ; SF/DF constraint for arithmetic on altivec registers
446 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
447
448 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
449 (define_mode_attr Fs            [(SF "s")  (DF "d")])
450
451 ; FRE/FRES support
452 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
453 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
454
455 ; Conditional returns.
456 (define_code_iterator any_return [return simple_return])
457 (define_code_attr return_pred [(return "direct_return ()")
458                                (simple_return "1")])
459 (define_code_attr return_str [(return "") (simple_return "simple_")])
460
461 ; Logical operators.
462 (define_code_iterator iorxor [ior xor])
463
464 ; Signed/unsigned variants of ops.
465 (define_code_iterator any_extend [sign_extend zero_extend])
466 (define_code_attr u [(sign_extend "") (zero_extend "u")])
467 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
468
469 ; Various instructions that come in SI and DI forms.
470 ; A generic w/d attribute, for things like cmpw/cmpd.
471 (define_mode_attr wd [(QI    "b")
472                       (HI    "h")
473                       (SI    "w")
474                       (DI    "d")
475                       (V16QI "b")
476                       (V8HI  "h")
477                       (V4SI  "w")
478                       (V2DI  "d")])
479
480 ;; How many bits in this mode?
481 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
482
483 ; DImode bits
484 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
485
486 ;; ISEL/ISEL64 target selection
487 (define_mode_attr sel [(SI "") (DI "64")])
488
489 ;; Bitmask for shift instructions
490 (define_mode_attr hH [(SI "h") (DI "H")])
491
492 ;; A mode twice the size of the given mode
493 (define_mode_attr dmode [(SI "di") (DI "ti")])
494 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
495
496 ;; Suffix for reload patterns
497 (define_mode_attr ptrsize [(SI "32bit")
498                            (DI "64bit")])
499
500 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
501                             (DI "TARGET_64BIT")])
502
503 (define_mode_attr mptrsize [(SI "si")
504                             (DI "di")])
505
506 (define_mode_attr ptrload [(SI "lwz")
507                            (DI "ld")])
508
509 (define_mode_attr ptrm [(SI "m")
510                         (DI "Y")])
511
512 (define_mode_attr rreg [(SF   "f")
513                         (DF   "ws")
514                         (TF   "f")
515                         (TD   "f")
516                         (V4SF "wf")
517                         (V2DF "wd")])
518
519 (define_mode_attr rreg2 [(SF   "f")
520                          (DF   "d")])
521
522 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
523                                  (DF "TARGET_FCFID")])
524
525 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
526                                 (DF "TARGET_E500_DOUBLE")])
527
528 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
529                                 (DF "TARGET_DOUBLE_FLOAT")])
530
531 ;; Mode iterator for logical operations on 128-bit types
532 (define_mode_iterator BOOL_128          [TI
533                                          PTI
534                                          (V16QI "TARGET_ALTIVEC")
535                                          (V8HI  "TARGET_ALTIVEC")
536                                          (V4SI  "TARGET_ALTIVEC")
537                                          (V4SF  "TARGET_ALTIVEC")
538                                          (V2DI  "TARGET_ALTIVEC")
539                                          (V2DF  "TARGET_ALTIVEC")
540                                          (V1TI  "TARGET_ALTIVEC")])
541
542 ;; For the GPRs we use 3 constraints for register outputs, two that are the
543 ;; same as the output register, and a third where the output register is an
544 ;; early clobber, so we don't have to deal with register overlaps.  For the
545 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
546 ;; either.
547
548 ;; Mode attribute for boolean operation register constraints for output
549 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
550                                          (PTI   "&r,r,r")
551                                          (V16QI "wa,v,&?r,?r,?r")
552                                          (V8HI  "wa,v,&?r,?r,?r")
553                                          (V4SI  "wa,v,&?r,?r,?r")
554                                          (V4SF  "wa,v,&?r,?r,?r")
555                                          (V2DI  "wa,v,&?r,?r,?r")
556                                          (V2DF  "wa,v,&?r,?r,?r")
557                                          (V1TI  "wa,v,&?r,?r,?r")])
558
559 ;; Mode attribute for boolean operation register constraints for operand1
560 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
561                                          (PTI   "r,0,r")
562                                          (V16QI "wa,v,r,0,r")
563                                          (V8HI  "wa,v,r,0,r")
564                                          (V4SI  "wa,v,r,0,r")
565                                          (V4SF  "wa,v,r,0,r")
566                                          (V2DI  "wa,v,r,0,r")
567                                          (V2DF  "wa,v,r,0,r")
568                                          (V1TI  "wa,v,r,0,r")])
569
570 ;; Mode attribute for boolean operation register constraints for operand2
571 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
572                                          (PTI   "r,r,0")
573                                          (V16QI "wa,v,r,r,0")
574                                          (V8HI  "wa,v,r,r,0")
575                                          (V4SI  "wa,v,r,r,0")
576                                          (V4SF  "wa,v,r,r,0")
577                                          (V2DI  "wa,v,r,r,0")
578                                          (V2DF  "wa,v,r,r,0")
579                                          (V1TI  "wa,v,r,r,0")])
580
581 ;; Mode attribute for boolean operation register constraints for operand1
582 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
583 ;; is used for operand1 or operand2
584 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
585                                          (PTI   "r,0,0")
586                                          (V16QI "wa,v,r,0,0")
587                                          (V8HI  "wa,v,r,0,0")
588                                          (V4SI  "wa,v,r,0,0")
589                                          (V4SF  "wa,v,r,0,0")
590                                          (V2DI  "wa,v,r,0,0")
591                                          (V2DF  "wa,v,r,0,0")
592                                          (V1TI  "wa,v,r,0,0")])
593
594 ;; Reload iterator for creating the function to allocate a base register to
595 ;; supplement addressing modes.
596 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
597                               SF SD SI DF DD DI TI PTI])
598
599 \f
600 ;; Start with fixed-point load and store insns.  Here we put only the more
601 ;; complex forms.  Basic data transfer is done later.
602
603 (define_insn "zero_extendqi<mode>2"
604   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
605         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
606   ""
607   "@
608    lbz%U1%X1 %0,%1
609    rlwinm %0,%1,0,0xff"
610   [(set_attr "type" "load,shift")])
611
612 (define_insn_and_split "*zero_extendqi<mode>2_dot"
613   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
614         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
615                     (const_int 0)))
616    (clobber (match_scratch:EXTQI 0 "=r,r"))]
617   "rs6000_gen_cell_microcode"
618   "@
619    andi. %0,%1,0xff
620    #"
621   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
622   [(set (match_dup 0)
623         (zero_extend:EXTQI (match_dup 1)))
624    (set (match_dup 2)
625         (compare:CC (match_dup 0)
626                     (const_int 0)))]
627   ""
628   [(set_attr "type" "logical")
629    (set_attr "dot" "yes")
630    (set_attr "length" "4,8")])
631
632 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
633   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
634         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
635                     (const_int 0)))
636    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
637         (zero_extend:EXTQI (match_dup 1)))]
638   "rs6000_gen_cell_microcode"
639   "@
640    andi. %0,%1,0xff
641    #"
642   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
643   [(set (match_dup 0)
644         (zero_extend:EXTQI (match_dup 1)))
645    (set (match_dup 2)
646         (compare:CC (match_dup 0)
647                     (const_int 0)))]
648   ""
649   [(set_attr "type" "logical")
650    (set_attr "dot" "yes")
651    (set_attr "length" "4,8")])
652
653
654 (define_insn "zero_extendhi<mode>2"
655   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
656         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
657   ""
658   "@
659    lhz%U1%X1 %0,%1
660    rlwinm %0,%1,0,0xffff"
661   [(set_attr "type" "load,shift")])
662
663 (define_insn_and_split "*zero_extendhi<mode>2_dot"
664   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
665         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
666                     (const_int 0)))
667    (clobber (match_scratch:EXTHI 0 "=r,r"))]
668   "rs6000_gen_cell_microcode"
669   "@
670    andi. %0,%1,0xffff
671    #"
672   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
673   [(set (match_dup 0)
674         (zero_extend:EXTHI (match_dup 1)))
675    (set (match_dup 2)
676         (compare:CC (match_dup 0)
677                     (const_int 0)))]
678   ""
679   [(set_attr "type" "logical")
680    (set_attr "dot" "yes")
681    (set_attr "length" "4,8")])
682
683 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
684   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
685         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
686                     (const_int 0)))
687    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
688         (zero_extend:EXTHI (match_dup 1)))]
689   "rs6000_gen_cell_microcode"
690   "@
691    andi. %0,%1,0xffff
692    #"
693   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
694   [(set (match_dup 0)
695         (zero_extend:EXTHI (match_dup 1)))
696    (set (match_dup 2)
697         (compare:CC (match_dup 0)
698                     (const_int 0)))]
699   ""
700   [(set_attr "type" "logical")
701    (set_attr "dot" "yes")
702    (set_attr "length" "4,8")])
703
704
705 (define_insn "zero_extendsi<mode>2"
706   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
707         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
708   ""
709   "@
710    lwz%U1%X1 %0,%1
711    rldicl %0,%1,0,32
712    mtvsrwz %x0,%1
713    lfiwzx %0,%y1
714    lxsiwzx %x0,%y1"
715   [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
716
717 (define_insn_and_split "*zero_extendsi<mode>2_dot"
718   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
719         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
720                     (const_int 0)))
721    (clobber (match_scratch:EXTSI 0 "=r,r"))]
722   "rs6000_gen_cell_microcode"
723   "@
724    rldicl. %0,%1,0,32
725    #"
726   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
727   [(set (match_dup 0)
728         (zero_extend:DI (match_dup 1)))
729    (set (match_dup 2)
730         (compare:CC (match_dup 0)
731                     (const_int 0)))]
732   ""
733   [(set_attr "type" "shift")
734    (set_attr "dot" "yes")
735    (set_attr "length" "4,8")])
736
737 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
738   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
739         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
740                     (const_int 0)))
741    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
742         (zero_extend:EXTSI (match_dup 1)))]
743   "rs6000_gen_cell_microcode"
744   "@
745    rldicl. %0,%1,0,32
746    #"
747   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
748   [(set (match_dup 0)
749         (zero_extend:EXTSI (match_dup 1)))
750    (set (match_dup 2)
751         (compare:CC (match_dup 0)
752                     (const_int 0)))]
753   ""
754   [(set_attr "type" "shift")
755    (set_attr "dot" "yes")
756    (set_attr "length" "4,8")])
757
758
759 (define_insn "extendqi<mode>2"
760   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
761         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
762   ""
763   "extsb %0,%1"
764   [(set_attr "type" "exts")])
765
766 (define_insn_and_split "*extendqi<mode>2_dot"
767   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
768         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
769                     (const_int 0)))
770    (clobber (match_scratch:EXTQI 0 "=r,r"))]
771   "rs6000_gen_cell_microcode"
772   "@
773    extsb. %0,%1
774    #"
775   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
776   [(set (match_dup 0)
777         (sign_extend:EXTQI (match_dup 1)))
778    (set (match_dup 2)
779         (compare:CC (match_dup 0)
780                     (const_int 0)))]
781   ""
782   [(set_attr "type" "exts")
783    (set_attr "dot" "yes")
784    (set_attr "length" "4,8")])
785
786 (define_insn_and_split "*extendqi<mode>2_dot2"
787   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
788         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
789                     (const_int 0)))
790    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
791         (sign_extend:EXTQI (match_dup 1)))]
792   "rs6000_gen_cell_microcode"
793   "@
794    extsb. %0,%1
795    #"
796   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
797   [(set (match_dup 0)
798         (sign_extend:EXTQI (match_dup 1)))
799    (set (match_dup 2)
800         (compare:CC (match_dup 0)
801                     (const_int 0)))]
802   ""
803   [(set_attr "type" "exts")
804    (set_attr "dot" "yes")
805    (set_attr "length" "4,8")])
806
807
808 (define_expand "extendhi<mode>2"
809   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
810         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
811   ""
812   "")
813
814 (define_insn "*extendhi<mode>2"
815   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
816         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
817   "rs6000_gen_cell_microcode"
818   "@
819    lha%U1%X1 %0,%1
820    extsh %0,%1"
821   [(set_attr "type" "load,exts")
822    (set_attr "sign_extend" "yes")])
823
824 (define_insn "*extendhi<mode>2_noload"
825   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
826         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
827   "!rs6000_gen_cell_microcode"
828   "extsh %0,%1"
829   [(set_attr "type" "exts")])
830
831 (define_insn_and_split "*extendhi<mode>2_dot"
832   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
833         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
834                     (const_int 0)))
835    (clobber (match_scratch:EXTHI 0 "=r,r"))]
836   "rs6000_gen_cell_microcode"
837   "@
838    extsh. %0,%1
839    #"
840   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
841   [(set (match_dup 0)
842         (sign_extend:EXTHI (match_dup 1)))
843    (set (match_dup 2)
844         (compare:CC (match_dup 0)
845                     (const_int 0)))]
846   ""
847   [(set_attr "type" "exts")
848    (set_attr "dot" "yes")
849    (set_attr "length" "4,8")])
850
851 (define_insn_and_split "*extendhi<mode>2_dot2"
852   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
853         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
854                     (const_int 0)))
855    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
856         (sign_extend:EXTHI (match_dup 1)))]
857   "rs6000_gen_cell_microcode"
858   "@
859    extsh. %0,%1
860    #"
861   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
862   [(set (match_dup 0)
863         (sign_extend:EXTHI (match_dup 1)))
864    (set (match_dup 2)
865         (compare:CC (match_dup 0)
866                     (const_int 0)))]
867   ""
868   [(set_attr "type" "exts")
869    (set_attr "dot" "yes")
870    (set_attr "length" "4,8")])
871
872
873 (define_insn "extendsi<mode>2"
874   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
875         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
876   ""
877   "@
878    lwa%U1%X1 %0,%1
879    extsw %0,%1
880    mtvsrwa %x0,%1
881    lfiwax %0,%y1
882    lxsiwax %x0,%y1"
883   [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
884    (set_attr "sign_extend" "yes")])
885
886 (define_insn_and_split "*extendsi<mode>2_dot"
887   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
888         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
889                     (const_int 0)))
890    (clobber (match_scratch:EXTSI 0 "=r,r"))]
891   "rs6000_gen_cell_microcode"
892   "@
893    extsw. %0,%1
894    #"
895   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
896   [(set (match_dup 0)
897         (sign_extend:EXTSI (match_dup 1)))
898    (set (match_dup 2)
899         (compare:CC (match_dup 0)
900                     (const_int 0)))]
901   ""
902   [(set_attr "type" "exts")
903    (set_attr "dot" "yes")
904    (set_attr "length" "4,8")])
905
906 (define_insn_and_split "*extendsi<mode>2_dot2"
907   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
908         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
909                     (const_int 0)))
910    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
911         (sign_extend:EXTSI (match_dup 1)))]
912   "rs6000_gen_cell_microcode"
913   "@
914    extsw. %0,%1
915    #"
916   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
917   [(set (match_dup 0)
918         (sign_extend:EXTSI (match_dup 1)))
919    (set (match_dup 2)
920         (compare:CC (match_dup 0)
921                     (const_int 0)))]
922   ""
923   [(set_attr "type" "exts")
924    (set_attr "dot" "yes")
925    (set_attr "length" "4,8")])
926 \f
927 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
928
929 (define_insn "*macchwc"
930   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
931         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
932                                        (match_operand:SI 2 "gpc_reg_operand" "r")
933                                        (const_int 16))
934                                       (sign_extend:SI
935                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
936                              (match_operand:SI 4 "gpc_reg_operand" "0"))
937                     (const_int 0)))
938    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
939         (plus:SI (mult:SI (ashiftrt:SI
940                            (match_dup 2)
941                            (const_int 16))
942                           (sign_extend:SI
943                            (match_dup 1)))
944                  (match_dup 4)))]
945   "TARGET_MULHW"
946   "macchw. %0,%1,%2"
947   [(set_attr "type" "halfmul")])
948
949 (define_insn "*macchw"
950   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
951         (plus:SI (mult:SI (ashiftrt:SI
952                            (match_operand:SI 2 "gpc_reg_operand" "r")
953                            (const_int 16))
954                           (sign_extend:SI
955                            (match_operand:HI 1 "gpc_reg_operand" "r")))
956                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
957   "TARGET_MULHW"
958   "macchw %0,%1,%2"
959   [(set_attr "type" "halfmul")])
960
961 (define_insn "*macchwuc"
962   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
963         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
964                                        (match_operand:SI 2 "gpc_reg_operand" "r")
965                                        (const_int 16))
966                                       (zero_extend:SI
967                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
968                              (match_operand:SI 4 "gpc_reg_operand" "0"))
969                     (const_int 0)))
970    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
971         (plus:SI (mult:SI (lshiftrt:SI
972                            (match_dup 2)
973                            (const_int 16))
974                           (zero_extend:SI
975                            (match_dup 1)))
976                  (match_dup 4)))]
977   "TARGET_MULHW"
978   "macchwu. %0,%1,%2"
979   [(set_attr "type" "halfmul")])
980
981 (define_insn "*macchwu"
982   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
983         (plus:SI (mult:SI (lshiftrt:SI
984                            (match_operand:SI 2 "gpc_reg_operand" "r")
985                            (const_int 16))
986                           (zero_extend:SI
987                            (match_operand:HI 1 "gpc_reg_operand" "r")))
988                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
989   "TARGET_MULHW"
990   "macchwu %0,%1,%2"
991   [(set_attr "type" "halfmul")])
992
993 (define_insn "*machhwc"
994   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
995         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
996                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
997                                        (const_int 16))
998                                       (ashiftrt:SI
999                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1000                                        (const_int 16)))
1001                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1002                     (const_int 0)))
1003    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1004         (plus:SI (mult:SI (ashiftrt:SI
1005                            (match_dup 1)
1006                            (const_int 16))
1007                           (ashiftrt:SI
1008                            (match_dup 2)
1009                            (const_int 16)))
1010                  (match_dup 4)))]
1011   "TARGET_MULHW"
1012   "machhw. %0,%1,%2"
1013   [(set_attr "type" "halfmul")])
1014
1015 (define_insn "*machhw"
1016   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1017         (plus:SI (mult:SI (ashiftrt:SI
1018                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1019                            (const_int 16))
1020                           (ashiftrt:SI
1021                            (match_operand:SI 2 "gpc_reg_operand" "r")
1022                            (const_int 16)))
1023                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1024   "TARGET_MULHW"
1025   "machhw %0,%1,%2"
1026   [(set_attr "type" "halfmul")])
1027
1028 (define_insn "*machhwuc"
1029   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1030         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1031                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1032                                        (const_int 16))
1033                                       (lshiftrt:SI
1034                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1035                                        (const_int 16)))
1036                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1037                     (const_int 0)))
1038    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1039         (plus:SI (mult:SI (lshiftrt:SI
1040                            (match_dup 1)
1041                            (const_int 16))
1042                           (lshiftrt:SI
1043                            (match_dup 2)
1044                            (const_int 16)))
1045                  (match_dup 4)))]
1046   "TARGET_MULHW"
1047   "machhwu. %0,%1,%2"
1048   [(set_attr "type" "halfmul")])
1049
1050 (define_insn "*machhwu"
1051   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1052         (plus:SI (mult:SI (lshiftrt:SI
1053                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1054                            (const_int 16))
1055                           (lshiftrt:SI
1056                            (match_operand:SI 2 "gpc_reg_operand" "r")
1057                            (const_int 16)))
1058                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1059   "TARGET_MULHW"
1060   "machhwu %0,%1,%2"
1061   [(set_attr "type" "halfmul")])
1062
1063 (define_insn "*maclhwc"
1064   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1065         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1066                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1067                                       (sign_extend:SI
1068                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1069                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1070                     (const_int 0)))
1071    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1072         (plus:SI (mult:SI (sign_extend:SI
1073                            (match_dup 1))
1074                           (sign_extend:SI
1075                            (match_dup 2)))
1076                  (match_dup 4)))]
1077   "TARGET_MULHW"
1078   "maclhw. %0,%1,%2"
1079   [(set_attr "type" "halfmul")])
1080
1081 (define_insn "*maclhw"
1082   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1083         (plus:SI (mult:SI (sign_extend:SI
1084                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1085                           (sign_extend:SI
1086                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1087                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1088   "TARGET_MULHW"
1089   "maclhw %0,%1,%2"
1090   [(set_attr "type" "halfmul")])
1091
1092 (define_insn "*maclhwuc"
1093   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1094         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1095                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1096                                       (zero_extend:SI
1097                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1098                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1099                     (const_int 0)))
1100    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1101         (plus:SI (mult:SI (zero_extend:SI
1102                            (match_dup 1))
1103                           (zero_extend:SI
1104                            (match_dup 2)))
1105                  (match_dup 4)))]
1106   "TARGET_MULHW"
1107   "maclhwu. %0,%1,%2"
1108   [(set_attr "type" "halfmul")])
1109
1110 (define_insn "*maclhwu"
1111   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1112         (plus:SI (mult:SI (zero_extend:SI
1113                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1114                           (zero_extend:SI
1115                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1116                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1117   "TARGET_MULHW"
1118   "maclhwu %0,%1,%2"
1119   [(set_attr "type" "halfmul")])
1120
1121 (define_insn "*nmacchwc"
1122   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1123         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1124                               (mult:SI (ashiftrt:SI
1125                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1126                                         (const_int 16))
1127                                        (sign_extend:SI
1128                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1129                     (const_int 0)))
1130    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1131         (minus:SI (match_dup 4)
1132                   (mult:SI (ashiftrt:SI
1133                             (match_dup 2)
1134                             (const_int 16))
1135                            (sign_extend:SI
1136                             (match_dup 1)))))]
1137   "TARGET_MULHW"
1138   "nmacchw. %0,%1,%2"
1139   [(set_attr "type" "halfmul")])
1140
1141 (define_insn "*nmacchw"
1142   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1143         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1144                   (mult:SI (ashiftrt:SI
1145                             (match_operand:SI 2 "gpc_reg_operand" "r")
1146                             (const_int 16))
1147                            (sign_extend:SI
1148                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1149   "TARGET_MULHW"
1150   "nmacchw %0,%1,%2"
1151   [(set_attr "type" "halfmul")])
1152
1153 (define_insn "*nmachhwc"
1154   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1155         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1156                               (mult:SI (ashiftrt:SI
1157                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1158                                         (const_int 16))
1159                                        (ashiftrt:SI
1160                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1161                                         (const_int 16))))
1162                     (const_int 0)))
1163    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1164         (minus:SI (match_dup 4)
1165                   (mult:SI (ashiftrt:SI
1166                             (match_dup 1)
1167                             (const_int 16))
1168                            (ashiftrt:SI
1169                             (match_dup 2)
1170                             (const_int 16)))))]
1171   "TARGET_MULHW"
1172   "nmachhw. %0,%1,%2"
1173   [(set_attr "type" "halfmul")])
1174
1175 (define_insn "*nmachhw"
1176   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1177         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1178                   (mult:SI (ashiftrt:SI
1179                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1180                             (const_int 16))
1181                            (ashiftrt:SI
1182                             (match_operand:SI 2 "gpc_reg_operand" "r")
1183                             (const_int 16)))))]
1184   "TARGET_MULHW"
1185   "nmachhw %0,%1,%2"
1186   [(set_attr "type" "halfmul")])
1187
1188 (define_insn "*nmaclhwc"
1189   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1190         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1191                               (mult:SI (sign_extend:SI
1192                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1193                                        (sign_extend:SI
1194                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1195                     (const_int 0)))
1196    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1197         (minus:SI (match_dup 4)
1198                   (mult:SI (sign_extend:SI
1199                             (match_dup 1))
1200                            (sign_extend:SI
1201                             (match_dup 2)))))]
1202   "TARGET_MULHW"
1203   "nmaclhw. %0,%1,%2"
1204   [(set_attr "type" "halfmul")])
1205
1206 (define_insn "*nmaclhw"
1207   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1208         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1209                   (mult:SI (sign_extend:SI
1210                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1211                            (sign_extend:SI
1212                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1213   "TARGET_MULHW"
1214   "nmaclhw %0,%1,%2"
1215   [(set_attr "type" "halfmul")])
1216
1217 (define_insn "*mulchwc"
1218   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1219         (compare:CC (mult:SI (ashiftrt:SI
1220                               (match_operand:SI 2 "gpc_reg_operand" "r")
1221                               (const_int 16))
1222                              (sign_extend:SI
1223                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1224                     (const_int 0)))
1225    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1226         (mult:SI (ashiftrt:SI
1227                   (match_dup 2)
1228                   (const_int 16))
1229                  (sign_extend:SI
1230                   (match_dup 1))))]
1231   "TARGET_MULHW"
1232   "mulchw. %0,%1,%2"
1233   [(set_attr "type" "halfmul")])
1234
1235 (define_insn "*mulchw"
1236   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1237         (mult:SI (ashiftrt:SI
1238                   (match_operand:SI 2 "gpc_reg_operand" "r")
1239                   (const_int 16))
1240                  (sign_extend:SI
1241                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1242   "TARGET_MULHW"
1243   "mulchw %0,%1,%2"
1244   [(set_attr "type" "halfmul")])
1245
1246 (define_insn "*mulchwuc"
1247   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1248         (compare:CC (mult:SI (lshiftrt:SI
1249                               (match_operand:SI 2 "gpc_reg_operand" "r")
1250                               (const_int 16))
1251                              (zero_extend:SI
1252                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1253                     (const_int 0)))
1254    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1255         (mult:SI (lshiftrt:SI
1256                   (match_dup 2)
1257                   (const_int 16))
1258                  (zero_extend:SI
1259                   (match_dup 1))))]
1260   "TARGET_MULHW"
1261   "mulchwu. %0,%1,%2"
1262   [(set_attr "type" "halfmul")])
1263
1264 (define_insn "*mulchwu"
1265   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1266         (mult:SI (lshiftrt:SI
1267                   (match_operand:SI 2 "gpc_reg_operand" "r")
1268                   (const_int 16))
1269                  (zero_extend:SI
1270                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1271   "TARGET_MULHW"
1272   "mulchwu %0,%1,%2"
1273   [(set_attr "type" "halfmul")])
1274
1275 (define_insn "*mulhhwc"
1276   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1277         (compare:CC (mult:SI (ashiftrt:SI
1278                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1279                               (const_int 16))
1280                              (ashiftrt:SI
1281                               (match_operand:SI 2 "gpc_reg_operand" "r")
1282                               (const_int 16)))
1283                     (const_int 0)))
1284    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1285         (mult:SI (ashiftrt:SI
1286                   (match_dup 1)
1287                   (const_int 16))
1288                  (ashiftrt:SI
1289                   (match_dup 2)
1290                   (const_int 16))))]
1291   "TARGET_MULHW"
1292   "mulhhw. %0,%1,%2"
1293   [(set_attr "type" "halfmul")])
1294
1295 (define_insn "*mulhhw"
1296   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1297         (mult:SI (ashiftrt:SI
1298                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1299                   (const_int 16))
1300                  (ashiftrt:SI
1301                   (match_operand:SI 2 "gpc_reg_operand" "r")
1302                   (const_int 16))))]
1303   "TARGET_MULHW"
1304   "mulhhw %0,%1,%2"
1305   [(set_attr "type" "halfmul")])
1306
1307 (define_insn "*mulhhwuc"
1308   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1309         (compare:CC (mult:SI (lshiftrt:SI
1310                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1311                               (const_int 16))
1312                              (lshiftrt:SI
1313                               (match_operand:SI 2 "gpc_reg_operand" "r")
1314                               (const_int 16)))
1315                     (const_int 0)))
1316    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1317         (mult:SI (lshiftrt:SI
1318                   (match_dup 1)
1319                   (const_int 16))
1320                  (lshiftrt:SI
1321                   (match_dup 2)
1322                   (const_int 16))))]
1323   "TARGET_MULHW"
1324   "mulhhwu. %0,%1,%2"
1325   [(set_attr "type" "halfmul")])
1326
1327 (define_insn "*mulhhwu"
1328   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1329         (mult:SI (lshiftrt:SI
1330                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1331                   (const_int 16))
1332                  (lshiftrt:SI
1333                   (match_operand:SI 2 "gpc_reg_operand" "r")
1334                   (const_int 16))))]
1335   "TARGET_MULHW"
1336   "mulhhwu %0,%1,%2"
1337   [(set_attr "type" "halfmul")])
1338
1339 (define_insn "*mullhwc"
1340   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1341         (compare:CC (mult:SI (sign_extend:SI
1342                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1343                              (sign_extend:SI
1344                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1345                     (const_int 0)))
1346    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1347         (mult:SI (sign_extend:SI
1348                   (match_dup 1))
1349                  (sign_extend:SI
1350                   (match_dup 2))))]
1351   "TARGET_MULHW"
1352   "mullhw. %0,%1,%2"
1353   [(set_attr "type" "halfmul")])
1354
1355 (define_insn "*mullhw"
1356   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1357         (mult:SI (sign_extend:SI
1358                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1359                  (sign_extend:SI
1360                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1361   "TARGET_MULHW"
1362   "mullhw %0,%1,%2"
1363   [(set_attr "type" "halfmul")])
1364
1365 (define_insn "*mullhwuc"
1366   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1367         (compare:CC (mult:SI (zero_extend:SI
1368                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1369                              (zero_extend:SI
1370                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1371                     (const_int 0)))
1372    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1373         (mult:SI (zero_extend:SI
1374                   (match_dup 1))
1375                  (zero_extend:SI
1376                   (match_dup 2))))]
1377   "TARGET_MULHW"
1378   "mullhwu. %0,%1,%2"
1379   [(set_attr "type" "halfmul")])
1380
1381 (define_insn "*mullhwu"
1382   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1383         (mult:SI (zero_extend:SI
1384                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1385                  (zero_extend:SI
1386                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1387   "TARGET_MULHW"
1388   "mullhwu %0,%1,%2"
1389   [(set_attr "type" "halfmul")])
1390 \f
1391 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1392 (define_insn "dlmzb"
1393   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1394         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1395                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1396                    UNSPEC_DLMZB_CR))
1397    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1398         (unspec:SI [(match_dup 1)
1399                     (match_dup 2)]
1400                    UNSPEC_DLMZB))]
1401   "TARGET_DLMZB"
1402   "dlmzb. %0,%1,%2")
1403
1404 (define_expand "strlensi"
1405   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1406         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1407                     (match_operand:QI 2 "const_int_operand" "")
1408                     (match_operand 3 "const_int_operand" "")]
1409                    UNSPEC_DLMZB_STRLEN))
1410    (clobber (match_scratch:CC 4 "=x"))]
1411   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1412 {
1413   rtx result = operands[0];
1414   rtx src = operands[1];
1415   rtx search_char = operands[2];
1416   rtx align = operands[3];
1417   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1418   rtx loop_label, end_label, mem, cr0, cond;
1419   if (search_char != const0_rtx
1420       || GET_CODE (align) != CONST_INT
1421       || INTVAL (align) < 8)
1422         FAIL;
1423   word1 = gen_reg_rtx (SImode);
1424   word2 = gen_reg_rtx (SImode);
1425   scratch_dlmzb = gen_reg_rtx (SImode);
1426   scratch_string = gen_reg_rtx (Pmode);
1427   loop_label = gen_label_rtx ();
1428   end_label = gen_label_rtx ();
1429   addr = force_reg (Pmode, XEXP (src, 0));
1430   emit_move_insn (scratch_string, addr);
1431   emit_label (loop_label);
1432   mem = change_address (src, SImode, scratch_string);
1433   emit_move_insn (word1, mem);
1434   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1435   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1436   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1437   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1438   emit_jump_insn (gen_rtx_SET (pc_rtx,
1439                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1440                                                      cond,
1441                                                      gen_rtx_LABEL_REF
1442                                                        (VOIDmode,
1443                                                         end_label),
1444                                                      pc_rtx)));
1445   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1446   emit_jump_insn (gen_rtx_SET (pc_rtx,
1447                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1448   emit_barrier ();
1449   emit_label (end_label);
1450   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1451   emit_insn (gen_subsi3 (result, scratch_string, addr));
1452   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1453   DONE;
1454 })
1455 \f
1456 ;; Fixed-point arithmetic insns.
1457
1458 (define_expand "add<mode>3"
1459   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1460         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1461                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1462   ""
1463 {
1464   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1465     {
1466       rtx lo0 = gen_lowpart (SImode, operands[0]);
1467       rtx lo1 = gen_lowpart (SImode, operands[1]);
1468       rtx lo2 = gen_lowpart (SImode, operands[2]);
1469       rtx hi0 = gen_highpart (SImode, operands[0]);
1470       rtx hi1 = gen_highpart (SImode, operands[1]);
1471       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1472
1473       if (!reg_or_short_operand (lo2, SImode))
1474         lo2 = force_reg (SImode, lo2);
1475       if (!adde_operand (hi2, SImode))
1476         hi2 = force_reg (SImode, hi2);
1477
1478       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1479       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1480       DONE;
1481     }
1482
1483   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1484     {
1485       rtx tmp = ((!can_create_pseudo_p ()
1486                   || rtx_equal_p (operands[0], operands[1]))
1487                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1488
1489       HOST_WIDE_INT val = INTVAL (operands[2]);
1490       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1491       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1492
1493       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1494         FAIL;
1495
1496       /* The ordering here is important for the prolog expander.
1497          When space is allocated from the stack, adding 'low' first may
1498          produce a temporary deallocation (which would be bad).  */
1499       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1500       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1501       DONE;
1502     }
1503 })
1504
1505 (define_insn "*add<mode>3"
1506   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1507         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1508                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1509   ""
1510   "@
1511    add %0,%1,%2
1512    addi %0,%1,%2
1513    addis %0,%1,%v2"
1514   [(set_attr "type" "add")])
1515
1516 (define_insn "addsi3_high"
1517   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1518         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1519                  (high:SI (match_operand 2 "" ""))))]
1520   "TARGET_MACHO && !TARGET_64BIT"
1521   "addis %0,%1,ha16(%2)"
1522   [(set_attr "type" "add")])
1523
1524 (define_insn_and_split "*add<mode>3_dot"
1525   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1526         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1527                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1528                     (const_int 0)))
1529    (clobber (match_scratch:GPR 0 "=r,r"))]
1530   "<MODE>mode == Pmode"
1531   "@
1532    add. %0,%1,%2
1533    #"
1534   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1535   [(set (match_dup 0)
1536         (plus:GPR (match_dup 1)
1537                  (match_dup 2)))
1538    (set (match_dup 3)
1539         (compare:CC (match_dup 0)
1540                     (const_int 0)))]
1541   ""
1542   [(set_attr "type" "add")
1543    (set_attr "dot" "yes")
1544    (set_attr "length" "4,8")])
1545
1546 (define_insn_and_split "*add<mode>3_dot2"
1547   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1548         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1549                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1550                     (const_int 0)))
1551    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1552         (plus:GPR (match_dup 1)
1553                   (match_dup 2)))]
1554   "<MODE>mode == Pmode"
1555   "@
1556    add. %0,%1,%2
1557    #"
1558   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1559   [(set (match_dup 0)
1560         (plus:GPR (match_dup 1)
1561                   (match_dup 2)))
1562    (set (match_dup 3)
1563         (compare:CC (match_dup 0)
1564                     (const_int 0)))]
1565   ""
1566   [(set_attr "type" "add")
1567    (set_attr "dot" "yes")
1568    (set_attr "length" "4,8")])
1569
1570 (define_insn_and_split "*add<mode>3_imm_dot"
1571   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1572         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1573                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1574                     (const_int 0)))
1575    (clobber (match_scratch:GPR 0 "=r,r"))
1576    (clobber (reg:GPR CA_REGNO))]
1577   "<MODE>mode == Pmode"
1578   "@
1579    addic. %0,%1,%2
1580    #"
1581   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1582   [(set (match_dup 0)
1583         (plus:GPR (match_dup 1)
1584                   (match_dup 2)))
1585    (set (match_dup 3)
1586         (compare:CC (match_dup 0)
1587                     (const_int 0)))]
1588   ""
1589   [(set_attr "type" "add")
1590    (set_attr "dot" "yes")
1591    (set_attr "length" "4,8")])
1592
1593 (define_insn_and_split "*add<mode>3_imm_dot2"
1594   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1595         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1596                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1597                     (const_int 0)))
1598    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1599         (plus:GPR (match_dup 1)
1600                   (match_dup 2)))
1601    (clobber (reg:GPR CA_REGNO))]
1602   "<MODE>mode == Pmode"
1603   "@
1604    addic. %0,%1,%2
1605    #"
1606   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1607   [(set (match_dup 0)
1608         (plus:GPR (match_dup 1)
1609                   (match_dup 2)))
1610    (set (match_dup 3)
1611         (compare:CC (match_dup 0)
1612                     (const_int 0)))]
1613   ""
1614   [(set_attr "type" "add")
1615    (set_attr "dot" "yes")
1616    (set_attr "length" "4,8")])
1617
1618 ;; Split an add that we can't do in one insn into two insns, each of which
1619 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1620 ;; add should be last in case the result gets used in an address.
1621
1622 (define_split
1623   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1624         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1625                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1626   ""
1627   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1628    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1629 {
1630   HOST_WIDE_INT val = INTVAL (operands[2]);
1631   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1632   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1633
1634   operands[4] = GEN_INT (low);
1635   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1636     operands[3] = GEN_INT (rest);
1637   else if (can_create_pseudo_p ())
1638     {
1639       operands[3] = gen_reg_rtx (DImode);
1640       emit_move_insn (operands[3], operands[2]);
1641       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1642       DONE;
1643     }
1644   else
1645     FAIL;
1646 })
1647
1648
1649 (define_insn "add<mode>3_carry"
1650   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1651         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1652                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1653    (set (reg:P CA_REGNO)
1654         (ltu:P (plus:P (match_dup 1)
1655                        (match_dup 2))
1656                (match_dup 1)))]
1657   ""
1658   "add%I2c %0,%1,%2"
1659   [(set_attr "type" "add")])
1660
1661 (define_insn "*add<mode>3_imm_carry_pos"
1662   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1663         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1664                 (match_operand:P 2 "short_cint_operand" "n")))
1665    (set (reg:P CA_REGNO)
1666         (geu:P (match_dup 1)
1667                (match_operand:P 3 "const_int_operand" "n")))]
1668   "INTVAL (operands[2]) > 0
1669    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1670   "addic %0,%1,%2"
1671   [(set_attr "type" "add")])
1672
1673 (define_insn "*add<mode>3_imm_carry_0"
1674   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1675         (match_operand:P 1 "gpc_reg_operand" "r"))
1676    (set (reg:P CA_REGNO)
1677         (const_int 0))]
1678   ""
1679   "addic %0,%1,0"
1680   [(set_attr "type" "add")])
1681
1682 (define_insn "*add<mode>3_imm_carry_m1"
1683   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1684         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1685                 (const_int -1)))
1686    (set (reg:P CA_REGNO)
1687         (ne:P (match_dup 1)
1688               (const_int 0)))]
1689   ""
1690   "addic %0,%1,-1"
1691   [(set_attr "type" "add")])
1692
1693 (define_insn "*add<mode>3_imm_carry_neg"
1694   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1695         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1696                 (match_operand:P 2 "short_cint_operand" "n")))
1697    (set (reg:P CA_REGNO)
1698         (gtu:P (match_dup 1)
1699                (match_operand:P 3 "const_int_operand" "n")))]
1700   "INTVAL (operands[2]) < 0
1701    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1702   "addic %0,%1,%2"
1703   [(set_attr "type" "add")])
1704
1705
1706 (define_expand "add<mode>3_carry_in"
1707   [(parallel [
1708      (set (match_operand:GPR 0 "gpc_reg_operand")
1709           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1710                               (match_operand:GPR 2 "adde_operand"))
1711                     (reg:GPR CA_REGNO)))
1712      (clobber (reg:GPR CA_REGNO))])]
1713   ""
1714 {
1715   if (operands[2] == const0_rtx)
1716     {
1717       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1718       DONE;
1719     }
1720   if (operands[2] == constm1_rtx)
1721     {
1722       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1723       DONE;
1724     }
1725 })
1726
1727 (define_insn "*add<mode>3_carry_in_internal"
1728   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1729         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1730                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1731                   (reg:GPR CA_REGNO)))
1732    (clobber (reg:GPR CA_REGNO))]
1733   ""
1734   "adde %0,%1,%2"
1735   [(set_attr "type" "add")])
1736
1737 (define_insn "add<mode>3_carry_in_0"
1738   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1739         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1740                   (reg:GPR CA_REGNO)))
1741    (clobber (reg:GPR CA_REGNO))]
1742   ""
1743   "addze %0,%1"
1744   [(set_attr "type" "add")])
1745
1746 (define_insn "add<mode>3_carry_in_m1"
1747   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1748         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1749                             (reg:GPR CA_REGNO))
1750                   (const_int -1)))
1751    (clobber (reg:GPR CA_REGNO))]
1752   ""
1753   "addme %0,%1"
1754   [(set_attr "type" "add")])
1755
1756
1757 (define_expand "one_cmpl<mode>2"
1758   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1759         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1760   ""
1761 {
1762   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1763     {
1764       rs6000_split_logical (operands, NOT, false, false, false);
1765       DONE;
1766     }
1767 })
1768
1769 (define_insn "*one_cmpl<mode>2"
1770   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1771         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1772   ""
1773   "not %0,%1")
1774
1775 (define_insn_and_split "*one_cmpl<mode>2_dot"
1776   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1777         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1778                     (const_int 0)))
1779    (clobber (match_scratch:GPR 0 "=r,r"))]
1780   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1781   "@
1782    not. %0,%1
1783    #"
1784   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1785   [(set (match_dup 0)
1786         (not:GPR (match_dup 1)))
1787    (set (match_dup 2)
1788         (compare:CC (match_dup 0)
1789                     (const_int 0)))]
1790   ""
1791   [(set_attr "type" "logical")
1792    (set_attr "dot" "yes")
1793    (set_attr "length" "4,8")])
1794
1795 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1796   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1797         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1798                     (const_int 0)))
1799    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1800         (not:GPR (match_dup 1)))]
1801   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1802   "@
1803    not. %0,%1
1804    #"
1805   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1806   [(set (match_dup 0)
1807         (not:GPR (match_dup 1)))
1808    (set (match_dup 2)
1809         (compare:CC (match_dup 0)
1810                     (const_int 0)))]
1811   ""
1812   [(set_attr "type" "logical")
1813    (set_attr "dot" "yes")
1814    (set_attr "length" "4,8")])
1815
1816
1817 (define_expand "sub<mode>3"
1818   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1819         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1820                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1821   ""
1822 {
1823   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1824     {
1825       rtx lo0 = gen_lowpart (SImode, operands[0]);
1826       rtx lo1 = gen_lowpart (SImode, operands[1]);
1827       rtx lo2 = gen_lowpart (SImode, operands[2]);
1828       rtx hi0 = gen_highpart (SImode, operands[0]);
1829       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1830       rtx hi2 = gen_highpart (SImode, operands[2]);
1831
1832       if (!reg_or_short_operand (lo1, SImode))
1833         lo1 = force_reg (SImode, lo1);
1834       if (!adde_operand (hi1, SImode))
1835         hi1 = force_reg (SImode, hi1);
1836
1837       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1838       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1839       DONE;
1840     }
1841
1842   if (short_cint_operand (operands[1], <MODE>mode))
1843     {
1844       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1845       DONE;
1846     }
1847 })
1848
1849 (define_insn "*subf<mode>3"
1850   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1851         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1852                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1853   ""
1854   "subf %0,%1,%2"
1855   [(set_attr "type" "add")])
1856
1857 (define_insn_and_split "*subf<mode>3_dot"
1858   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1859         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1860                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1861                     (const_int 0)))
1862    (clobber (match_scratch:GPR 0 "=r,r"))]
1863   "<MODE>mode == Pmode"
1864   "@
1865    subf. %0,%1,%2
1866    #"
1867   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1868   [(set (match_dup 0)
1869         (minus:GPR (match_dup 2)
1870                    (match_dup 1)))
1871    (set (match_dup 3)
1872         (compare:CC (match_dup 0)
1873                     (const_int 0)))]
1874   ""
1875   [(set_attr "type" "add")
1876    (set_attr "dot" "yes")
1877    (set_attr "length" "4,8")])
1878
1879 (define_insn_and_split "*subf<mode>3_dot2"
1880   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1881         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1882                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1883                     (const_int 0)))
1884    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1885         (minus:GPR (match_dup 2)
1886                    (match_dup 1)))]
1887   "<MODE>mode == Pmode"
1888   "@
1889    subf. %0,%1,%2
1890    #"
1891   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1892   [(set (match_dup 0)
1893         (minus:GPR (match_dup 2)
1894                    (match_dup 1)))
1895    (set (match_dup 3)
1896         (compare:CC (match_dup 0)
1897                     (const_int 0)))]
1898   ""
1899   [(set_attr "type" "add")
1900    (set_attr "dot" "yes")
1901    (set_attr "length" "4,8")])
1902
1903 (define_insn "subf<mode>3_imm"
1904   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1905         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
1906                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
1907    (clobber (reg:GPR CA_REGNO))]
1908   ""
1909   "subfic %0,%1,%2"
1910   [(set_attr "type" "add")])
1911
1912
1913 (define_insn "subf<mode>3_carry"
1914   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1915         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
1916                  (match_operand:P 1 "gpc_reg_operand" "r")))
1917    (set (reg:P CA_REGNO)
1918         (leu:P (match_dup 1)
1919                (match_dup 2)))]
1920   ""
1921   "subf%I2c %0,%1,%2"
1922   [(set_attr "type" "add")])
1923
1924 (define_insn "*subf<mode>3_imm_carry_0"
1925   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1926         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
1927    (set (reg:P CA_REGNO)
1928         (eq:P (match_dup 1)
1929               (const_int 0)))]
1930   ""
1931   "subfic %0,%1,0"
1932   [(set_attr "type" "add")])
1933
1934 (define_insn "*subf<mode>3_imm_carry_m1"
1935   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1936         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
1937    (set (reg:P CA_REGNO)
1938         (const_int 1))]
1939   ""
1940   "subfic %0,%1,-1"
1941   [(set_attr "type" "add")])
1942
1943
1944 (define_expand "subf<mode>3_carry_in"
1945   [(parallel [
1946      (set (match_operand:GPR 0 "gpc_reg_operand")
1947           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
1948                               (reg:GPR CA_REGNO))
1949                     (match_operand:GPR 2 "adde_operand")))
1950      (clobber (reg:GPR CA_REGNO))])]
1951   ""
1952 {
1953   if (operands[2] == const0_rtx)
1954     {
1955       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
1956       DONE;
1957     }
1958   if (operands[2] == constm1_rtx)
1959     {
1960       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
1961       DONE;
1962     }
1963 })
1964
1965 (define_insn "*subf<mode>3_carry_in_internal"
1966   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1967         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
1968                             (reg:GPR CA_REGNO))
1969                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
1970    (clobber (reg:GPR CA_REGNO))]
1971   ""
1972   "subfe %0,%1,%2"
1973   [(set_attr "type" "add")])
1974
1975 (define_insn "subf<mode>3_carry_in_0"
1976   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1977         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
1978                   (reg:GPR CA_REGNO)))
1979    (clobber (reg:GPR CA_REGNO))]
1980   ""
1981   "subfze %0,%1"
1982   [(set_attr "type" "add")])
1983
1984 (define_insn "subf<mode>3_carry_in_m1"
1985   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1986         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
1987                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
1988                   (const_int -2)))
1989    (clobber (reg:GPR CA_REGNO))]
1990   ""
1991   "subfme %0,%1"
1992   [(set_attr "type" "add")])
1993
1994 (define_insn "subf<mode>3_carry_in_xx"
1995   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1996         (plus:GPR (reg:GPR CA_REGNO)
1997                   (const_int -1)))
1998    (clobber (reg:GPR CA_REGNO))]
1999   ""
2000   "subfe %0,%0,%0"
2001   [(set_attr "type" "add")])
2002
2003
2004 (define_insn "neg<mode>2"
2005   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2006         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2007   ""
2008   "neg %0,%1"
2009   [(set_attr "type" "add")])
2010
2011 (define_insn_and_split "*neg<mode>2_dot"
2012   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2013         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2014                     (const_int 0)))
2015    (clobber (match_scratch:GPR 0 "=r,r"))]
2016   "<MODE>mode == Pmode"
2017   "@
2018    neg. %0,%1
2019    #"
2020   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2021   [(set (match_dup 0)
2022         (neg:GPR (match_dup 1)))
2023    (set (match_dup 2)
2024         (compare:CC (match_dup 0)
2025                     (const_int 0)))]
2026   ""
2027   [(set_attr "type" "add")
2028    (set_attr "dot" "yes")
2029    (set_attr "length" "4,8")])
2030
2031 (define_insn_and_split "*neg<mode>2_dot2"
2032   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2033         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2034                     (const_int 0)))
2035    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2036         (neg:GPR (match_dup 1)))]
2037   "<MODE>mode == Pmode"
2038   "@
2039    neg. %0,%1
2040    #"
2041   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2042   [(set (match_dup 0)
2043         (neg:GPR (match_dup 1)))
2044    (set (match_dup 2)
2045         (compare:CC (match_dup 0)
2046                     (const_int 0)))]
2047   ""
2048   [(set_attr "type" "add")
2049    (set_attr "dot" "yes")
2050    (set_attr "length" "4,8")])
2051
2052
2053 (define_insn "clz<mode>2"
2054   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2055         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2056   ""
2057   "cntlz<wd> %0,%1"
2058   [(set_attr "type" "cntlz")])
2059
2060 (define_expand "ctz<mode>2"
2061   [(set (match_dup 2)
2062         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2063    (set (match_dup 3)
2064         (and:GPR (match_dup 1)
2065                  (match_dup 2)))
2066    (set (match_dup 4)
2067         (clz:GPR (match_dup 3)))
2068    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2069                    (minus:GPR (match_dup 5)
2070                               (match_dup 4)))
2071               (clobber (reg:GPR CA_REGNO))])]
2072   ""
2073 {
2074   operands[2] = gen_reg_rtx (<MODE>mode);
2075   operands[3] = gen_reg_rtx (<MODE>mode);
2076   operands[4] = gen_reg_rtx (<MODE>mode);
2077   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2078 })
2079
2080 (define_expand "ffs<mode>2"
2081   [(set (match_dup 2)
2082         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2083    (set (match_dup 3)
2084         (and:GPR (match_dup 1)
2085                  (match_dup 2)))
2086    (set (match_dup 4)
2087         (clz:GPR (match_dup 3)))
2088    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2089                    (minus:GPR (match_dup 5)
2090                               (match_dup 4)))
2091               (clobber (reg:GPR CA_REGNO))])]
2092   ""
2093 {
2094   operands[2] = gen_reg_rtx (<MODE>mode);
2095   operands[3] = gen_reg_rtx (<MODE>mode);
2096   operands[4] = gen_reg_rtx (<MODE>mode);
2097   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2098 })
2099
2100
2101 (define_expand "popcount<mode>2"
2102   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2103         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2104   "TARGET_POPCNTB || TARGET_POPCNTD"
2105 {
2106   rs6000_emit_popcount (operands[0], operands[1]);
2107   DONE;
2108 })
2109
2110 (define_insn "popcntb<mode>2"
2111   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2112         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2113                     UNSPEC_POPCNTB))]
2114   "TARGET_POPCNTB"
2115   "popcntb %0,%1"
2116   [(set_attr "type" "popcnt")])
2117
2118 (define_insn "popcntd<mode>2"
2119   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2120         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2121   "TARGET_POPCNTD"
2122   "popcnt<wd> %0,%1"
2123   [(set_attr "type" "popcnt")])
2124
2125
2126 (define_expand "parity<mode>2"
2127   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2128         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2129   "TARGET_POPCNTB"
2130 {
2131   rs6000_emit_parity (operands[0], operands[1]);
2132   DONE;
2133 })
2134
2135 (define_insn "parity<mode>2_cmpb"
2136   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2137         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2138   "TARGET_CMPB && TARGET_POPCNTB"
2139   "prty<wd> %0,%1"
2140   [(set_attr "type" "popcnt")])
2141
2142
2143 ;; Since the hardware zeros the upper part of the register, save generating the
2144 ;; AND immediate if we are converting to unsigned
2145 (define_insn "*bswaphi2_extenddi"
2146   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2147         (zero_extend:DI
2148          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2149   "TARGET_POWERPC64"
2150   "lhbrx %0,%y1"
2151   [(set_attr "length" "4")
2152    (set_attr "type" "load")])
2153
2154 (define_insn "*bswaphi2_extendsi"
2155   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2156         (zero_extend:SI
2157          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2158   ""
2159   "lhbrx %0,%y1"
2160   [(set_attr "length" "4")
2161    (set_attr "type" "load")])
2162
2163 (define_expand "bswaphi2"
2164   [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2165                    (bswap:HI
2166                     (match_operand:HI 1 "reg_or_mem_operand" "")))
2167               (clobber (match_scratch:SI 2 ""))])]
2168   ""
2169 {
2170   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2171     operands[1] = force_reg (HImode, operands[1]);
2172 })
2173
2174 (define_insn "bswaphi2_internal"
2175   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2176         (bswap:HI
2177          (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2178    (clobber (match_scratch:SI 2 "=X,X,&r"))]
2179   ""
2180   "@
2181    lhbrx %0,%y1
2182    sthbrx %1,%y0
2183    #"
2184   [(set_attr "length" "4,4,12")
2185    (set_attr "type" "load,store,*")])
2186
2187 (define_split
2188   [(set (match_operand:HI 0 "gpc_reg_operand" "")
2189         (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2190    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2191   "reload_completed"
2192   [(set (match_dup 3)
2193         (and:SI (lshiftrt:SI (match_dup 4)
2194                              (const_int 8))
2195                 (const_int 255)))
2196    (set (match_dup 2)
2197         (and:SI (ashift:SI (match_dup 4)
2198                            (const_int 8))
2199                 (const_int 65280)))             ;; 0xff00
2200    (set (match_dup 3)
2201         (ior:SI (match_dup 3)
2202                 (match_dup 2)))]
2203   "
2204 {
2205   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2206   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2207 }")
2208
2209 (define_insn "*bswapsi2_extenddi"
2210   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2211         (zero_extend:DI
2212          (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2213   "TARGET_POWERPC64"
2214   "lwbrx %0,%y1"
2215   [(set_attr "length" "4")
2216    (set_attr "type" "load")])
2217
2218 (define_expand "bswapsi2"
2219   [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2220         (bswap:SI
2221          (match_operand:SI 1 "reg_or_mem_operand" "")))]
2222   ""
2223 {
2224   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2225     operands[1] = force_reg (SImode, operands[1]);
2226 })
2227
2228 (define_insn "*bswapsi2_internal"
2229   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2230         (bswap:SI
2231          (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2232   ""
2233   "@
2234    lwbrx %0,%y1
2235    stwbrx %1,%y0
2236    #"
2237   [(set_attr "length" "4,4,12")
2238    (set_attr "type" "load,store,*")])
2239
2240 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2241 ;; zero_extract insns do not change for -mlittle.
2242 (define_split
2243   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2244         (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2245   "reload_completed"
2246   [(set (match_dup 0)
2247         (rotate:SI (match_dup 1) (const_int 8)))
2248    (set (zero_extract:SI (match_dup 0)
2249                          (const_int 8)
2250                          (const_int 0))
2251         (match_dup 1))
2252    (set (zero_extract:SI (match_dup 0)
2253                          (const_int 8)
2254                          (const_int 16))
2255         (rotate:SI (match_dup 1)
2256                    (const_int 16)))]
2257   "")
2258
2259 (define_expand "bswapdi2"
2260   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2261                    (bswap:DI
2262                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2263               (clobber (match_scratch:DI 2 ""))
2264               (clobber (match_scratch:DI 3 ""))])]
2265   ""
2266 {
2267   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2268     operands[1] = force_reg (DImode, operands[1]);
2269
2270   if (!TARGET_POWERPC64)
2271     {
2272       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2273          that uses 64-bit registers needs the same scratch registers as 64-bit
2274          mode.  */
2275       emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2276       DONE;
2277     }
2278 })
2279
2280 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2281 (define_insn "*bswapdi2_ldbrx"
2282   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2283         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2284    (clobber (match_scratch:DI 2 "=X,X,&r"))
2285    (clobber (match_scratch:DI 3 "=X,X,&r"))]
2286   "TARGET_POWERPC64 && TARGET_LDBRX
2287    && (REG_P (operands[0]) || REG_P (operands[1]))"
2288   "@
2289    ldbrx %0,%y1
2290    stdbrx %1,%y0
2291    #"
2292   [(set_attr "length" "4,4,36")
2293    (set_attr "type" "load,store,*")])
2294
2295 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2296 (define_insn "*bswapdi2_64bit"
2297   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2298         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2299    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2300    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2301   "TARGET_POWERPC64 && !TARGET_LDBRX
2302    && (REG_P (operands[0]) || REG_P (operands[1]))
2303    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2304    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2305   "#"
2306   [(set_attr "length" "16,12,36")])
2307
2308 (define_split
2309   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2310         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2311    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2312    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2313   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2314   [(const_int 0)]
2315   "
2316 {
2317   rtx dest   = operands[0];
2318   rtx src    = operands[1];
2319   rtx op2    = operands[2];
2320   rtx op3    = operands[3];
2321   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2322                                     BYTES_BIG_ENDIAN ? 4 : 0);
2323   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2324                                      BYTES_BIG_ENDIAN ? 4 : 0);
2325   rtx addr1;
2326   rtx addr2;
2327   rtx word1;
2328   rtx word2;
2329
2330   addr1 = XEXP (src, 0);
2331   if (GET_CODE (addr1) == PLUS)
2332     {
2333       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2334       if (TARGET_AVOID_XFORM)
2335         {
2336           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2337           addr2 = op2;
2338         }
2339       else
2340         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2341     }
2342   else if (TARGET_AVOID_XFORM)
2343     {
2344       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2345       addr2 = op2;
2346     }
2347   else
2348     {
2349       emit_move_insn (op2, GEN_INT (4));
2350       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2351     }
2352
2353   word1 = change_address (src, SImode, addr1);
2354   word2 = change_address (src, SImode, addr2);
2355
2356   if (BYTES_BIG_ENDIAN)
2357     {
2358       emit_insn (gen_bswapsi2 (op3_32, word2));
2359       emit_insn (gen_bswapsi2 (dest_32, word1));
2360     }
2361   else
2362     {
2363       emit_insn (gen_bswapsi2 (op3_32, word1));
2364       emit_insn (gen_bswapsi2 (dest_32, word2));
2365     }
2366
2367   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2368   emit_insn (gen_iordi3 (dest, dest, op3));
2369   DONE;
2370 }")
2371
2372 (define_split
2373   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2374         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2375    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2376    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2377   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2378   [(const_int 0)]
2379   "
2380 {
2381   rtx dest   = operands[0];
2382   rtx src    = operands[1];
2383   rtx op2    = operands[2];
2384   rtx op3    = operands[3];
2385   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2386                                     BYTES_BIG_ENDIAN ? 4 : 0);
2387   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2388                                     BYTES_BIG_ENDIAN ? 4 : 0);
2389   rtx addr1;
2390   rtx addr2;
2391   rtx word1;
2392   rtx word2;
2393
2394   addr1 = XEXP (dest, 0);
2395   if (GET_CODE (addr1) == PLUS)
2396     {
2397       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2398       if (TARGET_AVOID_XFORM)
2399         {
2400           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2401           addr2 = op2;
2402         }
2403       else
2404         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2405     }
2406   else if (TARGET_AVOID_XFORM)
2407     {
2408       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2409       addr2 = op2;
2410     }
2411   else
2412     {
2413       emit_move_insn (op2, GEN_INT (4));
2414       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2415     }
2416
2417   word1 = change_address (dest, SImode, addr1);
2418   word2 = change_address (dest, SImode, addr2);
2419
2420   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2421
2422   if (BYTES_BIG_ENDIAN)
2423     {
2424       emit_insn (gen_bswapsi2 (word1, src_si));
2425       emit_insn (gen_bswapsi2 (word2, op3_si));
2426     }
2427   else
2428     {
2429       emit_insn (gen_bswapsi2 (word2, src_si));
2430       emit_insn (gen_bswapsi2 (word1, op3_si));
2431     }
2432   DONE;
2433 }")
2434
2435 (define_split
2436   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2437         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2438    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2439    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2440   "TARGET_POWERPC64 && reload_completed"
2441   [(const_int 0)]
2442   "
2443 {
2444   rtx dest    = operands[0];
2445   rtx src     = operands[1];
2446   rtx op2     = operands[2];
2447   rtx op3     = operands[3];
2448   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2449   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2450   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2451   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2452   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2453
2454   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2455   emit_insn (gen_bswapsi2 (dest_si, src_si));
2456   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2457   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2458   emit_insn (gen_iordi3 (dest, dest, op3));
2459   DONE;
2460 }")
2461
2462 (define_insn "bswapdi2_32bit"
2463   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2464         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2465    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2466   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2467   "#"
2468   [(set_attr "length" "16,12,36")])
2469
2470 (define_split
2471   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2472         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2473    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2474   "!TARGET_POWERPC64 && reload_completed"
2475   [(const_int 0)]
2476   "
2477 {
2478   rtx dest  = operands[0];
2479   rtx src   = operands[1];
2480   rtx op2   = operands[2];
2481   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2482   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2483   rtx addr1;
2484   rtx addr2;
2485   rtx word1;
2486   rtx word2;
2487
2488   addr1 = XEXP (src, 0);
2489   if (GET_CODE (addr1) == PLUS)
2490     {
2491       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2492       if (TARGET_AVOID_XFORM
2493           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2494         {
2495           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2496           addr2 = op2;
2497         }
2498       else
2499         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2500     }
2501   else if (TARGET_AVOID_XFORM
2502            || REGNO (addr1) == REGNO (dest2))
2503     {
2504       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2505       addr2 = op2;
2506     }
2507   else
2508     {
2509       emit_move_insn (op2, GEN_INT (4));
2510       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2511     }
2512
2513   word1 = change_address (src, SImode, addr1);
2514   word2 = change_address (src, SImode, addr2);
2515
2516   emit_insn (gen_bswapsi2 (dest2, word1));
2517   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2518      thus allowing us to omit an early clobber on the output.  */
2519   emit_insn (gen_bswapsi2 (dest1, word2));
2520   DONE;
2521 }")
2522
2523 (define_split
2524   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2525         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2526    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2527   "!TARGET_POWERPC64 && reload_completed"
2528   [(const_int 0)]
2529   "
2530 {
2531   rtx dest = operands[0];
2532   rtx src  = operands[1];
2533   rtx op2  = operands[2];
2534   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2535   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2536   rtx addr1;
2537   rtx addr2;
2538   rtx word1;
2539   rtx word2;
2540
2541   addr1 = XEXP (dest, 0);
2542   if (GET_CODE (addr1) == PLUS)
2543     {
2544       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2545       if (TARGET_AVOID_XFORM)
2546         {
2547           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2548           addr2 = op2;
2549         }
2550       else
2551         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2552     }
2553   else if (TARGET_AVOID_XFORM)
2554     {
2555       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2556       addr2 = op2;
2557     }
2558   else
2559     {
2560       emit_move_insn (op2, GEN_INT (4));
2561       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2562     }
2563
2564   word1 = change_address (dest, SImode, addr1);
2565   word2 = change_address (dest, SImode, addr2);
2566
2567   emit_insn (gen_bswapsi2 (word2, src1));
2568   emit_insn (gen_bswapsi2 (word1, src2));
2569   DONE;
2570 }")
2571
2572 (define_split
2573   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2574         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2575    (clobber (match_operand:SI 2 "" ""))]
2576   "!TARGET_POWERPC64 && reload_completed"
2577   [(const_int 0)]
2578   "
2579 {
2580   rtx dest  = operands[0];
2581   rtx src   = operands[1];
2582   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2583   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2584   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2585   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2586
2587   emit_insn (gen_bswapsi2 (dest1, src2));
2588   emit_insn (gen_bswapsi2 (dest2, src1));
2589   DONE;
2590 }")
2591
2592
2593 (define_insn "mul<mode>3"
2594   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2595         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2596                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2597   ""
2598   "@
2599    mull<wd> %0,%1,%2
2600    mulli %0,%1,%2"
2601    [(set_attr "type" "mul")
2602     (set (attr "size")
2603       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2604                 (const_string "8")
2605              (match_operand:GPR 2 "short_cint_operand" "")
2606                 (const_string "16")]
2607         (const_string "<bits>")))])
2608
2609 (define_insn_and_split "*mul<mode>3_dot"
2610   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2611         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2612                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2613                     (const_int 0)))
2614    (clobber (match_scratch:GPR 0 "=r,r"))]
2615   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2616   "@
2617    mull<wd>. %0,%1,%2
2618    #"
2619   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2620   [(set (match_dup 0)
2621         (mult:GPR (match_dup 1)
2622                   (match_dup 2)))
2623    (set (match_dup 3)
2624         (compare:CC (match_dup 0)
2625                     (const_int 0)))]
2626   ""
2627   [(set_attr "type" "mul")
2628    (set_attr "size" "<bits>")
2629    (set_attr "dot" "yes")
2630    (set_attr "length" "4,8")])
2631
2632 (define_insn_and_split "*mul<mode>3_dot2"
2633   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2634         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2635                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2636                     (const_int 0)))
2637    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2638         (mult:GPR (match_dup 1)
2639                   (match_dup 2)))]
2640   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2641   "@
2642    mull<wd>. %0,%1,%2
2643    #"
2644   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2645   [(set (match_dup 0)
2646         (mult:GPR (match_dup 1)
2647                   (match_dup 2)))
2648    (set (match_dup 3)
2649         (compare:CC (match_dup 0)
2650                     (const_int 0)))]
2651   ""
2652   [(set_attr "type" "mul")
2653    (set_attr "size" "<bits>")
2654    (set_attr "dot" "yes")
2655    (set_attr "length" "4,8")])
2656
2657
2658 (define_expand "<su>mul<mode>3_highpart"
2659   [(set (match_operand:GPR 0 "gpc_reg_operand")
2660         (subreg:GPR
2661           (mult:<DMODE> (any_extend:<DMODE>
2662                           (match_operand:GPR 1 "gpc_reg_operand"))
2663                         (any_extend:<DMODE>
2664                           (match_operand:GPR 2 "gpc_reg_operand")))
2665          0))]
2666   ""
2667 {
2668   if (<MODE>mode == SImode && TARGET_POWERPC64)
2669     {
2670       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2671                                              operands[2]));
2672       DONE;
2673     }
2674
2675   if (!WORDS_BIG_ENDIAN)
2676     {
2677       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2678                                                  operands[2]));
2679       DONE;
2680     }
2681 })
2682
2683 (define_insn "*<su>mul<mode>3_highpart"
2684   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2685         (subreg:GPR
2686           (mult:<DMODE> (any_extend:<DMODE>
2687                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2688                         (any_extend:<DMODE>
2689                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2690          0))]
2691   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2692   "mulh<wd><u> %0,%1,%2"
2693   [(set_attr "type" "mul")
2694    (set_attr "size" "<bits>")])
2695
2696 (define_insn "<su>mulsi3_highpart_le"
2697   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2698         (subreg:SI
2699           (mult:DI (any_extend:DI
2700                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2701                    (any_extend:DI
2702                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2703          4))]
2704   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2705   "mulhw<u> %0,%1,%2"
2706   [(set_attr "type" "mul")])
2707
2708 (define_insn "<su>muldi3_highpart_le"
2709   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2710         (subreg:DI
2711           (mult:TI (any_extend:TI
2712                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2713                    (any_extend:TI
2714                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2715          8))]
2716   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2717   "mulhd<u> %0,%1,%2"
2718   [(set_attr "type" "mul")
2719    (set_attr "size" "64")])
2720
2721 (define_insn "<su>mulsi3_highpart_64"
2722   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2723         (truncate:SI
2724           (lshiftrt:DI
2725             (mult:DI (any_extend:DI
2726                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2727                      (any_extend:DI
2728                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2729             (const_int 32))))]
2730   "TARGET_POWERPC64"
2731   "mulhw<u> %0,%1,%2"
2732   [(set_attr "type" "mul")])
2733
2734 (define_expand "<u>mul<mode><dmode>3"
2735   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2736         (mult:<DMODE> (any_extend:<DMODE>
2737                         (match_operand:GPR 1 "gpc_reg_operand"))
2738                       (any_extend:<DMODE>
2739                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2740   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2741 {
2742   rtx l = gen_reg_rtx (<MODE>mode);
2743   rtx h = gen_reg_rtx (<MODE>mode);
2744   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2745   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2746   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2747   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2748   DONE;
2749 })
2750
2751
2752 (define_insn "udiv<mode>3"
2753   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2754         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2755                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2756   ""
2757   "div<wd>u %0,%1,%2"
2758   [(set_attr "type" "div")
2759    (set_attr "size" "<bits>")])
2760
2761
2762 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2763 ;; modulus.  If it isn't a power of two, force operands into register and do
2764 ;; a normal divide.
2765 (define_expand "div<mode>3"
2766   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2767         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2768                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2769   ""
2770 {
2771   if (CONST_INT_P (operands[2])
2772       && INTVAL (operands[2]) > 0
2773       && exact_log2 (INTVAL (operands[2])) >= 0)
2774     {
2775       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2776       DONE;
2777     }
2778
2779   operands[2] = force_reg (<MODE>mode, operands[2]);
2780 })
2781
2782 (define_insn "*div<mode>3"
2783   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2784         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2785                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2786   ""
2787   "div<wd> %0,%1,%2"
2788   [(set_attr "type" "div")
2789    (set_attr "size" "<bits>")])
2790
2791 (define_insn "div<mode>3_sra"
2792   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2793         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2794                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2795    (clobber (reg:GPR CA_REGNO))]
2796   ""
2797   "sra<wd>i %0,%1,%p2\;addze %0,%0"
2798   [(set_attr "type" "two")
2799    (set_attr "length" "8")])
2800
2801 (define_insn_and_split "*div<mode>3_sra_dot"
2802   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2803         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2804                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2805                     (const_int 0)))
2806    (clobber (match_scratch:GPR 0 "=r,r"))
2807    (clobber (reg:GPR CA_REGNO))]
2808   "<MODE>mode == Pmode"
2809   "@
2810    sra<wd>i %0,%1,%p2\;addze. %0,%0
2811    #"
2812   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2813   [(parallel [(set (match_dup 0)
2814                    (div:GPR (match_dup 1)
2815                             (match_dup 2)))
2816               (clobber (reg:GPR CA_REGNO))])
2817    (set (match_dup 3)
2818         (compare:CC (match_dup 0)
2819                     (const_int 0)))]
2820   ""
2821   [(set_attr "type" "two")
2822    (set_attr "length" "8,12")
2823    (set_attr "cell_micro" "not")])
2824
2825 (define_insn_and_split "*div<mode>3_sra_dot2"
2826   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2827         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2828                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2829                     (const_int 0)))
2830    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2831         (div:GPR (match_dup 1)
2832                  (match_dup 2)))
2833    (clobber (reg:GPR CA_REGNO))]
2834   "<MODE>mode == Pmode"
2835   "@
2836    sra<wd>i %0,%1,%p2\;addze. %0,%0
2837    #"
2838   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2839   [(parallel [(set (match_dup 0)
2840                    (div:GPR (match_dup 1)
2841                             (match_dup 2)))
2842               (clobber (reg:GPR CA_REGNO))])
2843    (set (match_dup 3)
2844         (compare:CC (match_dup 0)
2845                     (const_int 0)))]
2846   ""
2847   [(set_attr "type" "two")
2848    (set_attr "length" "8,12")
2849    (set_attr "cell_micro" "not")])
2850
2851 (define_expand "mod<mode>3"
2852   [(use (match_operand:GPR 0 "gpc_reg_operand" ""))
2853    (use (match_operand:GPR 1 "gpc_reg_operand" ""))
2854    (use (match_operand:GPR 2 "reg_or_cint_operand" ""))]
2855   ""
2856 {
2857   int i;
2858   rtx temp1;
2859   rtx temp2;
2860
2861   if (GET_CODE (operands[2]) != CONST_INT
2862       || INTVAL (operands[2]) <= 0
2863       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
2864     FAIL;
2865
2866   temp1 = gen_reg_rtx (<MODE>mode);
2867   temp2 = gen_reg_rtx (<MODE>mode);
2868
2869   emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
2870   emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
2871   emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
2872   DONE;
2873 })
2874 \f
2875 ;; Logical instructions
2876 ;; The logical instructions are mostly combined by using match_operator,
2877 ;; but the plain AND insns are somewhat different because there is no
2878 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
2879 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
2880
2881 (define_expand "and<mode>3"
2882   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2883         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
2884                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
2885   ""
2886 {
2887   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2888     {
2889       rs6000_split_logical (operands, AND, false, false, false);
2890       DONE;
2891     }
2892
2893   if (logical_const_operand (operands[2], <MODE>mode)
2894       && !any_mask_operand (operands[2], <MODE>mode))
2895     {
2896       if (rs6000_gen_cell_microcode)
2897         {
2898           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
2899           DONE;
2900         }
2901       else
2902         operands[2] = force_reg (<MODE>mode, operands[2]);
2903     }
2904
2905   if ((<MODE>mode == DImode && !and64_2_operand (operands[2], <MODE>mode))
2906       || (<MODE>mode != DImode && !and_operand (operands[2], <MODE>mode)))
2907     operands[2] = force_reg (<MODE>mode, operands[2]);
2908 })
2909
2910
2911 (define_insn "and<mode>3_imm"
2912   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2913         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
2914                  (match_operand:GPR 2 "logical_const_operand" "n")))
2915    (clobber (match_scratch:CC 3 "=x"))]
2916   "rs6000_gen_cell_microcode
2917    && !any_mask_operand (operands[2], <MODE>mode)"
2918   "andi%e2. %0,%1,%u2"
2919   [(set_attr "type" "logical")
2920    (set_attr "dot" "yes")])
2921
2922 (define_insn_and_split "*and<mode>3_imm_dot"
2923   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2924         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2925                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
2926                     (const_int 0)))
2927    (clobber (match_scratch:GPR 0 "=r,r"))
2928    (clobber (match_scratch:CC 4 "=X,x"))]
2929   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2930    && rs6000_gen_cell_microcode
2931    && !any_mask_operand (operands[2], <MODE>mode)"
2932   "@
2933    andi%e2. %0,%1,%u2
2934    #"
2935   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2936   [(parallel [(set (match_dup 0)
2937                    (and:GPR (match_dup 1)
2938                             (match_dup 2)))
2939               (clobber (match_dup 4))])
2940    (set (match_dup 3)
2941         (compare:CC (match_dup 0)
2942                     (const_int 0)))]
2943   ""
2944   [(set_attr "type" "logical")
2945    (set_attr "dot" "yes")
2946    (set_attr "length" "4,8")])
2947
2948 (define_insn_and_split "*and<mode>3_imm_dot2"
2949   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2950         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2951                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
2952                     (const_int 0)))
2953    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2954         (and:GPR (match_dup 1)
2955                  (match_dup 2)))
2956    (clobber (match_scratch:CC 4 "=X,x"))]
2957   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2958    && rs6000_gen_cell_microcode
2959    && !any_mask_operand (operands[2], <MODE>mode)"
2960   "@
2961    andi%e2. %0,%1,%u2
2962    #"
2963   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2964   [(parallel [(set (match_dup 0)
2965                    (and:GPR (match_dup 1)
2966                             (match_dup 2)))
2967               (clobber (match_dup 4))])
2968    (set (match_dup 3)
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")])
2975
2976 (define_insn_and_split "*and<mode>3_imm_mask_dot"
2977   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2978         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2979                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
2980                     (const_int 0)))
2981    (clobber (match_scratch:GPR 0 "=r,r"))]
2982   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2983    && rs6000_gen_cell_microcode
2984    && any_mask_operand (operands[2], <MODE>mode)"
2985   "@
2986    andi%e2. %0,%1,%u2
2987    #"
2988   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2989   [(set (match_dup 0)
2990         (and:GPR (match_dup 1)
2991                  (match_dup 2)))
2992    (set (match_dup 3)
2993         (compare:CC (match_dup 0)
2994                     (const_int 0)))]
2995   ""
2996   [(set_attr "type" "logical")
2997    (set_attr "dot" "yes")
2998    (set_attr "length" "4,8")])
2999
3000 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3001   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3002         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3003                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3004                     (const_int 0)))
3005    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3006         (and:GPR (match_dup 1)
3007                  (match_dup 2)))]
3008   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3009    && rs6000_gen_cell_microcode
3010    && any_mask_operand (operands[2], <MODE>mode)"
3011   "@
3012    andi%e2. %0,%1,%u2
3013    #"
3014   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3015   [(set (match_dup 0)
3016         (and:GPR (match_dup 1)
3017                  (match_dup 2)))
3018    (set (match_dup 3)
3019         (compare:CC (match_dup 0)
3020                     (const_int 0)))]
3021   ""
3022   [(set_attr "type" "logical")
3023    (set_attr "dot" "yes")
3024    (set_attr "length" "4,8")])
3025
3026
3027 (define_insn "*and<mode>3_mask"
3028   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3029         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3030                  (match_operand:GPR 2 "any_mask_operand" "S,T")))]
3031   ""
3032   "@
3033    rldic%B2 %0,%1,0,%S2
3034    rlwinm %0,%1,0,%m2,%M2"
3035   [(set_attr "type" "shift")])
3036
3037 (define_insn_and_split "*and<mode>3_mask_dot"
3038   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
3039         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")
3040                              (match_operand:GPR 2 "any_mask_operand" "S,T,S,T"))
3041                     (const_int 0)))
3042    (clobber (match_scratch:GPR 0 "=r,r,r,r"))]
3043   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3044    && rs6000_gen_cell_microcode
3045    && !logical_const_operand (operands[2], <MODE>mode)"
3046   "@
3047    rldic%B2. %0,%1,0,%S2
3048    rlwinm. %0,%1,0,%m2,%M2
3049    #
3050    #"
3051   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3052   [(set (match_dup 0)
3053         (and:GPR (match_dup 1)
3054                  (match_dup 2)))
3055    (set (match_dup 3)
3056         (compare:CC (match_dup 0)
3057                     (const_int 0)))]
3058   ""
3059   [(set_attr "type" "shift")
3060    (set_attr "dot" "yes")
3061    (set_attr "length" "4,4,8,8")])
3062
3063 (define_insn_and_split "*and<mode>3_mask_dot2"
3064   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
3065         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")
3066                              (match_operand:GPR 2 "any_mask_operand" "S,T,S,T"))
3067                     (const_int 0)))
3068    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
3069         (and:GPR (match_dup 1)
3070                  (match_dup 2)))]
3071   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3072    && rs6000_gen_cell_microcode
3073    && !logical_const_operand (operands[2], <MODE>mode)"
3074   "@
3075    rldic%B2. %0,%1,0,%S2
3076    rlwinm. %0,%1,0,%m2,%M2
3077    #
3078    #"
3079   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3080   [(set (match_dup 0)
3081         (and:GPR (match_dup 1)
3082                  (match_dup 2)))
3083    (set (match_dup 3)
3084         (compare:CC (match_dup 0)
3085                     (const_int 0)))]
3086   ""
3087   [(set_attr "type" "shift")
3088    (set_attr "dot" "yes")
3089    (set_attr "length" "4,4,8,8")])
3090
3091
3092
3093 (define_insn "andsi3_internal0_nomc"
3094   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3095         (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
3096                 (match_operand:SI 2 "and_operand" "?r,T")))]
3097   "!rs6000_gen_cell_microcode"
3098   "@
3099    and %0,%1,%2
3100    rlwinm %0,%1,0,%m2,%M2"
3101   [(set_attr "type" "logical,shift")])
3102
3103
3104 ;; Handle the PowerPC64 rlwinm corner case
3105
3106 (define_insn_and_split "*andsi3_internal6"
3107   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3108         (and:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3109                 (match_operand:SI 2 "mask_operand_wrap" "i")))]
3110   "TARGET_POWERPC64"
3111   "#"
3112   "TARGET_POWERPC64"
3113   [(set (match_dup 0)
3114         (and:SI (rotate:SI (match_dup 1) (match_dup 3))
3115                 (match_dup 4)))
3116    (set (match_dup 0)
3117         (rotate:SI (match_dup 0) (match_dup 5)))]
3118   "
3119 {
3120   int mb = extract_MB (operands[2]);
3121   int me = extract_ME (operands[2]);
3122   operands[3] = GEN_INT (me + 1);
3123   operands[5] = GEN_INT (32 - (me + 1));
3124   operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
3125 }"
3126   [(set_attr "length" "8")])
3127
3128
3129 (define_expand "<code><mode>3"
3130   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3131         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3132                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3133   ""
3134 {
3135   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3136     {
3137       rs6000_split_logical (operands, <CODE>, false, false, false);
3138       DONE;
3139     }
3140
3141   if (non_logical_cint_operand (operands[2], <MODE>mode))
3142     {
3143       rtx tmp = ((!can_create_pseudo_p ()
3144                   || rtx_equal_p (operands[0], operands[1]))
3145                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3146
3147       HOST_WIDE_INT value = INTVAL (operands[2]);
3148       HOST_WIDE_INT lo = value & 0xffff;
3149       HOST_WIDE_INT hi = value - lo;
3150
3151       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3152       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3153       DONE;
3154     }
3155
3156   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3157     operands[2] = force_reg (<MODE>mode, operands[2]);
3158 })
3159
3160 (define_split
3161   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3162         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3163                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3164   ""
3165   [(set (match_dup 3)
3166         (iorxor:GPR (match_dup 1)
3167                     (match_dup 4)))
3168    (set (match_dup 0)
3169         (iorxor:GPR (match_dup 3)
3170                     (match_dup 5)))]
3171 {
3172   operands[3] = ((!can_create_pseudo_p ()
3173                   || rtx_equal_p (operands[0], operands[1]))
3174                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3175
3176   HOST_WIDE_INT value = INTVAL (operands[2]);
3177   HOST_WIDE_INT lo = value & 0xffff;
3178   HOST_WIDE_INT hi = value - lo;
3179
3180   operands[4] = GEN_INT (hi);
3181   operands[5] = GEN_INT (lo);
3182 })
3183
3184 (define_insn "*bool<mode>3_imm"
3185   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3186         (match_operator:GPR 3 "boolean_or_operator"
3187          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3188           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3189   ""
3190   "%q3i%e2 %0,%1,%u2"
3191   [(set_attr "type" "logical")])
3192
3193 (define_insn "*bool<mode>3"
3194   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3195         (match_operator:GPR 3 "boolean_operator"
3196          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3197           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3198   ""
3199   "%q3 %0,%1,%2"
3200   [(set_attr "type" "logical")])
3201
3202 (define_insn_and_split "*bool<mode>3_dot"
3203   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3204         (compare:CC (match_operator:GPR 3 "boolean_operator"
3205          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3206           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3207          (const_int 0)))
3208    (clobber (match_scratch:GPR 0 "=r,r"))]
3209   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3210   "@
3211    %q3. %0,%1,%2
3212    #"
3213   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3214   [(set (match_dup 0)
3215         (match_dup 3))
3216    (set (match_dup 4)
3217         (compare:CC (match_dup 0)
3218                     (const_int 0)))]
3219   ""
3220   [(set_attr "type" "logical")
3221    (set_attr "dot" "yes")
3222    (set_attr "length" "4,8")])
3223
3224 (define_insn_and_split "*bool<mode>3_dot2"
3225   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3226         (compare:CC (match_operator:GPR 3 "boolean_operator"
3227          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3228           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3229          (const_int 0)))
3230    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3231         (match_dup 3))]
3232   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3233   "@
3234    %q3. %0,%1,%2
3235    #"
3236   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3237   [(set (match_dup 0)
3238         (match_dup 3))
3239    (set (match_dup 4)
3240         (compare:CC (match_dup 0)
3241                     (const_int 0)))]
3242   ""
3243   [(set_attr "type" "logical")
3244    (set_attr "dot" "yes")
3245    (set_attr "length" "4,8")])
3246
3247
3248 (define_insn "*boolc<mode>3"
3249   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3250         (match_operator:GPR 3 "boolean_operator"
3251          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3252           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3253   ""
3254   "%q3 %0,%1,%2"
3255   [(set_attr "type" "logical")])
3256
3257 (define_insn_and_split "*boolc<mode>3_dot"
3258   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3259         (compare:CC (match_operator:GPR 3 "boolean_operator"
3260          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3261           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3262          (const_int 0)))
3263    (clobber (match_scratch:GPR 0 "=r,r"))]
3264   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3265   "@
3266    %q3. %0,%1,%2
3267    #"
3268   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3269   [(set (match_dup 0)
3270         (match_dup 3))
3271    (set (match_dup 4)
3272         (compare:CC (match_dup 0)
3273                     (const_int 0)))]
3274   ""
3275   [(set_attr "type" "logical")
3276    (set_attr "dot" "yes")
3277    (set_attr "length" "4,8")])
3278
3279 (define_insn_and_split "*boolc<mode>3_dot2"
3280   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3281         (compare:CC (match_operator:GPR 3 "boolean_operator"
3282          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3283           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3284          (const_int 0)))
3285    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3286         (match_dup 3))]
3287   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3288   "@
3289    %q3. %0,%1,%2
3290    #"
3291   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3292   [(set (match_dup 0)
3293         (match_dup 3))
3294    (set (match_dup 4)
3295         (compare:CC (match_dup 0)
3296                     (const_int 0)))]
3297   ""
3298   [(set_attr "type" "logical")
3299    (set_attr "dot" "yes")
3300    (set_attr "length" "4,8")])
3301
3302
3303 (define_insn "*boolcc<mode>3"
3304   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3305         (match_operator:GPR 3 "boolean_operator"
3306          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3307           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3308   ""
3309   "%q3 %0,%1,%2"
3310   [(set_attr "type" "logical")])
3311
3312 (define_insn_and_split "*boolcc<mode>3_dot"
3313   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3314         (compare:CC (match_operator:GPR 3 "boolean_operator"
3315          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3316           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3317          (const_int 0)))
3318    (clobber (match_scratch:GPR 0 "=r,r"))]
3319   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3320   "@
3321    %q3. %0,%1,%2
3322    #"
3323   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3324   [(set (match_dup 0)
3325         (match_dup 3))
3326    (set (match_dup 4)
3327         (compare:CC (match_dup 0)
3328                     (const_int 0)))]
3329   ""
3330   [(set_attr "type" "logical")
3331    (set_attr "dot" "yes")
3332    (set_attr "length" "4,8")])
3333
3334 (define_insn_and_split "*boolcc<mode>3_dot2"
3335   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3336         (compare:CC (match_operator:GPR 3 "boolean_operator"
3337          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3338           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3339          (const_int 0)))
3340    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3341         (match_dup 3))]
3342   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3343   "@
3344    %q3. %0,%1,%2
3345    #"
3346   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3347   [(set (match_dup 0)
3348         (match_dup 3))
3349    (set (match_dup 4)
3350         (compare:CC (match_dup 0)
3351                     (const_int 0)))]
3352   ""
3353   [(set_attr "type" "logical")
3354    (set_attr "dot" "yes")
3355    (set_attr "length" "4,8")])
3356
3357
3358 ;; TODO: Should have dots of this as well.
3359 (define_insn "*eqv<mode>3"
3360   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3361         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3362                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3363   ""
3364   "eqv %0,%1,%2"
3365   [(set_attr "type" "logical")])
3366 \f
3367 ;; Rotate and shift insns, in all their variants.  These support shifts,
3368 ;; field inserts and extracts, and various combinations thereof.
3369 (define_expand "insv"
3370   [(set (zero_extract (match_operand 0 "gpc_reg_operand" "")
3371                        (match_operand:SI 1 "const_int_operand" "")
3372                        (match_operand:SI 2 "const_int_operand" ""))
3373         (match_operand 3 "gpc_reg_operand" ""))]
3374   ""
3375   "
3376 {
3377   /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
3378      the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
3379      compiler if the address of the structure is taken later.  Likewise, do
3380      not handle invalid E500 subregs.  */
3381   if (GET_CODE (operands[0]) == SUBREG
3382       && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD
3383           || ((TARGET_E500_DOUBLE || TARGET_SPE)
3384               && invalid_e500_subreg (operands[0], GET_MODE (operands[0])))))
3385     FAIL;
3386
3387   if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode)
3388     emit_insn (gen_insvdi_internal (operands[0], operands[1], operands[2],
3389                                     operands[3]));
3390   else
3391     emit_insn (gen_insvsi_internal (operands[0], operands[1], operands[2],
3392                                     operands[3]));
3393   DONE;
3394 }")
3395
3396 (define_insn "insvsi_internal"
3397   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3398                          (match_operand:SI 1 "const_int_operand" "i")
3399                          (match_operand:SI 2 "const_int_operand" "i"))
3400         (match_operand:SI 3 "gpc_reg_operand" "r"))]
3401   ""
3402   "*
3403 {
3404   int start = INTVAL (operands[2]) & 31;
3405   int size = INTVAL (operands[1]) & 31;
3406
3407   operands[4] = GEN_INT (32 - start - size);
3408   operands[1] = GEN_INT (start + size - 1);
3409   return \"rlwimi %0,%3,%h4,%h2,%h1\";
3410 }"
3411   [(set_attr "type" "insert")])
3412
3413 (define_insn "*insvsi_internal1"
3414   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3415                          (match_operand:SI 1 "const_int_operand" "i")
3416                          (match_operand:SI 2 "const_int_operand" "i"))
3417         (rotate:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3418                    (match_operand:SI 4 "const_int_operand" "i")))]
3419   "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3420   "*
3421 {
3422   int shift = INTVAL (operands[4]) & 31;
3423   int start = INTVAL (operands[2]) & 31;
3424   int size = INTVAL (operands[1]) & 31;
3425
3426   operands[4] = GEN_INT (shift - start - size);
3427   operands[1] = GEN_INT (start + size - 1);
3428   return \"rlwimi %0,%3,%h4,%h2,%h1\";
3429 }"
3430   [(set_attr "type" "insert")])
3431
3432 (define_insn "*insvsi_internal2"
3433   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3434                          (match_operand:SI 1 "const_int_operand" "i")
3435                          (match_operand:SI 2 "const_int_operand" "i"))
3436         (ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3437                      (match_operand:SI 4 "const_int_operand" "i")))]
3438   "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3439   "*
3440 {
3441   int shift = INTVAL (operands[4]) & 31;
3442   int start = INTVAL (operands[2]) & 31;
3443   int size = INTVAL (operands[1]) & 31;
3444
3445   operands[4] = GEN_INT (32 - shift - start - size);
3446   operands[1] = GEN_INT (start + size - 1);
3447   return \"rlwimi %0,%3,%h4,%h2,%h1\";
3448 }"
3449   [(set_attr "type" "insert")])
3450
3451 (define_insn "*insvsi_internal3"
3452   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3453                          (match_operand:SI 1 "const_int_operand" "i")
3454                          (match_operand:SI 2 "const_int_operand" "i"))
3455         (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3456                      (match_operand:SI 4 "const_int_operand" "i")))]
3457   "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3458   "*
3459 {
3460   int shift = INTVAL (operands[4]) & 31;
3461   int start = INTVAL (operands[2]) & 31;
3462   int size = INTVAL (operands[1]) & 31;
3463
3464   operands[4] = GEN_INT (32 - shift - start - size);
3465   operands[1] = GEN_INT (start + size - 1);
3466   return \"rlwimi %0,%3,%h4,%h2,%h1\";
3467 }"
3468   [(set_attr "type" "insert")])
3469
3470 (define_insn "*insvsi_internal4"
3471   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3472                          (match_operand:SI 1 "const_int_operand" "i")
3473                          (match_operand:SI 2 "const_int_operand" "i"))
3474         (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3475                          (match_operand:SI 4 "const_int_operand" "i")
3476                          (match_operand:SI 5 "const_int_operand" "i")))]
3477   "INTVAL (operands[4]) >= INTVAL (operands[1])"
3478   "*
3479 {
3480   int extract_start = INTVAL (operands[5]) & 31;
3481   int extract_size = INTVAL (operands[4]) & 31;
3482   int insert_start = INTVAL (operands[2]) & 31;
3483   int insert_size = INTVAL (operands[1]) & 31;
3484
3485 /* Align extract field with insert field */
3486   operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size);
3487   operands[1] = GEN_INT (insert_start + insert_size - 1);
3488   return \"rlwimi %0,%3,%h5,%h2,%h1\";
3489 }"
3490   [(set_attr "type" "insert")])
3491
3492 ;; combine patterns for rlwimi
3493 (define_insn "*insvsi_internal5"
3494   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3495         (ior:SI (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
3496                         (match_operand:SI 1 "mask_operand" "i"))
3497                 (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3498                                      (match_operand:SI 2 "const_int_operand" "i"))
3499                         (match_operand:SI 5 "mask_operand" "i"))))]
3500   "INTVAL(operands[1]) == ~INTVAL(operands[5])"
3501   "*
3502 {
3503  int me = extract_ME(operands[5]);
3504  int mb = extract_MB(operands[5]);
3505  operands[4] = GEN_INT(32 - INTVAL(operands[2]));
3506  operands[2] = GEN_INT(mb);
3507  operands[1] = GEN_INT(me);
3508  return \"rlwimi %0,%3,%h4,%h2,%h1\";
3509 }"
3510   [(set_attr "type" "insert")])
3511
3512 (define_insn "*insvsi_internal6"
3513   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3514         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3515                                      (match_operand:SI 2 "const_int_operand" "i"))
3516                         (match_operand:SI 5 "mask_operand" "i"))
3517                 (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
3518                         (match_operand:SI 1 "mask_operand" "i"))))]
3519   "INTVAL(operands[1]) == ~INTVAL(operands[5])"
3520   "*
3521 {
3522  int me = extract_ME(operands[5]);
3523  int mb = extract_MB(operands[5]);
3524  operands[4] = GEN_INT(32 - INTVAL(operands[2]));
3525  operands[2] = GEN_INT(mb);
3526  operands[1] = GEN_INT(me);
3527  return \"rlwimi %0,%3,%h4,%h2,%h1\";
3528 }"
3529   [(set_attr "type" "insert")])
3530
3531 (define_insn "insvdi_internal"
3532   [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3533                          (match_operand:SI 1 "const_int_operand" "i")
3534                          (match_operand:SI 2 "const_int_operand" "i"))
3535         (match_operand:DI 3 "gpc_reg_operand" "r"))]
3536   "TARGET_POWERPC64"
3537   "*
3538 {
3539   int start = INTVAL (operands[2]) & 63;
3540   int size = INTVAL (operands[1]) & 63;
3541
3542   operands[1] = GEN_INT (64 - start - size);
3543   return \"rldimi %0,%3,%H1,%H2\";
3544 }"
3545   [(set_attr "type" "insert")
3546    (set_attr "size" "64")])
3547
3548 (define_insn "*insvdi_internal2"
3549   [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3550                          (match_operand:SI 1 "const_int_operand" "i")
3551                          (match_operand:SI 2 "const_int_operand" "i"))
3552         (ashiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3553                      (match_operand:SI 4 "const_int_operand" "i")))]
3554   "TARGET_POWERPC64
3555    && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
3556   "*
3557 {
3558   int shift = INTVAL (operands[4]) & 63;
3559   int start = (INTVAL (operands[2]) & 63) - 32;
3560   int size = INTVAL (operands[1]) & 63;
3561
3562   operands[4] = GEN_INT (64 - shift - start - size);
3563   operands[2] = GEN_INT (start);
3564   operands[1] = GEN_INT (start + size - 1);
3565   return \"rlwimi %0,%3,%h4,%h2,%h1\";
3566 }")
3567
3568 (define_insn "*insvdi_internal3"
3569   [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3570                          (match_operand:SI 1 "const_int_operand" "i")
3571                          (match_operand:SI 2 "const_int_operand" "i"))
3572         (lshiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3573                      (match_operand:SI 4 "const_int_operand" "i")))]
3574   "TARGET_POWERPC64
3575    && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
3576   "*
3577 {
3578   int shift = INTVAL (operands[4]) & 63;
3579   int start = (INTVAL (operands[2]) & 63) - 32;
3580   int size = INTVAL (operands[1]) & 63;
3581
3582   operands[4] = GEN_INT (64 - shift - start - size);
3583   operands[2] = GEN_INT (start);
3584   operands[1] = GEN_INT (start + size - 1);
3585   return \"rlwimi %0,%3,%h4,%h2,%h1\";
3586 }")
3587
3588 (define_expand "extzv"
3589   [(set (match_operand 0 "gpc_reg_operand" "")
3590         (zero_extract (match_operand 1 "gpc_reg_operand" "")
3591                        (match_operand:SI 2 "const_int_operand" "")
3592                        (match_operand:SI 3 "const_int_operand" "")))]
3593   ""
3594   "
3595 {
3596   /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
3597      the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
3598      compiler if the address of the structure is taken later.  */
3599   if (GET_CODE (operands[0]) == SUBREG
3600       && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
3601     FAIL;
3602
3603   if (TARGET_POWERPC64 && GET_MODE (operands[1]) == DImode)
3604     emit_insn (gen_extzvdi_internal (operands[0], operands[1], operands[2],
3605                                      operands[3]));
3606   else
3607     FAIL;
3608
3609   DONE;
3610 }")
3611
3612 (define_insn "extzvdi_internal"
3613   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3614         (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3615                          (match_operand:SI 2 "const_int_operand" "i")
3616                          (match_operand:SI 3 "const_int_operand" "i")))]
3617   "TARGET_POWERPC64"
3618   "*
3619 {
3620   int start = INTVAL (operands[3]) & 63;
3621   int size = INTVAL (operands[2]) & 63;
3622
3623   if (start + size >= 64)
3624     operands[3] = const0_rtx;
3625   else
3626     operands[3] = GEN_INT (start + size);
3627   operands[2] = GEN_INT (64 - size);
3628   return \"rldicl %0,%1,%3,%2\";
3629 }"
3630   [(set_attr "type" "shift")])
3631
3632 (define_insn "*extzvdi_internal1"
3633   [(set (match_operand:CC 0 "gpc_reg_operand" "=x")
3634         (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3635                          (match_operand:SI 2 "const_int_operand" "i")
3636                          (match_operand:SI 3 "const_int_operand" "i"))
3637                     (const_int 0)))
3638    (clobber (match_scratch:DI 4 "=r"))]
3639   "TARGET_64BIT && rs6000_gen_cell_microcode"
3640   "*
3641 {
3642   int start = INTVAL (operands[3]) & 63;
3643   int size = INTVAL (operands[2]) & 63;
3644
3645   if (start + size >= 64)
3646     operands[3] = const0_rtx;
3647   else
3648     operands[3] = GEN_INT (start + size);
3649   operands[2] = GEN_INT (64 - size);
3650   return \"rldicl. %4,%1,%3,%2\";
3651 }"
3652   [(set_attr "type" "shift")
3653    (set_attr "dot" "yes")])
3654
3655 (define_insn "*extzvdi_internal2"
3656   [(set (match_operand:CC 4 "gpc_reg_operand" "=x")
3657         (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3658                          (match_operand:SI 2 "const_int_operand" "i")
3659                          (match_operand:SI 3 "const_int_operand" "i"))
3660                     (const_int 0)))
3661    (set (match_operand:DI 0 "gpc_reg_operand" "=r")
3662         (zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
3663   "TARGET_64BIT && rs6000_gen_cell_microcode"
3664   "*
3665 {
3666   int start = INTVAL (operands[3]) & 63;
3667   int size = INTVAL (operands[2]) & 63;
3668
3669   if (start + size >= 64)
3670     operands[3] = const0_rtx;
3671   else
3672     operands[3] = GEN_INT (start + size);
3673   operands[2] = GEN_INT (64 - size);
3674   return \"rldicl. %0,%1,%3,%2\";
3675 }"
3676   [(set_attr "type" "shift")
3677    (set_attr "dot" "yes")])
3678
3679
3680 (define_insn "rotl<mode>3"
3681   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3682         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3683                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3684   ""
3685   "rotl<wd>%I2 %0,%1,%<hH>2"
3686   [(set_attr "type" "shift")
3687    (set_attr "maybe_var_shift" "yes")])
3688
3689 (define_insn "*rotlsi3_64"
3690   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3691         (zero_extend:DI
3692             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3693                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3694   "TARGET_POWERPC64"
3695   "rotlw%I2 %0,%1,%h2"
3696   [(set_attr "type" "shift")
3697    (set_attr "maybe_var_shift" "yes")])
3698
3699 (define_insn_and_split "*rotl<mode>3_dot"
3700   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3701         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3702                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3703                     (const_int 0)))
3704    (clobber (match_scratch:GPR 0 "=r,r"))]
3705   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3706   "@
3707    rotl<wd>%I2. %0,%1,%<hH>2
3708    #"
3709   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3710   [(set (match_dup 0)
3711         (rotate:GPR (match_dup 1)
3712                     (match_dup 2)))
3713    (set (match_dup 3)
3714         (compare:CC (match_dup 0)
3715                     (const_int 0)))]
3716   ""
3717   [(set_attr "type" "shift")
3718    (set_attr "maybe_var_shift" "yes")
3719    (set_attr "dot" "yes")
3720    (set_attr "length" "4,8")])
3721
3722 (define_insn_and_split "*rotl<mode>3_dot2"
3723   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3724         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3725                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3726                     (const_int 0)))
3727    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3728         (rotate:GPR (match_dup 1)
3729                     (match_dup 2)))]
3730   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3731   "@
3732    rotl<wd>%I2. %0,%1,%<hH>2
3733    #"
3734   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3735   [(set (match_dup 0)
3736         (rotate:GPR (match_dup 1)
3737                     (match_dup 2)))
3738    (set (match_dup 3)
3739         (compare:CC (match_dup 0)
3740                     (const_int 0)))]
3741   ""
3742   [(set_attr "type" "shift")
3743    (set_attr "maybe_var_shift" "yes")
3744    (set_attr "dot" "yes")
3745    (set_attr "length" "4,8")])
3746
3747
3748 (define_insn "*rotlsi3_mask"
3749   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3750         (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3751                            (match_operand:SI 2 "reg_or_cint_operand" "rn"))
3752                 (match_operand:SI 3 "mask_operand" "n")))]
3753   ""
3754   "rlw%I2nm %0,%1,%h2,%m3,%M3"
3755   [(set_attr "type" "shift")
3756    (set_attr "maybe_var_shift" "yes")])
3757
3758 (define_insn_and_split "*rotlsi3_mask_dot"
3759   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3760         (compare:CC
3761          (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3762                             (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3763                  (match_operand:SI 3 "mask_operand" "n,n"))
3764          (const_int 0)))
3765    (clobber (match_scratch:SI 0 "=r,r"))]
3766   "rs6000_gen_cell_microcode
3767    && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)"
3768   "@
3769    rlw%I2nm. %0,%1,%h2,%m3,%M3
3770    #"
3771   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3772   [(set (match_dup 0)
3773         (and:SI (rotate:SI (match_dup 1)
3774                            (match_dup 2))
3775                 (match_dup 3)))
3776    (set (match_dup 4)
3777         (compare:CC (match_dup 0)
3778                     (const_int 0)))]
3779   ""
3780   [(set_attr "type" "shift")
3781    (set_attr "maybe_var_shift" "yes")
3782    (set_attr "dot" "yes")
3783    (set_attr "length" "4,8")])
3784
3785 (define_insn_and_split "*rotlsi3_mask_dot2"
3786   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3787         (compare:CC
3788          (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3789                             (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3790                  (match_operand:SI 3 "mask_operand" "n,n"))
3791          (const_int 0)))
3792    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3793         (and:SI (rotate:SI (match_dup 1)
3794                            (match_dup 2))
3795                 (match_dup 3)))]
3796   "rs6000_gen_cell_microcode
3797    && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)"
3798   "@
3799    rlw%I2nm. %0,%1,%h2,%m3,%M3
3800    #"
3801   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3802   [(set (match_dup 0)
3803         (and:SI (rotate:SI (match_dup 1)
3804                            (match_dup 2))
3805                 (match_dup 3)))
3806    (set (match_dup 4)
3807         (compare:CC (match_dup 0)
3808                     (const_int 0)))]
3809   ""
3810   [(set_attr "type" "shift")
3811    (set_attr "maybe_var_shift" "yes")
3812    (set_attr "dot" "yes")
3813    (set_attr "length" "4,8")])
3814
3815
3816 (define_insn "ashl<mode>3"
3817   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3818         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3819                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3820   ""
3821   "sl<wd>%I2 %0,%1,%<hH>2"
3822   [(set_attr "type" "shift")
3823    (set_attr "maybe_var_shift" "yes")])
3824
3825 (define_insn "*ashlsi3_64"
3826   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3827         (zero_extend:DI
3828             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3829                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3830   "TARGET_POWERPC64"
3831   "slw%I2 %0,%1,%h2"
3832   [(set_attr "type" "shift")
3833    (set_attr "maybe_var_shift" "yes")])
3834
3835 (define_insn_and_split "*ashl<mode>3_dot"
3836   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3837         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3838                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3839                     (const_int 0)))
3840    (clobber (match_scratch:GPR 0 "=r,r"))]
3841   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3842   "@
3843    sl<wd>%I2. %0,%1,%<hH>2
3844    #"
3845   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3846   [(set (match_dup 0)
3847         (ashift:GPR (match_dup 1)
3848                     (match_dup 2)))
3849    (set (match_dup 3)
3850         (compare:CC (match_dup 0)
3851                     (const_int 0)))]
3852   ""
3853   [(set_attr "type" "shift")
3854    (set_attr "maybe_var_shift" "yes")
3855    (set_attr "dot" "yes")
3856    (set_attr "length" "4,8")])
3857
3858 (define_insn_and_split "*ashl<mode>3_dot2"
3859   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3860         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3861                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3862                     (const_int 0)))
3863    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3864         (ashift:GPR (match_dup 1)
3865                     (match_dup 2)))]
3866   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3867   "@
3868    sl<wd>%I2. %0,%1,%<hH>2
3869    #"
3870   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3871   [(set (match_dup 0)
3872         (ashift:GPR (match_dup 1)
3873                     (match_dup 2)))
3874    (set (match_dup 3)
3875         (compare:CC (match_dup 0)
3876                     (const_int 0)))]
3877   ""
3878   [(set_attr "type" "shift")
3879    (set_attr "maybe_var_shift" "yes")
3880    (set_attr "dot" "yes")
3881    (set_attr "length" "4,8")])
3882
3883
3884 (define_insn "*ashlsi3_imm_mask"
3885   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3886         (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3887                            (match_operand:SI 2 "const_int_operand" "i"))
3888                 (match_operand:SI 3 "mask_operand" "n")))]
3889   "includes_lshift_p (operands[2], operands[3])"
3890   "rlwinm %0,%1,%h2,%m3,%M3"
3891   [(set_attr "type" "shift")])
3892
3893 (define_insn_and_split "*ashlsi3_imm_mask_dot"
3894   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3895         (compare:CC
3896          (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3897                             (match_operand:SI 2 "const_int_operand" "i,i"))
3898                  (match_operand:SI 3 "mask_operand" "n,n"))
3899          (const_int 0)))
3900    (clobber (match_scratch:SI 0 "=r,r"))]
3901   "rs6000_gen_cell_microcode
3902    && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)
3903    && includes_lshift_p (operands[2], operands[3])"
3904   "@
3905    rlwinm. %0,%1,%h2,%m3,%M3
3906    #"
3907   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3908   [(set (match_dup 0)
3909         (and:SI (ashift:SI (match_dup 1)
3910                            (match_dup 2))
3911                 (match_dup 3)))
3912    (set (match_dup 4)
3913         (compare:CC (match_dup 0)
3914                     (const_int 0)))]
3915   ""
3916   [(set_attr "type" "shift")
3917    (set_attr "dot" "yes")
3918    (set_attr "length" "4,8")])
3919
3920 (define_insn_and_split "*ashlsi3_imm_mask_dot2"
3921   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3922         (compare:CC
3923          (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3924                             (match_operand:SI 2 "const_int_operand" "i,i"))
3925                  (match_operand:SI 3 "mask_operand" "n,n"))
3926          (const_int 0)))
3927    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3928         (and:SI (ashift:SI (match_dup 1)
3929                            (match_dup 2))
3930                 (match_dup 3)))]
3931   "rs6000_gen_cell_microcode
3932    && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)
3933    && includes_lshift_p (operands[2], operands[3])"
3934   "@
3935    rlwinm. %0,%1,%h2,%m3,%M3
3936    #"
3937   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3938   [(set (match_dup 0)
3939         (and:SI (ashift:SI (match_dup 1)
3940                            (match_dup 2))
3941                 (match_dup 3)))
3942    (set (match_dup 4)
3943         (compare:CC (match_dup 0)
3944                     (const_int 0)))]
3945   ""
3946   [(set_attr "type" "shift")
3947    (set_attr "dot" "yes")
3948    (set_attr "length" "4,8")])
3949
3950
3951 (define_insn "lshr<mode>3"
3952   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3953         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3954                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3955   ""
3956   "sr<wd>%I2 %0,%1,%<hH>2"
3957   [(set_attr "type" "shift")
3958    (set_attr "maybe_var_shift" "yes")])
3959
3960 (define_insn "*lshrsi3_64"
3961   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3962         (zero_extend:DI
3963             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3964                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3965   "TARGET_POWERPC64"
3966   "srw%I2 %0,%1,%h2"
3967   [(set_attr "type" "shift")
3968    (set_attr "maybe_var_shift" "yes")])
3969
3970 (define_insn_and_split "*lshr<mode>3_dot"
3971   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3972         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3973                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3974                     (const_int 0)))
3975    (clobber (match_scratch:GPR 0 "=r,r"))]
3976   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3977   "@
3978    sr<wd>%I2. %0,%1,%<hH>2
3979    #"
3980   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3981   [(set (match_dup 0)
3982         (lshiftrt:GPR (match_dup 1)
3983                       (match_dup 2)))
3984    (set (match_dup 3)
3985         (compare:CC (match_dup 0)
3986                     (const_int 0)))]
3987   ""
3988   [(set_attr "type" "shift")
3989    (set_attr "maybe_var_shift" "yes")
3990    (set_attr "dot" "yes")
3991    (set_attr "length" "4,8")])
3992
3993 (define_insn_and_split "*lshr<mode>3_dot2"
3994   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3995         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3996                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3997                     (const_int 0)))
3998    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3999         (lshiftrt:GPR (match_dup 1)
4000                       (match_dup 2)))]
4001   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4002   "@
4003    sr<wd>%I2. %0,%1,%<hH>2
4004    #"
4005   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4006   [(set (match_dup 0)
4007         (lshiftrt:GPR (match_dup 1)
4008                       (match_dup 2)))
4009    (set (match_dup 3)
4010         (compare:CC (match_dup 0)
4011                     (const_int 0)))]
4012   ""
4013   [(set_attr "type" "shift")
4014    (set_attr "maybe_var_shift" "yes")
4015    (set_attr "dot" "yes")
4016    (set_attr "length" "4,8")])
4017
4018
4019 (define_insn "*lshrsi3_imm_mask"
4020   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4021         (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4022                              (match_operand:SI 2 "const_int_operand" "i"))
4023                 (match_operand:SI 3 "mask_operand" "n")))]
4024   "includes_rshift_p (operands[2], operands[3])"
4025   "rlwinm %0,%1,%s2,%m3,%M3"
4026   [(set_attr "type" "shift")])
4027
4028 (define_insn_and_split "*lshrsi3_imm_mask_dot"
4029   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4030         (compare:CC
4031          (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4032                               (match_operand:SI 2 "const_int_operand" "i,i"))
4033                  (match_operand:SI 3 "mask_operand" "n,n"))
4034          (const_int 0)))
4035    (clobber (match_scratch:SI 0 "=r,r"))]
4036   "rs6000_gen_cell_microcode
4037    && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)
4038    && includes_rshift_p (operands[2], operands[3])"
4039   "@
4040    rlwinm. %0,%1,%s2,%m3,%M3
4041    #"
4042   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4043   [(set (match_dup 0)
4044         (and:SI (lshiftrt:SI (match_dup 1)
4045                              (match_dup 2))
4046                 (match_dup 3)))
4047    (set (match_dup 4)
4048         (compare:CC (match_dup 0)
4049                     (const_int 0)))]
4050   ""
4051   [(set_attr "type" "shift")
4052    (set_attr "dot" "yes")
4053    (set_attr "length" "4,8")])
4054
4055 (define_insn_and_split "*lshrsi3_imm_mask_dot2"
4056   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4057         (compare:CC
4058          (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4059                               (match_operand:SI 2 "const_int_operand" "i,i"))
4060                  (match_operand:SI 3 "mask_operand" "n,n"))
4061          (const_int 0)))
4062    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4063         (and:SI (lshiftrt:SI (match_dup 1)
4064                              (match_dup 2))
4065                 (match_dup 3)))]
4066   "rs6000_gen_cell_microcode
4067    && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)
4068    && includes_rshift_p (operands[2], operands[3])"
4069   "@
4070    rlwinm. %0,%1,%s2,%m3,%M3
4071    #"
4072   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4073   [(set (match_dup 0)
4074         (and:SI (lshiftrt:SI (match_dup 1)
4075                              (match_dup 2))
4076                 (match_dup 3)))
4077    (set (match_dup 4)
4078         (compare:CC (match_dup 0)
4079                     (const_int 0)))]
4080   ""
4081   [(set_attr "type" "shift")
4082    (set_attr "dot" "yes")
4083    (set_attr "length" "4,8")])
4084
4085
4086 (define_expand "ashr<mode>3"
4087   [(parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4088                    (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
4089                                  (match_operand:SI 2 "reg_or_cint_operand" "")))
4090               (clobber (reg:GPR CA_REGNO))])]
4091   ""
4092 {
4093   /* The generic code does not generate optimal code for the low word
4094      (it should be a rlwimi and a rot).  Until we have target code to
4095      solve this generically, keep this expander.  */
4096
4097   if (<MODE>mode == DImode && !TARGET_POWERPC64)
4098     {
4099       if (CONST_INT_P (operands[2]))
4100         {
4101           emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2]));
4102           DONE;
4103         }
4104       else
4105         FAIL;
4106     }
4107 })
4108
4109 (define_insn "*ashr<mode>3"
4110   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4111         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4112                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4113    (clobber (reg:GPR CA_REGNO))]
4114   ""
4115   "sra<wd>%I2 %0,%1,%<hH>2"
4116   [(set_attr "type" "shift")
4117    (set_attr "maybe_var_shift" "yes")])
4118
4119 (define_insn "*ashrsi3_64"
4120   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4121         (sign_extend:DI
4122             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4123                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4124    (clobber (reg:SI CA_REGNO))]
4125   "TARGET_POWERPC64"
4126   "sraw%I2 %0,%1,%h2"
4127   [(set_attr "type" "shift")
4128    (set_attr "maybe_var_shift" "yes")])
4129
4130 (define_insn_and_split "*ashr<mode>3_dot"
4131   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4132         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4133                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4134                     (const_int 0)))
4135    (clobber (match_scratch:GPR 0 "=r,r"))
4136    (clobber (reg:GPR CA_REGNO))]
4137   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4138   "@
4139    sra<wd>%I2. %0,%1,%<hH>2
4140    #"
4141   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4142   [(parallel [(set (match_dup 0)
4143                    (ashiftrt:GPR (match_dup 1)
4144                                  (match_dup 2)))
4145               (clobber (reg:GPR CA_REGNO))])
4146    (set (match_dup 3)
4147         (compare:CC (match_dup 0)
4148                     (const_int 0)))]
4149   ""
4150   [(set_attr "type" "shift")
4151    (set_attr "maybe_var_shift" "yes")
4152    (set_attr "dot" "yes")
4153    (set_attr "length" "4,8")])
4154
4155 (define_insn_and_split "*ashr<mode>3_dot2"
4156   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4157         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4158                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4159                     (const_int 0)))
4160    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4161         (ashiftrt:GPR (match_dup 1)
4162                       (match_dup 2)))
4163    (clobber (reg:GPR CA_REGNO))]
4164   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4165   "@
4166    sra<wd>%I2. %0,%1,%<hH>2
4167    #"
4168   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4169   [(parallel [(set (match_dup 0)
4170                    (ashiftrt:GPR (match_dup 1)
4171                                  (match_dup 2)))
4172               (clobber (reg:GPR CA_REGNO))])
4173    (set (match_dup 3)
4174         (compare:CC (match_dup 0)
4175                     (const_int 0)))]
4176   ""
4177   [(set_attr "type" "shift")
4178    (set_attr "maybe_var_shift" "yes")
4179    (set_attr "dot" "yes")
4180    (set_attr "length" "4,8")])
4181 \f
4182 ;; Builtins to replace a division to generate FRE reciprocal estimate
4183 ;; instructions and the necessary fixup instructions
4184 (define_expand "recip<mode>3"
4185   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4186    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4187    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4188   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4189 {
4190    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4191    DONE;
4192 })
4193
4194 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4195 ;; hardware division.  This is only done before register allocation and with
4196 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4197 (define_split
4198   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4199         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4200                     (match_operand 2 "gpc_reg_operand" "")))]
4201   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4202    && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4203    && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4204   [(const_int 0)]
4205 {
4206   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4207   DONE;
4208 })
4209
4210 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4211 ;; appropriate fixup.
4212 (define_expand "rsqrt<mode>2"
4213   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4214    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4215   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4216 {
4217   rs6000_emit_swrsqrt (operands[0], operands[1]);
4218   DONE;
4219 })
4220 \f
4221 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4222 ;; modes here, and also add in conditional vsx/power8-vector support to access
4223 ;; values in the traditional Altivec registers if the appropriate
4224 ;; -mupper-regs-{df,sf} option is enabled.
4225
4226 (define_expand "abs<mode>2"
4227   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4228         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4229   "TARGET_<MODE>_INSN"
4230   "")
4231
4232 (define_insn "*abs<mode>2_fpr"
4233   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4234         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4235   "TARGET_<MODE>_FPR"
4236   "@
4237    fabs %0,%1
4238    xsabsdp %x0,%x1"
4239   [(set_attr "type" "fp")
4240    (set_attr "fp_type" "fp_addsub_<Fs>")])
4241
4242 (define_insn "*nabs<mode>2_fpr"
4243   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4244         (neg:SFDF
4245          (abs:SFDF
4246           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4247   "TARGET_<MODE>_FPR"
4248   "@
4249    fnabs %0,%1
4250    xsnabsdp %x0,%x1"
4251   [(set_attr "type" "fp")
4252    (set_attr "fp_type" "fp_addsub_<Fs>")])
4253
4254 (define_expand "neg<mode>2"
4255   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4256         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4257   "TARGET_<MODE>_INSN"
4258   "")
4259
4260 (define_insn "*neg<mode>2_fpr"
4261   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4262         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4263   "TARGET_<MODE>_FPR"
4264   "@
4265    fneg %0,%1
4266    xsnegdp %x0,%x1"
4267   [(set_attr "type" "fp")
4268    (set_attr "fp_type" "fp_addsub_<Fs>")])
4269
4270 (define_expand "add<mode>3"
4271   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4272         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4273                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4274   "TARGET_<MODE>_INSN"
4275   "")
4276
4277 (define_insn "*add<mode>3_fpr"
4278   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4279         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4280                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4281   "TARGET_<MODE>_FPR"
4282   "@
4283    fadd<Ftrad> %0,%1,%2
4284    xsadd<Fvsx> %x0,%x1,%x2"
4285   [(set_attr "type" "fp")
4286    (set_attr "fp_type" "fp_addsub_<Fs>")])
4287
4288 (define_expand "sub<mode>3"
4289   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4290         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4291                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4292   "TARGET_<MODE>_INSN"
4293   "")
4294
4295 (define_insn "*sub<mode>3_fpr"
4296   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4297         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4298                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4299   "TARGET_<MODE>_FPR"
4300   "@
4301    fsub<Ftrad> %0,%1,%2
4302    xssub<Fvsx> %x0,%x1,%x2"
4303   [(set_attr "type" "fp")
4304    (set_attr "fp_type" "fp_addsub_<Fs>")])
4305
4306 (define_expand "mul<mode>3"
4307   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4308         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4309                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4310   "TARGET_<MODE>_INSN"
4311   "")
4312
4313 (define_insn "*mul<mode>3_fpr"
4314   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4315         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4316                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4317   "TARGET_<MODE>_FPR"
4318   "@
4319    fmul<Ftrad> %0,%1,%2
4320    xsmul<Fvsx> %x0,%x1,%x2"
4321   [(set_attr "type" "dmul")
4322    (set_attr "fp_type" "fp_mul_<Fs>")])
4323
4324 (define_expand "div<mode>3"
4325   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4326         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4327                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4328   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4329   "")
4330
4331 (define_insn "*div<mode>3_fpr"
4332   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4333         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4334                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4335   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4336   "@
4337    fdiv<Ftrad> %0,%1,%2
4338    xsdiv<Fvsx> %x0,%x1,%x2"
4339   [(set_attr "type" "<Fs>div")
4340    (set_attr "fp_type" "fp_div_<Fs>")])
4341
4342 (define_insn "sqrt<mode>2"
4343   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4344         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4345   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4346    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4347   "@
4348    fsqrt<Ftrad> %0,%1
4349    xssqrt<Fvsx> %x0,%x1"
4350   [(set_attr "type" "<Fs>sqrt")
4351    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4352
4353 ;; Floating point reciprocal approximation
4354 (define_insn "fre<Fs>"
4355   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4356         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
4357                      UNSPEC_FRES))]
4358   "TARGET_<FFRE>"
4359   "@
4360    fre<Ftrad> %0,%1
4361    xsre<Fvsx> %x0,%x1"
4362   [(set_attr "type" "fp")])
4363
4364 (define_insn "*rsqrt<mode>2"
4365   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4366         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
4367                      UNSPEC_RSQRT))]
4368   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4369   "@
4370    frsqrte<Ftrad> %0,%1
4371    xsrsqrte<Fvsx> %x0,%x1"
4372   [(set_attr "type" "fp")])
4373
4374 ;; Floating point comparisons
4375 (define_insn "*cmp<mode>_fpr"
4376   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4377         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4378                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4379   "TARGET_<MODE>_FPR"
4380   "@
4381    fcmpu %0,%1,%2
4382    xscmpudp %0,%x1,%x2"
4383   [(set_attr "type" "fpcompare")])
4384
4385 ;; Floating point conversions
4386 (define_expand "extendsfdf2"
4387   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4388         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4389   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4390   "")
4391
4392 (define_insn_and_split "*extendsfdf2_fpr"
4393   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu")
4394         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z")))]
4395   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4396   "@
4397    #
4398    fmr %0,%1
4399    lfs%U1%X1 %0,%1
4400    #
4401    xscpsgndp %x0,%x1,%x1
4402    lxsspx %x0,%y1"
4403   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4404   [(const_int 0)]
4405 {
4406   emit_note (NOTE_INSN_DELETED);
4407   DONE;
4408 }
4409   [(set_attr "type" "fp,fp,fpload,fp,fp,fpload")])
4410
4411 (define_expand "truncdfsf2"
4412   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4413         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4414   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4415   "")
4416
4417 (define_insn "*truncdfsf2_fpr"
4418   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4419         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4420   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4421   "@
4422    frsp %0,%1
4423    xsrsp %x0,%x1"
4424   [(set_attr "type" "fp")])
4425
4426 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4427 ;; builtins.c and optabs.c that are not correct for IBM long double
4428 ;; when little-endian.
4429 (define_expand "signbittf2"
4430   [(set (match_dup 2)
4431         (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
4432    (set (match_dup 3)
4433         (subreg:DI (match_dup 2) 0))
4434    (set (match_dup 4)
4435         (match_dup 5))
4436    (set (match_operand:SI 0 "gpc_reg_operand" "")
4437         (match_dup 6))]
4438   "!TARGET_IEEEQUAD
4439    && TARGET_HARD_FLOAT
4440    && (TARGET_FPRS || TARGET_E500_DOUBLE)
4441    && TARGET_LONG_DOUBLE_128"
4442 {
4443   operands[2] = gen_reg_rtx (DFmode);
4444   operands[3] = gen_reg_rtx (DImode);
4445   if (TARGET_POWERPC64)
4446     {
4447       operands[4] = gen_reg_rtx (DImode);
4448       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4449       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4450                                     WORDS_BIG_ENDIAN ? 4 : 0);
4451     }
4452   else
4453     {
4454       operands[4] = gen_reg_rtx (SImode);
4455       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4456                                     WORDS_BIG_ENDIAN ? 0 : 4);
4457       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4458     }
4459 })
4460
4461 (define_expand "copysign<mode>3"
4462   [(set (match_dup 3)
4463         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4464    (set (match_dup 4)
4465         (neg:SFDF (abs:SFDF (match_dup 1))))
4466    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4467         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4468                                (match_dup 5))
4469                          (match_dup 3)
4470                          (match_dup 4)))]
4471   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4472    && ((TARGET_PPC_GFXOPT
4473         && !HONOR_NANS (<MODE>mode)
4474         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4475        || TARGET_CMPB
4476        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4477 {
4478   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4479     {
4480       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4481                                              operands[2]));
4482       DONE;
4483     }
4484
4485    operands[3] = gen_reg_rtx (<MODE>mode);
4486    operands[4] = gen_reg_rtx (<MODE>mode);
4487    operands[5] = CONST0_RTX (<MODE>mode);
4488   })
4489
4490 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4491 ;; compiler from optimizing -0.0
4492 (define_insn "copysign<mode>3_fcpsgn"
4493   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4494         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4495                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4496                      UNSPEC_COPYSIGN))]
4497   "TARGET_<MODE>_FPR && TARGET_CMPB"
4498   "@
4499    fcpsgn %0,%2,%1
4500    xscpsgndp %x0,%x2,%x1"
4501   [(set_attr "type" "fp")])
4502
4503 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4504 ;; fsel instruction and some auxiliary computations.  Then we just have a
4505 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4506 ;; combine.
4507 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4508 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4509 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4510 ;; define_splits to make them if made by combine.  On VSX machines we have the
4511 ;; min/max instructions.
4512 ;;
4513 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4514 ;; to allow either DF/SF to use only traditional registers.
4515
4516 (define_expand "smax<mode>3"
4517   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4518         (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4519                                (match_operand:SFDF 2 "gpc_reg_operand" ""))
4520                            (match_dup 1)
4521                            (match_dup 2)))]
4522   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4523 {
4524   rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
4525   DONE;
4526 })
4527
4528 (define_insn "*smax<mode>3_vsx"
4529   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4530         (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4531                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4532   "TARGET_<MODE>_FPR && TARGET_VSX"
4533   "xsmaxdp %x0,%x1,%x2"
4534   [(set_attr "type" "fp")])
4535
4536 (define_expand "smin<mode>3"
4537   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4538         (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4539                                (match_operand:SFDF 2 "gpc_reg_operand" ""))
4540                            (match_dup 2)
4541                            (match_dup 1)))]
4542   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4543 {
4544   rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
4545   DONE;
4546 })
4547
4548 (define_insn "*smin<mode>3_vsx"
4549   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4550         (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4551                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4552   "TARGET_<MODE>_FPR && TARGET_VSX"
4553   "xsmindp %x0,%x1,%x2"
4554   [(set_attr "type" "fp")])
4555
4556 (define_split
4557   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4558         (match_operator:SFDF 3 "min_max_operator"
4559          [(match_operand:SFDF 1 "gpc_reg_operand" "")
4560           (match_operand:SFDF 2 "gpc_reg_operand" "")]))]
4561   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math
4562    && !TARGET_VSX"
4563   [(const_int 0)]
4564 {
4565   rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1],
4566                       operands[2]);
4567   DONE;
4568 })
4569
4570 (define_split
4571   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4572         (match_operator:SF 3 "min_max_operator"
4573          [(match_operand:SF 1 "gpc_reg_operand" "")
4574           (match_operand:SF 2 "gpc_reg_operand" "")]))]
4575   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
4576    && TARGET_SINGLE_FLOAT && !flag_trapping_math"
4577   [(const_int 0)]
4578   "
4579 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4580                       operands[1], operands[2]);
4581   DONE;
4582 }")
4583
4584 (define_expand "mov<mode>cc"
4585    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4586          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4587                            (match_operand:GPR 2 "gpc_reg_operand" "")
4588                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4589   "TARGET_ISEL<sel>"
4590   "
4591 {
4592   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4593     DONE;
4594   else
4595     FAIL;
4596 }")
4597
4598 ;; We use the BASE_REGS for the isel input operands because, if rA is
4599 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4600 ;; because we may switch the operands and rB may end up being rA.
4601 ;;
4602 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4603 ;; leave out the mode in operand 4 and use one pattern, but reload can
4604 ;; change the mode underneath our feet and then gets confused trying
4605 ;; to reload the value.
4606 (define_insn "isel_signed_<mode>"
4607   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4608         (if_then_else:GPR
4609          (match_operator 1 "scc_comparison_operator"
4610                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4611                           (const_int 0)])
4612          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4613          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4614   "TARGET_ISEL<sel>"
4615   "*
4616 { return output_isel (operands); }"
4617   [(set_attr "type" "isel")
4618    (set_attr "length" "4")])
4619
4620 (define_insn "isel_unsigned_<mode>"
4621   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4622         (if_then_else:GPR
4623          (match_operator 1 "scc_comparison_operator"
4624                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4625                           (const_int 0)])
4626          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4627          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4628   "TARGET_ISEL<sel>"
4629   "*
4630 { return output_isel (operands); }"
4631   [(set_attr "type" "isel")
4632    (set_attr "length" "4")])
4633
4634 ;; These patterns can be useful for combine; they let combine know that
4635 ;; isel can handle reversed comparisons so long as the operands are
4636 ;; registers.
4637
4638 (define_insn "*isel_reversed_signed_<mode>"
4639   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4640         (if_then_else:GPR
4641          (match_operator 1 "scc_rev_comparison_operator"
4642                          [(match_operand:CC 4 "cc_reg_operand" "y")
4643                           (const_int 0)])
4644          (match_operand:GPR 2 "gpc_reg_operand" "b")
4645          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4646   "TARGET_ISEL<sel>"
4647   "*
4648 { return output_isel (operands); }"
4649   [(set_attr "type" "isel")
4650    (set_attr "length" "4")])
4651
4652 (define_insn "*isel_reversed_unsigned_<mode>"
4653   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4654         (if_then_else:GPR
4655          (match_operator 1 "scc_rev_comparison_operator"
4656                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4657                           (const_int 0)])
4658          (match_operand:GPR 2 "gpc_reg_operand" "b")
4659          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4660   "TARGET_ISEL<sel>"
4661   "*
4662 { return output_isel (operands); }"
4663   [(set_attr "type" "isel")
4664    (set_attr "length" "4")])
4665
4666 (define_expand "movsfcc"
4667    [(set (match_operand:SF 0 "gpc_reg_operand" "")
4668          (if_then_else:SF (match_operand 1 "comparison_operator" "")
4669                           (match_operand:SF 2 "gpc_reg_operand" "")
4670                           (match_operand:SF 3 "gpc_reg_operand" "")))]
4671   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4672   "
4673 {
4674   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4675     DONE;
4676   else
4677     FAIL;
4678 }")
4679
4680 (define_insn "*fselsfsf4"
4681   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4682         (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4683                              (match_operand:SF 4 "zero_fp_constant" "F"))
4684                          (match_operand:SF 2 "gpc_reg_operand" "f")
4685                          (match_operand:SF 3 "gpc_reg_operand" "f")))]
4686   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4687   "fsel %0,%1,%2,%3"
4688   [(set_attr "type" "fp")])
4689
4690 (define_insn "*fseldfsf4"
4691   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4692         (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4693                              (match_operand:DF 4 "zero_fp_constant" "F"))
4694                          (match_operand:SF 2 "gpc_reg_operand" "f")
4695                          (match_operand:SF 3 "gpc_reg_operand" "f")))]
4696   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4697   "fsel %0,%1,%2,%3"
4698   [(set_attr "type" "fp")])
4699
4700 ;; The conditional move instructions allow us to perform max and min
4701 ;; operations even when
4702
4703 (define_split
4704   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4705         (match_operator:DF 3 "min_max_operator"
4706          [(match_operand:DF 1 "gpc_reg_operand" "")
4707           (match_operand:DF 2 "gpc_reg_operand" "")]))]
4708   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
4709    && !flag_trapping_math"
4710   [(const_int 0)]
4711   "
4712 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4713                       operands[1], operands[2]);
4714   DONE;
4715 }")
4716
4717 (define_expand "movdfcc"
4718    [(set (match_operand:DF 0 "gpc_reg_operand" "")
4719          (if_then_else:DF (match_operand 1 "comparison_operator" "")
4720                           (match_operand:DF 2 "gpc_reg_operand" "")
4721                           (match_operand:DF 3 "gpc_reg_operand" "")))]
4722   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4723   "
4724 {
4725   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4726     DONE;
4727   else
4728     FAIL;
4729 }")
4730
4731 (define_insn "*fseldfdf4"
4732   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4733         (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4734                              (match_operand:DF 4 "zero_fp_constant" "F"))
4735                          (match_operand:DF 2 "gpc_reg_operand" "d")
4736                          (match_operand:DF 3 "gpc_reg_operand" "d")))]
4737   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4738   "fsel %0,%1,%2,%3"
4739   [(set_attr "type" "fp")])
4740
4741 (define_insn "*fselsfdf4"
4742   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4743         (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4744                              (match_operand:SF 4 "zero_fp_constant" "F"))
4745                          (match_operand:DF 2 "gpc_reg_operand" "d")
4746                          (match_operand:DF 3 "gpc_reg_operand" "d")))]
4747   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4748   "fsel %0,%1,%2,%3"
4749   [(set_attr "type" "fp")])
4750 \f
4751 ;; Conversions to and from floating-point.
4752
4753 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4754 ; don't want to support putting SImode in FPR registers.
4755 (define_insn "lfiwax"
4756   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4757         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4758                    UNSPEC_LFIWAX))]
4759   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4760   "@
4761    lfiwax %0,%y1
4762    lxsiwax %x0,%y1
4763    mtvsrwa %x0,%1"
4764   [(set_attr "type" "fpload,fpload,mffgpr")])
4765
4766 ; This split must be run before register allocation because it allocates the
4767 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
4768 ; it earlier to allow for the combiner to merge insns together where it might
4769 ; not be needed and also in case the insns are deleted as dead code.
4770
4771 (define_insn_and_split "floatsi<mode>2_lfiwax"
4772   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4773         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4774    (clobber (match_scratch:DI 2 "=wj"))]
4775   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4776    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4777   "#"
4778   ""
4779   [(pc)]
4780   "
4781 {
4782   rtx dest = operands[0];
4783   rtx src = operands[1];
4784   rtx tmp;
4785
4786   if (!MEM_P (src) && TARGET_POWERPC64
4787       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4788     tmp = convert_to_mode (DImode, src, false);
4789   else
4790     {
4791       tmp = operands[2];
4792       if (GET_CODE (tmp) == SCRATCH)
4793         tmp = gen_reg_rtx (DImode);
4794       if (MEM_P (src))
4795         {
4796           src = rs6000_address_for_fpconvert (src);
4797           emit_insn (gen_lfiwax (tmp, src));
4798         }
4799       else
4800         {
4801           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4802           emit_move_insn (stack, src);
4803           emit_insn (gen_lfiwax (tmp, stack));
4804         }
4805     }
4806   emit_insn (gen_floatdi<mode>2 (dest, tmp));
4807   DONE;
4808 }"
4809   [(set_attr "length" "12")
4810    (set_attr "type" "fpload")])
4811
4812 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
4813   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4814         (float:SFDF
4815          (sign_extend:DI
4816           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4817    (clobber (match_scratch:DI 2 "=0,d"))]
4818   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4819    && <SI_CONVERT_FP>"
4820   "#"
4821   ""
4822   [(pc)]
4823   "
4824 {
4825   operands[1] = rs6000_address_for_fpconvert (operands[1]);
4826   if (GET_CODE (operands[2]) == SCRATCH)
4827     operands[2] = gen_reg_rtx (DImode);
4828   emit_insn (gen_lfiwax (operands[2], operands[1]));
4829   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4830   DONE;
4831 }"
4832   [(set_attr "length" "8")
4833    (set_attr "type" "fpload")])
4834
4835 (define_insn "lfiwzx"
4836   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4837         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4838                    UNSPEC_LFIWZX))]
4839   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
4840   "@
4841    lfiwzx %0,%y1
4842    lxsiwzx %x0,%y1
4843    mtvsrwz %x0,%1"
4844   [(set_attr "type" "fpload,fpload,mftgpr")])
4845
4846 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
4847   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4848         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4849    (clobber (match_scratch:DI 2 "=wj"))]
4850   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4851    && <SI_CONVERT_FP>"
4852   "#"
4853   ""
4854   [(pc)]
4855   "
4856 {
4857   rtx dest = operands[0];
4858   rtx src = operands[1];
4859   rtx tmp;
4860
4861   if (!MEM_P (src) && TARGET_POWERPC64
4862       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4863     tmp = convert_to_mode (DImode, src, true);
4864   else
4865     {
4866       tmp = operands[2];
4867       if (GET_CODE (tmp) == SCRATCH)
4868         tmp = gen_reg_rtx (DImode);
4869       if (MEM_P (src))
4870         {
4871           src = rs6000_address_for_fpconvert (src);
4872           emit_insn (gen_lfiwzx (tmp, src));
4873         }
4874       else
4875         {
4876           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4877           emit_move_insn (stack, src);
4878           emit_insn (gen_lfiwzx (tmp, stack));
4879         }
4880     }
4881   emit_insn (gen_floatdi<mode>2 (dest, tmp));
4882   DONE;
4883 }"
4884   [(set_attr "length" "12")
4885    (set_attr "type" "fpload")])
4886
4887 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
4888   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4889         (unsigned_float:SFDF
4890          (zero_extend:DI
4891           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4892    (clobber (match_scratch:DI 2 "=0,d"))]
4893   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4894    && <SI_CONVERT_FP>"
4895   "#"
4896   ""
4897   [(pc)]
4898   "
4899 {
4900   operands[1] = rs6000_address_for_fpconvert (operands[1]);
4901   if (GET_CODE (operands[2]) == SCRATCH)
4902     operands[2] = gen_reg_rtx (DImode);
4903   emit_insn (gen_lfiwzx (operands[2], operands[1]));
4904   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4905   DONE;
4906 }"
4907   [(set_attr "length" "8")
4908    (set_attr "type" "fpload")])
4909
4910 ; For each of these conversions, there is a define_expand, a define_insn
4911 ; with a '#' template, and a define_split (with C code).  The idea is
4912 ; to allow constant folding with the template of the define_insn,
4913 ; then to have the insns split later (between sched1 and final).
4914
4915 (define_expand "floatsidf2"
4916   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
4917                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
4918               (use (match_dup 2))
4919               (use (match_dup 3))
4920               (clobber (match_dup 4))
4921               (clobber (match_dup 5))
4922               (clobber (match_dup 6))])]
4923   "TARGET_HARD_FLOAT 
4924    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4925   "
4926 {
4927   if (TARGET_E500_DOUBLE)
4928     {
4929       if (!REG_P (operands[1]))
4930         operands[1] = force_reg (SImode, operands[1]);
4931       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
4932       DONE;
4933     }
4934   else if (TARGET_LFIWAX && TARGET_FCFID)
4935     {
4936       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
4937       DONE;
4938     }
4939   else if (TARGET_FCFID)
4940     {
4941       rtx dreg = operands[1];
4942       if (!REG_P (dreg))
4943         dreg = force_reg (SImode, dreg);
4944       dreg = convert_to_mode (DImode, dreg, false);
4945       emit_insn (gen_floatdidf2 (operands[0], dreg));
4946       DONE;
4947     }
4948
4949   if (!REG_P (operands[1]))
4950     operands[1] = force_reg (SImode, operands[1]);
4951   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
4952   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
4953   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
4954   operands[5] = gen_reg_rtx (DFmode);
4955   operands[6] = gen_reg_rtx (SImode);
4956 }")
4957
4958 (define_insn_and_split "*floatsidf2_internal"
4959   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
4960         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
4961    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
4962    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
4963    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
4964    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
4965    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
4966   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4967   "#"
4968   ""
4969   [(pc)]
4970   "
4971 {
4972   rtx lowword, highword;
4973   gcc_assert (MEM_P (operands[4]));
4974   highword = adjust_address (operands[4], SImode, 0);
4975   lowword = adjust_address (operands[4], SImode, 4);
4976   if (! WORDS_BIG_ENDIAN)
4977     std::swap (lowword, highword);
4978
4979   emit_insn (gen_xorsi3 (operands[6], operands[1],
4980                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
4981   emit_move_insn (lowword, operands[6]);
4982   emit_move_insn (highword, operands[2]);
4983   emit_move_insn (operands[5], operands[4]);
4984   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
4985   DONE;
4986 }"
4987   [(set_attr "length" "24")
4988    (set_attr "type" "fp")])
4989
4990 ;; If we don't have a direct conversion to single precision, don't enable this
4991 ;; conversion for 32-bit without fast math, because we don't have the insn to
4992 ;; generate the fixup swizzle to avoid double rounding problems.
4993 (define_expand "floatunssisf2"
4994   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4995         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4996   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
4997    && (!TARGET_FPRS
4998        || (TARGET_FPRS
4999            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5000                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5001                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5002   "
5003 {
5004   if (!TARGET_FPRS)
5005     {
5006       if (!REG_P (operands[1]))
5007         operands[1] = force_reg (SImode, operands[1]);
5008     }
5009   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5010     {
5011       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5012       DONE;
5013     }
5014   else
5015     {
5016       rtx dreg = operands[1];
5017       if (!REG_P (dreg))
5018         dreg = force_reg (SImode, dreg);
5019       dreg = convert_to_mode (DImode, dreg, true);
5020       emit_insn (gen_floatdisf2 (operands[0], dreg));
5021       DONE;
5022     }
5023 }")
5024
5025 (define_expand "floatunssidf2"
5026   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5027                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5028               (use (match_dup 2))
5029               (use (match_dup 3))
5030               (clobber (match_dup 4))
5031               (clobber (match_dup 5))])]
5032   "TARGET_HARD_FLOAT
5033    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5034   "
5035 {
5036   if (TARGET_E500_DOUBLE)
5037     {
5038       if (!REG_P (operands[1]))
5039         operands[1] = force_reg (SImode, operands[1]);
5040       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5041       DONE;
5042     }
5043   else if (TARGET_LFIWZX && TARGET_FCFID)
5044     {
5045       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5046       DONE;
5047     }
5048   else if (TARGET_FCFID)
5049     {
5050       rtx dreg = operands[1];
5051       if (!REG_P (dreg))
5052         dreg = force_reg (SImode, dreg);
5053       dreg = convert_to_mode (DImode, dreg, true);
5054       emit_insn (gen_floatdidf2 (operands[0], dreg));
5055       DONE;
5056     }
5057
5058   if (!REG_P (operands[1]))
5059     operands[1] = force_reg (SImode, operands[1]);
5060   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5061   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5062   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5063   operands[5] = gen_reg_rtx (DFmode);
5064 }")
5065
5066 (define_insn_and_split "*floatunssidf2_internal"
5067   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5068         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5069    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5070    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5071    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5072    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5073   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5074    && !(TARGET_FCFID && TARGET_POWERPC64)"
5075   "#"
5076   ""
5077   [(pc)]
5078   "
5079 {
5080   rtx lowword, highword;
5081   gcc_assert (MEM_P (operands[4]));
5082   highword = adjust_address (operands[4], SImode, 0);
5083   lowword = adjust_address (operands[4], SImode, 4);
5084   if (! WORDS_BIG_ENDIAN)
5085     std::swap (lowword, highword);
5086
5087   emit_move_insn (lowword, operands[1]);
5088   emit_move_insn (highword, operands[2]);
5089   emit_move_insn (operands[5], operands[4]);
5090   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5091   DONE;
5092 }"
5093   [(set_attr "length" "20")
5094    (set_attr "type" "fp")])
5095
5096 (define_expand "fix_trunc<mode>si2"
5097   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5098         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5099   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5100   "
5101 {
5102   if (!<E500_CONVERT>)
5103     {
5104       rtx tmp, stack;
5105
5106       if (TARGET_STFIWX)
5107         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5108       else
5109         {
5110           tmp = gen_reg_rtx (DImode);
5111           stack = rs6000_allocate_stack_temp (DImode, true, false);
5112           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5113                                                       tmp, stack));
5114         }
5115       DONE;
5116     }
5117 }")
5118
5119 ; Like the convert to float patterns, this insn must be split before
5120 ; register allocation so that it can allocate the memory slot if it
5121 ; needed
5122 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5123   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5124         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5125    (clobber (match_scratch:DI 2 "=d"))]
5126   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5127    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5128    && TARGET_STFIWX && can_create_pseudo_p ()"
5129   "#"
5130   ""
5131   [(pc)]
5132 {
5133   rtx dest = operands[0];
5134   rtx src = operands[1];
5135   rtx tmp = operands[2];
5136
5137   if (GET_CODE (tmp) == SCRATCH)
5138     tmp = gen_reg_rtx (DImode);
5139
5140   emit_insn (gen_fctiwz_<mode> (tmp, src));
5141   if (MEM_P (dest))
5142     {
5143       dest = rs6000_address_for_fpconvert (dest);
5144       emit_insn (gen_stfiwx (dest, tmp));
5145       DONE;
5146     }
5147   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5148     {
5149       dest = gen_lowpart (DImode, dest);
5150       emit_move_insn (dest, tmp);
5151       DONE;
5152     }
5153   else
5154     {
5155       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5156       emit_insn (gen_stfiwx (stack, tmp));
5157       emit_move_insn (dest, stack);
5158       DONE;
5159     }
5160 }
5161   [(set_attr "length" "12")
5162    (set_attr "type" "fp")])
5163
5164 (define_insn_and_split "fix_trunc<mode>si2_internal"
5165   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5166         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5167    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5168    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5169   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5170   "#"
5171   ""
5172   [(pc)]
5173   "
5174 {
5175   rtx lowword;
5176   gcc_assert (MEM_P (operands[3]));
5177   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5178
5179   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5180   emit_move_insn (operands[3], operands[2]);
5181   emit_move_insn (operands[0], lowword);
5182   DONE;
5183 }"
5184   [(set_attr "length" "16")
5185    (set_attr "type" "fp")])
5186
5187 (define_expand "fix_trunc<mode>di2"
5188   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5189         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5190   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5191    && TARGET_FCFID"
5192   "")
5193
5194 (define_insn "*fix_trunc<mode>di2_fctidz"
5195   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5196         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5197   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5198     && TARGET_FCFID"
5199   "@
5200    fctidz %0,%1
5201    xscvdpsxds %x0,%x1"
5202   [(set_attr "type" "fp")])
5203
5204 (define_expand "fixuns_trunc<mode>si2"
5205   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5206         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5207   "TARGET_HARD_FLOAT
5208    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5209        || <E500_CONVERT>)"
5210   "
5211 {
5212   if (!<E500_CONVERT>)
5213     {
5214       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5215       DONE;
5216     }
5217 }")
5218
5219 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5220   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5221         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5222    (clobber (match_scratch:DI 2 "=d"))]
5223   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5224    && TARGET_STFIWX && can_create_pseudo_p ()"
5225   "#"
5226   ""
5227   [(pc)]
5228 {
5229   rtx dest = operands[0];
5230   rtx src = operands[1];
5231   rtx tmp = operands[2];
5232
5233   if (GET_CODE (tmp) == SCRATCH)
5234     tmp = gen_reg_rtx (DImode);
5235
5236   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5237   if (MEM_P (dest))
5238     {
5239       dest = rs6000_address_for_fpconvert (dest);
5240       emit_insn (gen_stfiwx (dest, tmp));
5241       DONE;
5242     }
5243   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5244     {
5245       dest = gen_lowpart (DImode, dest);
5246       emit_move_insn (dest, tmp);
5247       DONE;
5248     }
5249   else
5250     {
5251       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5252       emit_insn (gen_stfiwx (stack, tmp));
5253       emit_move_insn (dest, stack);
5254       DONE;
5255     }
5256 }
5257   [(set_attr "length" "12")
5258    (set_attr "type" "fp")])
5259
5260 (define_expand "fixuns_trunc<mode>di2"
5261   [(set (match_operand:DI 0 "register_operand" "")
5262         (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5263   "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5264   "")
5265
5266 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5267   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5268         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5269   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5270     && TARGET_FCTIDUZ"
5271   "@
5272    fctiduz %0,%1
5273    xscvdpuxds %x0,%x1"
5274   [(set_attr "type" "fp")])
5275
5276 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5277 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5278 ; because the first makes it clear that operand 0 is not live
5279 ; before the instruction.
5280 (define_insn "fctiwz_<mode>"
5281   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5282         (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5283                    UNSPEC_FCTIWZ))]
5284   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5285   "@
5286    fctiwz %0,%1
5287    xscvdpsxws %x0,%x1"
5288   [(set_attr "type" "fp")])
5289
5290 (define_insn "fctiwuz_<mode>"
5291   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5292         (unspec:DI [(unsigned_fix:SI
5293                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5294                    UNSPEC_FCTIWUZ))]
5295   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5296   "@
5297    fctiwuz %0,%1
5298    xscvdpuxws %x0,%x1"
5299   [(set_attr "type" "fp")])
5300
5301 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5302 ;; since the friz instruction does not truncate the value if the floating
5303 ;; point value is < LONG_MIN or > LONG_MAX.
5304 (define_insn "*friz"
5305   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5306         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5307   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5308    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5309   "@
5310    friz %0,%1
5311    xsrdpiz %x0,%x1"
5312   [(set_attr "type" "fp")])
5313
5314 ;; Since FCTIWZ doesn't sign extend the upper bits, we have to do a store and a
5315 ;; load to properly sign extend the value, but at least doing a store, load
5316 ;; into a GPR to sign extend, a store from the GPR and a load back into the FPR
5317 ;; if we have 32-bit memory ops
5318 (define_insn_and_split "*round32<mode>2_fprs"
5319   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5320         (float:SFDF
5321          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5322    (clobber (match_scratch:DI 2 "=d"))
5323    (clobber (match_scratch:DI 3 "=d"))]
5324   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5325    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5326    && can_create_pseudo_p ()"
5327   "#"
5328   ""
5329   [(pc)]
5330 {
5331   rtx dest = operands[0];
5332   rtx src = operands[1];
5333   rtx tmp1 = operands[2];
5334   rtx tmp2 = operands[3];
5335   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5336
5337   if (GET_CODE (tmp1) == SCRATCH)
5338     tmp1 = gen_reg_rtx (DImode);
5339   if (GET_CODE (tmp2) == SCRATCH)
5340     tmp2 = gen_reg_rtx (DImode);
5341
5342   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5343   emit_insn (gen_stfiwx (stack, tmp1));
5344   emit_insn (gen_lfiwax (tmp2, stack));
5345   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5346   DONE;
5347 }
5348   [(set_attr "type" "fpload")
5349    (set_attr "length" "16")])
5350
5351 (define_insn_and_split "*roundu32<mode>2_fprs"
5352   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5353         (unsigned_float:SFDF
5354          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5355    (clobber (match_scratch:DI 2 "=d"))
5356    (clobber (match_scratch:DI 3 "=d"))]
5357   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5358    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU
5359    && can_create_pseudo_p ()"
5360   "#"
5361   ""
5362   [(pc)]
5363 {
5364   rtx dest = operands[0];
5365   rtx src = operands[1];
5366   rtx tmp1 = operands[2];
5367   rtx tmp2 = operands[3];
5368   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5369
5370   if (GET_CODE (tmp1) == SCRATCH)
5371     tmp1 = gen_reg_rtx (DImode);
5372   if (GET_CODE (tmp2) == SCRATCH)
5373     tmp2 = gen_reg_rtx (DImode);
5374
5375   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5376   emit_insn (gen_stfiwx (stack, tmp1));
5377   emit_insn (gen_lfiwzx (tmp2, stack));
5378   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5379   DONE;
5380 }
5381   [(set_attr "type" "fpload")
5382    (set_attr "length" "16")])
5383
5384 ;; No VSX equivalent to fctid
5385 (define_insn "lrint<mode>di2"
5386   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5387         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5388                    UNSPEC_FCTID))]
5389   "TARGET_<MODE>_FPR && TARGET_FPRND"
5390   "fctid %0,%1"
5391   [(set_attr "type" "fp")])
5392
5393 (define_insn "btrunc<mode>2"
5394   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5395         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5396                      UNSPEC_FRIZ))]
5397   "TARGET_<MODE>_FPR && TARGET_FPRND"
5398   "@
5399    friz %0,%1
5400    xsrdpiz %x0,%x1"
5401   [(set_attr "type" "fp")
5402    (set_attr "fp_type" "fp_addsub_<Fs>")])
5403
5404 (define_insn "ceil<mode>2"
5405   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5406         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5407                      UNSPEC_FRIP))]
5408   "TARGET_<MODE>_FPR && TARGET_FPRND"
5409   "@
5410    frip %0,%1
5411    xsrdpip %x0,%x1"
5412   [(set_attr "type" "fp")
5413    (set_attr "fp_type" "fp_addsub_<Fs>")])
5414
5415 (define_insn "floor<mode>2"
5416   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5417         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5418                      UNSPEC_FRIM))]
5419   "TARGET_<MODE>_FPR && TARGET_FPRND"
5420   "@
5421    frim %0,%1
5422    xsrdpim %x0,%x1"
5423   [(set_attr "type" "fp")
5424    (set_attr "fp_type" "fp_addsub_<Fs>")])
5425
5426 ;; No VSX equivalent to frin
5427 (define_insn "round<mode>2"
5428   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5429         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5430                      UNSPEC_FRIN))]
5431   "TARGET_<MODE>_FPR && TARGET_FPRND"
5432   "frin %0,%1"
5433   [(set_attr "type" "fp")
5434    (set_attr "fp_type" "fp_addsub_<Fs>")])
5435
5436 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5437 (define_insn "stfiwx"
5438   [(set (match_operand:SI 0 "memory_operand" "=Z")
5439         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
5440                    UNSPEC_STFIWX))]
5441   "TARGET_PPC_GFXOPT"
5442   "stfiwx %1,%y0"
5443   [(set_attr "type" "fpstore")])
5444
5445 ;; If we don't have a direct conversion to single precision, don't enable this
5446 ;; conversion for 32-bit without fast math, because we don't have the insn to
5447 ;; generate the fixup swizzle to avoid double rounding problems.
5448 (define_expand "floatsisf2"
5449   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5450         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5451   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5452    && (!TARGET_FPRS
5453        || (TARGET_FPRS
5454            && ((TARGET_FCFIDS && TARGET_LFIWAX)
5455                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5456                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5457   "
5458 {
5459   if (!TARGET_FPRS)
5460     {
5461       if (!REG_P (operands[1]))
5462         operands[1] = force_reg (SImode, operands[1]);
5463     }
5464   else if (TARGET_FCFIDS && TARGET_LFIWAX)
5465     {
5466       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5467       DONE;
5468     }
5469   else if (TARGET_FCFID && TARGET_LFIWAX)
5470     {
5471       rtx dfreg = gen_reg_rtx (DFmode);
5472       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5473       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5474       DONE;
5475     }
5476   else
5477     {
5478       rtx dreg = operands[1];
5479       if (!REG_P (dreg))
5480         dreg = force_reg (SImode, dreg);
5481       dreg = convert_to_mode (DImode, dreg, false);
5482       emit_insn (gen_floatdisf2 (operands[0], dreg));
5483       DONE;
5484     }
5485 }")
5486
5487 (define_expand "floatdidf2"
5488   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5489         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5490   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5491   "")
5492
5493 (define_insn "*floatdidf2_fpr"
5494   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5495         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5496   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5497   "@
5498    fcfid %0,%1
5499    xscvsxddp %x0,%x1"
5500   [(set_attr "type" "fp")])
5501
5502 ; Allow the combiner to merge source memory operands to the conversion so that
5503 ; the optimizer/register allocator doesn't try to load the value too early in a
5504 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5505 ; hit.  We will split after reload to avoid the trip through the GPRs
5506
5507 (define_insn_and_split "*floatdidf2_mem"
5508   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5509         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5510    (clobber (match_scratch:DI 2 "=d,wi"))]
5511   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5512   "#"
5513   "&& reload_completed"
5514   [(set (match_dup 2) (match_dup 1))
5515    (set (match_dup 0) (float:DF (match_dup 2)))]
5516   ""
5517   [(set_attr "length" "8")
5518    (set_attr "type" "fpload")])
5519
5520 (define_expand "floatunsdidf2"
5521   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5522         (unsigned_float:DF
5523          (match_operand:DI 1 "gpc_reg_operand" "")))]
5524   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5525   "")
5526
5527 (define_insn "*floatunsdidf2_fcfidu"
5528   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5529         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5530   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5531   "@
5532    fcfidu %0,%1
5533    xscvuxddp %x0,%x1"
5534   [(set_attr "type" "fp")
5535    (set_attr "length" "4")])
5536
5537 (define_insn_and_split "*floatunsdidf2_mem"
5538   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5539         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5540    (clobber (match_scratch:DI 2 "=d,wi"))]
5541   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5542   "#"
5543   "&& reload_completed"
5544   [(set (match_dup 2) (match_dup 1))
5545    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5546   ""
5547   [(set_attr "length" "8")
5548    (set_attr "type" "fpload")])
5549
5550 (define_expand "floatdisf2"
5551   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5552         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5553   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5554    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5555   "
5556 {
5557   if (!TARGET_FCFIDS)
5558     {
5559       rtx val = operands[1];
5560       if (!flag_unsafe_math_optimizations)
5561         {
5562           rtx label = gen_label_rtx ();
5563           val = gen_reg_rtx (DImode);
5564           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5565           emit_label (label);
5566         }
5567       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5568       DONE;
5569     }
5570 }")
5571
5572 (define_insn "floatdisf2_fcfids"
5573   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5574         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5575   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5576    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5577   "@
5578    fcfids %0,%1
5579    xscvsxdsp %x0,%x1"
5580   [(set_attr "type" "fp")])
5581
5582 (define_insn_and_split "*floatdisf2_mem"
5583   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5584         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5585    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5586   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5587    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5588   "#"
5589   "&& reload_completed"
5590   [(pc)]
5591   "
5592 {
5593   emit_move_insn (operands[2], operands[1]);
5594   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5595   DONE;
5596 }"
5597   [(set_attr "length" "8")])
5598
5599 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5600 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5601 ;; from double rounding.
5602 ;; Instead of creating a new cpu type for two FP operations, just use fp
5603 (define_insn_and_split "floatdisf2_internal1"
5604   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5605         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5606    (clobber (match_scratch:DF 2 "=d"))]
5607   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5608    && !TARGET_FCFIDS"
5609   "#"
5610   "&& reload_completed"
5611   [(set (match_dup 2)
5612         (float:DF (match_dup 1)))
5613    (set (match_dup 0)
5614         (float_truncate:SF (match_dup 2)))]
5615   ""
5616   [(set_attr "length" "8")
5617    (set_attr "type" "fp")])
5618
5619 ;; Twiddles bits to avoid double rounding.
5620 ;; Bits that might be truncated when converting to DFmode are replaced
5621 ;; by a bit that won't be lost at that stage, but is below the SFmode
5622 ;; rounding position.
5623 (define_expand "floatdisf2_internal2"
5624   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5625                                               (const_int 53)))
5626               (clobber (reg:DI CA_REGNO))])
5627    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5628                                            (const_int 2047)))
5629    (set (match_dup 3) (plus:DI (match_dup 3)
5630                                (const_int 1)))
5631    (set (match_dup 0) (plus:DI (match_dup 0)
5632                                (const_int 2047)))
5633    (set (match_dup 4) (compare:CCUNS (match_dup 3)
5634                                      (const_int 2)))
5635    (set (match_dup 0) (ior:DI (match_dup 0)
5636                               (match_dup 1)))
5637    (set (match_dup 0) (and:DI (match_dup 0)
5638                               (const_int -2048)))
5639    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5640                            (label_ref (match_operand:DI 2 "" ""))
5641                            (pc)))
5642    (set (match_dup 0) (match_dup 1))]
5643   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5644    && !TARGET_FCFIDS"
5645   "
5646 {
5647   operands[3] = gen_reg_rtx (DImode);
5648   operands[4] = gen_reg_rtx (CCUNSmode);
5649 }")
5650
5651 (define_expand "floatunsdisf2"
5652   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5653         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5654   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5655    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5656   "")
5657
5658 (define_insn "floatunsdisf2_fcfidus"
5659   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5660         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5661   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5662    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5663   "@
5664    fcfidus %0,%1
5665    xscvuxdsp %x0,%x1"
5666   [(set_attr "type" "fp")])
5667
5668 (define_insn_and_split "*floatunsdisf2_mem"
5669   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5670         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5671    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5672   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5673    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5674   "#"
5675   "&& reload_completed"
5676   [(pc)]
5677   "
5678 {
5679   emit_move_insn (operands[2], operands[1]);
5680   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
5681   DONE;
5682 }"
5683   [(set_attr "length" "8")
5684    (set_attr "type" "fpload")])
5685 \f
5686 ;; Define the TImode operations that can be done in a small number
5687 ;; of instructions.  The & constraints are to prevent the register
5688 ;; allocator from allocating registers that overlap with the inputs
5689 ;; (for example, having an input in 7,8 and an output in 6,7).  We
5690 ;; also allow for the output being the same as one of the inputs.
5691
5692 (define_expand "addti3"
5693   [(set (match_operand:TI 0 "gpc_reg_operand" "")
5694         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
5695                  (match_operand:TI 2 "reg_or_short_operand" "")))]
5696   "TARGET_64BIT"
5697 {
5698   rtx lo0 = gen_lowpart (DImode, operands[0]);
5699   rtx lo1 = gen_lowpart (DImode, operands[1]);
5700   rtx lo2 = gen_lowpart (DImode, operands[2]);
5701   rtx hi0 = gen_highpart (DImode, operands[0]);
5702   rtx hi1 = gen_highpart (DImode, operands[1]);
5703   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
5704
5705   if (!reg_or_short_operand (lo2, DImode))
5706     lo2 = force_reg (DImode, lo2);
5707   if (!adde_operand (hi2, DImode))
5708     hi2 = force_reg (DImode, hi2);
5709
5710   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
5711   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
5712   DONE;
5713 })
5714
5715 (define_expand "subti3"
5716   [(set (match_operand:TI 0 "gpc_reg_operand" "")
5717         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
5718                   (match_operand:TI 2 "gpc_reg_operand" "")))]
5719   "TARGET_64BIT"
5720 {
5721   rtx lo0 = gen_lowpart (DImode, operands[0]);
5722   rtx lo1 = gen_lowpart (DImode, operands[1]);
5723   rtx lo2 = gen_lowpart (DImode, operands[2]);
5724   rtx hi0 = gen_highpart (DImode, operands[0]);
5725   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
5726   rtx hi2 = gen_highpart (DImode, operands[2]);
5727
5728   if (!reg_or_short_operand (lo1, DImode))
5729     lo1 = force_reg (DImode, lo1);
5730   if (!adde_operand (hi1, DImode))
5731     hi1 = force_reg (DImode, hi1);
5732
5733   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
5734   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
5735   DONE;
5736 })
5737
5738
5739 ;; Shift by a variable amount is too complex to be worth open-coding.  We
5740 ;; just handle shifts by constants.
5741 (define_insn "ashrdi3_no_power"
5742   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
5743         (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5744                      (match_operand:SI 2 "const_int_operand" "M,i")))
5745    (clobber (reg:SI CA_REGNO))]
5746   "!TARGET_POWERPC64"
5747 {
5748   switch (which_alternative)
5749     {
5750     default:
5751       gcc_unreachable ();
5752     case 0:
5753       if (WORDS_BIG_ENDIAN)
5754         return \"srawi %0,%1,31\;srawi %L0,%1,%h2\";
5755       else
5756         return \"srawi %L0,%L1,31\;srawi %0,%L1,%h2\";
5757     case 1:
5758       if (WORDS_BIG_ENDIAN)
5759         return \"srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2\";
5760       else
5761         return \"srwi %0,%1,%h2\;insrwi %0,%L1,%h2,0\;srawi %L0,%L1,%h2\";
5762     }
5763 }
5764   [(set_attr "type" "two,three")
5765    (set_attr "length" "8,12")])
5766
5767 (define_insn "*ashrdisi3_noppc64be"
5768   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5769         (subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
5770                                 (const_int 32)) 4))]
5771   "TARGET_32BIT && !TARGET_POWERPC64 && WORDS_BIG_ENDIAN"
5772   "*
5773 {
5774   if (REGNO (operands[0]) == REGNO (operands[1]))
5775     return \"\";
5776   else
5777     return \"mr %0,%1\";
5778 }"
5779    [(set_attr "length" "4")])
5780
5781 \f
5782 ;; PowerPC64 DImode operations.
5783
5784 (define_insn "*rotldi3_internal4"
5785   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
5786         (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
5787                            (match_operand:DI 2 "reg_or_cint_operand" "rn"))
5788                 (match_operand:DI 3 "mask64_operand" "n")))]
5789   "TARGET_POWERPC64"
5790   "rld%I2c%B3 %0,%1,%H2,%S3"
5791   [(set_attr "type" "shift")
5792    (set_attr "maybe_var_shift" "yes")])
5793
5794 (define_insn "*rotldi3_internal5"
5795   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
5796         (compare:CC (and:DI
5797                      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5798                                 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn"))
5799                      (match_operand:DI 3 "mask64_operand" "n,n"))
5800                     (const_int 0)))
5801    (clobber (match_scratch:DI 4 "=r,r"))]
5802   "TARGET_64BIT"
5803   "@
5804    rld%I2c%B3. %4,%1,%H2,%S3
5805    #"
5806   [(set_attr "type" "shift")
5807    (set_attr "maybe_var_shift" "yes")
5808    (set_attr "dot" "yes")
5809    (set_attr "length" "4,8")])
5810
5811 (define_split
5812   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
5813         (compare:CC (and:DI
5814                      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
5815                                 (match_operand:DI 2 "reg_or_cint_operand" ""))
5816                      (match_operand:DI 3 "mask64_operand" ""))
5817                     (const_int 0)))
5818    (clobber (match_scratch:DI 4 ""))]
5819   "TARGET_POWERPC64 && reload_completed"
5820   [(set (match_dup 4)
5821         (and:DI (rotate:DI (match_dup 1)
5822                                 (match_dup 2))
5823                      (match_dup 3)))
5824    (set (match_dup 0)
5825         (compare:CC (match_dup 4)
5826                     (const_int 0)))]
5827   "")
5828
5829 (define_insn "*rotldi3_internal6"
5830   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
5831         (compare:CC (and:DI
5832                      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5833                                 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn"))
5834                      (match_operand:DI 3 "mask64_operand" "n,n"))
5835                     (const_int 0)))
5836    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5837         (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
5838   "TARGET_64BIT"
5839   "@
5840    rld%I2c%B3. %0,%1,%H2,%S3
5841    #"
5842   [(set_attr "type" "shift")
5843    (set_attr "maybe_var_shift" "yes")
5844    (set_attr "dot" "yes")
5845    (set_attr "length" "4,8")])
5846
5847 (define_split
5848   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
5849         (compare:CC (and:DI
5850                      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
5851                                 (match_operand:DI 2 "reg_or_cint_operand" ""))
5852                      (match_operand:DI 3 "mask64_operand" ""))
5853                     (const_int 0)))
5854    (set (match_operand:DI 0 "gpc_reg_operand" "")
5855         (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
5856   "TARGET_POWERPC64 && reload_completed"
5857   [(set (match_dup 0)
5858         (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
5859    (set (match_dup 4)
5860         (compare:CC (match_dup 0)
5861                     (const_int 0)))]
5862   "")
5863
5864
5865 (define_insn "*ashldi3_internal4"
5866   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
5867         (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
5868                            (match_operand:SI 2 "const_int_operand" "i"))
5869                 (match_operand:DI 3 "const_int_operand" "n")))]
5870   "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
5871   "rldic %0,%1,%H2,%W3"
5872   [(set_attr "type" "shift")])
5873
5874 (define_insn "ashldi3_internal5"
5875   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
5876         (compare:CC
5877          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5878                             (match_operand:SI 2 "const_int_operand" "i,i"))
5879                  (match_operand:DI 3 "const_int_operand" "n,n"))
5880          (const_int 0)))
5881    (clobber (match_scratch:DI 4 "=r,r"))]
5882   "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
5883   "@
5884    rldic. %4,%1,%H2,%W3
5885    #"
5886   [(set_attr "type" "shift")
5887    (set_attr "dot" "yes")
5888    (set_attr "length" "4,8")])
5889
5890 (define_split
5891   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
5892         (compare:CC
5893          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
5894                             (match_operand:SI 2 "const_int_operand" ""))
5895                  (match_operand:DI 3 "const_int_operand" ""))
5896          (const_int 0)))
5897    (clobber (match_scratch:DI 4 ""))]
5898   "TARGET_POWERPC64 && reload_completed
5899    && includes_rldic_lshift_p (operands[2], operands[3])"
5900   [(set (match_dup 4)
5901         (and:DI (ashift:DI (match_dup 1) (match_dup 2))
5902                 (match_dup 3)))
5903    (set (match_dup 0)
5904         (compare:CC (match_dup 4)
5905                     (const_int 0)))]
5906   "")
5907
5908 (define_insn "*ashldi3_internal6"
5909   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
5910         (compare:CC
5911          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5912                             (match_operand:SI 2 "const_int_operand" "i,i"))
5913                     (match_operand:DI 3 "const_int_operand" "n,n"))
5914          (const_int 0)))
5915    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5916         (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
5917   "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
5918   "@
5919    rldic. %0,%1,%H2,%W3
5920    #"
5921   [(set_attr "type" "shift")
5922    (set_attr "dot" "yes")
5923    (set_attr "length" "4,8")])
5924
5925 (define_split
5926   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
5927         (compare:CC
5928          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
5929                             (match_operand:SI 2 "const_int_operand" ""))
5930                  (match_operand:DI 3 "const_int_operand" ""))
5931          (const_int 0)))
5932    (set (match_operand:DI 0 "gpc_reg_operand" "")
5933         (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
5934   "TARGET_POWERPC64 && reload_completed
5935    && includes_rldic_lshift_p (operands[2], operands[3])"
5936   [(set (match_dup 0)
5937         (and:DI (ashift:DI (match_dup 1) (match_dup 2))
5938                 (match_dup 3)))
5939    (set (match_dup 4)
5940         (compare:CC (match_dup 0)
5941                     (const_int 0)))]
5942   "")
5943
5944 (define_insn "*ashldi3_internal7"
5945   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
5946         (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
5947                            (match_operand:SI 2 "const_int_operand" "i"))
5948                 (match_operand:DI 3 "mask64_operand" "n")))]
5949   "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
5950   "rldicr %0,%1,%H2,%S3"
5951   [(set_attr "type" "shift")])
5952
5953 (define_insn "ashldi3_internal8"
5954   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
5955         (compare:CC
5956          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5957                             (match_operand:SI 2 "const_int_operand" "i,i"))
5958                  (match_operand:DI 3 "mask64_operand" "n,n"))
5959          (const_int 0)))
5960    (clobber (match_scratch:DI 4 "=r,r"))]
5961   "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
5962   "@
5963    rldicr. %4,%1,%H2,%S3
5964    #"
5965   [(set_attr "type" "shift")
5966    (set_attr "dot" "yes")
5967    (set_attr "length" "4,8")])
5968
5969 (define_split
5970   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
5971         (compare:CC
5972          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
5973                             (match_operand:SI 2 "const_int_operand" ""))
5974                  (match_operand:DI 3 "mask64_operand" ""))
5975          (const_int 0)))
5976    (clobber (match_scratch:DI 4 ""))]
5977   "TARGET_POWERPC64 && reload_completed
5978    && includes_rldicr_lshift_p (operands[2], operands[3])"
5979   [(set (match_dup 4)
5980         (and:DI (ashift:DI (match_dup 1) (match_dup 2))
5981                 (match_dup 3)))
5982    (set (match_dup 0)
5983         (compare:CC (match_dup 4)
5984                     (const_int 0)))]
5985   "")
5986
5987 (define_insn "*ashldi3_internal9"
5988   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
5989         (compare:CC
5990          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5991                             (match_operand:SI 2 "const_int_operand" "i,i"))
5992                     (match_operand:DI 3 "mask64_operand" "n,n"))
5993          (const_int 0)))
5994    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5995         (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
5996   "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
5997   "@
5998    rldicr. %0,%1,%H2,%S3
5999    #"
6000   [(set_attr "type" "shift")
6001    (set_attr "dot" "yes")
6002    (set_attr "length" "4,8")])
6003
6004 (define_split
6005   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
6006         (compare:CC
6007          (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
6008                             (match_operand:SI 2 "const_int_operand" ""))
6009                  (match_operand:DI 3 "mask64_operand" ""))
6010          (const_int 0)))
6011    (set (match_operand:DI 0 "gpc_reg_operand" "")
6012         (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
6013   "TARGET_POWERPC64 && reload_completed
6014    && includes_rldicr_lshift_p (operands[2], operands[3])"
6015   [(set (match_dup 0)
6016         (and:DI (ashift:DI (match_dup 1) (match_dup 2))
6017                 (match_dup 3)))
6018    (set (match_dup 4)
6019         (compare:CC (match_dup 0)
6020                     (const_int 0)))]
6021   "")
6022
6023
6024 (define_insn_and_split "*anddi3_2rld"
6025   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6026         (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
6027                 (match_operand:DI 2 "and_2rld_operand" "n")))]
6028   "TARGET_POWERPC64"
6029   "#"
6030   ""
6031   [(set (match_dup 0)
6032         (and:DI (rotate:DI (match_dup 1)
6033                            (match_dup 4))
6034                 (match_dup 5)))
6035    (set (match_dup 0)
6036         (and:DI (rotate:DI (match_dup 0)
6037                            (match_dup 6))
6038                 (match_dup 7)))]
6039 {
6040   build_mask64_2_operands (operands[2], &operands[4]);
6041 }
6042   [(set_attr "length" "8")])
6043
6044 (define_insn_and_split "*anddi3_2rld_dot"
6045   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6046         (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
6047                             (match_operand:DI 2 "and_2rld_operand" "n,n"))
6048                     (const_int 0)))
6049    (clobber (match_scratch:DI 0 "=r,r"))]
6050   "TARGET_64BIT && rs6000_gen_cell_microcode"
6051   "@
6052    #
6053    #"
6054   "&& reload_completed"
6055   [(set (match_dup 0)
6056         (and:DI (rotate:DI (match_dup 1)
6057                            (match_dup 4))
6058                 (match_dup 5)))
6059    (parallel [(set (match_dup 3)
6060                    (compare:CC (and:DI (rotate:DI (match_dup 0)
6061                                                   (match_dup 6))
6062                                        (match_dup 7))
6063                                (const_int 0)))
6064               (clobber (match_dup 0))])]
6065 {
6066   build_mask64_2_operands (operands[2], &operands[4]);
6067 }
6068   [(set_attr "type" "two")
6069    (set_attr "dot" "yes")
6070    (set_attr "length" "8,12")])
6071
6072 (define_insn_and_split "*anddi3_2rld_dot2"
6073   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6074         (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
6075                             (match_operand:DI 2 "and_2rld_operand" "n,n"))
6076                     (const_int 0)))
6077    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6078         (and:DI (match_dup 1)
6079                 (match_dup 2)))]
6080   "TARGET_64BIT && rs6000_gen_cell_microcode"
6081   "@
6082    #
6083    #"
6084   "&& reload_completed"
6085   [(set (match_dup 0)
6086         (and:DI (rotate:DI (match_dup 1)
6087                            (match_dup 4))
6088                 (match_dup 5)))
6089    (parallel [(set (match_dup 3)
6090                    (compare:CC (and:DI (rotate:DI (match_dup 0)
6091                                                   (match_dup 6))
6092                                        (match_dup 7))
6093                                (const_int 0)))
6094               (set (match_dup 0)
6095                    (and:DI (rotate:DI (match_dup 0)
6096                                       (match_dup 6))
6097                            (match_dup 7)))])]
6098 {
6099   build_mask64_2_operands (operands[2], &operands[4]);
6100 }
6101   [(set_attr "type" "two")
6102    (set_attr "dot" "yes")
6103    (set_attr "length" "8,12")])
6104 \f
6105 ;; 128-bit logical operations expanders
6106
6107 (define_expand "and<mode>3"
6108   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6109         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6110                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6111   ""
6112   "")
6113
6114 (define_expand "ior<mode>3"
6115   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6116         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6117                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6118   ""
6119   "")
6120
6121 (define_expand "xor<mode>3"
6122   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6123         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6124                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6125   ""
6126   "")
6127
6128 (define_expand "one_cmpl<mode>2"
6129   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6130         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6131   ""
6132   "")
6133
6134 (define_expand "nor<mode>3"
6135   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6136         (and:BOOL_128
6137          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6138          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6139   ""
6140   "")
6141
6142 (define_expand "andc<mode>3"
6143   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6144         (and:BOOL_128
6145          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6146          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6147   ""
6148   "")
6149
6150 ;; Power8 vector logical instructions.
6151 (define_expand "eqv<mode>3"
6152   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6153         (not:BOOL_128
6154          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6155                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6156   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6157   "")
6158
6159 ;; Rewrite nand into canonical form
6160 (define_expand "nand<mode>3"
6161   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6162         (ior:BOOL_128
6163          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6164          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6165   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6166   "")
6167
6168 ;; The canonical form is to have the negated element first, so we need to
6169 ;; reverse arguments.
6170 (define_expand "orc<mode>3"
6171   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6172         (ior:BOOL_128
6173          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6174          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6175   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6176   "")
6177
6178 ;; 128-bit logical operations insns and split operations
6179 (define_insn_and_split "*and<mode>3_internal"
6180   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6181         (and:BOOL_128
6182          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6183          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6184   ""
6185 {
6186   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6187     return "xxland %x0,%x1,%x2";
6188
6189   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6190     return "vand %0,%1,%2";
6191
6192   return "#";
6193 }
6194   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6195   [(const_int 0)]
6196 {
6197   rs6000_split_logical (operands, AND, false, false, false);
6198   DONE;
6199 }
6200   [(set (attr "type")
6201       (if_then_else
6202         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6203         (const_string "vecsimple")
6204         (const_string "integer")))
6205    (set (attr "length")
6206       (if_then_else
6207         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6208         (const_string "4")
6209         (if_then_else
6210          (match_test "TARGET_POWERPC64")
6211          (const_string "8")
6212          (const_string "16"))))])
6213
6214 ;; 128-bit IOR/XOR
6215 (define_insn_and_split "*bool<mode>3_internal"
6216   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6217         (match_operator:BOOL_128 3 "boolean_or_operator"
6218          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6219           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6220   ""
6221 {
6222   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6223     return "xxl%q3 %x0,%x1,%x2";
6224
6225   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6226     return "v%q3 %0,%1,%2";
6227
6228   return "#";
6229 }
6230   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6231   [(const_int 0)]
6232 {
6233   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6234   DONE;
6235 }
6236   [(set (attr "type")
6237       (if_then_else
6238         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6239         (const_string "vecsimple")
6240         (const_string "integer")))
6241    (set (attr "length")
6242       (if_then_else
6243         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6244         (const_string "4")
6245         (if_then_else
6246          (match_test "TARGET_POWERPC64")
6247          (const_string "8")
6248          (const_string "16"))))])
6249
6250 ;; 128-bit ANDC/ORC
6251 (define_insn_and_split "*boolc<mode>3_internal1"
6252   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6253         (match_operator:BOOL_128 3 "boolean_operator"
6254          [(not:BOOL_128
6255            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6256           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6257   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6258 {
6259   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6260     return "xxl%q3 %x0,%x1,%x2";
6261
6262   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6263     return "v%q3 %0,%1,%2";
6264
6265   return "#";
6266 }
6267   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6268    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6269   [(const_int 0)]
6270 {
6271   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6272   DONE;
6273 }
6274   [(set (attr "type")
6275       (if_then_else
6276         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6277         (const_string "vecsimple")
6278         (const_string "integer")))
6279    (set (attr "length")
6280       (if_then_else
6281         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6282         (const_string "4")
6283         (if_then_else
6284          (match_test "TARGET_POWERPC64")
6285          (const_string "8")
6286          (const_string "16"))))])
6287
6288 (define_insn_and_split "*boolc<mode>3_internal2"
6289   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6290         (match_operator:TI2 3 "boolean_operator"
6291          [(not:TI2
6292            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6293           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6294   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6295   "#"
6296   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6297   [(const_int 0)]
6298 {
6299   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6300   DONE;
6301 }
6302   [(set_attr "type" "integer")
6303    (set (attr "length")
6304         (if_then_else
6305          (match_test "TARGET_POWERPC64")
6306          (const_string "8")
6307          (const_string "16")))])
6308
6309 ;; 128-bit NAND/NOR
6310 (define_insn_and_split "*boolcc<mode>3_internal1"
6311   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6312         (match_operator:BOOL_128 3 "boolean_operator"
6313          [(not:BOOL_128
6314            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6315           (not:BOOL_128
6316            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6317   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6318 {
6319   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6320     return "xxl%q3 %x0,%x1,%x2";
6321
6322   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6323     return "v%q3 %0,%1,%2";
6324
6325   return "#";
6326 }
6327   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6328    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6329   [(const_int 0)]
6330 {
6331   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6332   DONE;
6333 }
6334   [(set (attr "type")
6335       (if_then_else
6336         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6337         (const_string "vecsimple")
6338         (const_string "integer")))
6339    (set (attr "length")
6340       (if_then_else
6341         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6342         (const_string "4")
6343         (if_then_else
6344          (match_test "TARGET_POWERPC64")
6345          (const_string "8")
6346          (const_string "16"))))])
6347
6348 (define_insn_and_split "*boolcc<mode>3_internal2"
6349   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6350         (match_operator:TI2 3 "boolean_operator"
6351          [(not:TI2
6352            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6353           (not:TI2
6354            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6355   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6356   "#"
6357   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6358   [(const_int 0)]
6359 {
6360   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6361   DONE;
6362 }
6363   [(set_attr "type" "integer")
6364    (set (attr "length")
6365         (if_then_else
6366          (match_test "TARGET_POWERPC64")
6367          (const_string "8")
6368          (const_string "16")))])
6369
6370
6371 ;; 128-bit EQV
6372 (define_insn_and_split "*eqv<mode>3_internal1"
6373   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6374         (not:BOOL_128
6375          (xor:BOOL_128
6376           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6377           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6378   "TARGET_P8_VECTOR"
6379 {
6380   if (vsx_register_operand (operands[0], <MODE>mode))
6381     return "xxleqv %x0,%x1,%x2";
6382
6383   return "#";
6384 }
6385   "TARGET_P8_VECTOR && reload_completed
6386    && int_reg_operand (operands[0], <MODE>mode)"
6387   [(const_int 0)]
6388 {
6389   rs6000_split_logical (operands, XOR, true, false, false);
6390   DONE;
6391 }
6392   [(set (attr "type")
6393       (if_then_else
6394         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6395         (const_string "vecsimple")
6396         (const_string "integer")))
6397    (set (attr "length")
6398       (if_then_else
6399         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6400         (const_string "4")
6401         (if_then_else
6402          (match_test "TARGET_POWERPC64")
6403          (const_string "8")
6404          (const_string "16"))))])
6405
6406 (define_insn_and_split "*eqv<mode>3_internal2"
6407   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6408         (not:TI2
6409          (xor:TI2
6410           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6411           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6412   "!TARGET_P8_VECTOR"
6413   "#"
6414   "reload_completed && !TARGET_P8_VECTOR"
6415   [(const_int 0)]
6416 {
6417   rs6000_split_logical (operands, XOR, true, false, false);
6418   DONE;
6419 }
6420   [(set_attr "type" "integer")
6421    (set (attr "length")
6422         (if_then_else
6423          (match_test "TARGET_POWERPC64")
6424          (const_string "8")
6425          (const_string "16")))])
6426
6427 ;; 128-bit one's complement
6428 (define_insn_and_split "*one_cmpl<mode>3_internal"
6429   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6430         (not:BOOL_128
6431           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6432   ""
6433 {
6434   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6435     return "xxlnor %x0,%x1,%x1";
6436
6437   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6438     return "vnor %0,%1,%1";
6439
6440   return "#";
6441 }
6442   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6443   [(const_int 0)]
6444 {
6445   rs6000_split_logical (operands, NOT, false, false, false);
6446   DONE;
6447 }
6448   [(set (attr "type")
6449       (if_then_else
6450         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6451         (const_string "vecsimple")
6452         (const_string "integer")))
6453    (set (attr "length")
6454       (if_then_else
6455         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6456         (const_string "4")
6457         (if_then_else
6458          (match_test "TARGET_POWERPC64")
6459          (const_string "8")
6460          (const_string "16"))))])
6461
6462 \f
6463 ;; Now define ways of moving data around.
6464
6465 ;; Set up a register with a value from the GOT table
6466
6467 (define_expand "movsi_got"
6468   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6469         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6470                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6471   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6472   "
6473 {
6474   if (GET_CODE (operands[1]) == CONST)
6475     {
6476       rtx offset = const0_rtx;
6477       HOST_WIDE_INT value;
6478
6479       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6480       value = INTVAL (offset);
6481       if (value != 0)
6482         {
6483           rtx tmp = (!can_create_pseudo_p ()
6484                      ? operands[0]
6485                      : gen_reg_rtx (Pmode));
6486           emit_insn (gen_movsi_got (tmp, operands[1]));
6487           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6488           DONE;
6489         }
6490     }
6491
6492   operands[2] = rs6000_got_register (operands[1]);
6493 }")
6494
6495 (define_insn "*movsi_got_internal"
6496   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6497         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6498                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6499                    UNSPEC_MOVSI_GOT))]
6500   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6501   "lwz %0,%a1@got(%2)"
6502   [(set_attr "type" "load")])
6503
6504 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6505 ;; didn't get allocated to a hard register.
6506 (define_split
6507   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6508         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6509                     (match_operand:SI 2 "memory_operand" "")]
6510                    UNSPEC_MOVSI_GOT))]
6511   "DEFAULT_ABI == ABI_V4
6512     && flag_pic == 1
6513     && (reload_in_progress || reload_completed)"
6514   [(set (match_dup 0) (match_dup 2))
6515    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6516                                  UNSPEC_MOVSI_GOT))]
6517   "")
6518
6519 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6520 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6521 ;; and this is even supposed to be faster, but it is simpler not to get
6522 ;; integers in the TOC.
6523 (define_insn "movsi_low"
6524   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6525         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6526                            (match_operand 2 "" ""))))]
6527   "TARGET_MACHO && ! TARGET_64BIT"
6528   "lwz %0,lo16(%2)(%1)"
6529   [(set_attr "type" "load")
6530    (set_attr "length" "4")])
6531
6532 (define_insn "*movsi_internal1"
6533   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6534         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6535   "!TARGET_SINGLE_FPU &&
6536    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6537   "@
6538    mr %0,%1
6539    la %0,%a1
6540    lwz%U1%X1 %0,%1
6541    stw%U0%X0 %1,%0
6542    li %0,%1
6543    lis %0,%v1
6544    #
6545    mf%1 %0
6546    mt%0 %1
6547    mt%0 %1
6548    nop"
6549   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6550    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6551
6552 (define_insn "*movsi_internal1_single"
6553   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6554         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6555   "TARGET_SINGLE_FPU &&
6556    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6557   "@
6558    mr %0,%1
6559    la %0,%a1
6560    lwz%U1%X1 %0,%1
6561    stw%U0%X0 %1,%0
6562    li %0,%1
6563    lis %0,%v1
6564    #
6565    mf%1 %0
6566    mt%0 %1
6567    mt%0 %1
6568    nop
6569    stfs%U0%X0 %1,%0
6570    lfs%U1%X1 %0,%1"
6571   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6572    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6573
6574 ;; Split a load of a large constant into the appropriate two-insn
6575 ;; sequence.
6576
6577 (define_split
6578   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6579         (match_operand:SI 1 "const_int_operand" ""))]
6580   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6581    && (INTVAL (operands[1]) & 0xffff) != 0"
6582   [(set (match_dup 0)
6583         (match_dup 2))
6584    (set (match_dup 0)
6585         (ior:SI (match_dup 0)
6586                 (match_dup 3)))]
6587   "
6588 {
6589   if (rs6000_emit_set_const (operands[0], operands[1]))
6590     DONE;
6591   else
6592     FAIL;
6593 }")
6594
6595 (define_insn "*mov<mode>_internal2"
6596   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6597         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6598                     (const_int 0)))
6599    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6600   ""
6601   "@
6602    cmp<wd>i %2,%0,0
6603    mr. %0,%1
6604    #"
6605   [(set_attr "type" "cmp,logical,cmp")
6606    (set_attr "dot" "yes")
6607    (set_attr "length" "4,4,8")])
6608
6609 (define_split
6610   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6611         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6612                     (const_int 0)))
6613    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6614   "reload_completed"
6615   [(set (match_dup 0) (match_dup 1))
6616    (set (match_dup 2)
6617         (compare:CC (match_dup 0)
6618                     (const_int 0)))]
6619   "")
6620 \f
6621 (define_insn "*movhi_internal"
6622   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6623         (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6624   "gpc_reg_operand (operands[0], HImode)
6625    || gpc_reg_operand (operands[1], HImode)"
6626   "@
6627    mr %0,%1
6628    lhz%U1%X1 %0,%1
6629    sth%U0%X0 %1,%0
6630    li %0,%w1
6631    mf%1 %0
6632    mt%0 %1
6633    nop"
6634   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6635
6636 (define_expand "mov<mode>"
6637   [(set (match_operand:INT 0 "general_operand" "")
6638         (match_operand:INT 1 "any_operand" ""))]
6639   ""
6640   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6641
6642 (define_insn "*movqi_internal"
6643   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6644         (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6645   "gpc_reg_operand (operands[0], QImode)
6646    || gpc_reg_operand (operands[1], QImode)"
6647   "@
6648    mr %0,%1
6649    lbz%U1%X1 %0,%1
6650    stb%U0%X0 %1,%0
6651    li %0,%1
6652    mf%1 %0
6653    mt%0 %1
6654    nop"
6655   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6656 \f
6657 ;; Here is how to move condition codes around.  When we store CC data in
6658 ;; an integer register or memory, we store just the high-order 4 bits.
6659 ;; This lets us not shift in the most common case of CR0.
6660 (define_expand "movcc"
6661   [(set (match_operand:CC 0 "nonimmediate_operand" "")
6662         (match_operand:CC 1 "nonimmediate_operand" ""))]
6663   ""
6664   "")
6665
6666 (define_insn "*movcc_internal1"
6667   [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6668         (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6669   "register_operand (operands[0], CCmode)
6670    || register_operand (operands[1], CCmode)"
6671   "@
6672    mcrf %0,%1
6673    mtcrf 128,%1
6674    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6675    crxor %0,%0,%0
6676    mfcr %0%Q1
6677    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6678    mr %0,%1
6679    li %0,%1
6680    mf%1 %0
6681    mt%0 %1
6682    lwz%U1%X1 %0,%1
6683    stw%U0%X0 %1,%0"
6684   [(set (attr "type")
6685      (cond [(eq_attr "alternative" "0,3")
6686                 (const_string "cr_logical")
6687             (eq_attr "alternative" "1,2")
6688                 (const_string "mtcr")
6689             (eq_attr "alternative" "6,7")
6690                 (const_string "integer")
6691             (eq_attr "alternative" "8")
6692                 (const_string "mfjmpr")
6693             (eq_attr "alternative" "9")
6694                 (const_string "mtjmpr")
6695             (eq_attr "alternative" "10")
6696                 (const_string "load")
6697             (eq_attr "alternative" "11")
6698                 (const_string "store")
6699             (match_test "TARGET_MFCRF")
6700                 (const_string "mfcrf")
6701            ]
6702         (const_string "mfcr")))
6703    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6704 \f
6705 ;; For floating-point, we normally deal with the floating-point registers
6706 ;; unless -msoft-float is used.  The sole exception is that parameter passing
6707 ;; can produce floating-point values in fixed-point registers.  Unless the
6708 ;; value is a simple constant or already in memory, we deal with this by
6709 ;; allocating memory and copying the value explicitly via that memory location.
6710
6711 ;; Move 32-bit binary/decimal floating point
6712 (define_expand "mov<mode>"
6713   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6714         (match_operand:FMOVE32 1 "any_operand" ""))]
6715   "<fmove_ok>"
6716   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6717
6718 (define_split
6719   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6720         (match_operand:FMOVE32 1 "const_double_operand" ""))]
6721   "reload_completed
6722    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6723        || (GET_CODE (operands[0]) == SUBREG
6724            && GET_CODE (SUBREG_REG (operands[0])) == REG
6725            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6726   [(set (match_dup 2) (match_dup 3))]
6727   "
6728 {
6729   long l;
6730   REAL_VALUE_TYPE rv;
6731
6732   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
6733   <real_value_to_target> (rv, l);
6734
6735   if (! TARGET_POWERPC64)
6736     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6737   else
6738     operands[2] = gen_lowpart (SImode, operands[0]);
6739
6740   operands[3] = gen_int_mode (l, SImode);
6741 }")
6742
6743 (define_insn "mov<mode>_hardfloat"
6744   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_sm>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h")
6745         (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,j,<f32_lm>,<f32_sr>,Z,<f32_av>,r,<f32_dm>,r,h,0"))]
6746   "(gpc_reg_operand (operands[0], <MODE>mode)
6747    || gpc_reg_operand (operands[1], <MODE>mode))
6748    && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6749   "@
6750    mr %0,%1
6751    lwz%U1%X1 %0,%1
6752    stw%U0%X0 %1,%0
6753    fmr %0,%1
6754    xscpsgndp %x0,%x1,%x1
6755    xxlxor %x0,%x0,%x0
6756    li %0,0
6757    <f32_li>
6758    <f32_si>
6759    <f32_lv>
6760    <f32_sv>
6761    mtvsrwz %x0,%1
6762    mfvsrwz %0,%x1
6763    mt%0 %1
6764    mf%1 %0
6765    nop"
6766   [(set_attr "type" "*,load,store,fp,fp,vecsimple,integer,fpload,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*")
6767    (set_attr "length" "4")])
6768
6769 (define_insn "*mov<mode>_softfloat"
6770   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6771         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6772   "(gpc_reg_operand (operands[0], <MODE>mode)
6773    || gpc_reg_operand (operands[1], <MODE>mode))
6774    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6775   "@
6776    mr %0,%1
6777    mt%0 %1
6778    mf%1 %0
6779    lwz%U1%X1 %0,%1
6780    stw%U0%X0 %1,%0
6781    li %0,%1
6782    lis %0,%v1
6783    #
6784    #
6785    nop"
6786   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6787    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6788
6789 \f
6790 ;; Move 64-bit binary/decimal floating point
6791 (define_expand "mov<mode>"
6792   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6793         (match_operand:FMOVE64 1 "any_operand" ""))]
6794   ""
6795   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6796
6797 (define_split
6798   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6799         (match_operand:FMOVE64 1 "const_int_operand" ""))]
6800   "! TARGET_POWERPC64 && reload_completed
6801    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6802        || (GET_CODE (operands[0]) == SUBREG
6803            && GET_CODE (SUBREG_REG (operands[0])) == REG
6804            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6805   [(set (match_dup 2) (match_dup 4))
6806    (set (match_dup 3) (match_dup 1))]
6807   "
6808 {
6809   int endian = (WORDS_BIG_ENDIAN == 0);
6810   HOST_WIDE_INT value = INTVAL (operands[1]);
6811
6812   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6813   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6814   operands[4] = GEN_INT (value >> 32);
6815   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6816 }")
6817
6818 (define_split
6819   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6820         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6821   "! TARGET_POWERPC64 && reload_completed
6822    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6823        || (GET_CODE (operands[0]) == SUBREG
6824            && GET_CODE (SUBREG_REG (operands[0])) == REG
6825            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6826   [(set (match_dup 2) (match_dup 4))
6827    (set (match_dup 3) (match_dup 5))]
6828   "
6829 {
6830   int endian = (WORDS_BIG_ENDIAN == 0);
6831   long l[2];
6832   REAL_VALUE_TYPE rv;
6833
6834   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
6835   <real_value_to_target> (rv, l);
6836
6837   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6838   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6839   operands[4] = gen_int_mode (l[endian], SImode);
6840   operands[5] = gen_int_mode (l[1 - endian], SImode);
6841 }")
6842
6843 (define_split
6844   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6845         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6846   "TARGET_POWERPC64 && reload_completed
6847    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6848        || (GET_CODE (operands[0]) == SUBREG
6849            && GET_CODE (SUBREG_REG (operands[0])) == REG
6850            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6851   [(set (match_dup 2) (match_dup 3))]
6852   "
6853 {
6854   int endian = (WORDS_BIG_ENDIAN == 0);
6855   long l[2];
6856   REAL_VALUE_TYPE rv;
6857   HOST_WIDE_INT val;
6858
6859   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
6860   <real_value_to_target> (rv, l);
6861
6862   operands[2] = gen_lowpart (DImode, operands[0]);
6863   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
6864   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6865          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6866
6867   operands[3] = gen_int_mode (val, DImode);
6868 }")
6869
6870 ;; Don't have reload use general registers to load a constant.  It is
6871 ;; less efficient than loading the constant into an FP register, since
6872 ;; it will probably be used there.
6873
6874 ;; The move constraints are ordered to prefer floating point registers before
6875 ;; general purpose registers to avoid doing a store and a load to get the value
6876 ;; into a floating point register when it is needed for a floating point
6877 ;; operation.  Prefer traditional floating point registers over VSX registers,
6878 ;; since the D-form version of the memory instructions does not need a GPR for
6879 ;; reloading.
6880
6881 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6882 ;; except for 0.0 which can be created on VSX with an xor instruction.
6883
6884 (define_insn "*mov<mode>_hardfloat32"
6885   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6886         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r"))]
6887   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
6888    && (gpc_reg_operand (operands[0], <MODE>mode)
6889        || gpc_reg_operand (operands[1], <MODE>mode))"
6890   "@
6891    stfd%U0%X0 %1,%0
6892    lfd%U1%X1 %0,%1
6893    fmr %0,%1
6894    lxsd%U1x %x0,%y1
6895    stxsd%U0x %x1,%y0
6896    xxlor %x0,%x1,%x1
6897    xxlxor %x0,%x0,%x0
6898    #
6899    #
6900    #
6901    #"
6902   [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,two,store,load,two")
6903    (set_attr "length" "4,4,4,4,4,4,4,8,8,8,8")])
6904
6905 (define_insn "*mov<mode>_softfloat32"
6906   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6907         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6908   "! TARGET_POWERPC64 
6909    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
6910        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6911        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6912    && (gpc_reg_operand (operands[0], <MODE>mode)
6913        || gpc_reg_operand (operands[1], <MODE>mode))"
6914   "#"
6915   [(set_attr "type" "store,load,two,*,*,*")
6916    (set_attr "length" "8,8,8,8,12,16")])
6917
6918 ; ld/std require word-aligned displacements -> 'Y' constraint.
6919 ; List Y->r and r->Y before r->r for reload.
6920 (define_insn "*mov<mode>_hardfloat64"
6921   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
6922         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
6923   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6924    && (gpc_reg_operand (operands[0], <MODE>mode)
6925        || gpc_reg_operand (operands[1], <MODE>mode))"
6926   "@
6927    stfd%U0%X0 %1,%0
6928    lfd%U1%X1 %0,%1
6929    fmr %0,%1
6930    lxsd%U1x %x0,%y1
6931    stxsd%U0x %x1,%y0
6932    xxlor %x0,%x1,%x1
6933    xxlxor %x0,%x0,%x0
6934    li %0,0
6935    std%U0%X0 %1,%0
6936    ld%U1%X1 %0,%1
6937    mr %0,%1
6938    mt%0 %1
6939    mf%1 %0
6940    nop
6941    mftgpr %0,%1
6942    mffgpr %0,%1
6943    mfvsrd %0,%x1
6944    mtvsrd %x0,%1"
6945   [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6946    (set_attr "length" "4")])
6947
6948 (define_insn "*mov<mode>_softfloat64"
6949   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6950         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6951   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6952    && (gpc_reg_operand (operands[0], <MODE>mode)
6953        || gpc_reg_operand (operands[1], <MODE>mode))"
6954   "@
6955    std%U0%X0 %1,%0
6956    ld%U1%X1 %0,%1
6957    mr %0,%1
6958    mt%0 %1
6959    mf%1 %0
6960    #
6961    #
6962    #
6963    nop"
6964   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6965    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6966 \f
6967 (define_expand "mov<mode>"
6968   [(set (match_operand:FMOVE128 0 "general_operand" "")
6969         (match_operand:FMOVE128 1 "any_operand" ""))]
6970   ""
6971   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6972
6973 ;; It's important to list Y->r and r->Y before r->r because otherwise
6974 ;; reload, given m->r, will try to pick r->r and reload it, which
6975 ;; doesn't make progress.
6976
6977 ;; We can't split little endian direct moves of TDmode, because the words are
6978 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
6979 ;; problematical.  Don't allow direct move for this case.
6980
6981 (define_insn_and_split "*mov<mode>_64bit_dm"
6982   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r,r,wm")
6983         (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jY,r,wm,r"))]
6984   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6985    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6986    && (gpc_reg_operand (operands[0], <MODE>mode)
6987        || gpc_reg_operand (operands[1], <MODE>mode))"
6988   "#"
6989   "&& reload_completed"
6990   [(pc)]
6991 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6992   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6993
6994 (define_insn_and_split "*movtd_64bit_nodm"
6995   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
6996         (match_operand:TD 1 "input_operand" "d,m,d,j,r,jY,r"))]
6997   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6998    && (gpc_reg_operand (operands[0], TDmode)
6999        || gpc_reg_operand (operands[1], TDmode))"
7000   "#"
7001   "&& reload_completed"
7002   [(pc)]
7003 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7004   [(set_attr "length" "8,8,8,8,12,12,8")])
7005
7006 (define_insn_and_split "*mov<mode>_32bit"
7007   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
7008         (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jY,r"))]
7009   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7010    && (gpc_reg_operand (operands[0], <MODE>mode)
7011        || gpc_reg_operand (operands[1], <MODE>mode))"
7012   "#"
7013   "&& reload_completed"
7014   [(pc)]
7015 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7016   [(set_attr "length" "8,8,8,8,20,20,16")])
7017
7018 (define_insn_and_split "*mov<mode>_softfloat"
7019   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7020         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7021   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7022    && (gpc_reg_operand (operands[0], <MODE>mode)
7023        || gpc_reg_operand (operands[1], <MODE>mode))"
7024   "#"
7025   "&& reload_completed"
7026   [(pc)]
7027 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7028   [(set_attr "length" "20,20,16")])
7029
7030 (define_expand "extenddftf2"
7031   [(set (match_operand:TF 0 "nonimmediate_operand" "")
7032         (float_extend:TF (match_operand:DF 1 "input_operand" "")))]
7033   "!TARGET_IEEEQUAD
7034    && TARGET_HARD_FLOAT
7035    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7036    && TARGET_LONG_DOUBLE_128"
7037 {
7038   if (TARGET_E500_DOUBLE)
7039     emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7040   else
7041     emit_insn (gen_extenddftf2_fprs (operands[0], operands[1]));
7042   DONE;
7043 })
7044
7045 (define_expand "extenddftf2_fprs"
7046   [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
7047                    (float_extend:TF (match_operand:DF 1 "input_operand" "")))
7048               (use (match_dup 2))])]
7049   "!TARGET_IEEEQUAD
7050    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7051    && TARGET_LONG_DOUBLE_128"
7052 {
7053   /* VSX can create 0.0 directly, otherwise let rs6000_emit_move create
7054      the proper constant.  */
7055   if (TARGET_VSX)
7056     operands[2] = CONST0_RTX (DFmode);
7057   else
7058     {
7059       operands[2] = gen_reg_rtx (DFmode);
7060       rs6000_emit_move (operands[2], CONST0_RTX (DFmode), DFmode);
7061     }
7062 })
7063
7064 (define_insn_and_split "*extenddftf2_internal"
7065   [(set (match_operand:TF 0 "nonimmediate_operand" "=m,Y,ws,d,&d")
7066        (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,md")))
7067    (use (match_operand:DF 2 "zero_reg_mem_operand" "d,r,j,m,d"))]
7068   "!TARGET_IEEEQUAD
7069    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7070    && TARGET_LONG_DOUBLE_128"
7071   "#"
7072   "&& reload_completed"
7073   [(pc)]
7074 {
7075   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7076   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7077   emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word),
7078                   operands[1]);
7079   emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word),
7080                   operands[2]);
7081   DONE;
7082 })
7083
7084 (define_expand "extendsftf2"
7085   [(set (match_operand:TF 0 "nonimmediate_operand" "")
7086         (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
7087   "!TARGET_IEEEQUAD
7088    && TARGET_HARD_FLOAT
7089    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7090    && TARGET_LONG_DOUBLE_128"
7091 {
7092   rtx tmp = gen_reg_rtx (DFmode);
7093   emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7094   emit_insn (gen_extenddftf2 (operands[0], tmp));
7095   DONE;
7096 })
7097
7098 (define_expand "trunctfdf2"
7099   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7100         (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))]
7101   "!TARGET_IEEEQUAD
7102    && TARGET_HARD_FLOAT
7103    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7104    && TARGET_LONG_DOUBLE_128"
7105   "")
7106
7107 (define_insn_and_split "trunctfdf2_internal1"
7108   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7109         (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,d")))]
7110   "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
7111    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7112   "@
7113    #
7114    fmr %0,%1"
7115   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7116   [(const_int 0)]
7117 {
7118   emit_note (NOTE_INSN_DELETED);
7119   DONE;
7120 }
7121   [(set_attr "type" "fp")])
7122
7123 (define_insn "trunctfdf2_internal2"
7124   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7125         (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "d")))]
7126   "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
7127    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7128    && TARGET_LONG_DOUBLE_128"
7129   "fadd %0,%1,%L1"
7130   [(set_attr "type" "fp")
7131    (set_attr "fp_type" "fp_addsub_d")])
7132
7133 (define_expand "trunctfsf2"
7134   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7135         (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "")))]
7136   "!TARGET_IEEEQUAD
7137    && TARGET_HARD_FLOAT
7138    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7139    && TARGET_LONG_DOUBLE_128"
7140 {
7141   if (TARGET_E500_DOUBLE)
7142     emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7143   else
7144     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7145   DONE;
7146 })
7147
7148 (define_insn_and_split "trunctfsf2_fprs"
7149   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7150         (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "d")))
7151    (clobber (match_scratch:DF 2 "=d"))]
7152   "!TARGET_IEEEQUAD
7153    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
7154    && TARGET_LONG_DOUBLE_128"
7155   "#"
7156   "&& reload_completed"
7157   [(set (match_dup 2)
7158         (float_truncate:DF (match_dup 1)))
7159    (set (match_dup 0)
7160         (float_truncate:SF (match_dup 2)))]
7161   "")
7162
7163 (define_expand "floatsitf2"
7164   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7165         (float:TF (match_operand:SI 1 "gpc_reg_operand" "")))]
7166   "!TARGET_IEEEQUAD
7167    && TARGET_HARD_FLOAT
7168    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7169    && TARGET_LONG_DOUBLE_128"
7170 {
7171   rtx tmp = gen_reg_rtx (DFmode);
7172   expand_float (tmp, operands[1], false);
7173   emit_insn (gen_extenddftf2 (operands[0], tmp));
7174   DONE;
7175 })
7176
7177 ; fadd, but rounding towards zero.
7178 ; This is probably not the optimal code sequence.
7179 (define_insn "fix_trunc_helper"
7180   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7181         (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "d")]
7182                    UNSPEC_FIX_TRUNC_TF))
7183    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7184   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
7185   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7186   [(set_attr "type" "fp")
7187    (set_attr "length" "20")])
7188
7189 (define_expand "fix_trunctfsi2"
7190   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7191         (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))]
7192   "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT
7193    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7194 {
7195   if (TARGET_E500_DOUBLE)
7196     emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7197   else
7198     emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7199   DONE;
7200 })
7201
7202 (define_expand "fix_trunctfsi2_fprs"
7203   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7204                    (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))
7205               (clobber (match_dup 2))
7206               (clobber (match_dup 3))
7207               (clobber (match_dup 4))
7208               (clobber (match_dup 5))])]
7209   "!TARGET_IEEEQUAD
7210    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7211 {
7212   operands[2] = gen_reg_rtx (DFmode);
7213   operands[3] = gen_reg_rtx (DFmode);
7214   operands[4] = gen_reg_rtx (DImode);
7215   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7216 })
7217
7218 (define_insn_and_split "*fix_trunctfsi2_internal"
7219   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7220         (fix:SI (match_operand:TF 1 "gpc_reg_operand" "d")))
7221    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7222    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7223    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7224    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7225   "!TARGET_IEEEQUAD
7226    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7227   "#"
7228   ""
7229   [(pc)]
7230 {
7231   rtx lowword;
7232   emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
7233
7234   gcc_assert (MEM_P (operands[5]));
7235   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7236
7237   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7238   emit_move_insn (operands[5], operands[4]);
7239   emit_move_insn (operands[0], lowword);
7240   DONE;
7241 })
7242
7243 (define_expand "negtf2"
7244   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7245         (neg:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
7246   "!TARGET_IEEEQUAD
7247    && TARGET_HARD_FLOAT
7248    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7249    && TARGET_LONG_DOUBLE_128"
7250   "")
7251
7252 (define_insn "negtf2_internal"
7253   [(set (match_operand:TF 0 "gpc_reg_operand" "=d")
7254         (neg:TF (match_operand:TF 1 "gpc_reg_operand" "d")))]
7255   "!TARGET_IEEEQUAD
7256    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7257   "*
7258 {
7259   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7260     return \"fneg %L0,%L1\;fneg %0,%1\";
7261   else
7262     return \"fneg %0,%1\;fneg %L0,%L1\";
7263 }"
7264   [(set_attr "type" "fp")
7265    (set_attr "length" "8")])
7266
7267 (define_expand "abstf2"
7268   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7269         (abs:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
7270   "!TARGET_IEEEQUAD
7271    && TARGET_HARD_FLOAT
7272    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7273    && TARGET_LONG_DOUBLE_128"
7274   "
7275 {
7276   rtx label = gen_label_rtx ();
7277   if (TARGET_E500_DOUBLE)
7278     {
7279       if (flag_finite_math_only && !flag_trapping_math)
7280         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7281       else
7282         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7283     }
7284   else
7285     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7286   emit_label (label);
7287   DONE;
7288 }")
7289
7290 (define_expand "abstf2_internal"
7291   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7292         (match_operand:TF 1 "gpc_reg_operand" ""))
7293    (set (match_dup 3) (match_dup 5))
7294    (set (match_dup 5) (abs:DF (match_dup 5)))
7295    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7296    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7297                            (label_ref (match_operand 2 "" ""))
7298                            (pc)))
7299    (set (match_dup 6) (neg:DF (match_dup 6)))]
7300   "!TARGET_IEEEQUAD
7301    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7302    && TARGET_LONG_DOUBLE_128"
7303   "
7304 {
7305   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7306   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7307   operands[3] = gen_reg_rtx (DFmode);
7308   operands[4] = gen_reg_rtx (CCFPmode);
7309   operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
7310   operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
7311 }")
7312 \f
7313 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
7314 ;; must have 3 arguments, and scratch register constraint must be a single
7315 ;; constraint.
7316
7317 ;; Reload patterns to support gpr load/store with misaligned mem.
7318 ;; and multiple gpr load/store at offset >= 0xfffc
7319 (define_expand "reload_<mode>_store"
7320   [(parallel [(match_operand 0 "memory_operand" "=m")
7321               (match_operand 1 "gpc_reg_operand" "r")
7322               (match_operand:GPR 2 "register_operand" "=&b")])]
7323   ""
7324 {
7325   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7326   DONE;
7327 })
7328
7329 (define_expand "reload_<mode>_load"
7330   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7331               (match_operand 1 "memory_operand" "m")
7332               (match_operand:GPR 2 "register_operand" "=b")])]
7333   ""
7334 {
7335   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7336   DONE;
7337 })
7338
7339 \f
7340 ;; Reload patterns for various types using the vector registers.  We may need
7341 ;; an additional base register to convert the reg+offset addressing to reg+reg
7342 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7343 ;; index register for gpr registers.
7344 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7345   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7346               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7347               (match_operand:P 2 "register_operand" "=b")])]
7348   "<P:tptrsize>"
7349 {
7350   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7351   DONE;
7352 })
7353
7354 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7355   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7356               (match_operand:RELOAD 1 "memory_operand" "m")
7357               (match_operand:P 2 "register_operand" "=b")])]
7358   "<P:tptrsize>"
7359 {
7360   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7361   DONE;
7362 })
7363
7364
7365 ;; Reload sometimes tries to move the address to a GPR, and can generate
7366 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
7367 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7368
7369 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7370   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7371         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7372                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
7373                (const_int -16)))]
7374   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7375   "#"
7376   "&& reload_completed"
7377   [(set (match_dup 0)
7378         (plus:P (match_dup 1)
7379                 (match_dup 2)))
7380    (set (match_dup 0)
7381         (and:P (match_dup 0)
7382                (const_int -16)))])
7383 \f
7384 ;; Power8 merge instructions to allow direct move to/from floating point
7385 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
7386 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
7387 ;; value, since it is allocated in reload and not all of the flow information
7388 ;; is setup for it.  We have two patterns to do the two moves between gprs and
7389 ;; fprs.  There isn't a dependancy between the two, but we could potentially
7390 ;; schedule other instructions between the two instructions.  TFmode is
7391 ;; currently limited to traditional FPR registers.  If/when this is changed, we
7392 ;; will need to revist %L to make sure it works with VSX registers, or add an
7393 ;; %x version of %L.
7394
7395 (define_insn "p8_fmrgow_<mode>"
7396   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7397         (unspec:FMOVE64X [(match_operand:TF 1 "register_operand" "d")]
7398                          UNSPEC_P8V_FMRGOW))]
7399   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7400   "fmrgow %0,%1,%L1"
7401   [(set_attr "type" "vecperm")])
7402
7403 (define_insn "p8_mtvsrwz_1"
7404   [(set (match_operand:TF 0 "register_operand" "=d")
7405         (unspec:TF [(match_operand:SI 1 "register_operand" "r")]
7406                    UNSPEC_P8V_MTVSRWZ))]
7407   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7408   "mtvsrwz %x0,%1"
7409   [(set_attr "type" "mftgpr")])
7410
7411 (define_insn "p8_mtvsrwz_2"
7412   [(set (match_operand:TF 0 "register_operand" "+d")
7413         (unspec:TF [(match_dup 0)
7414                     (match_operand:SI 1 "register_operand" "r")]
7415                    UNSPEC_P8V_MTVSRWZ))]
7416   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7417   "mtvsrwz %L0,%1"
7418   [(set_attr "type" "mftgpr")])
7419
7420 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7421   [(set (match_operand:FMOVE64X 0 "register_operand" "=ws")
7422         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7423                          UNSPEC_P8V_RELOAD_FROM_GPR))
7424    (clobber (match_operand:TF 2 "register_operand" "=d"))]
7425   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7426   "#"
7427   "&& reload_completed"
7428   [(const_int 0)]
7429 {
7430   rtx dest = operands[0];
7431   rtx src = operands[1];
7432   rtx tmp = operands[2];
7433   rtx gpr_hi_reg = gen_highpart (SImode, src);
7434   rtx gpr_lo_reg = gen_lowpart (SImode, src);
7435
7436   emit_insn (gen_p8_mtvsrwz_1 (tmp, gpr_hi_reg));
7437   emit_insn (gen_p8_mtvsrwz_2 (tmp, gpr_lo_reg));
7438   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp));
7439   DONE;
7440 }
7441   [(set_attr "length" "12")
7442    (set_attr "type" "three")])
7443
7444 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7445 (define_insn "p8_mtvsrd_1"
7446   [(set (match_operand:TF 0 "register_operand" "=ws")
7447         (unspec:TF [(match_operand:DI 1 "register_operand" "r")]
7448                    UNSPEC_P8V_MTVSRD))]
7449   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7450   "mtvsrd %0,%1"
7451   [(set_attr "type" "mftgpr")])
7452
7453 (define_insn "p8_mtvsrd_2"
7454   [(set (match_operand:TF 0 "register_operand" "+ws")
7455         (unspec:TF [(match_dup 0)
7456                     (match_operand:DI 1 "register_operand" "r")]
7457                    UNSPEC_P8V_MTVSRD))]
7458   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7459   "mtvsrd %L0,%1"
7460   [(set_attr "type" "mftgpr")])
7461
7462 (define_insn "p8_xxpermdi_<mode>"
7463   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7464         (unspec:FMOVE128_GPR [(match_operand:TF 1 "register_operand" "ws")]
7465                              UNSPEC_P8V_XXPERMDI))]
7466   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7467   "xxpermdi %x0,%1,%L1,0"
7468   [(set_attr "type" "vecperm")])
7469
7470 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7471   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7472         (unspec:FMOVE128_GPR
7473          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7474          UNSPEC_P8V_RELOAD_FROM_GPR))
7475    (clobber (match_operand:TF 2 "register_operand" "=ws"))]
7476   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7477   "#"
7478   "&& reload_completed"
7479   [(const_int 0)]
7480 {
7481   rtx dest = operands[0];
7482   rtx src = operands[1];
7483   rtx tmp = operands[2];
7484   rtx gpr_hi_reg = gen_highpart (DImode, src);
7485   rtx gpr_lo_reg = gen_lowpart (DImode, src);
7486
7487   emit_insn (gen_p8_mtvsrd_1 (tmp, gpr_hi_reg));
7488   emit_insn (gen_p8_mtvsrd_2 (tmp, gpr_lo_reg));
7489   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp));
7490   DONE;
7491 }
7492   [(set_attr "length" "12")
7493    (set_attr "type" "three")])
7494
7495 (define_split
7496   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7497         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7498   "reload_completed
7499    && (int_reg_operand (operands[0], <MODE>mode)
7500        || int_reg_operand (operands[1], <MODE>mode))"
7501   [(pc)]
7502 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7503
7504 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
7505 ;; type is stored internally as double precision in the VSX registers, we have
7506 ;; to convert it from the vector format.
7507
7508 (define_insn_and_split "reload_vsx_from_gprsf"
7509   [(set (match_operand:SF 0 "register_operand" "=wa")
7510         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7511                    UNSPEC_P8V_RELOAD_FROM_GPR))
7512    (clobber (match_operand:DI 2 "register_operand" "=r"))]
7513   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7514   "#"
7515   "&& reload_completed"
7516   [(const_int 0)]
7517 {
7518   rtx op0 = operands[0];
7519   rtx op1 = operands[1];
7520   rtx op2 = operands[2];
7521   /* Also use the destination register to hold the unconverted DImode value.
7522      This is conceptually a separate value from OP0, so we use gen_rtx_REG
7523      rather than simplify_gen_subreg.  */
7524   rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
7525   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7526
7527   /* Move SF value to upper 32-bits for xscvspdpn.  */
7528   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7529   emit_move_insn (op0_di, op2);
7530   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0_di));
7531   DONE;
7532 }
7533   [(set_attr "length" "8")
7534    (set_attr "type" "two")])
7535
7536 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7537 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7538 ;; and then doing a move of that.
7539 (define_insn "p8_mfvsrd_3_<mode>"
7540   [(set (match_operand:DF 0 "register_operand" "=r")
7541         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7542                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7543   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7544   "mfvsrd %0,%x1"
7545   [(set_attr "type" "mftgpr")])
7546
7547 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7548   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7549         (unspec:FMOVE128_GPR
7550          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7551          UNSPEC_P8V_RELOAD_FROM_VSX))
7552    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7553   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7554   "#"
7555   "&& reload_completed"
7556   [(const_int 0)]
7557 {
7558   rtx dest = operands[0];
7559   rtx src = operands[1];
7560   rtx tmp = operands[2];
7561   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7562   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7563
7564   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7565   emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7566   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7567   DONE;
7568 }
7569   [(set_attr "length" "12")
7570    (set_attr "type" "three")])
7571
7572 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
7573 ;; type is stored internally as double precision, we have to convert it to the
7574 ;; vector format.
7575
7576 (define_insn_and_split "reload_gpr_from_vsxsf"
7577   [(set (match_operand:SF 0 "register_operand" "=r")
7578         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7579                    UNSPEC_P8V_RELOAD_FROM_VSX))
7580    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7581   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7582   "#"
7583   "&& reload_completed"
7584   [(const_int 0)]
7585 {
7586   rtx op0 = operands[0];
7587   rtx op1 = operands[1];
7588   rtx op2 = operands[2];
7589   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7590
7591   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7592   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7593   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7594   DONE;
7595 }
7596   [(set_attr "length" "12")
7597    (set_attr "type" "three")])
7598
7599 (define_insn "p8_mfvsrd_4_disf"
7600   [(set (match_operand:DI 0 "register_operand" "=r")
7601         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7602                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7603   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7604   "mfvsrd %0,%x1"
7605   [(set_attr "type" "mftgpr")])
7606
7607 \f
7608 ;; Next come the multi-word integer load and store and the load and store
7609 ;; multiple insns.
7610
7611 ;; List r->r after r->Y, otherwise reload will try to reload a
7612 ;; non-offsettable address by using r->r which won't make progress.
7613 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7614 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7615 (define_insn "*movdi_internal32"
7616   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
7617         (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
7618   "! TARGET_POWERPC64
7619    && (gpc_reg_operand (operands[0], DImode)
7620        || gpc_reg_operand (operands[1], DImode))"
7621   "@
7622    #
7623    #
7624    #
7625    stfd%U0%X0 %1,%0
7626    lfd%U1%X1 %0,%1
7627    fmr %0,%1
7628    #"
7629   [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
7630
7631 (define_split
7632   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7633         (match_operand:DI 1 "const_int_operand" ""))]
7634   "! TARGET_POWERPC64 && reload_completed
7635    && gpr_or_gpr_p (operands[0], operands[1])
7636    && !direct_move_p (operands[0], operands[1])"
7637   [(set (match_dup 2) (match_dup 4))
7638    (set (match_dup 3) (match_dup 1))]
7639   "
7640 {
7641   HOST_WIDE_INT value = INTVAL (operands[1]);
7642   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7643                                        DImode);
7644   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7645                                        DImode);
7646   operands[4] = GEN_INT (value >> 32);
7647   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7648 }")
7649
7650 (define_split
7651   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7652         (match_operand:DIFD 1 "input_operand" ""))]
7653   "reload_completed && !TARGET_POWERPC64
7654    && gpr_or_gpr_p (operands[0], operands[1])
7655    && !direct_move_p (operands[0], operands[1])"
7656   [(pc)]
7657 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7658
7659 (define_insn "*movdi_internal64"
7660   [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi")
7661         (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))]
7662   "TARGET_POWERPC64
7663    && (gpc_reg_operand (operands[0], DImode)
7664        || gpc_reg_operand (operands[1], DImode))"
7665   "@
7666    std%U0%X0 %1,%0
7667    ld%U1%X1 %0,%1
7668    mr %0,%1
7669    li %0,%1
7670    lis %0,%v1
7671    #
7672    stfd%U0%X0 %1,%0
7673    lfd%U1%X1 %0,%1
7674    fmr %0,%1
7675    mf%1 %0
7676    mt%0 %1
7677    nop
7678    mftgpr %0,%1
7679    mffgpr %0,%1
7680    mfvsrd %0,%x1
7681    mtvsrd %x0,%1
7682    xxlxor %x0,%x0,%x0"
7683   [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
7684    (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
7685
7686 ;; Generate all one-bits and clear left or right.
7687 ;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber.
7688 (define_split
7689   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7690         (match_operand:DI 1 "mask64_operand" ""))]
7691   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7692   [(set (match_dup 0) (const_int -1))
7693    (set (match_dup 0)
7694         (and:DI (rotate:DI (match_dup 0)
7695                            (const_int 0))
7696                 (match_dup 1)))]
7697   "")
7698
7699 ;; Split a load of a large constant into the appropriate five-instruction
7700 ;; sequence.  Handle anything in a constant number of insns.
7701 ;; When non-easy constants can go in the TOC, this should use
7702 ;; easy_fp_constant predicate.
7703 (define_split
7704   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7705         (match_operand:DI 1 "const_int_operand" ""))]
7706   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7707   [(set (match_dup 0) (match_dup 2))
7708    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7709   "
7710 {
7711   if (rs6000_emit_set_const (operands[0], operands[1]))
7712     DONE;
7713   else
7714     FAIL;
7715 }")
7716
7717 (define_split
7718   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7719         (match_operand:DI 1 "const_scalar_int_operand" ""))]
7720   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7721   [(set (match_dup 0) (match_dup 2))
7722    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7723   "
7724 {
7725   if (rs6000_emit_set_const (operands[0], operands[1]))
7726     DONE;
7727   else
7728     FAIL;
7729 }")
7730 \f
7731 ;; TImode/PTImode is similar, except that we usually want to compute the
7732 ;; address into a register and use lsi/stsi (the exception is during reload).
7733
7734 (define_insn "*mov<mode>_string"
7735   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
7736         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
7737   "! TARGET_POWERPC64
7738    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
7739    && (gpc_reg_operand (operands[0], <MODE>mode)
7740        || gpc_reg_operand (operands[1], <MODE>mode))"
7741   "*
7742 {
7743   switch (which_alternative)
7744     {
7745     default:
7746       gcc_unreachable ();
7747     case 0:
7748       if (TARGET_STRING)
7749         return \"stswi %1,%P0,16\";
7750     case 1:
7751       return \"#\";
7752     case 2:
7753       /* If the address is not used in the output, we can use lsi.  Otherwise,
7754          fall through to generating four loads.  */
7755       if (TARGET_STRING
7756           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
7757         return \"lswi %0,%P1,16\";
7758       /* ... fall through ...  */
7759     case 3:
7760     case 4:
7761     case 5:
7762       return \"#\";
7763     }
7764 }"
7765   [(set_attr "type" "store,store,load,load,*,*")
7766    (set_attr "update" "yes")
7767    (set_attr "indexed" "yes")
7768    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
7769                                           (const_string "always")
7770                                           (const_string "conditional")))])
7771
7772 (define_insn "*mov<mode>_ppc64"
7773   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
7774         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
7775   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
7776    && (gpc_reg_operand (operands[0], <MODE>mode)
7777        || gpc_reg_operand (operands[1], <MODE>mode)))"
7778 {
7779   return rs6000_output_move_128bit (operands);
7780 }
7781   [(set_attr "type" "store,store,load,load,*,*")
7782    (set_attr "length" "8")])
7783
7784 (define_split
7785   [(set (match_operand:TI2 0 "int_reg_operand" "")
7786         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
7787   "TARGET_POWERPC64
7788    && (VECTOR_MEM_NONE_P (<MODE>mode)
7789        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
7790   [(set (match_dup 2) (match_dup 4))
7791    (set (match_dup 3) (match_dup 5))]
7792   "
7793 {
7794   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7795                                        <MODE>mode);
7796   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7797                                        <MODE>mode);
7798   if (CONST_WIDE_INT_P (operands[1]))
7799     {
7800       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
7801       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
7802     }
7803   else if (CONST_INT_P (operands[1]))
7804     {
7805       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
7806       operands[5] = operands[1];
7807     }
7808   else
7809     FAIL;
7810 }")
7811
7812 (define_split
7813   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
7814         (match_operand:TI2 1 "input_operand" ""))]
7815   "reload_completed
7816    && gpr_or_gpr_p (operands[0], operands[1])
7817    && !direct_move_p (operands[0], operands[1])
7818    && !quad_load_store_p (operands[0], operands[1])"
7819   [(pc)]
7820 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7821 \f
7822 (define_expand "load_multiple"
7823   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7824                           (match_operand:SI 1 "" ""))
7825                      (use (match_operand:SI 2 "" ""))])]
7826   "TARGET_STRING && !TARGET_POWERPC64"
7827   "
7828 {
7829   int regno;
7830   int count;
7831   rtx op1;
7832   int i;
7833
7834   /* Support only loading a constant number of fixed-point registers from
7835      memory and only bother with this if more than two; the machine
7836      doesn't support more than eight.  */
7837   if (GET_CODE (operands[2]) != CONST_INT
7838       || INTVAL (operands[2]) <= 2
7839       || INTVAL (operands[2]) > 8
7840       || GET_CODE (operands[1]) != MEM
7841       || GET_CODE (operands[0]) != REG
7842       || REGNO (operands[0]) >= 32)
7843     FAIL;
7844
7845   count = INTVAL (operands[2]);
7846   regno = REGNO (operands[0]);
7847
7848   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
7849   op1 = replace_equiv_address (operands[1],
7850                                force_reg (SImode, XEXP (operands[1], 0)));
7851
7852   for (i = 0; i < count; i++)
7853     XVECEXP (operands[3], 0, i)
7854       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
7855                      adjust_address_nv (op1, SImode, i * 4));
7856 }")
7857
7858 (define_insn "*ldmsi8"
7859   [(match_parallel 0 "load_multiple_operation"
7860     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7861           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7862      (set (match_operand:SI 3 "gpc_reg_operand" "")
7863           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7864      (set (match_operand:SI 4 "gpc_reg_operand" "")
7865           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7866      (set (match_operand:SI 5 "gpc_reg_operand" "")
7867           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7868      (set (match_operand:SI 6 "gpc_reg_operand" "")
7869           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7870      (set (match_operand:SI 7 "gpc_reg_operand" "")
7871           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
7872      (set (match_operand:SI 8 "gpc_reg_operand" "")
7873           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
7874      (set (match_operand:SI 9 "gpc_reg_operand" "")
7875           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
7876   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
7877   "*
7878 { return rs6000_output_load_multiple (operands); }"
7879   [(set_attr "type" "load")
7880    (set_attr "update" "yes")
7881    (set_attr "indexed" "yes")
7882    (set_attr "length" "32")])
7883
7884 (define_insn "*ldmsi7"
7885   [(match_parallel 0 "load_multiple_operation"
7886     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7887           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7888      (set (match_operand:SI 3 "gpc_reg_operand" "")
7889           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7890      (set (match_operand:SI 4 "gpc_reg_operand" "")
7891           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7892      (set (match_operand:SI 5 "gpc_reg_operand" "")
7893           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7894      (set (match_operand:SI 6 "gpc_reg_operand" "")
7895           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7896      (set (match_operand:SI 7 "gpc_reg_operand" "")
7897           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
7898      (set (match_operand:SI 8 "gpc_reg_operand" "")
7899           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
7900   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
7901   "*
7902 { return rs6000_output_load_multiple (operands); }"
7903   [(set_attr "type" "load")
7904    (set_attr "update" "yes")
7905    (set_attr "indexed" "yes")
7906    (set_attr "length" "32")])
7907
7908 (define_insn "*ldmsi6"
7909   [(match_parallel 0 "load_multiple_operation"
7910     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7911           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7912      (set (match_operand:SI 3 "gpc_reg_operand" "")
7913           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7914      (set (match_operand:SI 4 "gpc_reg_operand" "")
7915           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7916      (set (match_operand:SI 5 "gpc_reg_operand" "")
7917           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7918      (set (match_operand:SI 6 "gpc_reg_operand" "")
7919           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7920      (set (match_operand:SI 7 "gpc_reg_operand" "")
7921           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
7922   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
7923   "*
7924 { return rs6000_output_load_multiple (operands); }"
7925   [(set_attr "type" "load")
7926    (set_attr "update" "yes")
7927    (set_attr "indexed" "yes")
7928    (set_attr "length" "32")])
7929
7930 (define_insn "*ldmsi5"
7931   [(match_parallel 0 "load_multiple_operation"
7932     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7933           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7934      (set (match_operand:SI 3 "gpc_reg_operand" "")
7935           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7936      (set (match_operand:SI 4 "gpc_reg_operand" "")
7937           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7938      (set (match_operand:SI 5 "gpc_reg_operand" "")
7939           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7940      (set (match_operand:SI 6 "gpc_reg_operand" "")
7941           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
7942   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
7943   "*
7944 { return rs6000_output_load_multiple (operands); }"
7945   [(set_attr "type" "load")
7946    (set_attr "update" "yes")
7947    (set_attr "indexed" "yes")
7948    (set_attr "length" "32")])
7949
7950 (define_insn "*ldmsi4"
7951   [(match_parallel 0 "load_multiple_operation"
7952     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7953           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7954      (set (match_operand:SI 3 "gpc_reg_operand" "")
7955           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7956      (set (match_operand:SI 4 "gpc_reg_operand" "")
7957           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7958      (set (match_operand:SI 5 "gpc_reg_operand" "")
7959           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
7960   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
7961   "*
7962 { return rs6000_output_load_multiple (operands); }"
7963   [(set_attr "type" "load")
7964    (set_attr "update" "yes")
7965    (set_attr "indexed" "yes")
7966    (set_attr "length" "32")])
7967
7968 (define_insn "*ldmsi3"
7969   [(match_parallel 0 "load_multiple_operation"
7970     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7971           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7972      (set (match_operand:SI 3 "gpc_reg_operand" "")
7973           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7974      (set (match_operand:SI 4 "gpc_reg_operand" "")
7975           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
7976   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
7977   "*
7978 { return rs6000_output_load_multiple (operands); }"
7979   [(set_attr "type" "load")
7980    (set_attr "update" "yes")
7981    (set_attr "indexed" "yes")
7982    (set_attr "length" "32")])
7983
7984 (define_expand "store_multiple"
7985   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7986                           (match_operand:SI 1 "" ""))
7987                      (clobber (scratch:SI))
7988                      (use (match_operand:SI 2 "" ""))])]
7989   "TARGET_STRING && !TARGET_POWERPC64"
7990   "
7991 {
7992   int regno;
7993   int count;
7994   rtx to;
7995   rtx op0;
7996   int i;
7997
7998   /* Support only storing a constant number of fixed-point registers to
7999      memory and only bother with this if more than two; the machine
8000      doesn't support more than eight.  */
8001   if (GET_CODE (operands[2]) != CONST_INT
8002       || INTVAL (operands[2]) <= 2
8003       || INTVAL (operands[2]) > 8
8004       || GET_CODE (operands[0]) != MEM
8005       || GET_CODE (operands[1]) != REG
8006       || REGNO (operands[1]) >= 32)
8007     FAIL;
8008
8009   count = INTVAL (operands[2]);
8010   regno = REGNO (operands[1]);
8011
8012   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8013   to = force_reg (SImode, XEXP (operands[0], 0));
8014   op0 = replace_equiv_address (operands[0], to);
8015
8016   XVECEXP (operands[3], 0, 0)
8017     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8018   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8019                                                  gen_rtx_SCRATCH (SImode));
8020
8021   for (i = 1; i < count; i++)
8022     XVECEXP (operands[3], 0, i + 1)
8023       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8024                      gen_rtx_REG (SImode, regno + i));
8025 }")
8026
8027 (define_insn "*stmsi8"
8028   [(match_parallel 0 "store_multiple_operation"
8029     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8030           (match_operand:SI 2 "gpc_reg_operand" "r"))
8031      (clobber (match_scratch:SI 3 "=X"))
8032      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8033           (match_operand:SI 4 "gpc_reg_operand" "r"))
8034      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8035           (match_operand:SI 5 "gpc_reg_operand" "r"))
8036      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8037           (match_operand:SI 6 "gpc_reg_operand" "r"))
8038      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8039           (match_operand:SI 7 "gpc_reg_operand" "r"))
8040      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8041           (match_operand:SI 8 "gpc_reg_operand" "r"))
8042      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8043           (match_operand:SI 9 "gpc_reg_operand" "r"))
8044      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8045           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8046   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8047   "stswi %2,%1,%O0"
8048   [(set_attr "type" "store")
8049    (set_attr "update" "yes")
8050    (set_attr "indexed" "yes")
8051    (set_attr "cell_micro" "always")])
8052
8053 (define_insn "*stmsi7"
8054   [(match_parallel 0 "store_multiple_operation"
8055     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8056           (match_operand:SI 2 "gpc_reg_operand" "r"))
8057      (clobber (match_scratch:SI 3 "=X"))
8058      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8059           (match_operand:SI 4 "gpc_reg_operand" "r"))
8060      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8061           (match_operand:SI 5 "gpc_reg_operand" "r"))
8062      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8063           (match_operand:SI 6 "gpc_reg_operand" "r"))
8064      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8065           (match_operand:SI 7 "gpc_reg_operand" "r"))
8066      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8067           (match_operand:SI 8 "gpc_reg_operand" "r"))
8068      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8069           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8070   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8071   "stswi %2,%1,%O0"
8072   [(set_attr "type" "store")
8073    (set_attr "update" "yes")
8074    (set_attr "indexed" "yes")
8075    (set_attr "cell_micro" "always")])
8076
8077 (define_insn "*stmsi6"
8078   [(match_parallel 0 "store_multiple_operation"
8079     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8080           (match_operand:SI 2 "gpc_reg_operand" "r"))
8081      (clobber (match_scratch:SI 3 "=X"))
8082      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8083           (match_operand:SI 4 "gpc_reg_operand" "r"))
8084      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8085           (match_operand:SI 5 "gpc_reg_operand" "r"))
8086      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8087           (match_operand:SI 6 "gpc_reg_operand" "r"))
8088      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8089           (match_operand:SI 7 "gpc_reg_operand" "r"))
8090      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8091           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8092   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8093   "stswi %2,%1,%O0"
8094   [(set_attr "type" "store")
8095    (set_attr "update" "yes")
8096    (set_attr "indexed" "yes")
8097    (set_attr "cell_micro" "always")])
8098
8099 (define_insn "*stmsi5"
8100   [(match_parallel 0 "store_multiple_operation"
8101     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8102           (match_operand:SI 2 "gpc_reg_operand" "r"))
8103      (clobber (match_scratch:SI 3 "=X"))
8104      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8105           (match_operand:SI 4 "gpc_reg_operand" "r"))
8106      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8107           (match_operand:SI 5 "gpc_reg_operand" "r"))
8108      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8109           (match_operand:SI 6 "gpc_reg_operand" "r"))
8110      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8111           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8112   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8113   "stswi %2,%1,%O0"
8114   [(set_attr "type" "store")
8115    (set_attr "update" "yes")
8116    (set_attr "indexed" "yes")
8117    (set_attr "cell_micro" "always")])
8118
8119 (define_insn "*stmsi4"
8120   [(match_parallel 0 "store_multiple_operation"
8121     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8122           (match_operand:SI 2 "gpc_reg_operand" "r"))
8123      (clobber (match_scratch:SI 3 "=X"))
8124      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8125           (match_operand:SI 4 "gpc_reg_operand" "r"))
8126      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8127           (match_operand:SI 5 "gpc_reg_operand" "r"))
8128      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8129           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8130   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8131   "stswi %2,%1,%O0"
8132   [(set_attr "type" "store")
8133    (set_attr "update" "yes")
8134    (set_attr "indexed" "yes")
8135    (set_attr "cell_micro" "always")])
8136
8137 (define_insn "*stmsi3"
8138   [(match_parallel 0 "store_multiple_operation"
8139     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8140           (match_operand:SI 2 "gpc_reg_operand" "r"))
8141      (clobber (match_scratch:SI 3 "=X"))
8142      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8143           (match_operand:SI 4 "gpc_reg_operand" "r"))
8144      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8145           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8146   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8147   "stswi %2,%1,%O0"
8148   [(set_attr "type" "store")
8149    (set_attr "update" "yes")
8150    (set_attr "indexed" "yes")
8151    (set_attr "cell_micro" "always")])
8152 \f
8153 (define_expand "setmemsi"
8154   [(parallel [(set (match_operand:BLK 0 "" "")
8155                    (match_operand 2 "const_int_operand" ""))
8156               (use (match_operand:SI 1 "" ""))
8157               (use (match_operand:SI 3 "" ""))])]
8158   ""
8159   "
8160 {
8161   /* If value to set is not zero, use the library routine.  */
8162   if (operands[2] != const0_rtx)
8163     FAIL;
8164
8165   if (expand_block_clear (operands))
8166     DONE;
8167   else
8168     FAIL;
8169 }")
8170
8171 ;; String/block move insn.
8172 ;; Argument 0 is the destination
8173 ;; Argument 1 is the source
8174 ;; Argument 2 is the length
8175 ;; Argument 3 is the alignment
8176
8177 (define_expand "movmemsi"
8178   [(parallel [(set (match_operand:BLK 0 "" "")
8179                    (match_operand:BLK 1 "" ""))
8180               (use (match_operand:SI 2 "" ""))
8181               (use (match_operand:SI 3 "" ""))])]
8182   ""
8183   "
8184 {
8185   if (expand_block_move (operands))
8186     DONE;
8187   else
8188     FAIL;
8189 }")
8190
8191 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
8192 ;; register allocator doesn't have a clue about allocating 8 word registers.
8193 ;; rD/rS = r5 is preferred, efficient form.
8194 (define_expand "movmemsi_8reg"
8195   [(parallel [(set (match_operand 0 "" "")
8196                    (match_operand 1 "" ""))
8197               (use (match_operand 2 "" ""))
8198               (use (match_operand 3 "" ""))
8199               (clobber (reg:SI  5))
8200               (clobber (reg:SI  6))
8201               (clobber (reg:SI  7))
8202               (clobber (reg:SI  8))
8203               (clobber (reg:SI  9))
8204               (clobber (reg:SI 10))
8205               (clobber (reg:SI 11))
8206               (clobber (reg:SI 12))
8207               (clobber (match_scratch:SI 4 ""))])]
8208   "TARGET_STRING"
8209   "")
8210
8211 (define_insn ""
8212   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8213         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8214    (use (match_operand:SI 2 "immediate_operand" "i"))
8215    (use (match_operand:SI 3 "immediate_operand" "i"))
8216    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8217    (clobber (reg:SI  6))
8218    (clobber (reg:SI  7))
8219    (clobber (reg:SI  8))
8220    (clobber (reg:SI  9))
8221    (clobber (reg:SI 10))
8222    (clobber (reg:SI 11))
8223    (clobber (reg:SI 12))
8224    (clobber (match_scratch:SI 5 "=X"))]
8225   "TARGET_STRING
8226    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8227        || INTVAL (operands[2]) == 0)
8228    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8229    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8230    && REGNO (operands[4]) == 5"
8231   "lswi %4,%1,%2\;stswi %4,%0,%2"
8232   [(set_attr "type" "store")
8233    (set_attr "update" "yes")
8234    (set_attr "indexed" "yes")
8235    (set_attr "cell_micro" "always")
8236    (set_attr "length" "8")])
8237
8238 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
8239 ;; register allocator doesn't have a clue about allocating 6 word registers.
8240 ;; rD/rS = r5 is preferred, efficient form.
8241 (define_expand "movmemsi_6reg"
8242   [(parallel [(set (match_operand 0 "" "")
8243                    (match_operand 1 "" ""))
8244               (use (match_operand 2 "" ""))
8245               (use (match_operand 3 "" ""))
8246               (clobber (reg:SI  5))
8247               (clobber (reg:SI  6))
8248               (clobber (reg:SI  7))
8249               (clobber (reg:SI  8))
8250               (clobber (reg:SI  9))
8251               (clobber (reg:SI 10))
8252               (clobber (match_scratch:SI 4 ""))])]
8253   "TARGET_STRING"
8254   "")
8255
8256 (define_insn ""
8257   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8258         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8259    (use (match_operand:SI 2 "immediate_operand" "i"))
8260    (use (match_operand:SI 3 "immediate_operand" "i"))
8261    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8262    (clobber (reg:SI  6))
8263    (clobber (reg:SI  7))
8264    (clobber (reg:SI  8))
8265    (clobber (reg:SI  9))
8266    (clobber (reg:SI 10))
8267    (clobber (match_scratch:SI 5 "=X"))]
8268   "TARGET_STRING
8269    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8270    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8271    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8272    && REGNO (operands[4]) == 5"
8273   "lswi %4,%1,%2\;stswi %4,%0,%2"
8274   [(set_attr "type" "store")
8275    (set_attr "update" "yes")
8276    (set_attr "indexed" "yes")
8277    (set_attr "cell_micro" "always")
8278    (set_attr "length" "8")])
8279
8280 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8281 ;; problems with TImode.
8282 ;; rD/rS = r5 is preferred, efficient form.
8283 (define_expand "movmemsi_4reg"
8284   [(parallel [(set (match_operand 0 "" "")
8285                    (match_operand 1 "" ""))
8286               (use (match_operand 2 "" ""))
8287               (use (match_operand 3 "" ""))
8288               (clobber (reg:SI 5))
8289               (clobber (reg:SI 6))
8290               (clobber (reg:SI 7))
8291               (clobber (reg:SI 8))
8292               (clobber (match_scratch:SI 4 ""))])]
8293   "TARGET_STRING"
8294   "")
8295
8296 (define_insn ""
8297   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8298         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8299    (use (match_operand:SI 2 "immediate_operand" "i"))
8300    (use (match_operand:SI 3 "immediate_operand" "i"))
8301    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8302    (clobber (reg:SI 6))
8303    (clobber (reg:SI 7))
8304    (clobber (reg:SI 8))
8305    (clobber (match_scratch:SI 5 "=X"))]
8306   "TARGET_STRING
8307    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8308    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8309    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8310    && REGNO (operands[4]) == 5"
8311   "lswi %4,%1,%2\;stswi %4,%0,%2"
8312   [(set_attr "type" "store")
8313    (set_attr "update" "yes")
8314    (set_attr "indexed" "yes")
8315    (set_attr "cell_micro" "always")
8316    (set_attr "length" "8")])
8317
8318 ;; Move up to 8 bytes at a time.
8319 (define_expand "movmemsi_2reg"
8320   [(parallel [(set (match_operand 0 "" "")
8321                    (match_operand 1 "" ""))
8322               (use (match_operand 2 "" ""))
8323               (use (match_operand 3 "" ""))
8324               (clobber (match_scratch:DI 4 ""))
8325               (clobber (match_scratch:SI 5 ""))])]
8326   "TARGET_STRING && ! TARGET_POWERPC64"
8327   "")
8328
8329 (define_insn ""
8330   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8331         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8332    (use (match_operand:SI 2 "immediate_operand" "i"))
8333    (use (match_operand:SI 3 "immediate_operand" "i"))
8334    (clobber (match_scratch:DI 4 "=&r"))
8335    (clobber (match_scratch:SI 5 "=X"))]
8336   "TARGET_STRING && ! TARGET_POWERPC64
8337    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8338   "lswi %4,%1,%2\;stswi %4,%0,%2"
8339   [(set_attr "type" "store")
8340    (set_attr "update" "yes")
8341    (set_attr "indexed" "yes")
8342    (set_attr "cell_micro" "always")
8343    (set_attr "length" "8")])
8344
8345 ;; Move up to 4 bytes at a time.
8346 (define_expand "movmemsi_1reg"
8347   [(parallel [(set (match_operand 0 "" "")
8348                    (match_operand 1 "" ""))
8349               (use (match_operand 2 "" ""))
8350               (use (match_operand 3 "" ""))
8351               (clobber (match_scratch:SI 4 ""))
8352               (clobber (match_scratch:SI 5 ""))])]
8353   "TARGET_STRING"
8354   "")
8355
8356 (define_insn ""
8357   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8358         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8359    (use (match_operand:SI 2 "immediate_operand" "i"))
8360    (use (match_operand:SI 3 "immediate_operand" "i"))
8361    (clobber (match_scratch:SI 4 "=&r"))
8362    (clobber (match_scratch:SI 5 "=X"))]
8363   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8364   "lswi %4,%1,%2\;stswi %4,%0,%2"
8365   [(set_attr "type" "store")
8366    (set_attr "update" "yes")
8367    (set_attr "indexed" "yes")
8368    (set_attr "cell_micro" "always")
8369    (set_attr "length" "8")])
8370 \f
8371 ;; Define insns that do load or store with update.  Some of these we can
8372 ;; get by using pre-decrement or pre-increment, but the hardware can also
8373 ;; do cases where the increment is not the size of the object.
8374 ;;
8375 ;; In all these cases, we use operands 0 and 1 for the register being
8376 ;; incremented because those are the operands that local-alloc will
8377 ;; tie and these are the pair most likely to be tieable (and the ones
8378 ;; that will benefit the most).
8379
8380 (define_insn "*movdi_update1"
8381   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8382         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8383                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8384    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8385         (plus:DI (match_dup 1) (match_dup 2)))]
8386   "TARGET_POWERPC64 && TARGET_UPDATE
8387    && (!avoiding_indexed_address_p (DImode)
8388        || !gpc_reg_operand (operands[2], DImode))"
8389   "@
8390    ldux %3,%0,%2
8391    ldu %3,%2(%0)"
8392   [(set_attr "type" "load")
8393    (set_attr "update" "yes")
8394    (set_attr "indexed" "yes,no")])
8395
8396 (define_insn "movdi_<mode>_update"
8397   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8398                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8399         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8400    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8401         (plus:P (match_dup 1) (match_dup 2)))]
8402   "TARGET_POWERPC64 && TARGET_UPDATE
8403    && (!avoiding_indexed_address_p (Pmode)
8404        || !gpc_reg_operand (operands[2], Pmode)
8405        || (REG_P (operands[0])
8406            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8407   "@
8408    stdux %3,%0,%2
8409    stdu %3,%2(%0)"
8410   [(set_attr "type" "store")
8411    (set_attr "update" "yes")
8412    (set_attr "indexed" "yes,no")])
8413
8414 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8415 ;; needed for stack allocation, even if the user passes -mno-update.
8416 (define_insn "movdi_<mode>_update_stack"
8417   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8418                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8419         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8420    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8421         (plus:P (match_dup 1) (match_dup 2)))]
8422   "TARGET_POWERPC64"
8423   "@
8424    stdux %3,%0,%2
8425    stdu %3,%2(%0)"
8426   [(set_attr "type" "store")
8427    (set_attr "update" "yes")
8428    (set_attr "indexed" "yes,no")])
8429
8430 (define_insn "*movsi_update1"
8431   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8432         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8433                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8434    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8435         (plus:SI (match_dup 1) (match_dup 2)))]
8436   "TARGET_UPDATE
8437    && (!avoiding_indexed_address_p (SImode)
8438        || !gpc_reg_operand (operands[2], SImode))"
8439   "@
8440    lwzux %3,%0,%2
8441    lwzu %3,%2(%0)"
8442   [(set_attr "type" "load")
8443    (set_attr "update" "yes")
8444    (set_attr "indexed" "yes,no")])
8445
8446 (define_insn "*movsi_update2"
8447   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8448         (sign_extend:DI
8449          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8450                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
8451    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8452         (plus:DI (match_dup 1) (match_dup 2)))]
8453   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8454    && !avoiding_indexed_address_p (DImode)"
8455   "lwaux %3,%0,%2"
8456   [(set_attr "type" "load")
8457    (set_attr "sign_extend" "yes")
8458    (set_attr "update" "yes")
8459    (set_attr "indexed" "yes")])
8460
8461 (define_insn "movsi_update"
8462   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8463                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8464         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8465    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8466         (plus:SI (match_dup 1) (match_dup 2)))]
8467   "TARGET_UPDATE
8468    && (!avoiding_indexed_address_p (SImode)
8469        || !gpc_reg_operand (operands[2], SImode)
8470        || (REG_P (operands[0])
8471            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8472   "@
8473    stwux %3,%0,%2
8474    stwu %3,%2(%0)"
8475   [(set_attr "type" "store")
8476    (set_attr "update" "yes")
8477    (set_attr "indexed" "yes,no")])
8478
8479 ;; This is an unconditional pattern; needed for stack allocation, even
8480 ;; if the user passes -mno-update.
8481 (define_insn "movsi_update_stack"
8482   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8483                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8484         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8485    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8486         (plus:SI (match_dup 1) (match_dup 2)))]
8487   ""
8488   "@
8489    stwux %3,%0,%2
8490    stwu %3,%2(%0)"
8491   [(set_attr "type" "store")
8492    (set_attr "update" "yes")
8493    (set_attr "indexed" "yes,no")])
8494
8495 (define_insn "*movhi_update1"
8496   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8497         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8498                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8499    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8500         (plus:SI (match_dup 1) (match_dup 2)))]
8501   "TARGET_UPDATE
8502    && (!avoiding_indexed_address_p (SImode)
8503        || !gpc_reg_operand (operands[2], SImode))"
8504   "@
8505    lhzux %3,%0,%2
8506    lhzu %3,%2(%0)"
8507   [(set_attr "type" "load")
8508    (set_attr "update" "yes")
8509    (set_attr "indexed" "yes,no")])
8510
8511 (define_insn "*movhi_update2"
8512   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8513         (zero_extend:SI
8514          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8515                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8516    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8517         (plus:SI (match_dup 1) (match_dup 2)))]
8518   "TARGET_UPDATE
8519    && (!avoiding_indexed_address_p (SImode)
8520        || !gpc_reg_operand (operands[2], SImode))"
8521   "@
8522    lhzux %3,%0,%2
8523    lhzu %3,%2(%0)"
8524   [(set_attr "type" "load")
8525    (set_attr "update" "yes")
8526    (set_attr "indexed" "yes,no")])
8527
8528 (define_insn "*movhi_update3"
8529   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8530         (sign_extend:SI
8531          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8532                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8533    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8534         (plus:SI (match_dup 1) (match_dup 2)))]
8535   "TARGET_UPDATE && rs6000_gen_cell_microcode
8536    && (!avoiding_indexed_address_p (SImode)
8537        || !gpc_reg_operand (operands[2], SImode))"
8538   "@
8539    lhaux %3,%0,%2
8540    lhau %3,%2(%0)"
8541   [(set_attr "type" "load")
8542    (set_attr "sign_extend" "yes")
8543    (set_attr "update" "yes")
8544    (set_attr "indexed" "yes,no")])
8545
8546 (define_insn "*movhi_update4"
8547   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8548                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8549         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8550    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8551         (plus:SI (match_dup 1) (match_dup 2)))]
8552   "TARGET_UPDATE
8553    && (!avoiding_indexed_address_p (SImode)
8554        || !gpc_reg_operand (operands[2], SImode))"
8555   "@
8556    sthux %3,%0,%2
8557    sthu %3,%2(%0)"
8558   [(set_attr "type" "store")
8559    (set_attr "update" "yes")
8560    (set_attr "indexed" "yes,no")])
8561
8562 (define_insn "*movqi_update1"
8563   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8564         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8565                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8566    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8567         (plus:SI (match_dup 1) (match_dup 2)))]
8568   "TARGET_UPDATE
8569    && (!avoiding_indexed_address_p (SImode)
8570        || !gpc_reg_operand (operands[2], SImode))"
8571   "@
8572    lbzux %3,%0,%2
8573    lbzu %3,%2(%0)"
8574   [(set_attr "type" "load")
8575    (set_attr "update" "yes")
8576    (set_attr "indexed" "yes,no")])
8577
8578 (define_insn "*movqi_update2"
8579   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8580         (zero_extend:SI
8581          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8582                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8583    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8584         (plus:SI (match_dup 1) (match_dup 2)))]
8585   "TARGET_UPDATE
8586    && (!avoiding_indexed_address_p (SImode)
8587        || !gpc_reg_operand (operands[2], SImode))"
8588   "@
8589    lbzux %3,%0,%2
8590    lbzu %3,%2(%0)"
8591   [(set_attr "type" "load")
8592    (set_attr "update" "yes")
8593    (set_attr "indexed" "yes,no")])
8594
8595 (define_insn "*movqi_update3"
8596   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8597                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8598         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
8599    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8600         (plus:SI (match_dup 1) (match_dup 2)))]
8601   "TARGET_UPDATE
8602    && (!avoiding_indexed_address_p (SImode)
8603        || !gpc_reg_operand (operands[2], SImode))"
8604   "@
8605    stbux %3,%0,%2
8606    stbu %3,%2(%0)"
8607   [(set_attr "type" "store")
8608    (set_attr "update" "yes")
8609    (set_attr "indexed" "yes,no")])
8610
8611 (define_insn "*movsf_update1"
8612   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
8613         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8614                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8615    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8616         (plus:SI (match_dup 1) (match_dup 2)))]
8617   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8618    && (!avoiding_indexed_address_p (SImode)
8619        || !gpc_reg_operand (operands[2], SImode))"
8620   "@
8621    lfsux %3,%0,%2
8622    lfsu %3,%2(%0)"
8623   [(set_attr "type" "fpload")
8624    (set_attr "update" "yes")
8625    (set_attr "indexed" "yes,no")])
8626
8627 (define_insn "*movsf_update2"
8628   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8629                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8630         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
8631    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8632         (plus:SI (match_dup 1) (match_dup 2)))]
8633   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8634    && (!avoiding_indexed_address_p (SImode)
8635        || !gpc_reg_operand (operands[2], SImode))"
8636   "@
8637    stfsux %3,%0,%2
8638    stfsu %3,%2(%0)"
8639   [(set_attr "type" "fpstore")
8640    (set_attr "update" "yes")
8641    (set_attr "indexed" "yes,no")])
8642
8643 (define_insn "*movsf_update3"
8644   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
8645         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8646                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8647    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8648         (plus:SI (match_dup 1) (match_dup 2)))]
8649   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8650    && (!avoiding_indexed_address_p (SImode)
8651        || !gpc_reg_operand (operands[2], SImode))"
8652   "@
8653    lwzux %3,%0,%2
8654    lwzu %3,%2(%0)"
8655   [(set_attr "type" "load")
8656    (set_attr "update" "yes")
8657    (set_attr "indexed" "yes,no")])
8658
8659 (define_insn "*movsf_update4"
8660   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8661                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8662         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
8663    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8664         (plus:SI (match_dup 1) (match_dup 2)))]
8665   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8666    && (!avoiding_indexed_address_p (SImode)
8667        || !gpc_reg_operand (operands[2], SImode))"
8668   "@
8669    stwux %3,%0,%2
8670    stwu %3,%2(%0)"
8671   [(set_attr "type" "store")
8672    (set_attr "update" "yes")
8673    (set_attr "indexed" "yes,no")])
8674
8675 (define_insn "*movdf_update1"
8676   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
8677         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8678                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8679    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8680         (plus:SI (match_dup 1) (match_dup 2)))]
8681   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8682    && (!avoiding_indexed_address_p (SImode)
8683        || !gpc_reg_operand (operands[2], SImode))"
8684   "@
8685    lfdux %3,%0,%2
8686    lfdu %3,%2(%0)"
8687   [(set_attr "type" "fpload")
8688    (set_attr "update" "yes")
8689    (set_attr "indexed" "yes,no")])
8690
8691 (define_insn "*movdf_update2"
8692   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8693                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8694         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
8695    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8696         (plus:SI (match_dup 1) (match_dup 2)))]
8697   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8698    && (!avoiding_indexed_address_p (SImode)
8699        || !gpc_reg_operand (operands[2], SImode))"
8700   "@
8701    stfdux %3,%0,%2
8702    stfdu %3,%2(%0)"
8703   [(set_attr "type" "fpstore")
8704    (set_attr "update" "yes")
8705    (set_attr "indexed" "yes,no")])
8706
8707
8708 ;; After inserting conditional returns we can sometimes have
8709 ;; unnecessary register moves.  Unfortunately we cannot have a
8710 ;; modeless peephole here, because some single SImode sets have early
8711 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
8712 ;; sequences, using get_attr_length here will smash the operands
8713 ;; array.  Neither is there an early_cobbler_p predicate.
8714 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
8715 ;; Also this optimization interferes with scalars going into
8716 ;; altivec registers (the code does reloading through the FPRs).
8717 (define_peephole2
8718   [(set (match_operand:DF 0 "gpc_reg_operand" "")
8719         (match_operand:DF 1 "any_operand" ""))
8720    (set (match_operand:DF 2 "gpc_reg_operand" "")
8721         (match_dup 0))]
8722   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
8723    && !TARGET_UPPER_REGS_DF
8724    && peep2_reg_dead_p (2, operands[0])"
8725   [(set (match_dup 2) (match_dup 1))])
8726
8727 (define_peephole2
8728   [(set (match_operand:SF 0 "gpc_reg_operand" "")
8729         (match_operand:SF 1 "any_operand" ""))
8730    (set (match_operand:SF 2 "gpc_reg_operand" "")
8731         (match_dup 0))]
8732   "!TARGET_UPPER_REGS_SF
8733    && peep2_reg_dead_p (2, operands[0])"
8734   [(set (match_dup 2) (match_dup 1))])
8735
8736 \f
8737 ;; TLS support.
8738
8739 ;; Mode attributes for different ABIs.
8740 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
8741 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
8742 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
8743 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
8744
8745 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
8746   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8747         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8748               (match_operand 4 "" "g")))
8749    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8750                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8751                    UNSPEC_TLSGD)
8752    (clobber (reg:SI LR_REGNO))]
8753   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8754 {
8755   if (TARGET_CMODEL != CMODEL_SMALL)
8756     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
8757            "bl %z3\;nop";
8758   else
8759     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
8760 }
8761   "&& TARGET_TLS_MARKERS"
8762   [(set (match_dup 0)
8763         (unspec:TLSmode [(match_dup 1)
8764                          (match_dup 2)]
8765                         UNSPEC_TLSGD))
8766    (parallel [(set (match_dup 0)
8767                    (call (mem:TLSmode (match_dup 3))
8768                          (match_dup 4)))
8769               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8770               (clobber (reg:SI LR_REGNO))])]
8771   ""
8772   [(set_attr "type" "two")
8773    (set (attr "length")
8774      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8775                    (const_int 16)
8776                    (const_int 12)))])
8777
8778 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
8779   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8780         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8781               (match_operand 4 "" "g")))
8782    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8783                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8784                    UNSPEC_TLSGD)
8785    (clobber (reg:SI LR_REGNO))]
8786   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
8787 {
8788   if (flag_pic)
8789     {
8790       if (TARGET_SECURE_PLT && flag_pic == 2)
8791         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
8792       else
8793         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
8794     }
8795   else
8796     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
8797 }
8798   "&& TARGET_TLS_MARKERS"
8799   [(set (match_dup 0)
8800         (unspec:TLSmode [(match_dup 1)
8801                          (match_dup 2)]
8802                         UNSPEC_TLSGD))
8803    (parallel [(set (match_dup 0)
8804                    (call (mem:TLSmode (match_dup 3))
8805                          (match_dup 4)))
8806               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8807               (clobber (reg:SI LR_REGNO))])]
8808   ""
8809   [(set_attr "type" "two")
8810    (set_attr "length" "8")])
8811
8812 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
8813   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8814         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8815                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8816                         UNSPEC_TLSGD))]
8817   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
8818   "addi %0,%1,%2@got@tlsgd"
8819   "&& TARGET_CMODEL != CMODEL_SMALL"
8820   [(set (match_dup 3)
8821         (high:TLSmode
8822             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
8823    (set (match_dup 0)
8824         (lo_sum:TLSmode (match_dup 3)
8825             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
8826   "
8827 {
8828   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
8829 }"
8830   [(set (attr "length")
8831      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8832                    (const_int 8)
8833                    (const_int 4)))])
8834
8835 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
8836   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8837      (high:TLSmode
8838        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8839                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8840                        UNSPEC_TLSGD)))]
8841   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8842   "addis %0,%1,%2@got@tlsgd@ha"
8843   [(set_attr "length" "4")])
8844
8845 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
8846   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8847      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
8848        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
8849                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8850                        UNSPEC_TLSGD)))]
8851   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8852   "addi %0,%1,%2@got@tlsgd@l"
8853   [(set_attr "length" "4")])
8854
8855 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
8856   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8857         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8858               (match_operand 2 "" "g")))
8859    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8860                    UNSPEC_TLSGD)
8861    (clobber (reg:SI LR_REGNO))]
8862   "HAVE_AS_TLS && TARGET_TLS_MARKERS
8863    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8864   "bl %z1(%3@tlsgd)\;nop"
8865   [(set_attr "type" "branch")
8866    (set_attr "length" "8")])
8867
8868 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
8869   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8870         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8871               (match_operand 2 "" "g")))
8872    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8873                    UNSPEC_TLSGD)
8874    (clobber (reg:SI LR_REGNO))]
8875   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
8876 {
8877   if (flag_pic)
8878     {
8879       if (TARGET_SECURE_PLT && flag_pic == 2)
8880         return "bl %z1+32768(%3@tlsgd)@plt";
8881       return "bl %z1(%3@tlsgd)@plt";
8882     }
8883   return "bl %z1(%3@tlsgd)";
8884 }
8885   [(set_attr "type" "branch")
8886    (set_attr "length" "4")])
8887
8888 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
8889   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8890         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
8891               (match_operand 3 "" "g")))
8892    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
8893                    UNSPEC_TLSLD)
8894    (clobber (reg:SI LR_REGNO))]
8895   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8896 {
8897   if (TARGET_CMODEL != CMODEL_SMALL)
8898     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
8899            "bl %z2\;nop";
8900   else
8901     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
8902 }
8903   "&& TARGET_TLS_MARKERS"
8904   [(set (match_dup 0)
8905         (unspec:TLSmode [(match_dup 1)]
8906                         UNSPEC_TLSLD))
8907    (parallel [(set (match_dup 0)
8908                    (call (mem:TLSmode (match_dup 2))
8909                          (match_dup 3)))
8910               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
8911               (clobber (reg:SI LR_REGNO))])]
8912   ""
8913   [(set_attr "type" "two")
8914    (set (attr "length")
8915      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8916                    (const_int 16)
8917                    (const_int 12)))])
8918
8919 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
8920   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8921         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
8922               (match_operand 3 "" "g")))
8923    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
8924                    UNSPEC_TLSLD)
8925    (clobber (reg:SI LR_REGNO))]
8926   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
8927 {
8928   if (flag_pic)
8929     {
8930       if (TARGET_SECURE_PLT && flag_pic == 2)
8931         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
8932       else
8933         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
8934     }
8935   else
8936     return "addi %0,%1,%&@got@tlsld\;bl %z2";
8937 }
8938   "&& TARGET_TLS_MARKERS"
8939   [(set (match_dup 0)
8940         (unspec:TLSmode [(match_dup 1)]
8941                         UNSPEC_TLSLD))
8942    (parallel [(set (match_dup 0)
8943                    (call (mem:TLSmode (match_dup 2))
8944                          (match_dup 3)))
8945               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
8946               (clobber (reg:SI LR_REGNO))])]
8947   ""
8948   [(set_attr "length" "8")])
8949
8950 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
8951   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8952         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
8953                         UNSPEC_TLSLD))]
8954   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
8955   "addi %0,%1,%&@got@tlsld"
8956   "&& TARGET_CMODEL != CMODEL_SMALL"
8957   [(set (match_dup 2)
8958         (high:TLSmode
8959             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
8960    (set (match_dup 0)
8961         (lo_sum:TLSmode (match_dup 2)
8962             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
8963   "
8964 {
8965   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
8966 }"
8967   [(set (attr "length")
8968      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8969                    (const_int 8)
8970                    (const_int 4)))])
8971
8972 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
8973   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8974      (high:TLSmode
8975        (unspec:TLSmode [(const_int 0)
8976                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
8977                        UNSPEC_TLSLD)))]
8978   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8979   "addis %0,%1,%&@got@tlsld@ha"
8980   [(set_attr "length" "4")])
8981
8982 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
8983   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8984      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
8985        (unspec:TLSmode [(const_int 0)
8986                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
8987                        UNSPEC_TLSLD)))]
8988   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8989   "addi %0,%1,%&@got@tlsld@l"
8990   [(set_attr "length" "4")])
8991
8992 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
8993   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8994         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8995               (match_operand 2 "" "g")))
8996    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
8997    (clobber (reg:SI LR_REGNO))]
8998   "HAVE_AS_TLS && TARGET_TLS_MARKERS
8999    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9000   "bl %z1(%&@tlsld)\;nop"
9001   [(set_attr "type" "branch")
9002    (set_attr "length" "8")])
9003
9004 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9005   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9006         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9007               (match_operand 2 "" "g")))
9008    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9009    (clobber (reg:SI LR_REGNO))]
9010   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9011 {
9012   if (flag_pic)
9013     {
9014       if (TARGET_SECURE_PLT && flag_pic == 2)
9015         return "bl %z1+32768(%&@tlsld)@plt";
9016       return "bl %z1(%&@tlsld)@plt";
9017     }
9018   return "bl %z1(%&@tlsld)";
9019 }
9020   [(set_attr "type" "branch")
9021    (set_attr "length" "4")])
9022
9023 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9024   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9025         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9026                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9027                         UNSPEC_TLSDTPREL))]
9028   "HAVE_AS_TLS"
9029   "addi %0,%1,%2@dtprel")
9030
9031 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9032   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9033         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9034                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9035                         UNSPEC_TLSDTPRELHA))]
9036   "HAVE_AS_TLS"
9037   "addis %0,%1,%2@dtprel@ha")
9038
9039 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9040   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9041         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9042                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9043                         UNSPEC_TLSDTPRELLO))]
9044   "HAVE_AS_TLS"
9045   "addi %0,%1,%2@dtprel@l")
9046
9047 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9048   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9049         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9050                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9051                         UNSPEC_TLSGOTDTPREL))]
9052   "HAVE_AS_TLS"
9053   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9054   "&& TARGET_CMODEL != CMODEL_SMALL"
9055   [(set (match_dup 3)
9056         (high:TLSmode
9057             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9058    (set (match_dup 0)
9059         (lo_sum:TLSmode (match_dup 3)
9060             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9061   "
9062 {
9063   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9064 }"
9065   [(set (attr "length")
9066      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9067                    (const_int 8)
9068                    (const_int 4)))])
9069
9070 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9071   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9072      (high:TLSmode
9073        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9074                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9075                        UNSPEC_TLSGOTDTPREL)))]
9076   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9077   "addis %0,%1,%2@got@dtprel@ha"
9078   [(set_attr "length" "4")])
9079
9080 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9081   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9082      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9083          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9084                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9085                          UNSPEC_TLSGOTDTPREL)))]
9086   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9087   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9088   [(set_attr "length" "4")])
9089
9090 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9091   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9092         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9093                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9094                         UNSPEC_TLSTPREL))]
9095   "HAVE_AS_TLS"
9096   "addi %0,%1,%2@tprel")
9097
9098 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9099   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9100         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9101                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9102                         UNSPEC_TLSTPRELHA))]
9103   "HAVE_AS_TLS"
9104   "addis %0,%1,%2@tprel@ha")
9105
9106 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9107   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9108         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9109                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9110                         UNSPEC_TLSTPRELLO))]
9111   "HAVE_AS_TLS"
9112   "addi %0,%1,%2@tprel@l")
9113
9114 ;; "b" output constraint here and on tls_tls input to support linker tls
9115 ;; optimization.  The linker may edit the instructions emitted by a
9116 ;; tls_got_tprel/tls_tls pair to addis,addi.
9117 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9118   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9119         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9120                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9121                         UNSPEC_TLSGOTTPREL))]
9122   "HAVE_AS_TLS"
9123   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9124   "&& TARGET_CMODEL != CMODEL_SMALL"
9125   [(set (match_dup 3)
9126         (high:TLSmode
9127             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9128    (set (match_dup 0)
9129         (lo_sum:TLSmode (match_dup 3)
9130             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9131   "
9132 {
9133   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9134 }"
9135   [(set (attr "length")
9136      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9137                    (const_int 8)
9138                    (const_int 4)))])
9139
9140 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9141   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9142      (high:TLSmode
9143        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9144                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9145                        UNSPEC_TLSGOTTPREL)))]
9146   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9147   "addis %0,%1,%2@got@tprel@ha"
9148   [(set_attr "length" "4")])
9149
9150 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9151   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9152      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9153          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9154                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9155                          UNSPEC_TLSGOTTPREL)))]
9156   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9157   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9158   [(set_attr "length" "4")])
9159
9160 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9161   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9162         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9163                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9164                         UNSPEC_TLSTLS))]
9165   "TARGET_ELF && HAVE_AS_TLS"
9166   "add %0,%1,%2@tls")
9167
9168 (define_expand "tls_get_tpointer"
9169   [(set (match_operand:SI 0 "gpc_reg_operand" "")
9170         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9171   "TARGET_XCOFF && HAVE_AS_TLS"
9172   "
9173 {
9174   emit_insn (gen_tls_get_tpointer_internal ());
9175   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9176   DONE;
9177 }")
9178
9179 (define_insn "tls_get_tpointer_internal"
9180   [(set (reg:SI 3)
9181         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9182    (clobber (reg:SI LR_REGNO))]
9183   "TARGET_XCOFF && HAVE_AS_TLS"
9184   "bla __get_tpointer")
9185
9186 (define_expand "tls_get_addr<mode>"
9187   [(set (match_operand:P 0 "gpc_reg_operand" "")
9188         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9189                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9190   "TARGET_XCOFF && HAVE_AS_TLS"
9191   "
9192 {
9193   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9194   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9195   emit_insn (gen_tls_get_addr_internal<mode> ());
9196   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9197   DONE;
9198 }")
9199
9200 (define_insn "tls_get_addr_internal<mode>"
9201   [(set (reg:P 3)
9202         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9203    (clobber (reg:P 0))
9204    (clobber (reg:P 4))
9205    (clobber (reg:P 5))
9206    (clobber (reg:P 11))
9207    (clobber (reg:CC CR0_REGNO))
9208    (clobber (reg:P LR_REGNO))]
9209   "TARGET_XCOFF && HAVE_AS_TLS"
9210   "bla __tls_get_addr")
9211 \f
9212 ;; Next come insns related to the calling sequence.
9213 ;;
9214 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9215 ;; We move the back-chain and decrement the stack pointer.
9216
9217 (define_expand "allocate_stack"
9218   [(set (match_operand 0 "gpc_reg_operand" "")
9219         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9220    (set (reg 1)
9221         (minus (reg 1) (match_dup 1)))]
9222   ""
9223   "
9224 { rtx chain = gen_reg_rtx (Pmode);
9225   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9226   rtx neg_op0;
9227   rtx insn, par, set, mem;
9228
9229   emit_move_insn (chain, stack_bot);
9230
9231   /* Check stack bounds if necessary.  */
9232   if (crtl->limit_stack)
9233     {
9234       rtx available;
9235       available = expand_binop (Pmode, sub_optab,
9236                                 stack_pointer_rtx, stack_limit_rtx,
9237                                 NULL_RTX, 1, OPTAB_WIDEN);
9238       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9239     }
9240
9241   if (GET_CODE (operands[1]) != CONST_INT
9242       || INTVAL (operands[1]) < -32767
9243       || INTVAL (operands[1]) > 32768)
9244     {
9245       neg_op0 = gen_reg_rtx (Pmode);
9246       if (TARGET_32BIT)
9247         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9248       else
9249         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9250     }
9251   else
9252     neg_op0 = GEN_INT (- INTVAL (operands[1]));
9253
9254   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9255                                        : gen_movdi_di_update_stack))
9256                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9257                          chain));
9258   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9259      it now and set the alias set/attributes. The above gen_*_update
9260      calls will generate a PARALLEL with the MEM set being the first
9261      operation. */
9262   par = PATTERN (insn);
9263   gcc_assert (GET_CODE (par) == PARALLEL);
9264   set = XVECEXP (par, 0, 0);
9265   gcc_assert (GET_CODE (set) == SET);
9266   mem = SET_DEST (set);
9267   gcc_assert (MEM_P (mem));
9268   MEM_NOTRAP_P (mem) = 1;
9269   set_mem_alias_set (mem, get_frame_alias_set ());
9270
9271   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9272   DONE;
9273 }")
9274
9275 ;; These patterns say how to save and restore the stack pointer.  We need not
9276 ;; save the stack pointer at function level since we are careful to
9277 ;; preserve the backchain.  At block level, we have to restore the backchain
9278 ;; when we restore the stack pointer.
9279 ;;
9280 ;; For nonlocal gotos, we must save both the stack pointer and its
9281 ;; backchain and restore both.  Note that in the nonlocal case, the
9282 ;; save area is a memory location.
9283
9284 (define_expand "save_stack_function"
9285   [(match_operand 0 "any_operand" "")
9286    (match_operand 1 "any_operand" "")]
9287   ""
9288   "DONE;")
9289
9290 (define_expand "restore_stack_function"
9291   [(match_operand 0 "any_operand" "")
9292    (match_operand 1 "any_operand" "")]
9293   ""
9294   "DONE;")
9295
9296 ;; Adjust stack pointer (op0) to a new value (op1).
9297 ;; First copy old stack backchain to new location, and ensure that the
9298 ;; scheduler won't reorder the sp assignment before the backchain write.
9299 (define_expand "restore_stack_block"
9300   [(set (match_dup 2) (match_dup 3))
9301    (set (match_dup 4) (match_dup 2))
9302    (match_dup 5)
9303    (set (match_operand 0 "register_operand" "")
9304         (match_operand 1 "register_operand" ""))]
9305   ""
9306   "
9307 {
9308   rtvec p;
9309
9310   operands[1] = force_reg (Pmode, operands[1]);
9311   operands[2] = gen_reg_rtx (Pmode);
9312   operands[3] = gen_frame_mem (Pmode, operands[0]);
9313   operands[4] = gen_frame_mem (Pmode, operands[1]);
9314   p = rtvec_alloc (1);
9315   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9316                                   const0_rtx);
9317   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9318 }")
9319
9320 (define_expand "save_stack_nonlocal"
9321   [(set (match_dup 3) (match_dup 4))
9322    (set (match_operand 0 "memory_operand" "") (match_dup 3))
9323    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9324   ""
9325   "
9326 {
9327   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9328
9329   /* Copy the backchain to the first word, sp to the second.  */
9330   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9331   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9332   operands[3] = gen_reg_rtx (Pmode);
9333   operands[4] = gen_frame_mem (Pmode, operands[1]);
9334 }")
9335
9336 (define_expand "restore_stack_nonlocal"
9337   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9338    (set (match_dup 3) (match_dup 4))
9339    (set (match_dup 5) (match_dup 2))
9340    (match_dup 6)
9341    (set (match_operand 0 "register_operand" "") (match_dup 3))]
9342   ""
9343   "
9344 {
9345   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9346   rtvec p;
9347
9348   /* Restore the backchain from the first word, sp from the second.  */
9349   operands[2] = gen_reg_rtx (Pmode);
9350   operands[3] = gen_reg_rtx (Pmode);
9351   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9352   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9353   operands[5] = gen_frame_mem (Pmode, operands[3]);
9354   p = rtvec_alloc (1);
9355   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9356                                   const0_rtx);
9357   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9358 }")
9359 \f
9360 ;; TOC register handling.
9361
9362 ;; Code to initialize the TOC register...
9363
9364 (define_insn "load_toc_aix_si"
9365   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9366                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9367               (use (reg:SI 2))])]
9368   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9369   "*
9370 {
9371   char buf[30];
9372   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9373   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9374   operands[2] = gen_rtx_REG (Pmode, 2);
9375   return \"lwz %0,%1(%2)\";
9376 }"
9377   [(set_attr "type" "load")
9378    (set_attr "update" "no")
9379    (set_attr "indexed" "no")])
9380
9381 (define_insn "load_toc_aix_di"
9382   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9383                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9384               (use (reg:DI 2))])]
9385   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9386   "*
9387 {
9388   char buf[30];
9389 #ifdef TARGET_RELOCATABLE
9390   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9391                                !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
9392 #else
9393   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9394 #endif
9395   if (TARGET_ELF)
9396     strcat (buf, \"@toc\");
9397   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9398   operands[2] = gen_rtx_REG (Pmode, 2);
9399   return \"ld %0,%1(%2)\";
9400 }"
9401   [(set_attr "type" "load")
9402    (set_attr "update" "no")
9403    (set_attr "indexed" "no")])
9404
9405 (define_insn "load_toc_v4_pic_si"
9406   [(set (reg:SI LR_REGNO)
9407         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9408   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9409   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9410   [(set_attr "type" "branch")
9411    (set_attr "length" "4")])
9412
9413 (define_expand "load_toc_v4_PIC_1"
9414   [(parallel [(set (reg:SI LR_REGNO)
9415                    (match_operand:SI 0 "immediate_operand" "s"))
9416               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9417   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9418    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9419   "")
9420
9421 (define_insn "load_toc_v4_PIC_1_normal"
9422   [(set (reg:SI LR_REGNO)
9423         (match_operand:SI 0 "immediate_operand" "s"))
9424    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9425   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9426    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9427   "bcl 20,31,%0\\n%0:"
9428   [(set_attr "type" "branch")
9429    (set_attr "length" "4")])
9430
9431 (define_insn "load_toc_v4_PIC_1_476"
9432   [(set (reg:SI LR_REGNO)
9433         (match_operand:SI 0 "immediate_operand" "s"))
9434    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9435   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9436    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9437   "*
9438 {
9439   char name[32];
9440   static char templ[32];
9441
9442   get_ppc476_thunk_name (name);
9443   sprintf (templ, \"bl %s\\n%%0:\", name);
9444   return templ;
9445 }"
9446   [(set_attr "type" "branch")
9447    (set_attr "length" "4")])
9448
9449 (define_expand "load_toc_v4_PIC_1b"
9450   [(parallel [(set (reg:SI LR_REGNO)
9451                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9452                                (label_ref (match_operand 1 "" ""))]
9453                            UNSPEC_TOCPTR))
9454               (match_dup 1)])]
9455   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9456   "")
9457
9458 (define_insn "load_toc_v4_PIC_1b_normal"
9459   [(set (reg:SI LR_REGNO)
9460         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9461                     (label_ref (match_operand 1 "" ""))]
9462                 UNSPEC_TOCPTR))
9463    (match_dup 1)]
9464   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9465   "bcl 20,31,$+8\;.long %0-$"
9466   [(set_attr "type" "branch")
9467    (set_attr "length" "8")])
9468
9469 (define_insn "load_toc_v4_PIC_1b_476"
9470   [(set (reg:SI LR_REGNO)
9471         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9472                     (label_ref (match_operand 1 "" ""))]
9473                 UNSPEC_TOCPTR))
9474    (match_dup 1)]
9475   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9476   "*
9477 {
9478   char name[32];
9479   static char templ[32];
9480
9481   get_ppc476_thunk_name (name);
9482   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9483   return templ;
9484 }"
9485   [(set_attr "type" "branch")
9486    (set_attr "length" "16")])
9487
9488 (define_insn "load_toc_v4_PIC_2"
9489   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9490         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9491                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9492                              (match_operand:SI 3 "immediate_operand" "s")))))]
9493   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9494   "lwz %0,%2-%3(%1)"
9495   [(set_attr "type" "load")])
9496
9497 (define_insn "load_toc_v4_PIC_3b"
9498   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9499         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9500                  (high:SI
9501                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9502                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9503   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9504   "addis %0,%1,%2-%3@ha")
9505
9506 (define_insn "load_toc_v4_PIC_3c"
9507   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9508         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9509                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9510                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9511   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9512   "addi %0,%1,%2-%3@l")
9513
9514 ;; If the TOC is shared over a translation unit, as happens with all
9515 ;; the kinds of PIC that we support, we need to restore the TOC
9516 ;; pointer only when jumping over units of translation.
9517 ;; On Darwin, we need to reload the picbase.
9518
9519 (define_expand "builtin_setjmp_receiver"
9520   [(use (label_ref (match_operand 0 "" "")))]
9521   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9522    || (TARGET_TOC && TARGET_MINIMAL_TOC)
9523    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9524   "
9525 {
9526 #if TARGET_MACHO
9527   if (DEFAULT_ABI == ABI_DARWIN)
9528     {
9529       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9530       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9531       rtx tmplabrtx;
9532       char tmplab[20];
9533
9534       crtl->uses_pic_offset_table = 1;
9535       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9536                                   CODE_LABEL_NUMBER (operands[0]));
9537       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9538
9539       emit_insn (gen_load_macho_picbase (tmplabrtx));
9540       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9541       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9542     }
9543   else
9544 #endif
9545     rs6000_emit_load_toc_table (FALSE);
9546   DONE;
9547 }")
9548
9549 ;; Largetoc support
9550 (define_insn "*largetoc_high"
9551   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9552         (high:DI
9553           (unspec [(match_operand:DI 1 "" "")
9554                    (match_operand:DI 2 "gpc_reg_operand" "b")]
9555                   UNSPEC_TOCREL)))]
9556    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9557    "addis %0,%2,%1@toc@ha")
9558
9559 (define_insn "*largetoc_high_aix<mode>"
9560   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9561         (high:P
9562           (unspec [(match_operand:P 1 "" "")
9563                    (match_operand:P 2 "gpc_reg_operand" "b")]
9564                   UNSPEC_TOCREL)))]
9565    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9566    "addis %0,%1@u(%2)")
9567
9568 (define_insn "*largetoc_high_plus"
9569   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9570         (high:DI
9571           (plus:DI
9572             (unspec [(match_operand:DI 1 "" "")
9573                      (match_operand:DI 2 "gpc_reg_operand" "b")]
9574                     UNSPEC_TOCREL)
9575             (match_operand:DI 3 "add_cint_operand" "n"))))]
9576    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9577    "addis %0,%2,%1+%3@toc@ha")
9578
9579 (define_insn "*largetoc_high_plus_aix<mode>"
9580   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9581         (high:P
9582           (plus:P
9583             (unspec [(match_operand:P 1 "" "")
9584                      (match_operand:P 2 "gpc_reg_operand" "b")]
9585                     UNSPEC_TOCREL)
9586             (match_operand:P 3 "add_cint_operand" "n"))))]
9587    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9588    "addis %0,%1+%3@u(%2)")
9589
9590 (define_insn "*largetoc_low"
9591   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9592         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9593                    (match_operand:DI 2 "" "")))]
9594    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9595    "addi %0,%1,%2@l")
9596
9597 (define_insn "*largetoc_low_aix<mode>"
9598   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9599         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9600                    (match_operand:P 2 "" "")))]
9601    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9602    "la %0,%2@l(%1)")
9603
9604 (define_insn_and_split "*tocref<mode>"
9605   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9606         (match_operand:P 1 "small_toc_ref" "R"))]
9607    "TARGET_TOC"
9608    "la %0,%a1"
9609    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
9610   [(set (match_dup 0) (high:P (match_dup 1)))
9611    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
9612
9613 ;; Elf specific ways of loading addresses for non-PIC code.
9614 ;; The output of this could be r0, but we make a very strong
9615 ;; preference for a base register because it will usually
9616 ;; be needed there.
9617 (define_insn "elf_high"
9618   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
9619         (high:SI (match_operand 1 "" "")))]
9620   "TARGET_ELF && ! TARGET_64BIT"
9621   "lis %0,%1@ha")
9622
9623 (define_insn "elf_low"
9624   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9625         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9626                    (match_operand 2 "" "")))]
9627    "TARGET_ELF && ! TARGET_64BIT"
9628    "la %0,%2@l(%1)")
9629 \f
9630 ;; Call and call_value insns
9631 (define_expand "call"
9632   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
9633                     (match_operand 1 "" ""))
9634               (use (match_operand 2 "" ""))
9635               (clobber (reg:SI LR_REGNO))])]
9636   ""
9637   "
9638 {
9639 #if TARGET_MACHO
9640   if (MACHOPIC_INDIRECT)
9641     operands[0] = machopic_indirect_call_target (operands[0]);
9642 #endif
9643
9644   gcc_assert (GET_CODE (operands[0]) == MEM);
9645   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
9646
9647   operands[0] = XEXP (operands[0], 0);
9648
9649   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9650     {
9651       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
9652       DONE;
9653     }
9654
9655   if (GET_CODE (operands[0]) != SYMBOL_REF
9656       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
9657     {
9658       if (INTVAL (operands[2]) & CALL_LONG)
9659         operands[0] = rs6000_longcall_ref (operands[0]);
9660
9661       switch (DEFAULT_ABI)
9662         {
9663         case ABI_V4:
9664         case ABI_DARWIN:
9665           operands[0] = force_reg (Pmode, operands[0]);
9666           break;
9667
9668         default:
9669           gcc_unreachable ();
9670         }
9671     }
9672 }")
9673
9674 (define_expand "call_value"
9675   [(parallel [(set (match_operand 0 "" "")
9676                    (call (mem:SI (match_operand 1 "address_operand" ""))
9677                          (match_operand 2 "" "")))
9678               (use (match_operand 3 "" ""))
9679               (clobber (reg:SI LR_REGNO))])]
9680   ""
9681   "
9682 {
9683 #if TARGET_MACHO
9684   if (MACHOPIC_INDIRECT)
9685     operands[1] = machopic_indirect_call_target (operands[1]);
9686 #endif
9687
9688   gcc_assert (GET_CODE (operands[1]) == MEM);
9689   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
9690
9691   operands[1] = XEXP (operands[1], 0);
9692
9693   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9694     {
9695       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
9696       DONE;
9697     }
9698
9699   if (GET_CODE (operands[1]) != SYMBOL_REF
9700       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
9701     {
9702       if (INTVAL (operands[3]) & CALL_LONG)
9703         operands[1] = rs6000_longcall_ref (operands[1]);
9704
9705       switch (DEFAULT_ABI)
9706         {
9707         case ABI_V4:
9708         case ABI_DARWIN:
9709           operands[1] = force_reg (Pmode, operands[1]);
9710           break;
9711
9712         default:
9713           gcc_unreachable ();
9714         }
9715     }
9716 }")
9717
9718 ;; Call to function in current module.  No TOC pointer reload needed.
9719 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
9720 ;; either the function was not prototyped, or it was prototyped as a
9721 ;; variable argument function.  It is > 0 if FP registers were passed
9722 ;; and < 0 if they were not.
9723
9724 (define_insn "*call_local32"
9725   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
9726          (match_operand 1 "" "g,g"))
9727    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9728    (clobber (reg:SI LR_REGNO))]
9729   "(INTVAL (operands[2]) & CALL_LONG) == 0"
9730   "*
9731 {
9732   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9733     output_asm_insn (\"crxor 6,6,6\", operands);
9734
9735   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9736     output_asm_insn (\"creqv 6,6,6\", operands);
9737
9738   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9739 }"
9740   [(set_attr "type" "branch")
9741    (set_attr "length" "4,8")])
9742
9743 (define_insn "*call_local64"
9744   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
9745          (match_operand 1 "" "g,g"))
9746    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9747    (clobber (reg:SI LR_REGNO))]
9748   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
9749   "*
9750 {
9751   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9752     output_asm_insn (\"crxor 6,6,6\", operands);
9753
9754   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9755     output_asm_insn (\"creqv 6,6,6\", operands);
9756
9757   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9758 }"
9759   [(set_attr "type" "branch")
9760    (set_attr "length" "4,8")])
9761
9762 (define_insn "*call_value_local32"
9763   [(set (match_operand 0 "" "")
9764         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
9765               (match_operand 2 "" "g,g")))
9766    (use (match_operand:SI 3 "immediate_operand" "O,n"))
9767    (clobber (reg:SI LR_REGNO))]
9768   "(INTVAL (operands[3]) & CALL_LONG) == 0"
9769   "*
9770 {
9771   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9772     output_asm_insn (\"crxor 6,6,6\", operands);
9773
9774   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9775     output_asm_insn (\"creqv 6,6,6\", operands);
9776
9777   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9778 }"
9779   [(set_attr "type" "branch")
9780    (set_attr "length" "4,8")])
9781
9782
9783 (define_insn "*call_value_local64"
9784   [(set (match_operand 0 "" "")
9785         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
9786               (match_operand 2 "" "g,g")))
9787    (use (match_operand:SI 3 "immediate_operand" "O,n"))
9788    (clobber (reg:SI LR_REGNO))]
9789   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
9790   "*
9791 {
9792   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9793     output_asm_insn (\"crxor 6,6,6\", operands);
9794
9795   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9796     output_asm_insn (\"creqv 6,6,6\", operands);
9797
9798   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9799 }"
9800   [(set_attr "type" "branch")
9801    (set_attr "length" "4,8")])
9802
9803
9804 ;; A function pointer under System V is just a normal pointer
9805 ;; operands[0] is the function pointer
9806 ;; operands[1] is the stack size to clean up
9807 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
9808 ;; which indicates how to set cr1
9809
9810 (define_insn "*call_indirect_nonlocal_sysv<mode>"
9811   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
9812          (match_operand 1 "" "g,g,g,g"))
9813    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
9814    (clobber (reg:SI LR_REGNO))]
9815   "DEFAULT_ABI == ABI_V4
9816    || DEFAULT_ABI == ABI_DARWIN"
9817 {
9818   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9819     output_asm_insn ("crxor 6,6,6", operands);
9820
9821   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9822     output_asm_insn ("creqv 6,6,6", operands);
9823
9824   return "b%T0l";
9825 }
9826   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
9827    (set_attr "length" "4,4,8,8")])
9828
9829 (define_insn_and_split "*call_nonlocal_sysv<mode>"
9830   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9831          (match_operand 1 "" "g,g"))
9832    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9833    (clobber (reg:SI LR_REGNO))]
9834   "(DEFAULT_ABI == ABI_DARWIN
9835    || (DEFAULT_ABI == ABI_V4
9836        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
9837 {
9838   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9839     output_asm_insn ("crxor 6,6,6", operands);
9840
9841   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9842     output_asm_insn ("creqv 6,6,6", operands);
9843
9844 #if TARGET_MACHO
9845   return output_call(insn, operands, 0, 2);
9846 #else
9847   if (DEFAULT_ABI == ABI_V4 && flag_pic)
9848     {
9849       gcc_assert (!TARGET_SECURE_PLT);
9850       return "bl %z0@plt";
9851     }
9852   else
9853     return "bl %z0";
9854 #endif
9855 }
9856   "DEFAULT_ABI == ABI_V4
9857    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9858    && (INTVAL (operands[2]) & CALL_LONG) == 0"
9859   [(parallel [(call (mem:SI (match_dup 0))
9860                     (match_dup 1))
9861               (use (match_dup 2))
9862               (use (match_dup 3))
9863               (clobber (reg:SI LR_REGNO))])]
9864 {
9865   operands[3] = pic_offset_table_rtx;
9866 }
9867   [(set_attr "type" "branch,branch")
9868    (set_attr "length" "4,8")])
9869
9870 (define_insn "*call_nonlocal_sysv_secure<mode>"
9871   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9872          (match_operand 1 "" "g,g"))
9873    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9874    (use (match_operand:SI 3 "register_operand" "r,r"))
9875    (clobber (reg:SI LR_REGNO))]
9876   "(DEFAULT_ABI == ABI_V4
9877     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9878     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
9879 {
9880   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9881     output_asm_insn ("crxor 6,6,6", operands);
9882
9883   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9884     output_asm_insn ("creqv 6,6,6", operands);
9885
9886   if (flag_pic == 2)
9887     /* The magic 32768 offset here and in the other sysv call insns
9888        corresponds to the offset of r30 in .got2, as given by LCTOC1.
9889        See sysv4.h:toc_section.  */
9890     return "bl %z0+32768@plt";
9891   else
9892     return "bl %z0@plt";
9893 }
9894   [(set_attr "type" "branch,branch")
9895    (set_attr "length" "4,8")])
9896
9897 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
9898   [(set (match_operand 0 "" "")
9899         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
9900               (match_operand 2 "" "g,g,g,g")))
9901    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
9902    (clobber (reg:SI LR_REGNO))]
9903   "DEFAULT_ABI == ABI_V4
9904    || DEFAULT_ABI == ABI_DARWIN"
9905 {
9906   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9907     output_asm_insn ("crxor 6,6,6", operands);
9908
9909   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9910     output_asm_insn ("creqv 6,6,6", operands);
9911
9912   return "b%T1l";
9913 }
9914   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
9915    (set_attr "length" "4,4,8,8")])
9916
9917 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
9918   [(set (match_operand 0 "" "")
9919         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
9920               (match_operand 2 "" "g,g")))
9921    (use (match_operand:SI 3 "immediate_operand" "O,n"))
9922    (clobber (reg:SI LR_REGNO))]
9923   "(DEFAULT_ABI == ABI_DARWIN
9924    || (DEFAULT_ABI == ABI_V4
9925        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
9926 {
9927   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9928     output_asm_insn ("crxor 6,6,6", operands);
9929
9930   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9931     output_asm_insn ("creqv 6,6,6", operands);
9932
9933 #if TARGET_MACHO
9934   return output_call(insn, operands, 1, 3);
9935 #else
9936   if (DEFAULT_ABI == ABI_V4 && flag_pic)
9937     {
9938       gcc_assert (!TARGET_SECURE_PLT);
9939       return "bl %z1@plt";
9940     }
9941   else
9942     return "bl %z1";
9943 #endif
9944 }
9945   "DEFAULT_ABI == ABI_V4
9946    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
9947    && (INTVAL (operands[3]) & CALL_LONG) == 0"
9948   [(parallel [(set (match_dup 0)
9949                    (call (mem:SI (match_dup 1))
9950                          (match_dup 2)))
9951               (use (match_dup 3))
9952               (use (match_dup 4))
9953               (clobber (reg:SI LR_REGNO))])]
9954 {
9955   operands[4] = pic_offset_table_rtx;
9956 }
9957   [(set_attr "type" "branch,branch")
9958    (set_attr "length" "4,8")])
9959
9960 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
9961   [(set (match_operand 0 "" "")
9962         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
9963               (match_operand 2 "" "g,g")))
9964    (use (match_operand:SI 3 "immediate_operand" "O,n"))
9965    (use (match_operand:SI 4 "register_operand" "r,r"))
9966    (clobber (reg:SI LR_REGNO))]
9967   "(DEFAULT_ABI == ABI_V4
9968     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
9969     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
9970 {
9971   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9972     output_asm_insn ("crxor 6,6,6", operands);
9973
9974   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9975     output_asm_insn ("creqv 6,6,6", operands);
9976
9977   if (flag_pic == 2)
9978     return "bl %z1+32768@plt";
9979   else
9980     return "bl %z1@plt";
9981 }
9982   [(set_attr "type" "branch,branch")
9983    (set_attr "length" "4,8")])
9984
9985
9986 ;; Call to AIX abi function in the same module.
9987
9988 (define_insn "*call_local_aix<mode>"
9989   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
9990          (match_operand 1 "" "g"))
9991    (clobber (reg:P LR_REGNO))]
9992   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
9993   "bl %z0"
9994   [(set_attr "type" "branch")
9995    (set_attr "length" "4")])
9996
9997 (define_insn "*call_value_local_aix<mode>"
9998   [(set (match_operand 0 "" "")
9999         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10000               (match_operand 2 "" "g")))
10001    (clobber (reg:P LR_REGNO))]
10002   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10003   "bl %z1"
10004   [(set_attr "type" "branch")
10005    (set_attr "length" "4")])
10006
10007 ;; Call to AIX abi function which may be in another module.
10008 ;; Restore the TOC pointer (r2) after the call.
10009
10010 (define_insn "*call_nonlocal_aix<mode>"
10011   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10012          (match_operand 1 "" "g"))
10013    (clobber (reg:P LR_REGNO))]
10014   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10015   "bl %z0\;nop"
10016   [(set_attr "type" "branch")
10017    (set_attr "length" "8")])
10018
10019 (define_insn "*call_value_nonlocal_aix<mode>"
10020   [(set (match_operand 0 "" "")
10021         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10022               (match_operand 2 "" "g")))
10023    (clobber (reg:P LR_REGNO))]
10024   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10025   "bl %z1\;nop"
10026   [(set_attr "type" "branch")
10027    (set_attr "length" "8")])
10028
10029 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10030 ;; Operand0 is the addresss of the function to call
10031 ;; Operand2 is the location in the function descriptor to load r2 from
10032 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10033
10034 (define_insn "*call_indirect_aix<mode>"
10035   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10036          (match_operand 1 "" "g,g"))
10037    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10038    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10039    (clobber (reg:P LR_REGNO))]
10040   "DEFAULT_ABI == ABI_AIX"
10041   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10042   [(set_attr "type" "jmpreg")
10043    (set_attr "length" "12")])
10044
10045 (define_insn "*call_value_indirect_aix<mode>"
10046   [(set (match_operand 0 "" "")
10047         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10048               (match_operand 2 "" "g,g")))
10049    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10050    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10051    (clobber (reg:P LR_REGNO))]
10052   "DEFAULT_ABI == ABI_AIX"
10053   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10054   [(set_attr "type" "jmpreg")
10055    (set_attr "length" "12")])
10056
10057 ;; Call to indirect functions with the ELFv2 ABI.
10058 ;; Operand0 is the addresss of the function to call
10059 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10060
10061 (define_insn "*call_indirect_elfv2<mode>"
10062   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10063          (match_operand 1 "" "g,g"))
10064    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10065    (clobber (reg:P LR_REGNO))]
10066   "DEFAULT_ABI == ABI_ELFv2"
10067   "b%T0l\;<ptrload> 2,%2(1)"
10068   [(set_attr "type" "jmpreg")
10069    (set_attr "length" "8")])
10070
10071 (define_insn "*call_value_indirect_elfv2<mode>"
10072   [(set (match_operand 0 "" "")
10073         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10074               (match_operand 2 "" "g,g")))
10075    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10076    (clobber (reg:P LR_REGNO))]
10077   "DEFAULT_ABI == ABI_ELFv2"
10078   "b%T1l\;<ptrload> 2,%3(1)"
10079   [(set_attr "type" "jmpreg")
10080    (set_attr "length" "8")])
10081
10082
10083 ;; Call subroutine returning any type.
10084 (define_expand "untyped_call"
10085   [(parallel [(call (match_operand 0 "" "")
10086                     (const_int 0))
10087               (match_operand 1 "" "")
10088               (match_operand 2 "" "")])]
10089   ""
10090   "
10091 {
10092   int i;
10093
10094   emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx));
10095
10096   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10097     {
10098       rtx set = XVECEXP (operands[2], 0, i);
10099       emit_move_insn (SET_DEST (set), SET_SRC (set));
10100     }
10101
10102   /* The optimizer does not know that the call sets the function value
10103      registers we stored in the result block.  We avoid problems by
10104      claiming that all hard registers are used and clobbered at this
10105      point.  */
10106   emit_insn (gen_blockage ());
10107
10108   DONE;
10109 }")
10110
10111 ;; sibling call patterns
10112 (define_expand "sibcall"
10113   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10114                     (match_operand 1 "" ""))
10115               (use (match_operand 2 "" ""))
10116               (use (reg:SI LR_REGNO))
10117               (simple_return)])]
10118   ""
10119   "
10120 {
10121 #if TARGET_MACHO
10122   if (MACHOPIC_INDIRECT)
10123     operands[0] = machopic_indirect_call_target (operands[0]);
10124 #endif
10125
10126   gcc_assert (GET_CODE (operands[0]) == MEM);
10127   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10128
10129   operands[0] = XEXP (operands[0], 0);
10130
10131   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10132     {
10133       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10134       DONE;
10135     }
10136 }")
10137
10138 (define_expand "sibcall_value"
10139   [(parallel [(set (match_operand 0 "register_operand" "")
10140                 (call (mem:SI (match_operand 1 "address_operand" ""))
10141                       (match_operand 2 "" "")))
10142               (use (match_operand 3 "" ""))
10143               (use (reg:SI LR_REGNO))
10144               (simple_return)])]
10145   ""
10146   "
10147 {
10148 #if TARGET_MACHO
10149   if (MACHOPIC_INDIRECT)
10150     operands[1] = machopic_indirect_call_target (operands[1]);
10151 #endif
10152
10153   gcc_assert (GET_CODE (operands[1]) == MEM);
10154   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10155
10156   operands[1] = XEXP (operands[1], 0);
10157
10158   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10159     {
10160       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10161       DONE;
10162     }
10163 }")
10164
10165 ;; this and similar patterns must be marked as using LR, otherwise
10166 ;; dataflow will try to delete the store into it.  This is true
10167 ;; even when the actual reg to jump to is in CTR, when LR was
10168 ;; saved and restored around the PIC-setting BCL.
10169 (define_insn "*sibcall_local32"
10170   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10171          (match_operand 1 "" "g,g"))
10172    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10173    (use (reg:SI LR_REGNO))
10174    (simple_return)]
10175   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10176   "*
10177 {
10178   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10179     output_asm_insn (\"crxor 6,6,6\", operands);
10180
10181   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10182     output_asm_insn (\"creqv 6,6,6\", operands);
10183
10184   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10185 }"
10186   [(set_attr "type" "branch")
10187    (set_attr "length" "4,8")])
10188
10189 (define_insn "*sibcall_local64"
10190   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10191          (match_operand 1 "" "g,g"))
10192    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10193    (use (reg:SI LR_REGNO))
10194    (simple_return)]
10195   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10196   "*
10197 {
10198   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10199     output_asm_insn (\"crxor 6,6,6\", operands);
10200
10201   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10202     output_asm_insn (\"creqv 6,6,6\", operands);
10203
10204   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10205 }"
10206   [(set_attr "type" "branch")
10207    (set_attr "length" "4,8")])
10208
10209 (define_insn "*sibcall_value_local32"
10210   [(set (match_operand 0 "" "")
10211         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10212               (match_operand 2 "" "g,g")))
10213    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10214    (use (reg:SI LR_REGNO))
10215    (simple_return)]
10216   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10217   "*
10218 {
10219   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10220     output_asm_insn (\"crxor 6,6,6\", operands);
10221
10222   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10223     output_asm_insn (\"creqv 6,6,6\", operands);
10224
10225   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10226 }"
10227   [(set_attr "type" "branch")
10228    (set_attr "length" "4,8")])
10229
10230 (define_insn "*sibcall_value_local64"
10231   [(set (match_operand 0 "" "")
10232         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10233               (match_operand 2 "" "g,g")))
10234    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10235    (use (reg:SI LR_REGNO))
10236    (simple_return)]
10237   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10238   "*
10239 {
10240   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10241     output_asm_insn (\"crxor 6,6,6\", operands);
10242
10243   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10244     output_asm_insn (\"creqv 6,6,6\", operands);
10245
10246   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10247 }"
10248   [(set_attr "type" "branch")
10249    (set_attr "length" "4,8")])
10250
10251 (define_insn "*sibcall_nonlocal_sysv<mode>"
10252   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10253          (match_operand 1 "" ""))
10254    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10255    (use (reg:SI LR_REGNO))
10256    (simple_return)]
10257   "(DEFAULT_ABI == ABI_DARWIN
10258     || DEFAULT_ABI == ABI_V4)
10259    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10260   "*
10261 {
10262   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10263     output_asm_insn (\"crxor 6,6,6\", operands);
10264
10265   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10266     output_asm_insn (\"creqv 6,6,6\", operands);
10267
10268   if (which_alternative >= 2)
10269     return \"b%T0\";
10270   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10271     {
10272       gcc_assert (!TARGET_SECURE_PLT);
10273       return \"b %z0@plt\";
10274     }
10275   else
10276     return \"b %z0\";
10277 }"
10278   [(set_attr "type" "branch")
10279    (set_attr "length" "4,8,4,8")])
10280
10281 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10282   [(set (match_operand 0 "" "")
10283         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10284               (match_operand 2 "" "")))
10285    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10286    (use (reg:SI LR_REGNO))
10287    (simple_return)]
10288   "(DEFAULT_ABI == ABI_DARWIN
10289     || DEFAULT_ABI == ABI_V4)
10290    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10291   "*
10292 {
10293   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10294     output_asm_insn (\"crxor 6,6,6\", operands);
10295
10296   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10297     output_asm_insn (\"creqv 6,6,6\", operands);
10298
10299   if (which_alternative >= 2)
10300     return \"b%T1\";
10301   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10302     {
10303       gcc_assert (!TARGET_SECURE_PLT);
10304       return \"b %z1@plt\";
10305     }
10306   else
10307     return \"b %z1\";
10308 }"
10309   [(set_attr "type" "branch")
10310    (set_attr "length" "4,8,4,8")])
10311
10312 ;; AIX ABI sibling call patterns.
10313
10314 (define_insn "*sibcall_aix<mode>"
10315   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10316          (match_operand 1 "" "g,g"))
10317    (simple_return)]
10318   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10319   "@
10320    b %z0
10321    b%T0"
10322   [(set_attr "type" "branch")
10323    (set_attr "length" "4")])
10324
10325 (define_insn "*sibcall_value_aix<mode>"
10326   [(set (match_operand 0 "" "")
10327         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10328               (match_operand 2 "" "g,g")))
10329    (simple_return)]
10330   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10331   "@
10332    b %z1
10333    b%T1"
10334   [(set_attr "type" "branch")
10335    (set_attr "length" "4")])
10336
10337 (define_expand "sibcall_epilogue"
10338   [(use (const_int 0))]
10339   ""
10340 {
10341   if (!TARGET_SCHED_PROLOG)
10342     emit_insn (gen_blockage ());
10343   rs6000_emit_epilogue (TRUE);
10344   DONE;
10345 })
10346
10347 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10348 ;; all of memory.  This blocks insns from being moved across this point.
10349
10350 (define_insn "blockage"
10351   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10352   ""
10353   "")
10354
10355 (define_expand "probe_stack_address"
10356   [(use (match_operand 0 "address_operand"))]
10357   ""
10358 {
10359   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10360   MEM_VOLATILE_P (operands[0]) = 1;
10361
10362   if (TARGET_64BIT)
10363     emit_insn (gen_probe_stack_di (operands[0]));
10364   else
10365     emit_insn (gen_probe_stack_si (operands[0]));
10366   DONE;
10367 })
10368
10369 (define_insn "probe_stack_<mode>"
10370   [(set (match_operand:P 0 "memory_operand" "=m")
10371         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10372   ""
10373 {
10374   operands[1] = gen_rtx_REG (Pmode, 0);
10375   return "st<wd>%U0%X0 %1,%0";
10376 }
10377   [(set_attr "type" "store")
10378    (set (attr "update")
10379         (if_then_else (match_operand 0 "update_address_mem")
10380                       (const_string "yes")
10381                       (const_string "no")))
10382    (set (attr "indexed")
10383         (if_then_else (match_operand 0 "indexed_address_mem")
10384                       (const_string "yes")
10385                       (const_string "no")))
10386    (set_attr "length" "4")])
10387
10388 (define_insn "probe_stack_range<P:mode>"
10389   [(set (match_operand:P 0 "register_operand" "=r")
10390         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10391                             (match_operand:P 2 "register_operand" "r")]
10392                            UNSPECV_PROBE_STACK_RANGE))]
10393   ""
10394   "* return output_probe_stack_range (operands[0], operands[2]);"
10395   [(set_attr "type" "three")])
10396 \f
10397 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
10398 ;; signed & unsigned, and one type of branch.
10399 ;;
10400 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10401 ;; insns, and branches.
10402
10403 (define_expand "cbranch<mode>4"
10404   [(use (match_operator 0 "rs6000_cbranch_operator"
10405          [(match_operand:GPR 1 "gpc_reg_operand" "")
10406           (match_operand:GPR 2 "reg_or_short_operand" "")]))
10407    (use (match_operand 3 ""))]
10408   ""
10409   "
10410 {
10411   /* Take care of the possibility that operands[2] might be negative but
10412      this might be a logical operation.  That insn doesn't exist.  */
10413   if (GET_CODE (operands[2]) == CONST_INT
10414       && INTVAL (operands[2]) < 0)
10415     {
10416       operands[2] = force_reg (<MODE>mode, operands[2]);
10417       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10418                                     GET_MODE (operands[0]),
10419                                     operands[1], operands[2]);
10420    }
10421
10422   rs6000_emit_cbranch (<MODE>mode, operands);
10423   DONE;
10424 }")
10425
10426 (define_expand "cbranch<mode>4"
10427   [(use (match_operator 0 "rs6000_cbranch_operator"
10428          [(match_operand:FP 1 "gpc_reg_operand" "")
10429           (match_operand:FP 2 "gpc_reg_operand" "")]))
10430    (use (match_operand 3 ""))]
10431   ""
10432   "
10433 {
10434   rs6000_emit_cbranch (<MODE>mode, operands);
10435   DONE;
10436 }")
10437
10438 (define_expand "cstore<mode>4_unsigned"
10439   [(use (match_operator 1 "unsigned_comparison_operator"
10440          [(match_operand:P 2 "gpc_reg_operand" "")
10441           (match_operand:P 3 "reg_or_short_operand" "")]))
10442    (clobber (match_operand:P 0 "register_operand"))]
10443   ""
10444 {
10445   enum rtx_code cond_code = GET_CODE (operands[1]);
10446
10447   rtx op0 = operands[0];
10448   rtx op1 = operands[2];
10449   rtx op2 = operands[3];
10450
10451   if (cond_code == GEU || cond_code == LTU)
10452     {
10453       cond_code = swap_condition (cond_code);
10454       op1 = operands[3];
10455       op2 = operands[2];
10456     }
10457
10458   if (!gpc_reg_operand (op1, <MODE>mode))
10459     op1 = force_reg (<MODE>mode, op1);
10460   if (!reg_or_short_operand (op2, <MODE>mode))
10461     op2 = force_reg (<MODE>mode, op2);
10462
10463   rtx tmp = gen_reg_rtx (<MODE>mode);
10464   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10465
10466   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10467   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10468
10469   if (cond_code == LEU)
10470     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10471   else
10472     emit_insn (gen_neg<mode>2 (op0, tmp2));
10473
10474   DONE;
10475 })
10476
10477 (define_expand "cstore<mode>4_signed_imm"
10478   [(use (match_operator 1 "signed_comparison_operator"
10479          [(match_operand:GPR 2 "gpc_reg_operand")
10480           (match_operand:GPR 3 "immediate_operand")]))
10481    (clobber (match_operand:GPR 0 "register_operand"))]
10482   ""
10483 {
10484   bool invert = false;
10485
10486   enum rtx_code cond_code = GET_CODE (operands[1]);
10487
10488   rtx op0 = operands[0];
10489   rtx op1 = operands[2];
10490   HOST_WIDE_INT val = INTVAL (operands[3]);
10491
10492   if (cond_code == GE || cond_code == GT)
10493     {
10494       cond_code = reverse_condition (cond_code);
10495       invert = true;
10496     }
10497
10498   if (cond_code == LE)
10499     val++;
10500
10501   rtx tmp = gen_reg_rtx (<MODE>mode);
10502   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10503   rtx x = gen_reg_rtx (<MODE>mode);
10504   if (val < 0)
10505     emit_insn (gen_and<mode>3 (x, op1, tmp));
10506   else
10507     emit_insn (gen_ior<mode>3 (x, op1, tmp));
10508
10509   if (invert)
10510     {
10511       rtx tmp = gen_reg_rtx (<MODE>mode);
10512       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10513       x = tmp;
10514     }
10515
10516   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10517   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10518
10519   DONE;
10520 })
10521
10522 (define_expand "cstore<mode>4_unsigned_imm"
10523   [(use (match_operator 1 "unsigned_comparison_operator"
10524          [(match_operand:GPR 2 "gpc_reg_operand")
10525           (match_operand:GPR 3 "immediate_operand")]))
10526    (clobber (match_operand:GPR 0 "register_operand"))]
10527   ""
10528 {
10529   bool invert = false;
10530
10531   enum rtx_code cond_code = GET_CODE (operands[1]);
10532
10533   rtx op0 = operands[0];
10534   rtx op1 = operands[2];
10535   HOST_WIDE_INT val = INTVAL (operands[3]);
10536
10537   if (cond_code == GEU || cond_code == GTU)
10538     {
10539       cond_code = reverse_condition (cond_code);
10540       invert = true;
10541     }
10542
10543   if (cond_code == LEU)
10544     val++;
10545
10546   rtx tmp = gen_reg_rtx (<MODE>mode);
10547   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10548   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10549   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
10550   rtx x = gen_reg_rtx (<MODE>mode);
10551   if (val < 0)
10552     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
10553   else
10554     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
10555
10556   if (invert)
10557     {
10558       rtx tmp = gen_reg_rtx (<MODE>mode);
10559       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10560       x = tmp;
10561     }
10562
10563   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10564   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10565
10566   DONE;
10567 })
10568
10569 (define_expand "cstore<mode>4"
10570   [(use (match_operator 1 "rs6000_cbranch_operator"
10571          [(match_operand:GPR 2 "gpc_reg_operand")
10572           (match_operand:GPR 3 "reg_or_short_operand")]))
10573    (clobber (match_operand:GPR 0 "register_operand"))]
10574   ""
10575 {
10576   /* Use ISEL if the user asked for it.  */
10577   if (TARGET_ISEL)
10578     rs6000_emit_sISEL (<MODE>mode, operands);
10579
10580   /* Expanding EQ and NE directly to some machine instructions does not help
10581      but does hurt combine.  So don't.  */
10582   else if (GET_CODE (operands[1]) == EQ)
10583     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
10584   else if (<MODE>mode == Pmode
10585            && GET_CODE (operands[1]) == NE)
10586     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
10587   else if (GET_CODE (operands[1]) == NE)
10588     {
10589       rtx tmp = gen_reg_rtx (<MODE>mode);
10590       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
10591       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
10592     }
10593
10594   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
10595      etc. combinations magically work out just right.  */
10596   else if (<MODE>mode == Pmode
10597            && unsigned_comparison_operator (operands[1], VOIDmode))
10598     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
10599                                            operands[2], operands[3]));
10600
10601   /* For signed comparisons against a constant, we can do some simple
10602      bit-twiddling.  */
10603   else if (signed_comparison_operator (operands[1], VOIDmode)
10604            && CONST_INT_P (operands[3]))
10605     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
10606                                              operands[2], operands[3]));
10607
10608   /* And similarly for unsigned comparisons.  */
10609   else if (unsigned_comparison_operator (operands[1], VOIDmode)
10610            && CONST_INT_P (operands[3]))
10611     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
10612                                                operands[2], operands[3]));
10613
10614   /* Everything else, use the mfcr brute force.  */
10615   else
10616     rs6000_emit_sCOND (<MODE>mode, operands);
10617
10618   DONE;
10619 })
10620
10621 (define_expand "cstore<mode>4"
10622   [(use (match_operator 1 "rs6000_cbranch_operator"
10623          [(match_operand:FP 2 "gpc_reg_operand" "")
10624           (match_operand:FP 3 "gpc_reg_operand" "")]))
10625    (clobber (match_operand:SI 0 "register_operand"))]
10626   ""
10627 {
10628   rs6000_emit_sCOND (<MODE>mode, operands);
10629   DONE;
10630 })
10631
10632
10633 (define_expand "stack_protect_set"
10634   [(match_operand 0 "memory_operand" "")
10635    (match_operand 1 "memory_operand" "")]
10636   ""
10637 {
10638 #ifdef TARGET_THREAD_SSP_OFFSET
10639   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10640   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10641   operands[1] = gen_rtx_MEM (Pmode, addr);
10642 #endif
10643   if (TARGET_64BIT)
10644     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10645   else
10646     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10647   DONE;
10648 })
10649
10650 (define_insn "stack_protect_setsi"
10651   [(set (match_operand:SI 0 "memory_operand" "=m")
10652         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
10653    (set (match_scratch:SI 2 "=&r") (const_int 0))]
10654   "TARGET_32BIT"
10655   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
10656   [(set_attr "type" "three")
10657    (set_attr "length" "12")])
10658
10659 (define_insn "stack_protect_setdi"
10660   [(set (match_operand:DI 0 "memory_operand" "=Y")
10661         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
10662    (set (match_scratch:DI 2 "=&r") (const_int 0))]
10663   "TARGET_64BIT"
10664   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
10665   [(set_attr "type" "three")
10666    (set_attr "length" "12")])
10667
10668 (define_expand "stack_protect_test"
10669   [(match_operand 0 "memory_operand" "")
10670    (match_operand 1 "memory_operand" "")
10671    (match_operand 2 "" "")]
10672   ""
10673 {
10674   rtx test, op0, op1;
10675 #ifdef TARGET_THREAD_SSP_OFFSET
10676   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10677   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10678   operands[1] = gen_rtx_MEM (Pmode, addr);
10679 #endif
10680   op0 = operands[0];
10681   op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
10682   test = gen_rtx_EQ (VOIDmode, op0, op1);
10683   emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
10684   DONE;
10685 })
10686
10687 (define_insn "stack_protect_testsi"
10688   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10689         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
10690                       (match_operand:SI 2 "memory_operand" "m,m")]
10691                      UNSPEC_SP_TEST))
10692    (set (match_scratch:SI 4 "=r,r") (const_int 0))
10693    (clobber (match_scratch:SI 3 "=&r,&r"))]
10694   "TARGET_32BIT"
10695   "@
10696    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10697    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
10698   [(set_attr "length" "16,20")])
10699
10700 (define_insn "stack_protect_testdi"
10701   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10702         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
10703                       (match_operand:DI 2 "memory_operand" "Y,Y")]
10704                      UNSPEC_SP_TEST))
10705    (set (match_scratch:DI 4 "=r,r") (const_int 0))
10706    (clobber (match_scratch:DI 3 "=&r,&r"))]
10707   "TARGET_64BIT"
10708   "@
10709    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10710    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
10711   [(set_attr "length" "16,20")])
10712
10713 \f
10714 ;; Here are the actual compare insns.
10715 (define_insn "*cmp<mode>_internal1"
10716   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
10717         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
10718                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
10719   ""
10720   "cmp<wd>%I2 %0,%1,%2"
10721   [(set_attr "type" "cmp")])
10722
10723 ;; If we are comparing a register for equality with a large constant,
10724 ;; we can do this with an XOR followed by a compare.  But this is profitable
10725 ;; only if the large constant is only used for the comparison (and in this
10726 ;; case we already have a register to reuse as scratch).
10727 ;;
10728 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
10729 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
10730
10731 (define_peephole2
10732   [(set (match_operand:SI 0 "register_operand")
10733         (match_operand:SI 1 "logical_const_operand" ""))
10734    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
10735                        [(match_dup 0)
10736                         (match_operand:SI 2 "logical_const_operand" "")]))
10737    (set (match_operand:CC 4 "cc_reg_operand" "")
10738         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
10739                     (match_dup 0)))
10740    (set (pc)
10741         (if_then_else (match_operator 6 "equality_operator"
10742                        [(match_dup 4) (const_int 0)])
10743                       (match_operand 7 "" "")
10744                       (match_operand 8 "" "")))]
10745   "peep2_reg_dead_p (3, operands[0])
10746    && peep2_reg_dead_p (4, operands[4])
10747    && REGNO (operands[0]) != REGNO (operands[5])"
10748  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
10749   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
10750   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
10751  
10752 {
10753   /* Get the constant we are comparing against, and see what it looks like
10754      when sign-extended from 16 to 32 bits.  Then see what constant we could
10755      XOR with SEXTC to get the sign-extended value.  */
10756   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
10757                                               SImode,
10758                                               operands[1], operands[2]);
10759   HOST_WIDE_INT c = INTVAL (cnst);
10760   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
10761   HOST_WIDE_INT xorv = c ^ sextc;
10762
10763   operands[9] = GEN_INT (xorv);
10764   operands[10] = GEN_INT (sextc);
10765 })
10766
10767 (define_insn "*cmpsi_internal2"
10768   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
10769         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
10770                        (match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
10771   ""
10772   "cmplw%I2 %0,%1,%b2"
10773   [(set_attr "type" "cmp")])
10774
10775 (define_insn "*cmpdi_internal2"
10776   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
10777         (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
10778                        (match_operand:DI 2 "reg_or_u_short_operand" "rK")))]
10779   ""
10780   "cmpld%I2 %0,%1,%b2"
10781   [(set_attr "type" "cmp")])
10782
10783 ;; The following two insns don't exist as single insns, but if we provide
10784 ;; them, we can swap an add and compare, which will enable us to overlap more
10785 ;; of the required delay between a compare and branch.  We generate code for
10786 ;; them by splitting.
10787
10788 (define_insn ""
10789   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
10790         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
10791                     (match_operand:SI 2 "short_cint_operand" "i")))
10792    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
10793         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
10794   ""
10795   "#"
10796   [(set_attr "length" "8")])
10797
10798 (define_insn ""
10799   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
10800         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
10801                        (match_operand:SI 2 "u_short_cint_operand" "i")))
10802    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
10803         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
10804   ""
10805   "#"
10806   [(set_attr "length" "8")])
10807
10808 (define_split
10809   [(set (match_operand:CC 3 "cc_reg_operand" "")
10810         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
10811                     (match_operand:SI 2 "short_cint_operand" "")))
10812    (set (match_operand:SI 0 "gpc_reg_operand" "")
10813         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
10814   ""
10815   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
10816    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
10817
10818 (define_split
10819   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
10820         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
10821                        (match_operand:SI 2 "u_short_cint_operand" "")))
10822    (set (match_operand:SI 0 "gpc_reg_operand" "")
10823         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
10824   ""
10825   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
10826    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
10827
10828 ;; Only need to compare second words if first words equal
10829 (define_insn "*cmptf_internal1"
10830   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
10831         (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
10832                       (match_operand:TF 2 "gpc_reg_operand" "d")))]
10833   "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
10834    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
10835   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
10836   [(set_attr "type" "fpcompare")
10837    (set_attr "length" "12")])
10838
10839 (define_insn_and_split "*cmptf_internal2"
10840   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
10841         (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
10842                       (match_operand:TF 2 "gpc_reg_operand" "d")))
10843     (clobber (match_scratch:DF 3 "=d"))
10844     (clobber (match_scratch:DF 4 "=d"))
10845     (clobber (match_scratch:DF 5 "=d"))
10846     (clobber (match_scratch:DF 6 "=d"))
10847     (clobber (match_scratch:DF 7 "=d"))
10848     (clobber (match_scratch:DF 8 "=d"))
10849     (clobber (match_scratch:DF 9 "=d"))
10850     (clobber (match_scratch:DF 10 "=d"))
10851     (clobber (match_scratch:GPR 11 "=b"))]
10852   "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
10853    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
10854   "#"
10855   "&& reload_completed"
10856   [(set (match_dup 3) (match_dup 14))
10857    (set (match_dup 4) (match_dup 15))
10858    (set (match_dup 9) (abs:DF (match_dup 5)))
10859    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
10860    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
10861                            (label_ref (match_dup 12))
10862                            (pc)))
10863    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
10864    (set (pc) (label_ref (match_dup 13)))
10865    (match_dup 12)
10866    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
10867    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
10868    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
10869    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
10870    (match_dup 13)]
10871 {
10872   REAL_VALUE_TYPE rv;
10873   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
10874   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
10875
10876   operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word);
10877   operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word);
10878   operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word);
10879   operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word);
10880   operands[12] = gen_label_rtx ();
10881   operands[13] = gen_label_rtx ();
10882   real_inf (&rv);
10883   operands[14] = force_const_mem (DFmode,
10884                                   CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode));
10885   operands[15] = force_const_mem (DFmode,
10886                                   CONST_DOUBLE_FROM_REAL_VALUE (dconst0,
10887                                                                 DFmode));
10888   if (TARGET_TOC)
10889     {
10890       rtx tocref;
10891       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
10892       operands[14] = gen_const_mem (DFmode, tocref);
10893       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
10894       operands[15] = gen_const_mem (DFmode, tocref);
10895       set_mem_alias_set (operands[14], get_TOC_alias_set ());
10896       set_mem_alias_set (operands[15], get_TOC_alias_set ());
10897     }
10898 })
10899 \f
10900 ;; Now we have the scc insns.  We can do some combinations because of the
10901 ;; way the machine works.
10902 ;;
10903 ;; Note that this is probably faster if we can put an insn between the
10904 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
10905 ;; cases the insns below which don't use an intermediate CR field will
10906 ;; be used instead.
10907 (define_insn ""
10908   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10909         (match_operator:SI 1 "scc_comparison_operator"
10910                            [(match_operand 2 "cc_reg_operand" "y")
10911                             (const_int 0)]))]
10912   ""
10913   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
10914   [(set (attr "type")
10915      (cond [(match_test "TARGET_MFCRF")
10916                 (const_string "mfcrf")
10917            ]
10918         (const_string "mfcr")))
10919    (set_attr "length" "8")])
10920
10921 ;; Same as above, but get the GT bit.
10922 (define_insn "move_from_CR_gt_bit"
10923   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10924         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
10925   "TARGET_HARD_FLOAT && !TARGET_FPRS"
10926   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
10927   [(set_attr "type" "mfcr")
10928    (set_attr "length" "8")])
10929
10930 ;; Same as above, but get the OV/ORDERED bit.
10931 (define_insn "move_from_CR_ov_bit"
10932   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10933         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
10934                    UNSPEC_MV_CR_OV))]
10935   "TARGET_ISEL"
10936   "mfcr %0\;rlwinm %0,%0,%t1,1"
10937   [(set_attr "type" "mfcr")
10938    (set_attr "length" "8")])
10939
10940 (define_insn ""
10941   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10942         (match_operator:DI 1 "scc_comparison_operator"
10943                            [(match_operand 2 "cc_reg_operand" "y")
10944                             (const_int 0)]))]
10945   "TARGET_POWERPC64"
10946   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
10947   [(set (attr "type")
10948      (cond [(match_test "TARGET_MFCRF")
10949                 (const_string "mfcrf")
10950            ]
10951         (const_string "mfcr")))
10952    (set_attr "length" "8")])
10953
10954 (define_insn ""
10955   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
10956         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
10957                                        [(match_operand 2 "cc_reg_operand" "y,y")
10958                                         (const_int 0)])
10959                     (const_int 0)))
10960    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
10961         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10962   "TARGET_32BIT"
10963   "@
10964    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
10965    #"
10966   [(set_attr "type" "shift")
10967    (set_attr "dot" "yes")
10968    (set_attr "length" "8,16")])
10969
10970 (define_split
10971   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
10972         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
10973                                        [(match_operand 2 "cc_reg_operand" "")
10974                                         (const_int 0)])
10975                     (const_int 0)))
10976    (set (match_operand:SI 3 "gpc_reg_operand" "")
10977         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10978   "TARGET_32BIT && reload_completed"
10979   [(set (match_dup 3)
10980         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
10981    (set (match_dup 0)
10982         (compare:CC (match_dup 3)
10983                     (const_int 0)))]
10984   "")
10985
10986 (define_insn ""
10987   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10988         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
10989                                       [(match_operand 2 "cc_reg_operand" "y")
10990                                        (const_int 0)])
10991                    (match_operand:SI 3 "const_int_operand" "n")))]
10992   ""
10993   "*
10994 {
10995   int is_bit = ccr_bit (operands[1], 1);
10996   int put_bit = 31 - (INTVAL (operands[3]) & 31);
10997   int count;
10998
10999   if (is_bit >= put_bit)
11000     count = is_bit - put_bit;
11001   else
11002     count = 32 - (put_bit - is_bit);
11003
11004   operands[4] = GEN_INT (count);
11005   operands[5] = GEN_INT (put_bit);
11006
11007   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11008 }"
11009   [(set (attr "type")
11010      (cond [(match_test "TARGET_MFCRF")
11011                 (const_string "mfcrf")
11012            ]
11013         (const_string "mfcr")))
11014    (set_attr "length" "8")])
11015
11016 (define_insn ""
11017   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11018         (compare:CC
11019          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11020                                        [(match_operand 2 "cc_reg_operand" "y,y")
11021                                         (const_int 0)])
11022                     (match_operand:SI 3 "const_int_operand" "n,n"))
11023          (const_int 0)))
11024    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11025         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11026                    (match_dup 3)))]
11027   ""
11028   "*
11029 {
11030   int is_bit = ccr_bit (operands[1], 1);
11031   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11032   int count;
11033
11034   /* Force split for non-cc0 compare.  */
11035   if (which_alternative == 1)
11036      return \"#\";
11037
11038   if (is_bit >= put_bit)
11039     count = is_bit - put_bit;
11040   else
11041     count = 32 - (put_bit - is_bit);
11042
11043   operands[5] = GEN_INT (count);
11044   operands[6] = GEN_INT (put_bit);
11045
11046   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11047 }"
11048   [(set_attr "type" "shift")
11049    (set_attr "dot" "yes")
11050    (set_attr "length" "8,16")])
11051
11052 (define_split
11053   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11054         (compare:CC
11055          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11056                                        [(match_operand 2 "cc_reg_operand" "")
11057                                         (const_int 0)])
11058                     (match_operand:SI 3 "const_int_operand" ""))
11059          (const_int 0)))
11060    (set (match_operand:SI 4 "gpc_reg_operand" "")
11061         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11062                    (match_dup 3)))]
11063   "reload_completed"
11064   [(set (match_dup 4)
11065         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11066                    (match_dup 3)))
11067    (set (match_dup 0)
11068         (compare:CC (match_dup 4)
11069                     (const_int 0)))]
11070   "")
11071
11072 ;; There is a 3 cycle delay between consecutive mfcr instructions
11073 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
11074
11075 (define_peephole
11076   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11077         (match_operator:SI 1 "scc_comparison_operator"
11078                            [(match_operand 2 "cc_reg_operand" "y")
11079                             (const_int 0)]))
11080    (set (match_operand:SI 3 "gpc_reg_operand" "=r")
11081         (match_operator:SI 4 "scc_comparison_operator"
11082                            [(match_operand 5 "cc_reg_operand" "y")
11083                             (const_int 0)]))]
11084   "REGNO (operands[2]) != REGNO (operands[5])"
11085   "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11086   [(set_attr "type" "mfcr")
11087    (set_attr "length" "12")])
11088
11089 (define_peephole
11090   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11091         (match_operator:DI 1 "scc_comparison_operator"
11092                            [(match_operand 2 "cc_reg_operand" "y")
11093                             (const_int 0)]))
11094    (set (match_operand:DI 3 "gpc_reg_operand" "=r")
11095         (match_operator:DI 4 "scc_comparison_operator"
11096                            [(match_operand 5 "cc_reg_operand" "y")
11097                             (const_int 0)]))]
11098   "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
11099   "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11100   [(set_attr "type" "mfcr")
11101    (set_attr "length" "12")])
11102
11103
11104 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11105                               (DI "rKJI")])
11106
11107 (define_insn_and_split "eq<mode>3"
11108   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11109         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11110                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11111    (clobber (match_scratch:GPR 3 "=r"))
11112    (clobber (match_scratch:GPR 4 "=r"))]
11113   ""
11114   "#"
11115   ""
11116   [(set (match_dup 4)
11117         (clz:GPR (match_dup 3)))
11118    (set (match_dup 0)
11119         (lshiftrt:GPR (match_dup 4)
11120                       (match_dup 5)))]
11121 {
11122   operands[3] = rs6000_emit_eqne (<MODE>mode,
11123                                   operands[1], operands[2], operands[3]);
11124
11125   if (GET_CODE (operands[4]) == SCRATCH)
11126     operands[4] = gen_reg_rtx (<MODE>mode);
11127
11128   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11129 }
11130   [(set (attr "length")
11131         (if_then_else (match_test "operands[2] == const0_rtx")
11132                       (const_string "8")
11133                       (const_string "12")))])
11134
11135 (define_insn_and_split "ne<mode>3"
11136   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11137         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11138               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11139    (clobber (match_scratch:P 3 "=r"))
11140    (clobber (match_scratch:P 4 "=r"))
11141    (clobber (reg:P CA_REGNO))]
11142   "!TARGET_ISEL"
11143   "#"
11144   ""
11145   [(parallel [(set (match_dup 4)
11146                    (plus:P (match_dup 3)
11147                            (const_int -1)))
11148               (set (reg:P CA_REGNO)
11149                    (ne:P (match_dup 3)
11150                          (const_int 0)))])
11151    (parallel [(set (match_dup 0)
11152                    (plus:P (plus:P (not:P (match_dup 4))
11153                                    (reg:P CA_REGNO))
11154                            (match_dup 3)))
11155               (clobber (reg:P CA_REGNO))])]
11156 {
11157   operands[3] = rs6000_emit_eqne (<MODE>mode,
11158                                   operands[1], operands[2], operands[3]);
11159
11160   if (GET_CODE (operands[4]) == SCRATCH)
11161     operands[4] = gen_reg_rtx (<MODE>mode);
11162 }
11163   [(set (attr "length")
11164         (if_then_else (match_test "operands[2] == const0_rtx")
11165                       (const_string "8")
11166                       (const_string "12")))])
11167
11168 (define_insn_and_split "*neg_eq_<mode>"
11169   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11170         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11171                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11172    (clobber (match_scratch:P 3 "=r"))
11173    (clobber (match_scratch:P 4 "=r"))
11174    (clobber (reg:P CA_REGNO))]
11175   ""
11176   "#"
11177   ""
11178   [(parallel [(set (match_dup 4)
11179                    (plus:P (match_dup 3)
11180                            (const_int -1)))
11181               (set (reg:P CA_REGNO)
11182                    (ne:P (match_dup 3)
11183                          (const_int 0)))])
11184    (parallel [(set (match_dup 0)
11185                    (plus:P (reg:P CA_REGNO)
11186                            (const_int -1)))
11187               (clobber (reg:P CA_REGNO))])]
11188 {
11189   operands[3] = rs6000_emit_eqne (<MODE>mode,
11190                                   operands[1], operands[2], operands[3]);
11191
11192   if (GET_CODE (operands[4]) == SCRATCH)
11193     operands[4] = gen_reg_rtx (<MODE>mode);
11194 }
11195   [(set (attr "length")
11196         (if_then_else (match_test "operands[2] == const0_rtx")
11197                       (const_string "8")
11198                       (const_string "12")))])
11199
11200 (define_insn_and_split "*neg_ne_<mode>"
11201   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11202         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11203                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11204    (clobber (match_scratch:P 3 "=r"))
11205    (clobber (match_scratch:P 4 "=r"))
11206    (clobber (reg:P CA_REGNO))]
11207   ""
11208   "#"
11209   ""
11210   [(parallel [(set (match_dup 4)
11211                    (neg:P (match_dup 3)))
11212               (set (reg:P CA_REGNO)
11213                    (eq:P (match_dup 3)
11214                          (const_int 0)))])
11215    (parallel [(set (match_dup 0)
11216                    (plus:P (reg:P CA_REGNO)
11217                            (const_int -1)))
11218               (clobber (reg:P CA_REGNO))])]
11219 {
11220   operands[3] = rs6000_emit_eqne (<MODE>mode,
11221                                   operands[1], operands[2], operands[3]);
11222
11223   if (GET_CODE (operands[4]) == SCRATCH)
11224     operands[4] = gen_reg_rtx (<MODE>mode);
11225 }
11226   [(set (attr "length")
11227         (if_then_else (match_test "operands[2] == const0_rtx")
11228                       (const_string "8")
11229                       (const_string "12")))])
11230
11231 (define_insn_and_split "*plus_eq_<mode>"
11232   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11233         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11234                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11235                 (match_operand:P 3 "gpc_reg_operand" "r")))
11236    (clobber (match_scratch:P 4 "=r"))
11237    (clobber (match_scratch:P 5 "=r"))
11238    (clobber (reg:P CA_REGNO))]
11239   ""
11240   "#"
11241   ""
11242   [(parallel [(set (match_dup 5)
11243                    (neg:P (match_dup 4)))
11244               (set (reg:P CA_REGNO)
11245                    (eq:P (match_dup 4)
11246                          (const_int 0)))])
11247    (parallel [(set (match_dup 0)
11248                    (plus:P (match_dup 3)
11249                            (reg:P CA_REGNO)))
11250               (clobber (reg:P CA_REGNO))])]
11251 {
11252   operands[4] = rs6000_emit_eqne (<MODE>mode,
11253                                   operands[1], operands[2], operands[4]);
11254
11255   if (GET_CODE (operands[5]) == SCRATCH)
11256     operands[5] = gen_reg_rtx (<MODE>mode);
11257 }
11258   [(set (attr "length")
11259         (if_then_else (match_test "operands[2] == const0_rtx")
11260                       (const_string "8")
11261                       (const_string "12")))])
11262
11263 (define_insn_and_split "*plus_ne_<mode>"
11264   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11265         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11266                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11267                 (match_operand:P 3 "gpc_reg_operand" "r")))
11268    (clobber (match_scratch:P 4 "=r"))
11269    (clobber (match_scratch:P 5 "=r"))
11270    (clobber (reg:P CA_REGNO))]
11271   ""
11272   "#"
11273   ""
11274   [(parallel [(set (match_dup 5)
11275                    (plus:P (match_dup 4)
11276                            (const_int -1)))
11277               (set (reg:P CA_REGNO)
11278                    (ne:P (match_dup 4)
11279                          (const_int 0)))])
11280    (parallel [(set (match_dup 0)
11281                    (plus:P (match_dup 3)
11282                            (reg:P CA_REGNO)))
11283               (clobber (reg:P CA_REGNO))])]
11284 {
11285   operands[4] = rs6000_emit_eqne (<MODE>mode,
11286                                   operands[1], operands[2], operands[4]);
11287
11288   if (GET_CODE (operands[5]) == SCRATCH)
11289     operands[5] = gen_reg_rtx (<MODE>mode);
11290 }
11291   [(set (attr "length")
11292         (if_then_else (match_test "operands[2] == const0_rtx")
11293                       (const_string "8")
11294                       (const_string "12")))])
11295
11296 (define_insn_and_split "*minus_eq_<mode>"
11297   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11298         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11299                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11300                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11301    (clobber (match_scratch:P 4 "=r"))
11302    (clobber (match_scratch:P 5 "=r"))
11303    (clobber (reg:P CA_REGNO))]
11304   ""
11305   "#"
11306   ""
11307   [(parallel [(set (match_dup 5)
11308                    (plus:P (match_dup 4)
11309                            (const_int -1)))
11310               (set (reg:P CA_REGNO)
11311                    (ne:P (match_dup 4)
11312                          (const_int 0)))])
11313    (parallel [(set (match_dup 0)
11314                    (plus:P (plus:P (match_dup 3)
11315                                    (reg:P CA_REGNO))
11316                            (const_int -1)))
11317               (clobber (reg:P CA_REGNO))])]
11318 {
11319   operands[4] = rs6000_emit_eqne (<MODE>mode,
11320                                   operands[1], operands[2], operands[4]);
11321
11322   if (GET_CODE (operands[5]) == SCRATCH)
11323     operands[5] = gen_reg_rtx (<MODE>mode);
11324 }
11325   [(set (attr "length")
11326         (if_then_else (match_test "operands[2] == const0_rtx")
11327                       (const_string "8")
11328                       (const_string "12")))])
11329
11330 (define_insn_and_split "*minus_ne_<mode>"
11331   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11332         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11333                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11334                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11335    (clobber (match_scratch:P 4 "=r"))
11336    (clobber (match_scratch:P 5 "=r"))
11337    (clobber (reg:P CA_REGNO))]
11338   ""
11339   "#"
11340   ""
11341   [(parallel [(set (match_dup 5)
11342                    (neg:P (match_dup 4)))
11343               (set (reg:P CA_REGNO)
11344                    (eq:P (match_dup 4)
11345                          (const_int 0)))])
11346    (parallel [(set (match_dup 0)
11347                    (plus:P (plus:P (match_dup 3)
11348                                    (reg:P CA_REGNO))
11349                            (const_int -1)))
11350               (clobber (reg:P CA_REGNO))])]
11351 {
11352   operands[4] = rs6000_emit_eqne (<MODE>mode,
11353                                   operands[1], operands[2], operands[4]);
11354
11355   if (GET_CODE (operands[5]) == SCRATCH)
11356     operands[5] = gen_reg_rtx (<MODE>mode);
11357 }
11358   [(set (attr "length")
11359         (if_then_else (match_test "operands[2] == const0_rtx")
11360                       (const_string "8")
11361                       (const_string "12")))])
11362
11363 (define_insn_and_split "*eqsi3_ext<mode>"
11364   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11365         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11366                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11367    (clobber (match_scratch:SI 3 "=r"))
11368    (clobber (match_scratch:SI 4 "=r"))]
11369   ""
11370   "#"
11371   ""
11372   [(set (match_dup 4)
11373         (clz:SI (match_dup 3)))
11374    (set (match_dup 0)
11375         (zero_extend:EXTSI
11376           (lshiftrt:SI (match_dup 4)
11377                        (const_int 5))))]
11378 {
11379   operands[3] = rs6000_emit_eqne (SImode,
11380                                   operands[1], operands[2], operands[3]);
11381
11382   if (GET_CODE (operands[4]) == SCRATCH)
11383     operands[4] = gen_reg_rtx (SImode);
11384 }
11385   [(set (attr "length")
11386         (if_then_else (match_test "operands[2] == const0_rtx")
11387                       (const_string "8")
11388                       (const_string "12")))])
11389
11390 (define_insn_and_split "*nesi3_ext<mode>"
11391   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11392         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11393                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11394    (clobber (match_scratch:SI 3 "=r"))
11395    (clobber (match_scratch:SI 4 "=r"))
11396    (clobber (match_scratch:EXTSI 5 "=r"))]
11397   ""
11398   "#"
11399   ""
11400   [(set (match_dup 4)
11401         (clz:SI (match_dup 3)))
11402    (set (match_dup 5)
11403         (zero_extend:EXTSI
11404           (lshiftrt:SI (match_dup 4)
11405                        (const_int 5))))
11406    (set (match_dup 0)
11407         (xor:EXTSI (match_dup 5)
11408                    (const_int 1)))]
11409 {
11410   operands[3] = rs6000_emit_eqne (SImode,
11411                                   operands[1], operands[2], operands[3]);
11412
11413   if (GET_CODE (operands[4]) == SCRATCH)
11414     operands[4] = gen_reg_rtx (SImode);
11415   if (GET_CODE (operands[5]) == SCRATCH)
11416     operands[5] = gen_reg_rtx (<MODE>mode);
11417 }
11418   [(set (attr "length")
11419         (if_then_else (match_test "operands[2] == const0_rtx")
11420                       (const_string "12")
11421                       (const_string "16")))])
11422 \f
11423 ;; Define both directions of branch and return.  If we need a reload
11424 ;; register, we'd rather use CR0 since it is much easier to copy a
11425 ;; register CC value to there.
11426
11427 (define_insn ""
11428   [(set (pc)
11429         (if_then_else (match_operator 1 "branch_comparison_operator"
11430                                       [(match_operand 2
11431                                                       "cc_reg_operand" "y")
11432                                        (const_int 0)])
11433                       (label_ref (match_operand 0 "" ""))
11434                       (pc)))]
11435   ""
11436   "*
11437 {
11438   return output_cbranch (operands[1], \"%l0\", 0, insn);
11439 }"
11440   [(set_attr "type" "branch")])
11441
11442 (define_insn ""
11443   [(set (pc)
11444         (if_then_else (match_operator 0 "branch_comparison_operator"
11445                                       [(match_operand 1
11446                                                       "cc_reg_operand" "y")
11447                                        (const_int 0)])
11448                       (any_return)
11449                       (pc)))]
11450   "<return_pred>"
11451   "*
11452 {
11453   return output_cbranch (operands[0], NULL, 0, insn);
11454 }"
11455   [(set_attr "type" "jmpreg")
11456    (set_attr "length" "4")])
11457
11458 (define_insn ""
11459   [(set (pc)
11460         (if_then_else (match_operator 1 "branch_comparison_operator"
11461                                       [(match_operand 2
11462                                                       "cc_reg_operand" "y")
11463                                        (const_int 0)])
11464                       (pc)
11465                       (label_ref (match_operand 0 "" ""))))]
11466   ""
11467   "*
11468 {
11469   return output_cbranch (operands[1], \"%l0\", 1, insn);
11470 }"
11471   [(set_attr "type" "branch")])
11472
11473 (define_insn ""
11474   [(set (pc)
11475         (if_then_else (match_operator 0 "branch_comparison_operator"
11476                                       [(match_operand 1
11477                                                       "cc_reg_operand" "y")
11478                                        (const_int 0)])
11479                       (pc)
11480                       (any_return)))]
11481   "<return_pred>"
11482   "*
11483 {
11484   return output_cbranch (operands[0], NULL, 1, insn);
11485 }"
11486   [(set_attr "type" "jmpreg")
11487    (set_attr "length" "4")])
11488
11489 ;; Logic on condition register values.
11490
11491 ; This pattern matches things like
11492 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11493 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
11494 ;                                  (const_int 1)))
11495 ; which are generated by the branch logic.
11496 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11497
11498 (define_insn "*cceq_ior_compare"
11499   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11500         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11501                         [(match_operator:SI 2
11502                                       "branch_positive_comparison_operator"
11503                                       [(match_operand 3
11504                                                       "cc_reg_operand" "y,y")
11505                                        (const_int 0)])
11506                          (match_operator:SI 4
11507                                       "branch_positive_comparison_operator"
11508                                       [(match_operand 5
11509                                                       "cc_reg_operand" "0,y")
11510                                        (const_int 0)])])
11511                       (const_int 1)))]
11512   ""
11513   "cr%q1 %E0,%j2,%j4"
11514   [(set_attr "type" "cr_logical,delayed_cr")])
11515
11516 ; Why is the constant -1 here, but 1 in the previous pattern?
11517 ; Because ~1 has all but the low bit set.
11518 (define_insn ""
11519   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11520         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11521                         [(not:SI (match_operator:SI 2
11522                                       "branch_positive_comparison_operator"
11523                                       [(match_operand 3
11524                                                       "cc_reg_operand" "y,y")
11525                                        (const_int 0)]))
11526                          (match_operator:SI 4
11527                                 "branch_positive_comparison_operator"
11528                                 [(match_operand 5
11529                                                 "cc_reg_operand" "0,y")
11530                                  (const_int 0)])])
11531                       (const_int -1)))]
11532   ""
11533   "cr%q1 %E0,%j2,%j4"
11534   [(set_attr "type" "cr_logical,delayed_cr")])
11535
11536 (define_insn "*cceq_rev_compare"
11537   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11538         (compare:CCEQ (match_operator:SI 1
11539                                       "branch_positive_comparison_operator"
11540                                       [(match_operand 2
11541                                                       "cc_reg_operand" "0,y")
11542                                        (const_int 0)])
11543                       (const_int 0)))]
11544   ""
11545   "crnot %E0,%j1"
11546   [(set_attr "type" "cr_logical,delayed_cr")])
11547
11548 ;; If we are comparing the result of two comparisons, this can be done
11549 ;; using creqv or crxor.
11550
11551 (define_insn_and_split ""
11552   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
11553         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
11554                               [(match_operand 2 "cc_reg_operand" "y")
11555                                (const_int 0)])
11556                       (match_operator 3 "branch_comparison_operator"
11557                               [(match_operand 4 "cc_reg_operand" "y")
11558                                (const_int 0)])))]
11559   ""
11560   "#"
11561   ""
11562   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
11563                                     (match_dup 5)))]
11564   "
11565 {
11566   int positive_1, positive_2;
11567
11568   positive_1 = branch_positive_comparison_operator (operands[1],
11569                                                     GET_MODE (operands[1]));
11570   positive_2 = branch_positive_comparison_operator (operands[3],
11571                                                     GET_MODE (operands[3]));
11572
11573   if (! positive_1)
11574     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
11575                                                             GET_CODE (operands[1])),
11576                                   SImode,
11577                                   operands[2], const0_rtx);
11578   else if (GET_MODE (operands[1]) != SImode)
11579     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
11580                                   operands[2], const0_rtx);
11581
11582   if (! positive_2)
11583     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
11584                                                             GET_CODE (operands[3])),
11585                                   SImode,
11586                                   operands[4], const0_rtx);
11587   else if (GET_MODE (operands[3]) != SImode)
11588     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
11589                                   operands[4], const0_rtx);
11590
11591   if (positive_1 == positive_2)
11592     {
11593       operands[1] = gen_rtx_NOT (SImode, operands[1]);
11594       operands[5] = constm1_rtx;
11595     }
11596   else
11597     {
11598       operands[5] = const1_rtx;
11599     }
11600 }")
11601
11602 ;; Unconditional branch and return.
11603
11604 (define_insn "jump"
11605   [(set (pc)
11606         (label_ref (match_operand 0 "" "")))]
11607   ""
11608   "b %l0"
11609   [(set_attr "type" "branch")])
11610
11611 (define_insn "<return_str>return"
11612   [(any_return)]
11613   "<return_pred>"
11614   "blr"
11615   [(set_attr "type" "jmpreg")])
11616
11617 (define_expand "indirect_jump"
11618   [(set (pc) (match_operand 0 "register_operand" ""))])
11619
11620 (define_insn "*indirect_jump<mode>"
11621   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
11622   ""
11623   "@
11624    bctr
11625    blr"
11626   [(set_attr "type" "jmpreg")])
11627
11628 ;; Table jump for switch statements:
11629 (define_expand "tablejump"
11630   [(use (match_operand 0 "" ""))
11631    (use (label_ref (match_operand 1 "" "")))]
11632   ""
11633   "
11634 {
11635   if (TARGET_32BIT)
11636     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
11637   else
11638     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
11639   DONE;
11640 }")
11641
11642 (define_expand "tablejumpsi"
11643   [(set (match_dup 3)
11644         (plus:SI (match_operand:SI 0 "" "")
11645                  (match_dup 2)))
11646    (parallel [(set (pc) (match_dup 3))
11647               (use (label_ref (match_operand 1 "" "")))])]
11648   "TARGET_32BIT"
11649   "
11650 { operands[0] = force_reg (SImode, operands[0]);
11651   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
11652   operands[3] = gen_reg_rtx (SImode);
11653 }")
11654
11655 (define_expand "tablejumpdi"
11656   [(set (match_dup 4)
11657         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
11658    (set (match_dup 3)
11659         (plus:DI (match_dup 4)
11660                  (match_dup 2)))
11661    (parallel [(set (pc) (match_dup 3))
11662               (use (label_ref (match_operand 1 "" "")))])]
11663   "TARGET_64BIT"
11664   "
11665 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
11666   operands[3] = gen_reg_rtx (DImode);
11667   operands[4] = gen_reg_rtx (DImode);
11668 }")
11669
11670 (define_insn "*tablejump<mode>_internal1"
11671   [(set (pc)
11672         (match_operand:P 0 "register_operand" "c,*l"))
11673    (use (label_ref (match_operand 1 "" "")))]
11674   ""
11675   "@
11676    bctr
11677    blr"
11678   [(set_attr "type" "jmpreg")])
11679
11680 (define_insn "nop"
11681   [(unspec [(const_int 0)] UNSPEC_NOP)]
11682   ""
11683   "nop")
11684
11685 (define_insn "group_ending_nop"
11686   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
11687   ""
11688   "*
11689 {
11690   if (rs6000_cpu_attr == CPU_POWER6)
11691     return \"ori 1,1,0\";
11692   return \"ori 2,2,0\";
11693 }")
11694 \f
11695 ;; Define the subtract-one-and-jump insns, starting with the template
11696 ;; so loop.c knows what to generate.
11697
11698 (define_expand "doloop_end"
11699   [(use (match_operand 0 "" ""))        ; loop pseudo
11700    (use (match_operand 1 "" ""))]       ; label
11701   ""
11702   "
11703 {
11704   if (TARGET_64BIT)
11705     {
11706       if (GET_MODE (operands[0]) != DImode)
11707         FAIL;
11708       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
11709     }
11710   else
11711     {
11712       if (GET_MODE (operands[0]) != SImode)
11713         FAIL;
11714       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
11715     }
11716   DONE;
11717 }")
11718
11719 (define_expand "ctr<mode>"
11720   [(parallel [(set (pc)
11721                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
11722                                      (const_int 1))
11723                                  (label_ref (match_operand 1 "" ""))
11724                                  (pc)))
11725               (set (match_dup 0)
11726                    (plus:P (match_dup 0)
11727                             (const_int -1)))
11728               (clobber (match_scratch:CC 2 ""))
11729               (clobber (match_scratch:P 3 ""))])]
11730   ""
11731   "")
11732
11733 ;; We need to be able to do this for any operand, including MEM, or we
11734 ;; will cause reload to blow up since we don't allow output reloads on
11735 ;; JUMP_INSNs.
11736 ;; For the length attribute to be calculated correctly, the
11737 ;; label MUST be operand 0.
11738
11739 (define_insn "*ctr<mode>_internal1"
11740   [(set (pc)
11741         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11742                           (const_int 1))
11743                       (label_ref (match_operand 0 "" ""))
11744                       (pc)))
11745    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11746         (plus:P (match_dup 1)
11747                  (const_int -1)))
11748    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11749    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11750   ""
11751   "*
11752 {
11753   if (which_alternative != 0)
11754     return \"#\";
11755   else if (get_attr_length (insn) == 4)
11756     return \"bdnz %l0\";
11757   else
11758     return \"bdz $+8\;b %l0\";
11759 }"
11760   [(set_attr "type" "branch")
11761    (set_attr "length" "*,16,20,20")])
11762
11763 (define_insn "*ctr<mode>_internal2"
11764   [(set (pc)
11765         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11766                           (const_int 1))
11767                       (pc)
11768                       (label_ref (match_operand 0 "" ""))))
11769    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11770         (plus:P (match_dup 1)
11771                  (const_int -1)))
11772    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11773    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11774   ""
11775   "*
11776 {
11777   if (which_alternative != 0)
11778     return \"#\";
11779   else if (get_attr_length (insn) == 4)
11780     return \"bdz %l0\";
11781   else
11782     return \"bdnz $+8\;b %l0\";
11783 }"
11784   [(set_attr "type" "branch")
11785    (set_attr "length" "*,16,20,20")])
11786
11787 ;; Similar but use EQ
11788
11789 (define_insn "*ctr<mode>_internal5"
11790   [(set (pc)
11791         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11792                           (const_int 1))
11793                       (label_ref (match_operand 0 "" ""))
11794                       (pc)))
11795    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11796         (plus:P (match_dup 1)
11797                  (const_int -1)))
11798    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11799    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11800   ""
11801   "*
11802 {
11803   if (which_alternative != 0)
11804     return \"#\";
11805   else if (get_attr_length (insn) == 4)
11806     return \"bdz %l0\";
11807   else
11808     return \"bdnz $+8\;b %l0\";
11809 }"
11810   [(set_attr "type" "branch")
11811    (set_attr "length" "*,16,20,20")])
11812
11813 (define_insn "*ctr<mode>_internal6"
11814   [(set (pc)
11815         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11816                           (const_int 1))
11817                       (pc)
11818                       (label_ref (match_operand 0 "" ""))))
11819    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11820         (plus:P (match_dup 1)
11821                  (const_int -1)))
11822    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11823    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11824   ""
11825   "*
11826 {
11827   if (which_alternative != 0)
11828     return \"#\";
11829   else if (get_attr_length (insn) == 4)
11830     return \"bdnz %l0\";
11831   else
11832     return \"bdz $+8\;b %l0\";
11833 }"
11834   [(set_attr "type" "branch")
11835    (set_attr "length" "*,16,20,20")])
11836
11837 ;; Now the splitters if we could not allocate the CTR register
11838
11839 (define_split
11840   [(set (pc)
11841         (if_then_else (match_operator 2 "comparison_operator"
11842                                       [(match_operand:P 1 "gpc_reg_operand" "")
11843                                        (const_int 1)])
11844                       (match_operand 5 "" "")
11845                       (match_operand 6 "" "")))
11846    (set (match_operand:P 0 "gpc_reg_operand" "")
11847         (plus:P (match_dup 1) (const_int -1)))
11848    (clobber (match_scratch:CC 3 ""))
11849    (clobber (match_scratch:P 4 ""))]
11850   "reload_completed"
11851   [(set (match_dup 3)
11852         (compare:CC (match_dup 1)
11853                     (const_int 1)))
11854    (set (match_dup 0)
11855         (plus:P (match_dup 1)
11856                 (const_int -1)))
11857    (set (pc) (if_then_else (match_dup 7)
11858                            (match_dup 5)
11859                            (match_dup 6)))]
11860   "
11861 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
11862                                 operands[3], const0_rtx); }")
11863
11864 (define_split
11865   [(set (pc)
11866         (if_then_else (match_operator 2 "comparison_operator"
11867                                       [(match_operand:P 1 "gpc_reg_operand" "")
11868                                        (const_int 1)])
11869                       (match_operand 5 "" "")
11870                       (match_operand 6 "" "")))
11871    (set (match_operand:P 0 "nonimmediate_operand" "")
11872         (plus:P (match_dup 1) (const_int -1)))
11873    (clobber (match_scratch:CC 3 ""))
11874    (clobber (match_scratch:P 4 ""))]
11875   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
11876   [(set (match_dup 3)
11877         (compare:CC (match_dup 1)
11878                     (const_int 1)))
11879    (set (match_dup 4)
11880         (plus:P (match_dup 1)
11881                 (const_int -1)))
11882    (set (match_dup 0)
11883         (match_dup 4))
11884    (set (pc) (if_then_else (match_dup 7)
11885                            (match_dup 5)
11886                            (match_dup 6)))]
11887   "
11888 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
11889                                 operands[3], const0_rtx); }")
11890 \f
11891 (define_insn "trap"
11892   [(trap_if (const_int 1) (const_int 0))]
11893   ""
11894   "trap"
11895   [(set_attr "type" "trap")])
11896
11897 (define_expand "ctrap<mode>4"
11898   [(trap_if (match_operator 0 "ordered_comparison_operator"
11899                             [(match_operand:GPR 1 "register_operand")
11900                              (match_operand:GPR 2 "reg_or_short_operand")])
11901             (match_operand 3 "zero_constant" ""))]
11902   ""
11903   "")
11904
11905 (define_insn ""
11906   [(trap_if (match_operator 0 "ordered_comparison_operator"
11907                             [(match_operand:GPR 1 "register_operand" "r")
11908                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
11909             (const_int 0))]
11910   ""
11911   "t<wd>%V0%I2 %1,%2"
11912   [(set_attr "type" "trap")])
11913 \f
11914 ;; Insns related to generating the function prologue and epilogue.
11915
11916 (define_expand "prologue"
11917   [(use (const_int 0))]
11918   ""
11919 {
11920   rs6000_emit_prologue ();
11921   if (!TARGET_SCHED_PROLOG)
11922     emit_insn (gen_blockage ());
11923   DONE;
11924 })
11925
11926 (define_insn "*movesi_from_cr_one"
11927   [(match_parallel 0 "mfcr_operation"
11928                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
11929                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
11930                                      (match_operand 3 "immediate_operand" "n")]
11931                           UNSPEC_MOVESI_FROM_CR))])]
11932   "TARGET_MFCRF"
11933   "*
11934 {
11935   int mask = 0;
11936   int i;
11937   for (i = 0; i < XVECLEN (operands[0], 0); i++)
11938   {
11939     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
11940     operands[4] = GEN_INT (mask);
11941     output_asm_insn (\"mfcr %1,%4\", operands);
11942   }
11943   return \"\";
11944 }"
11945   [(set_attr "type" "mfcrf")])
11946
11947 (define_insn "movesi_from_cr"
11948   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11949         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
11950                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
11951                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
11952                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
11953                    UNSPEC_MOVESI_FROM_CR))]
11954   ""
11955   "mfcr %0"
11956   [(set_attr "type" "mfcr")])
11957
11958 (define_insn "*crsave"
11959   [(match_parallel 0 "crsave_operation"
11960                    [(set (match_operand:SI 1 "memory_operand" "=m")
11961                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
11962   ""
11963   "stw %2,%1"
11964   [(set_attr "type" "store")])
11965
11966 (define_insn "*stmw"
11967   [(match_parallel 0 "stmw_operation"
11968                    [(set (match_operand:SI 1 "memory_operand" "=m")
11969                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
11970   "TARGET_MULTIPLE"
11971   "stmw %2,%1"
11972   [(set_attr "type" "store")
11973    (set_attr "update" "yes")
11974    (set_attr "indexed" "yes")])
11975
11976 ; The following comment applies to:
11977 ;     save_gpregs_*
11978 ;     save_fpregs_*
11979 ;     restore_gpregs*
11980 ;     return_and_restore_gpregs*
11981 ;     return_and_restore_fpregs*
11982 ;     return_and_restore_fpregs_aix*
11983 ;
11984 ; The out-of-line save / restore functions expects one input argument.
11985 ; Since those are not standard call_insn's, we must avoid using
11986 ; MATCH_OPERAND for that argument. That way the register rename
11987 ; optimization will not try to rename this register.
11988 ; Each pattern is repeated for each possible register number used in 
11989 ; various ABIs (r11, r1, and for some functions r12)
11990
11991 (define_insn "*save_gpregs_<mode>_r11"
11992   [(match_parallel 0 "any_parallel_operand"
11993                    [(clobber (reg:P 65))
11994                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
11995                     (use (reg:P 11))
11996                     (set (match_operand:P 2 "memory_operand" "=m")
11997                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
11998   ""
11999   "bl %1"
12000   [(set_attr "type" "branch")
12001    (set_attr "length" "4")])
12002
12003 (define_insn "*save_gpregs_<mode>_r12"
12004   [(match_parallel 0 "any_parallel_operand"
12005                    [(clobber (reg:P 65))
12006                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12007                     (use (reg:P 12))
12008                     (set (match_operand:P 2 "memory_operand" "=m")
12009                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12010   ""
12011   "bl %1"
12012   [(set_attr "type" "branch")
12013    (set_attr "length" "4")])
12014
12015 (define_insn "*save_gpregs_<mode>_r1"
12016   [(match_parallel 0 "any_parallel_operand"
12017                    [(clobber (reg:P 65))
12018                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12019                     (use (reg:P 1))
12020                     (set (match_operand:P 2 "memory_operand" "=m")
12021                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12022   ""
12023   "bl %1"
12024   [(set_attr "type" "branch")
12025    (set_attr "length" "4")])
12026
12027 (define_insn "*save_fpregs_<mode>_r11"
12028   [(match_parallel 0 "any_parallel_operand"
12029                    [(clobber (reg:P 65))
12030                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12031                     (use (reg:P 11))
12032                     (set (match_operand:DF 2 "memory_operand" "=m")
12033                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12034   ""
12035   "bl %1"
12036   [(set_attr "type" "branch")
12037    (set_attr "length" "4")])
12038
12039 (define_insn "*save_fpregs_<mode>_r12"
12040   [(match_parallel 0 "any_parallel_operand"
12041                    [(clobber (reg:P 65))
12042                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12043                     (use (reg:P 12))
12044                     (set (match_operand:DF 2 "memory_operand" "=m")
12045                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12046   ""
12047   "bl %1"
12048   [(set_attr "type" "branch")
12049    (set_attr "length" "4")])
12050
12051 (define_insn "*save_fpregs_<mode>_r1"
12052   [(match_parallel 0 "any_parallel_operand"
12053                    [(clobber (reg:P 65))
12054                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12055                     (use (reg:P 1))
12056                     (set (match_operand:DF 2 "memory_operand" "=m")
12057                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12058   ""
12059   "bl %1"
12060   [(set_attr "type" "branch")
12061    (set_attr "length" "4")])
12062
12063 ; This is to explain that changes to the stack pointer should
12064 ; not be moved over loads from or stores to stack memory.
12065 (define_insn "stack_tie"
12066   [(match_parallel 0 "tie_operand"
12067                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12068   ""
12069   ""
12070   [(set_attr "length" "0")])
12071
12072 (define_expand "epilogue"
12073   [(use (const_int 0))]
12074   ""
12075 {
12076   if (!TARGET_SCHED_PROLOG)
12077     emit_insn (gen_blockage ());
12078   rs6000_emit_epilogue (FALSE);
12079   DONE;
12080 })
12081
12082 ; On some processors, doing the mtcrf one CC register at a time is
12083 ; faster (like on the 604e).  On others, doing them all at once is
12084 ; faster; for instance, on the 601 and 750.
12085
12086 (define_expand "movsi_to_cr_one"
12087   [(set (match_operand:CC 0 "cc_reg_operand" "")
12088         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12089                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12090   ""
12091   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12092
12093 (define_insn "*movsi_to_cr"
12094   [(match_parallel 0 "mtcrf_operation"
12095                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12096                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12097                                      (match_operand 3 "immediate_operand" "n")]
12098                                     UNSPEC_MOVESI_TO_CR))])]
12099  ""
12100  "*
12101 {
12102   int mask = 0;
12103   int i;
12104   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12105     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12106   operands[4] = GEN_INT (mask);
12107   return \"mtcrf %4,%2\";
12108 }"
12109   [(set_attr "type" "mtcr")])
12110
12111 (define_insn "*mtcrfsi"
12112   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12113         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12114                     (match_operand 2 "immediate_operand" "n")]
12115                    UNSPEC_MOVESI_TO_CR))]
12116   "GET_CODE (operands[0]) == REG
12117    && CR_REGNO_P (REGNO (operands[0]))
12118    && GET_CODE (operands[2]) == CONST_INT
12119    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12120   "mtcrf %R0,%1"
12121   [(set_attr "type" "mtcr")])
12122
12123 ; The load-multiple instructions have similar properties.
12124 ; Note that "load_multiple" is a name known to the machine-independent
12125 ; code that actually corresponds to the PowerPC load-string.
12126
12127 (define_insn "*lmw"
12128   [(match_parallel 0 "lmw_operation"
12129                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12130                          (match_operand:SI 2 "memory_operand" "m"))])]
12131   "TARGET_MULTIPLE"
12132   "lmw %1,%2"
12133   [(set_attr "type" "load")
12134    (set_attr "update" "yes")
12135    (set_attr "indexed" "yes")
12136    (set_attr "cell_micro" "always")])
12137
12138 (define_insn "*return_internal_<mode>"
12139   [(simple_return)
12140    (use (match_operand:P 0 "register_operand" "lc"))]
12141   ""
12142   "b%T0"
12143   [(set_attr "type" "jmpreg")])
12144
12145 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12146 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
12147
12148 ; The following comment applies to:
12149 ;     save_gpregs_*
12150 ;     save_fpregs_*
12151 ;     restore_gpregs*
12152 ;     return_and_restore_gpregs*
12153 ;     return_and_restore_fpregs*
12154 ;     return_and_restore_fpregs_aix*
12155 ;
12156 ; The out-of-line save / restore functions expects one input argument.
12157 ; Since those are not standard call_insn's, we must avoid using
12158 ; MATCH_OPERAND for that argument. That way the register rename
12159 ; optimization will not try to rename this register.
12160 ; Each pattern is repeated for each possible register number used in 
12161 ; various ABIs (r11, r1, and for some functions r12)
12162
12163 (define_insn "*restore_gpregs_<mode>_r11"
12164  [(match_parallel 0 "any_parallel_operand"
12165                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12166                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12167                    (use (reg:P 11))
12168                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12169                         (match_operand:P 4 "memory_operand" "m"))])]
12170  ""
12171  "bl %2"
12172  [(set_attr "type" "branch")
12173   (set_attr "length" "4")])
12174
12175 (define_insn "*restore_gpregs_<mode>_r12"
12176  [(match_parallel 0 "any_parallel_operand"
12177                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12178                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12179                    (use (reg:P 12))
12180                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12181                         (match_operand:P 4 "memory_operand" "m"))])]
12182  ""
12183  "bl %2"
12184  [(set_attr "type" "branch")
12185   (set_attr "length" "4")])
12186
12187 (define_insn "*restore_gpregs_<mode>_r1"
12188  [(match_parallel 0 "any_parallel_operand"
12189                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12190                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12191                    (use (reg:P 1))
12192                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12193                         (match_operand:P 4 "memory_operand" "m"))])]
12194  ""
12195  "bl %2"
12196  [(set_attr "type" "branch")
12197   (set_attr "length" "4")])
12198
12199 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12200  [(match_parallel 0 "any_parallel_operand"
12201                   [(return)
12202                    (clobber (match_operand:P 1 "register_operand" "=l"))
12203                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12204                    (use (reg:P 11))
12205                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12206                         (match_operand:P 4 "memory_operand" "m"))])]
12207  ""
12208  "b %2"
12209  [(set_attr "type" "branch")
12210   (set_attr "length" "4")])
12211
12212 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12213  [(match_parallel 0 "any_parallel_operand"
12214                   [(return)
12215                    (clobber (match_operand:P 1 "register_operand" "=l"))
12216                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12217                    (use (reg:P 12))
12218                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12219                         (match_operand:P 4 "memory_operand" "m"))])]
12220  ""
12221  "b %2"
12222  [(set_attr "type" "branch")
12223   (set_attr "length" "4")])
12224
12225 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12226  [(match_parallel 0 "any_parallel_operand"
12227                   [(return)
12228                    (clobber (match_operand:P 1 "register_operand" "=l"))
12229                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12230                    (use (reg:P 1))
12231                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12232                         (match_operand:P 4 "memory_operand" "m"))])]
12233  ""
12234  "b %2"
12235  [(set_attr "type" "branch")
12236   (set_attr "length" "4")])
12237
12238 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12239  [(match_parallel 0 "any_parallel_operand"
12240                   [(return)
12241                    (clobber (match_operand:P 1 "register_operand" "=l"))
12242                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12243                    (use (reg:P 11))
12244                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12245                         (match_operand:DF 4 "memory_operand" "m"))])]
12246  ""
12247  "b %2"
12248  [(set_attr "type" "branch")
12249   (set_attr "length" "4")])
12250
12251 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12252  [(match_parallel 0 "any_parallel_operand"
12253                   [(return)
12254                    (clobber (match_operand:P 1 "register_operand" "=l"))
12255                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12256                    (use (reg:P 12))
12257                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12258                         (match_operand:DF 4 "memory_operand" "m"))])]
12259  ""
12260  "b %2"
12261  [(set_attr "type" "branch")
12262   (set_attr "length" "4")])
12263
12264 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12265  [(match_parallel 0 "any_parallel_operand"
12266                   [(return)
12267                    (clobber (match_operand:P 1 "register_operand" "=l"))
12268                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12269                    (use (reg:P 1))
12270                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12271                         (match_operand:DF 4 "memory_operand" "m"))])]
12272  ""
12273  "b %2"
12274  [(set_attr "type" "branch")
12275   (set_attr "length" "4")])
12276
12277 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12278  [(match_parallel 0 "any_parallel_operand"
12279                   [(return)
12280                    (use (match_operand:P 1 "register_operand" "l"))
12281                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12282                    (use (reg:P 11))
12283                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12284                         (match_operand:DF 4 "memory_operand" "m"))])]
12285  ""
12286  "b %2"
12287  [(set_attr "type" "branch")
12288   (set_attr "length" "4")])
12289
12290 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12291  [(match_parallel 0 "any_parallel_operand"
12292                   [(return)
12293                    (use (match_operand:P 1 "register_operand" "l"))
12294                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12295                    (use (reg:P 1))
12296                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12297                         (match_operand:DF 4 "memory_operand" "m"))])]
12298  ""
12299  "b %2"
12300  [(set_attr "type" "branch")
12301   (set_attr "length" "4")])
12302
12303 ; This is used in compiling the unwind routines.
12304 (define_expand "eh_return"
12305   [(use (match_operand 0 "general_operand" ""))]
12306   ""
12307   "
12308 {
12309   if (TARGET_32BIT)
12310     emit_insn (gen_eh_set_lr_si (operands[0]));
12311   else
12312     emit_insn (gen_eh_set_lr_di (operands[0]));
12313   DONE;
12314 }")
12315
12316 ; We can't expand this before we know where the link register is stored.
12317 (define_insn "eh_set_lr_<mode>"
12318   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12319                     UNSPECV_EH_RR)
12320    (clobber (match_scratch:P 1 "=&b"))]
12321   ""
12322   "#")
12323
12324 (define_split
12325   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12326    (clobber (match_scratch 1 ""))]
12327   "reload_completed"
12328   [(const_int 0)]
12329   "
12330 {
12331   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12332   DONE;
12333 }")
12334
12335 (define_insn "prefetch"
12336   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12337              (match_operand:SI 1 "const_int_operand" "n")
12338              (match_operand:SI 2 "const_int_operand" "n"))]
12339   ""
12340   "*
12341 {
12342   if (GET_CODE (operands[0]) == REG)
12343     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12344   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12345 }"
12346   [(set_attr "type" "load")])
12347 \f
12348 (define_insn "bpermd_<mode>"
12349   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12350         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12351                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12352   "TARGET_POPCNTD"
12353   "bpermd %0,%1,%2"
12354   [(set_attr "type" "popcnt")])
12355
12356 \f
12357 ;; Builtin fma support.  Handle 
12358 ;; Note that the conditions for expansion are in the FMA_F iterator.
12359
12360 (define_expand "fma<mode>4"
12361   [(set (match_operand:FMA_F 0 "register_operand" "")
12362         (fma:FMA_F
12363           (match_operand:FMA_F 1 "register_operand" "")
12364           (match_operand:FMA_F 2 "register_operand" "")
12365           (match_operand:FMA_F 3 "register_operand" "")))]
12366   ""
12367   "")
12368
12369 (define_insn "*fma<mode>4_fpr"
12370   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
12371         (fma:SFDF
12372           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>,<Fv>")
12373           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
12374           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))]
12375   "TARGET_<MODE>_FPR"
12376   "@
12377    fmadd<Ftrad> %0,%1,%2,%3
12378    xsmadda<Fvsx> %x0,%x1,%x2
12379    xsmaddm<Fvsx> %x0,%x1,%x3"
12380   [(set_attr "type" "fp")
12381    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12382
12383 ; Altivec only has fma and nfms.
12384 (define_expand "fms<mode>4"
12385   [(set (match_operand:FMA_F 0 "register_operand" "")
12386         (fma:FMA_F
12387           (match_operand:FMA_F 1 "register_operand" "")
12388           (match_operand:FMA_F 2 "register_operand" "")
12389           (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12390   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12391   "")
12392
12393 (define_insn "*fms<mode>4_fpr"
12394   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
12395         (fma:SFDF
12396          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
12397          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
12398          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
12399   "TARGET_<MODE>_FPR"
12400   "@
12401    fmsub<Ftrad> %0,%1,%2,%3
12402    xsmsuba<Fvsx> %x0,%x1,%x2
12403    xsmsubm<Fvsx> %x0,%x1,%x3"
12404   [(set_attr "type" "fp")
12405    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12406
12407 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12408 (define_expand "fnma<mode>4"
12409   [(set (match_operand:FMA_F 0 "register_operand" "")
12410         (neg:FMA_F
12411           (fma:FMA_F
12412             (match_operand:FMA_F 1 "register_operand" "")
12413             (match_operand:FMA_F 2 "register_operand" "")
12414             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12415   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12416   "")
12417
12418 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12419 (define_expand "fnms<mode>4"
12420   [(set (match_operand:FMA_F 0 "register_operand" "")
12421         (neg:FMA_F
12422           (fma:FMA_F
12423             (match_operand:FMA_F 1 "register_operand" "")
12424             (match_operand:FMA_F 2 "register_operand" "")
12425             (match_operand:FMA_F 3 "register_operand" ""))))]
12426   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12427   "")
12428
12429 ; Not an official optab name, but used from builtins.
12430 (define_expand "nfma<mode>4"
12431   [(set (match_operand:FMA_F 0 "register_operand" "")
12432         (neg:FMA_F
12433           (fma:FMA_F
12434             (match_operand:FMA_F 1 "register_operand" "")
12435             (match_operand:FMA_F 2 "register_operand" "")
12436             (match_operand:FMA_F 3 "register_operand" ""))))]
12437   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12438   "")
12439
12440 (define_insn "*nfma<mode>4_fpr"
12441   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
12442         (neg:SFDF
12443          (fma:SFDF
12444           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
12445           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
12446           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
12447   "TARGET_<MODE>_FPR"
12448   "@
12449    fnmadd<Ftrad> %0,%1,%2,%3
12450    xsnmadda<Fvsx> %x0,%x1,%x2
12451    xsnmaddm<Fvsx> %x0,%x1,%x3"
12452   [(set_attr "type" "fp")
12453    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12454
12455 ; Not an official optab name, but used from builtins.
12456 (define_expand "nfms<mode>4"
12457   [(set (match_operand:FMA_F 0 "register_operand" "")
12458         (neg:FMA_F
12459           (fma:FMA_F
12460             (match_operand:FMA_F 1 "register_operand" "")
12461             (match_operand:FMA_F 2 "register_operand" "")
12462             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12463   ""
12464   "")
12465
12466 (define_insn "*nfmssf4_fpr"
12467   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
12468         (neg:SFDF
12469          (fma:SFDF
12470           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
12471           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
12472           (neg:SFDF
12473            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))))]
12474   "TARGET_<MODE>_FPR"
12475   "@
12476    fnmsub<Ftrad> %0,%1,%2,%3
12477    xsnmsuba<Fvsx> %x0,%x1,%x2
12478    xsnmsubm<Fvsx> %x0,%x1,%x3"
12479   [(set_attr "type" "fp")
12480    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12481
12482 \f
12483 (define_expand "rs6000_get_timebase"
12484   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
12485   ""
12486 {
12487   if (TARGET_POWERPC64)
12488     emit_insn (gen_rs6000_mftb_di (operands[0]));
12489   else
12490     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
12491   DONE;
12492 })
12493
12494 (define_insn "rs6000_get_timebase_ppc32"
12495   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12496         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
12497    (clobber (match_scratch:SI 1 "=r"))
12498    (clobber (match_scratch:CC 2 "=y"))]
12499   "!TARGET_POWERPC64"
12500 {
12501   if (WORDS_BIG_ENDIAN)
12502     if (TARGET_MFCRF)
12503       {
12504         return "mfspr %0,269\;"
12505                "mfspr %L0,268\;"
12506                "mfspr %1,269\;"
12507                "cmpw %2,%0,%1\;"
12508                "bne- %2,$-16";
12509       }
12510     else
12511       {
12512         return "mftbu %0\;"
12513                "mftb %L0\;"
12514                "mftbu %1\;"
12515                "cmpw %2,%0,%1\;"
12516                "bne- %2,$-16";
12517       }
12518   else
12519     if (TARGET_MFCRF)
12520       {
12521         return "mfspr %L0,269\;"
12522                "mfspr %0,268\;"
12523                "mfspr %1,269\;"
12524                "cmpw %2,%L0,%1\;"
12525                "bne- %2,$-16";
12526       }
12527     else
12528       {
12529         return "mftbu %L0\;"
12530                "mftb %0\;"
12531                "mftbu %1\;"
12532                "cmpw %2,%L0,%1\;"
12533                "bne- %2,$-16";
12534       }
12535 }
12536   [(set_attr "length" "20")])
12537
12538 (define_insn "rs6000_mftb_<mode>"
12539   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12540         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
12541   ""
12542 {
12543   if (TARGET_MFCRF)
12544     return "mfspr %0,268";
12545   else
12546     return "mftb %0";
12547 })
12548
12549 \f
12550 (define_insn "rs6000_mffs"
12551   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
12552         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
12553   "TARGET_HARD_FLOAT && TARGET_FPRS"
12554   "mffs %0")
12555
12556 (define_insn "rs6000_mtfsf"
12557   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
12558                      (match_operand:DF 1 "gpc_reg_operand" "d")]
12559                     UNSPECV_MTFSF)]
12560   "TARGET_HARD_FLOAT && TARGET_FPRS"
12561   "mtfsf %0,%1")
12562
12563 \f
12564 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
12565 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
12566 ;; register that is being loaded.  The fused ops must be physically adjacent.
12567
12568 ;; Find cases where the addis that feeds into a load instruction is either used
12569 ;; once or is the same as the target register, and replace it with the fusion
12570 ;; insn
12571
12572 (define_peephole2
12573   [(set (match_operand:P 0 "base_reg_operand" "")
12574         (match_operand:P 1 "fusion_gpr_addis" ""))
12575    (set (match_operand:INT1 2 "base_reg_operand" "")
12576         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
12577   "TARGET_P8_FUSION
12578    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
12579                          operands[3])"
12580   [(const_int 0)]
12581 {
12582   expand_fusion_gpr_load (operands);
12583   DONE;
12584 })
12585
12586 ;; Fusion insn, created by the define_peephole2 above (and eventually by
12587 ;; reload)
12588
12589 (define_insn "fusion_gpr_load_<mode>"
12590   [(set (match_operand:INT1 0 "base_reg_operand" "=&b")
12591         (unspec:INT1 [(match_operand:INT1 1 "fusion_gpr_mem_combo" "")]
12592                      UNSPEC_FUSION_GPR))]
12593   "TARGET_P8_FUSION"
12594 {
12595   return emit_fusion_gpr_load (operands[0], operands[1]);
12596 }
12597   [(set_attr "type" "load")
12598    (set_attr "length" "8")])
12599
12600 \f
12601 ;; Miscellaneous ISA 2.06 (power7) instructions
12602 (define_insn "addg6s"
12603   [(set (match_operand:SI 0 "register_operand" "=r")
12604         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
12605                     (match_operand:SI 2 "register_operand" "r")]
12606                    UNSPEC_ADDG6S))]
12607   "TARGET_POPCNTD"
12608   "addg6s %0,%1,%2"
12609   [(set_attr "type" "integer")
12610    (set_attr "length" "4")])
12611
12612 (define_insn "cdtbcd"
12613   [(set (match_operand:SI 0 "register_operand" "=r")
12614         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
12615                    UNSPEC_CDTBCD))]
12616   "TARGET_POPCNTD"
12617   "cdtbcd %0,%1"
12618   [(set_attr "type" "integer")
12619    (set_attr "length" "4")])
12620
12621 (define_insn "cbcdtd"
12622   [(set (match_operand:SI 0 "register_operand" "=r")
12623         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
12624                    UNSPEC_CBCDTD))]
12625   "TARGET_POPCNTD"
12626   "cbcdtd %0,%1"
12627   [(set_attr "type" "integer")
12628    (set_attr "length" "4")])
12629
12630 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
12631                                         UNSPEC_DIVEO
12632                                         UNSPEC_DIVEU
12633                                         UNSPEC_DIVEUO])
12634
12635 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
12636                              (UNSPEC_DIVEO      "eo")
12637                              (UNSPEC_DIVEU      "eu")
12638                              (UNSPEC_DIVEUO     "euo")])
12639
12640 (define_insn "div<div_extend>_<mode>"
12641   [(set (match_operand:GPR 0 "register_operand" "=r")
12642         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
12643                      (match_operand:GPR 2 "register_operand" "r")]
12644                     UNSPEC_DIV_EXTEND))]
12645   "TARGET_POPCNTD"
12646   "div<wd><div_extend> %0,%1,%2"
12647   [(set_attr "type" "div")
12648    (set_attr "size" "<bits>")])
12649
12650 \f
12651 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
12652
12653 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
12654 (define_mode_attr FP128_64 [(TF "DF") (TD "DI")])
12655
12656 (define_expand "unpack<mode>"
12657   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
12658         (unspec:<FP128_64>
12659          [(match_operand:FMOVE128 1 "register_operand" "")
12660           (match_operand:QI 2 "const_0_to_1_operand" "")]
12661          UNSPEC_UNPACK_128BIT))]
12662   ""
12663   "")
12664
12665 (define_insn_and_split "unpack<mode>_dm"
12666   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
12667         (unspec:<FP128_64>
12668          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
12669           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
12670          UNSPEC_UNPACK_128BIT))]
12671   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
12672   "#"
12673   "&& reload_completed"
12674   [(set (match_dup 0) (match_dup 3))]
12675 {
12676   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
12677
12678   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
12679     {
12680       emit_note (NOTE_INSN_DELETED);
12681       DONE;
12682     }
12683
12684   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
12685 }
12686   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
12687    (set_attr "length" "4")])
12688
12689 (define_insn_and_split "unpack<mode>_nodm"
12690   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
12691         (unspec:<FP128_64>
12692          [(match_operand:FMOVE128 1 "register_operand" "d,d")
12693           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
12694          UNSPEC_UNPACK_128BIT))]
12695   "!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE"
12696   "#"
12697   "&& reload_completed"
12698   [(set (match_dup 0) (match_dup 3))]
12699 {
12700   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
12701
12702   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
12703     {
12704       emit_note (NOTE_INSN_DELETED);
12705       DONE;
12706     }
12707
12708   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
12709 }
12710   [(set_attr "type" "fp,fpstore")
12711    (set_attr "length" "4")])
12712
12713 (define_insn_and_split "pack<mode>"
12714   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
12715         (unspec:FMOVE128
12716          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
12717           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
12718          UNSPEC_PACK_128BIT))]
12719   ""
12720   "@
12721    fmr %L0,%2
12722    #"
12723   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
12724   [(set (match_dup 3) (match_dup 1))
12725    (set (match_dup 4) (match_dup 2))]
12726 {
12727   unsigned dest_hi = REGNO (operands[0]);
12728   unsigned dest_lo = dest_hi + 1;
12729
12730   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
12731   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
12732
12733   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
12734   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
12735 }
12736   [(set_attr "type" "fp,fp")
12737    (set_attr "length" "4,8")])
12738
12739 (define_insn "unpackv1ti"
12740   [(set (match_operand:DI 0 "register_operand" "=d,d")
12741         (unspec:DI [(match_operand:V1TI 1 "register_operand" "0,wa")
12742                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
12743          UNSPEC_UNPACK_128BIT))]
12744   "TARGET_VSX"
12745 {
12746   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
12747     return ASM_COMMENT_START " xxpermdi to same register";
12748
12749   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
12750   return "xxpermdi %x0,%x1,%x1,%3";
12751 }
12752   [(set_attr "type" "vecperm")
12753    (set_attr "length" "4")])
12754
12755 (define_insn "packv1ti"
12756   [(set (match_operand:V1TI 0 "register_operand" "=wa")
12757         (unspec:V1TI
12758          [(match_operand:DI 1 "register_operand" "d")
12759           (match_operand:DI 2 "register_operand" "d")]
12760          UNSPEC_PACK_128BIT))]
12761   "TARGET_VSX"
12762   "xxpermdi %x0,%x1,%x2,0"
12763   [(set_attr "type" "vecperm")
12764    (set_attr "length" "4")])
12765
12766 \f
12767
12768 (include "sync.md")
12769 (include "vector.md")
12770 (include "vsx.md")
12771 (include "altivec.md")
12772 (include "spe.md")
12773 (include "dfp.md")
12774 (include "paired.md")
12775 (include "crypto.md")
12776 (include "htm.md")