1e0ee26cb511f4856c5b85183cbbfd3a01bf8e60
[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-2018 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    (FRAME_POINTER_REGNUM        111)
54    (TFHAR_REGNO                 112)
55    (TFIAR_REGNO                 113)
56    (TEXASR_REGNO                114)
57   ])
58
59 ;;
60 ;; UNSPEC usage
61 ;;
62
63 (define_c_enum "unspec"
64   [UNSPEC_FRSP                  ; frsp for POWER machines
65    UNSPEC_PROBE_STACK           ; probe stack memory reference
66    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
67    UNSPEC_TOC                   ; address of the TOC (more-or-less)
68    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
69    UNSPEC_MOVSI_GOT
70    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
71    UNSPEC_FCTIWZ
72    UNSPEC_FRIM
73    UNSPEC_FRIN
74    UNSPEC_FRIP
75    UNSPEC_FRIZ
76    UNSPEC_XSRDPI
77    UNSPEC_LD_MPIC               ; load_macho_picbase
78    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
79    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
80    UNSPEC_TLSGD
81    UNSPEC_TLSLD
82    UNSPEC_MOVESI_FROM_CR
83    UNSPEC_MOVESI_TO_CR
84    UNSPEC_TLSDTPREL
85    UNSPEC_TLSDTPRELHA
86    UNSPEC_TLSDTPRELLO
87    UNSPEC_TLSGOTDTPREL
88    UNSPEC_TLSTPREL
89    UNSPEC_TLSTPRELHA
90    UNSPEC_TLSTPRELLO
91    UNSPEC_TLSGOTTPREL
92    UNSPEC_TLSTLS
93    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
94    UNSPEC_STFIWX
95    UNSPEC_POPCNTB
96    UNSPEC_FRES
97    UNSPEC_SP_SET
98    UNSPEC_SP_TEST
99    UNSPEC_SYNC
100    UNSPEC_LWSYNC
101    UNSPEC_SYNC_OP
102    UNSPEC_ATOMIC
103    UNSPEC_CMPXCHG
104    UNSPEC_XCHG
105    UNSPEC_AND
106    UNSPEC_DLMZB
107    UNSPEC_DLMZB_CR
108    UNSPEC_DLMZB_STRLEN
109    UNSPEC_RSQRT
110    UNSPEC_TOCREL
111    UNSPEC_MACHOPIC_OFFSET
112    UNSPEC_BPERM
113    UNSPEC_COPYSIGN
114    UNSPEC_PARITY
115    UNSPEC_CMPB
116    UNSPEC_FCTIW
117    UNSPEC_FCTID
118    UNSPEC_LFIWAX
119    UNSPEC_LFIWZX
120    UNSPEC_FCTIWUZ
121    UNSPEC_NOP
122    UNSPEC_GRP_END_NOP
123    UNSPEC_P8V_FMRGOW
124    UNSPEC_P8V_MTVSRWZ
125    UNSPEC_P8V_RELOAD_FROM_GPR
126    UNSPEC_P8V_MTVSRD
127    UNSPEC_P8V_XXPERMDI
128    UNSPEC_P8V_RELOAD_FROM_VSX
129    UNSPEC_ADDG6S
130    UNSPEC_CDTBCD
131    UNSPEC_CBCDTD
132    UNSPEC_DIVE
133    UNSPEC_DIVEU
134    UNSPEC_UNPACK_128BIT
135    UNSPEC_PACK_128BIT
136    UNSPEC_LSQ
137    UNSPEC_FUSION_GPR
138    UNSPEC_STACK_CHECK
139    UNSPEC_FUSION_P9
140    UNSPEC_FUSION_ADDIS
141    UNSPEC_ADD_ROUND_TO_ODD
142    UNSPEC_SUB_ROUND_TO_ODD
143    UNSPEC_MUL_ROUND_TO_ODD
144    UNSPEC_DIV_ROUND_TO_ODD
145    UNSPEC_FMA_ROUND_TO_ODD
146    UNSPEC_SQRT_ROUND_TO_ODD
147    UNSPEC_TRUNC_ROUND_TO_ODD
148    UNSPEC_SIGNBIT
149    UNSPEC_SF_FROM_SI
150    UNSPEC_SI_FROM_SF
151   ])
152
153 ;;
154 ;; UNSPEC_VOLATILE usage
155 ;;
156
157 (define_c_enum "unspecv"
158   [UNSPECV_BLOCK
159    UNSPECV_LL                   ; load-locked
160    UNSPECV_SC                   ; store-conditional
161    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
162    UNSPECV_EH_RR                ; eh_reg_restore
163    UNSPECV_ISYNC                ; isync instruction
164    UNSPECV_MFTB                 ; move from time base
165    UNSPECV_NLGR                 ; non-local goto receiver
166    UNSPECV_MFFS                 ; Move from FPSCR
167    UNSPECV_MTFSF                ; Move to FPSCR Fields
168    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
169    UNSPECV_SPEC_BARRIER         ; Speculation barrier
170   ])
171
172 \f
173 ;; Define an insn type attribute.  This is used in function unit delay
174 ;; computations.
175 (define_attr "type"
176   "integer,two,three,
177    add,logical,shift,insert,
178    mul,halfmul,div,
179    exts,cntlz,popcnt,isel,
180    load,store,fpload,fpstore,vecload,vecstore,
181    cmp,
182    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183    cr_logical,mfcr,mfcrf,mtcr,
184    fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
185    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
186    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
187    veclogical,veccmpfx,vecexts,vecmove,
188    htm,htmsimple,dfp"
189   (const_string "integer"))
190
191 ;; What data size does this instruction work on?
192 ;; This is used for insert, mul and others as necessary.
193 (define_attr "size" "8,16,32,64,128" (const_string "32"))
194
195 ;; What is the insn_cost for this insn?  The target hook can still override
196 ;; this.  For optimizing for size the "length" attribute is used instead.
197 (define_attr "cost" "" (const_int 0))
198
199 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
200 ;; This is used for add, logical, shift, exts, mul.
201 (define_attr "dot" "no,yes" (const_string "no"))
202
203 ;; Does this instruction sign-extend its result?
204 ;; This is used for load insns.
205 (define_attr "sign_extend" "no,yes" (const_string "no"))
206
207 ;; Does this cr_logical instruction have three operands?  That is, BT != BB.
208 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
209
210 ;; Does this instruction use indexed (that is, reg+reg) addressing?
211 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
212 ;; it is automatically set based on that.  If a load or store instruction
213 ;; has fewer than two operands it needs to set this attribute manually
214 ;; or the compiler will crash.
215 (define_attr "indexed" "no,yes"
216   (if_then_else (ior (match_operand 0 "indexed_address_mem")
217                      (match_operand 1 "indexed_address_mem"))
218                 (const_string "yes")
219                 (const_string "no")))
220
221 ;; Does this instruction use update addressing?
222 ;; This is used for load and store insns.  See the comments for "indexed".
223 (define_attr "update" "no,yes"
224   (if_then_else (ior (match_operand 0 "update_address_mem")
225                      (match_operand 1 "update_address_mem"))
226                 (const_string "yes")
227                 (const_string "no")))
228
229 ;; Is this instruction using operands[2] as shift amount, and can that be a
230 ;; register?
231 ;; This is used for shift insns.
232 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
233
234 ;; Is this instruction using a shift amount from a register?
235 ;; This is used for shift insns.
236 (define_attr "var_shift" "no,yes"
237   (if_then_else (and (eq_attr "type" "shift")
238                      (eq_attr "maybe_var_shift" "yes"))
239                 (if_then_else (match_operand 2 "gpc_reg_operand")
240                               (const_string "yes")
241                               (const_string "no"))
242                 (const_string "no")))
243
244 ;; Is copying of this instruction disallowed?
245 (define_attr "cannot_copy" "no,yes" (const_string "no"))
246
247 ;; Length (in bytes).
248 ; '(pc)' in the following doesn't include the instruction itself; it is
249 ; calculated as if the instruction had zero size.
250 (define_attr "length" ""
251   (if_then_else (eq_attr "type" "branch")
252                 (if_then_else (and (ge (minus (match_dup 0) (pc))
253                                        (const_int -32768))
254                                    (lt (minus (match_dup 0) (pc))
255                                        (const_int 32764)))
256                               (const_int 4)
257                               (const_int 8))
258                 (const_int 4)))
259
260 ;; Processor type -- this attribute must exactly match the processor_type
261 ;; enumeration in rs6000-opts.h.
262 (define_attr "cpu"
263   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
264    ppc750,ppc7400,ppc7450,
265    ppc403,ppc405,ppc440,ppc476,
266    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
267    power4,power5,power6,power7,power8,power9,
268    rs64a,mpccore,cell,ppca2,titan"
269   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
270
271
272 ;; If this instruction is microcoded on the CELL processor
273 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
274 (define_attr "cell_micro" "not,conditional,always"
275   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
276                           (eq_attr "dot" "yes"))
277                      (and (eq_attr "type" "load")
278                           (eq_attr "sign_extend" "yes"))
279                      (and (eq_attr "type" "shift")
280                           (eq_attr "var_shift" "yes")))
281                 (const_string "always")
282                 (const_string "not")))
283
284 (automata_option "ndfa")
285
286 (include "rs64.md")
287 (include "mpc.md")
288 (include "40x.md")
289 (include "440.md")
290 (include "476.md")
291 (include "601.md")
292 (include "603.md")
293 (include "6xx.md")
294 (include "7xx.md")
295 (include "7450.md")
296 (include "8540.md")
297 (include "e300c2c3.md")
298 (include "e500mc.md")
299 (include "e500mc64.md")
300 (include "e5500.md")
301 (include "e6500.md")
302 (include "power4.md")
303 (include "power5.md")
304 (include "power6.md")
305 (include "power7.md")
306 (include "power8.md")
307 (include "power9.md")
308 (include "cell.md")
309 (include "a2.md")
310 (include "titan.md")
311
312 (include "predicates.md")
313 (include "constraints.md")
314
315 (include "darwin.md")
316
317 \f
318 ;; Mode iterators
319
320 ; This mode iterator allows :GPR to be used to indicate the allowable size
321 ; of whole values in GPRs.
322 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
323
324 ; And again, for patterns that need two (potentially) different integer modes.
325 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
326
327 ; Any supported integer mode.
328 (define_mode_iterator INT [QI HI SI DI TI PTI])
329
330 ; Any supported integer mode that fits in one register.
331 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
332
333 ; Integer modes supported in VSX registers with ISA 3.0 instructions
334 (define_mode_iterator INT_ISA3 [QI HI SI DI])
335
336 ; Everything we can extend QImode to.
337 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
338
339 ; Everything we can extend HImode to.
340 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
341
342 ; Everything we can extend SImode to.
343 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
344
345 ; QImode or HImode for small integer moves and small atomic ops
346 (define_mode_iterator QHI [QI HI])
347
348 ; QImode, HImode, SImode for fused ops only for GPR loads
349 (define_mode_iterator QHSI [QI HI SI])
350
351 ; HImode or SImode for sign extended fusion ops
352 (define_mode_iterator HSI [HI SI])
353
354 ; SImode or DImode, even if DImode doesn't fit in GPRs.
355 (define_mode_iterator SDI [SI DI])
356
357 ; Types that can be fused with an ADDIS instruction to load or store a GPR
358 ; register that has reg+offset addressing.
359 (define_mode_iterator GPR_FUSION [QI
360                                   HI
361                                   SI
362                                   (DI   "TARGET_POWERPC64")
363                                   SF
364                                   (DF   "TARGET_POWERPC64")])
365
366 ; Types that can be fused with an ADDIS instruction to load or store a FPR
367 ; register that has reg+offset addressing.
368 (define_mode_iterator FPR_FUSION [DI SF DF])
369
370 ; The size of a pointer.  Also, the size of the value that a record-condition
371 ; (one with a '.') will compare; and the size used for arithmetic carries.
372 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
373
374 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
375 ; PTImode is GPR only)
376 (define_mode_iterator TI2 [TI PTI])
377
378 ; Any hardware-supported floating-point mode
379 (define_mode_iterator FP [
380   (SF "TARGET_HARD_FLOAT")
381   (DF "TARGET_HARD_FLOAT")
382   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
383   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
384   (KF "TARGET_FLOAT128_TYPE")
385   (DD "TARGET_DFP")
386   (TD "TARGET_DFP")])
387
388 ; Any fma capable floating-point mode.
389 (define_mode_iterator FMA_F [
390   (SF "TARGET_HARD_FLOAT")
391   (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
392   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
393   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
394   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
395   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
396   ])
397
398 ; Floating point move iterators to combine binary and decimal moves
399 (define_mode_iterator FMOVE32 [SF SD])
400 (define_mode_iterator FMOVE64 [DF DD])
401 (define_mode_iterator FMOVE64X [DI DF DD])
402 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
403                                 (IF "FLOAT128_IBM_P (IFmode)")
404                                 (TD "TARGET_HARD_FLOAT")])
405
406 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
407                                     (IF "FLOAT128_2REG_P (IFmode)")
408                                     (TD "TARGET_HARD_FLOAT")])
409
410 ; Iterators for 128 bit types for direct move
411 (define_mode_iterator FMOVE128_GPR [TI
412                                     V16QI
413                                     V8HI
414                                     V4SI
415                                     V4SF
416                                     V2DI
417                                     V2DF
418                                     V1TI
419                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
420                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
421
422 ; Iterator for 128-bit VSX types for pack/unpack
423 (define_mode_iterator FMOVE128_VSX [V1TI KF])
424
425 ; Whether a floating point move is ok, don't allow SD without hardware FP
426 (define_mode_attr fmove_ok [(SF "")
427                             (DF "")
428                             (SD "TARGET_HARD_FLOAT")
429                             (DD "")])
430
431 ; Convert REAL_VALUE to the appropriate bits
432 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
433                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
434                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
435                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
436
437 ; Whether 0.0 has an all-zero bit pattern
438 (define_mode_attr zero_fp [(SF "j")
439                            (DF "j")
440                            (TF "j")
441                            (IF "j")
442                            (KF "j")
443                            (SD "wn")
444                            (DD "wn")
445                            (TD "wn")])
446
447 ; Definitions for 64-bit VSX
448 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
449
450 ; Definitions for 64-bit direct move
451 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
452
453 ; Definitions for 64-bit use of altivec registers
454 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
455
456 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
457 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
458
459 ; These modes do not fit in integer registers in 32-bit mode.
460 (define_mode_iterator DIFD [DI DF DD])
461
462 ; Iterator for reciprocal estimate instructions
463 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
464
465 ; Iterator for just SF/DF
466 (define_mode_iterator SFDF [SF DF])
467
468 ; Like SFDF, but a different name to match conditional move where the
469 ; comparison operands may be a different mode than the input operands.
470 (define_mode_iterator SFDF2 [SF DF])
471
472 ; Iterator for 128-bit floating point that uses the IBM double-double format
473 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
474                               (TF "FLOAT128_IBM_P (TFmode)")])
475
476 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
477 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
478                                (TF "FLOAT128_IEEE_P (TFmode)")])
479
480 ; Iterator for 128-bit floating point
481 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
482                                 (IF "TARGET_FLOAT128_TYPE")
483                                 (TF "TARGET_LONG_DOUBLE_128")])
484
485 ; Iterator for signbit on 64-bit machines with direct move
486 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
487                                (TF "FLOAT128_VECTOR_P (TFmode)")])
488
489 ; Iterator for ISA 3.0 supported floating point types
490 (define_mode_iterator FP_ISA3 [SF DF])
491
492 ; SF/DF suffix for traditional floating instructions
493 (define_mode_attr Ftrad         [(SF "s") (DF "")])
494
495 ; SF/DF suffix for VSX instructions
496 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
497
498 ; SF/DF constraint for arithmetic on traditional floating point registers
499 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
500
501 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
502 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
503 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
504 ; format.
505 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
506
507 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
508 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
509 ; instructions added in ISA 2.07 (power8)
510 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
511
512 ; SF/DF constraint for arithmetic on altivec registers
513 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
514
515 ; s/d suffix for things like sdiv/ddiv
516 (define_mode_attr Fs            [(SF "s")  (DF "d")])
517
518 ; FRE/FRES support
519 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
520 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
521
522 ; Conditional returns.
523 (define_code_iterator any_return [return simple_return])
524 (define_code_attr return_pred [(return "direct_return ()")
525                                (simple_return "1")])
526 (define_code_attr return_str [(return "") (simple_return "simple_")])
527
528 ; Logical operators.
529 (define_code_iterator iorxor            [ior xor])
530 (define_code_iterator and_ior_xor       [and ior xor])
531
532 ; Signed/unsigned variants of ops.
533 (define_code_iterator any_extend        [sign_extend zero_extend])
534 (define_code_iterator any_fix           [fix unsigned_fix])
535 (define_code_iterator any_float         [float unsigned_float])
536
537 (define_code_attr u  [(sign_extend      "")
538                       (zero_extend      "u")
539                       (fix              "")
540                       (unsigned_fix     "u")])
541
542 (define_code_attr su [(sign_extend      "s")
543                       (zero_extend      "u")
544                       (fix              "s")
545                       (unsigned_fix     "u")
546                       (float            "s")
547                       (unsigned_float   "u")])
548
549 (define_code_attr az [(sign_extend      "a")
550                       (zero_extend      "z")
551                       (fix              "a")
552                       (unsigned_fix     "z")
553                       (float            "a")
554                       (unsigned_float   "z")])
555
556 (define_code_attr uns [(fix             "")
557                        (unsigned_fix    "uns")
558                        (float           "")
559                        (unsigned_float  "uns")])
560
561 ; Various instructions that come in SI and DI forms.
562 ; A generic w/d attribute, for things like cmpw/cmpd.
563 (define_mode_attr wd [(QI    "b")
564                       (HI    "h")
565                       (SI    "w")
566                       (DI    "d")
567                       (V16QI "b")
568                       (V8HI  "h")
569                       (V4SI  "w")
570                       (V2DI  "d")
571                       (V1TI  "q")
572                       (TI    "q")])
573
574 ;; How many bits in this mode?
575 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
576
577 ; DImode bits
578 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
579
580 ;; Bitmask for shift instructions
581 (define_mode_attr hH [(SI "h") (DI "H")])
582
583 ;; A mode twice the size of the given mode
584 (define_mode_attr dmode [(SI "di") (DI "ti")])
585 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
586
587 ;; Suffix for reload patterns
588 (define_mode_attr ptrsize [(SI "32bit")
589                            (DI "64bit")])
590
591 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
592                             (DI "TARGET_64BIT")])
593
594 (define_mode_attr mptrsize [(SI "si")
595                             (DI "di")])
596
597 (define_mode_attr ptrload [(SI "lwz")
598                            (DI "ld")])
599
600 (define_mode_attr ptrm [(SI "m")
601                         (DI "Y")])
602
603 (define_mode_attr rreg [(SF   "f")
604                         (DF   "ws")
605                         (TF   "f")
606                         (TD   "f")
607                         (V4SF "wf")
608                         (V2DF "wd")])
609
610 (define_mode_attr rreg2 [(SF   "f")
611                          (DF   "d")])
612
613 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
614                                  (DF "TARGET_FCFID")])
615
616 ;; Mode iterator for logical operations on 128-bit types
617 (define_mode_iterator BOOL_128          [TI
618                                          PTI
619                                          (V16QI "TARGET_ALTIVEC")
620                                          (V8HI  "TARGET_ALTIVEC")
621                                          (V4SI  "TARGET_ALTIVEC")
622                                          (V4SF  "TARGET_ALTIVEC")
623                                          (V2DI  "TARGET_ALTIVEC")
624                                          (V2DF  "TARGET_ALTIVEC")
625                                          (V1TI  "TARGET_ALTIVEC")])
626
627 ;; For the GPRs we use 3 constraints for register outputs, two that are the
628 ;; same as the output register, and a third where the output register is an
629 ;; early clobber, so we don't have to deal with register overlaps.  For the
630 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
631 ;; either.
632
633 ;; Mode attribute for boolean operation register constraints for output
634 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
635                                          (PTI   "&r,r,r")
636                                          (V16QI "wa,v,&?r,?r,?r")
637                                          (V8HI  "wa,v,&?r,?r,?r")
638                                          (V4SI  "wa,v,&?r,?r,?r")
639                                          (V4SF  "wa,v,&?r,?r,?r")
640                                          (V2DI  "wa,v,&?r,?r,?r")
641                                          (V2DF  "wa,v,&?r,?r,?r")
642                                          (V1TI  "wa,v,&?r,?r,?r")])
643
644 ;; Mode attribute for boolean operation register constraints for operand1
645 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
646                                          (PTI   "r,0,r")
647                                          (V16QI "wa,v,r,0,r")
648                                          (V8HI  "wa,v,r,0,r")
649                                          (V4SI  "wa,v,r,0,r")
650                                          (V4SF  "wa,v,r,0,r")
651                                          (V2DI  "wa,v,r,0,r")
652                                          (V2DF  "wa,v,r,0,r")
653                                          (V1TI  "wa,v,r,0,r")])
654
655 ;; Mode attribute for boolean operation register constraints for operand2
656 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
657                                          (PTI   "r,r,0")
658                                          (V16QI "wa,v,r,r,0")
659                                          (V8HI  "wa,v,r,r,0")
660                                          (V4SI  "wa,v,r,r,0")
661                                          (V4SF  "wa,v,r,r,0")
662                                          (V2DI  "wa,v,r,r,0")
663                                          (V2DF  "wa,v,r,r,0")
664                                          (V1TI  "wa,v,r,r,0")])
665
666 ;; Mode attribute for boolean operation register constraints for operand1
667 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
668 ;; is used for operand1 or operand2
669 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
670                                          (PTI   "r,0,0")
671                                          (V16QI "wa,v,r,0,0")
672                                          (V8HI  "wa,v,r,0,0")
673                                          (V4SI  "wa,v,r,0,0")
674                                          (V4SF  "wa,v,r,0,0")
675                                          (V2DI  "wa,v,r,0,0")
676                                          (V2DF  "wa,v,r,0,0")
677                                          (V1TI  "wa,v,r,0,0")])
678
679 ;; Reload iterator for creating the function to allocate a base register to
680 ;; supplement addressing modes.
681 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
682                               SF SD SI DF DD DI TI PTI KF IF TF])
683
684 ;; Iterate over smin, smax
685 (define_code_iterator fp_minmax [smin smax])
686
687 (define_code_attr     minmax    [(smin "min")
688                                  (smax "max")])
689
690 (define_code_attr     SMINMAX   [(smin "SMIN")
691                                  (smax "SMAX")])
692
693 ;; Iterator to optimize the following cases:
694 ;;      D-form load to FPR register & move to Altivec register
695 ;;      Move Altivec register to FPR register and store
696 (define_mode_iterator ALTIVEC_DFORM [DF
697                                      (SF "TARGET_P8_VECTOR")
698                                      (DI "TARGET_POWERPC64")])
699
700 \f
701 ;; Start with fixed-point load and store insns.  Here we put only the more
702 ;; complex forms.  Basic data transfer is done later.
703
704 (define_insn "zero_extendqi<mode>2"
705   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
706         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
707   ""
708   "@
709    lbz%U1%X1 %0,%1
710    rlwinm %0,%1,0,0xff
711    lxsibzx %x0,%y1
712    vextractub %0,%1,7"
713   [(set_attr "type" "load,shift,fpload,vecperm")])
714
715 (define_insn_and_split "*zero_extendqi<mode>2_dot"
716   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
717         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
718                     (const_int 0)))
719    (clobber (match_scratch:EXTQI 0 "=r,r"))]
720   ""
721   "@
722    andi. %0,%1,0xff
723    #"
724   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
725   [(set (match_dup 0)
726         (zero_extend:EXTQI (match_dup 1)))
727    (set (match_dup 2)
728         (compare:CC (match_dup 0)
729                     (const_int 0)))]
730   ""
731   [(set_attr "type" "logical")
732    (set_attr "dot" "yes")
733    (set_attr "length" "4,8")])
734
735 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
736   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
737         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
738                     (const_int 0)))
739    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
740         (zero_extend:EXTQI (match_dup 1)))]
741   ""
742   "@
743    andi. %0,%1,0xff
744    #"
745   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
746   [(set (match_dup 0)
747         (zero_extend:EXTQI (match_dup 1)))
748    (set (match_dup 2)
749         (compare:CC (match_dup 0)
750                     (const_int 0)))]
751   ""
752   [(set_attr "type" "logical")
753    (set_attr "dot" "yes")
754    (set_attr "length" "4,8")])
755
756
757 (define_insn "zero_extendhi<mode>2"
758   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
759         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
760   ""
761   "@
762    lhz%U1%X1 %0,%1
763    rlwinm %0,%1,0,0xffff
764    lxsihzx %x0,%y1
765    vextractuh %0,%1,6"
766   [(set_attr "type" "load,shift,fpload,vecperm")])
767
768 (define_insn_and_split "*zero_extendhi<mode>2_dot"
769   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
770         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
771                     (const_int 0)))
772    (clobber (match_scratch:EXTHI 0 "=r,r"))]
773   ""
774   "@
775    andi. %0,%1,0xffff
776    #"
777   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
778   [(set (match_dup 0)
779         (zero_extend:EXTHI (match_dup 1)))
780    (set (match_dup 2)
781         (compare:CC (match_dup 0)
782                     (const_int 0)))]
783   ""
784   [(set_attr "type" "logical")
785    (set_attr "dot" "yes")
786    (set_attr "length" "4,8")])
787
788 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
789   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
790         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
791                     (const_int 0)))
792    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
793         (zero_extend:EXTHI (match_dup 1)))]
794   ""
795   "@
796    andi. %0,%1,0xffff
797    #"
798   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
799   [(set (match_dup 0)
800         (zero_extend:EXTHI (match_dup 1)))
801    (set (match_dup 2)
802         (compare:CC (match_dup 0)
803                     (const_int 0)))]
804   ""
805   [(set_attr "type" "logical")
806    (set_attr "dot" "yes")
807    (set_attr "length" "4,8")])
808
809
810 (define_insn "zero_extendsi<mode>2"
811   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
812         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
813   ""
814   "@
815    lwz%U1%X1 %0,%1
816    rldicl %0,%1,0,32
817    lfiwzx %0,%y1
818    lxsiwzx %x0,%y1
819    mtvsrwz %x0,%1
820    mfvsrwz %0,%x1
821    xxextractuw %x0,%x1,4"
822   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
823
824 (define_insn_and_split "*zero_extendsi<mode>2_dot"
825   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
826         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
827                     (const_int 0)))
828    (clobber (match_scratch:EXTSI 0 "=r,r"))]
829   ""
830   "@
831    rldicl. %0,%1,0,32
832    #"
833   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
834   [(set (match_dup 0)
835         (zero_extend:DI (match_dup 1)))
836    (set (match_dup 2)
837         (compare:CC (match_dup 0)
838                     (const_int 0)))]
839   ""
840   [(set_attr "type" "shift")
841    (set_attr "dot" "yes")
842    (set_attr "length" "4,8")])
843
844 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
845   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
846         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
847                     (const_int 0)))
848    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
849         (zero_extend:EXTSI (match_dup 1)))]
850   ""
851   "@
852    rldicl. %0,%1,0,32
853    #"
854   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
855   [(set (match_dup 0)
856         (zero_extend:EXTSI (match_dup 1)))
857    (set (match_dup 2)
858         (compare:CC (match_dup 0)
859                     (const_int 0)))]
860   ""
861   [(set_attr "type" "shift")
862    (set_attr "dot" "yes")
863    (set_attr "length" "4,8")])
864
865
866 (define_insn "extendqi<mode>2"
867   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
868         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
869   ""
870   "@
871    extsb %0,%1
872    vextsb2d %0,%1"
873   [(set_attr "type" "exts,vecperm")])
874
875 (define_insn_and_split "*extendqi<mode>2_dot"
876   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
877         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
878                     (const_int 0)))
879    (clobber (match_scratch:EXTQI 0 "=r,r"))]
880   ""
881   "@
882    extsb. %0,%1
883    #"
884   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
885   [(set (match_dup 0)
886         (sign_extend:EXTQI (match_dup 1)))
887    (set (match_dup 2)
888         (compare:CC (match_dup 0)
889                     (const_int 0)))]
890   ""
891   [(set_attr "type" "exts")
892    (set_attr "dot" "yes")
893    (set_attr "length" "4,8")])
894
895 (define_insn_and_split "*extendqi<mode>2_dot2"
896   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
897         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
898                     (const_int 0)))
899    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
900         (sign_extend:EXTQI (match_dup 1)))]
901   ""
902   "@
903    extsb. %0,%1
904    #"
905   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
906   [(set (match_dup 0)
907         (sign_extend:EXTQI (match_dup 1)))
908    (set (match_dup 2)
909         (compare:CC (match_dup 0)
910                     (const_int 0)))]
911   ""
912   [(set_attr "type" "exts")
913    (set_attr "dot" "yes")
914    (set_attr "length" "4,8")])
915
916
917 (define_expand "extendhi<mode>2"
918   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
919         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
920   ""
921   "")
922
923 (define_insn "*extendhi<mode>2"
924   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
925         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
926   ""
927   "@
928    lha%U1%X1 %0,%1
929    extsh %0,%1
930    #
931    vextsh2d %0,%1"
932   [(set_attr "type" "load,exts,fpload,vecperm")
933    (set_attr "sign_extend" "yes")
934    (set_attr "length" "4,4,8,4")])
935
936 (define_split
937   [(set (match_operand:EXTHI 0 "altivec_register_operand")
938         (sign_extend:EXTHI
939          (match_operand:HI 1 "indexed_or_indirect_operand")))]
940   "TARGET_P9_VECTOR && reload_completed"
941   [(set (match_dup 2)
942         (match_dup 1))
943    (set (match_dup 0)
944         (sign_extend:EXTHI (match_dup 2)))]
945 {
946   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
947 })
948
949 (define_insn_and_split "*extendhi<mode>2_dot"
950   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
951         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
952                     (const_int 0)))
953    (clobber (match_scratch:EXTHI 0 "=r,r"))]
954   ""
955   "@
956    extsh. %0,%1
957    #"
958   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
959   [(set (match_dup 0)
960         (sign_extend:EXTHI (match_dup 1)))
961    (set (match_dup 2)
962         (compare:CC (match_dup 0)
963                     (const_int 0)))]
964   ""
965   [(set_attr "type" "exts")
966    (set_attr "dot" "yes")
967    (set_attr "length" "4,8")])
968
969 (define_insn_and_split "*extendhi<mode>2_dot2"
970   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
971         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
972                     (const_int 0)))
973    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
974         (sign_extend:EXTHI (match_dup 1)))]
975   ""
976   "@
977    extsh. %0,%1
978    #"
979   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
980   [(set (match_dup 0)
981         (sign_extend:EXTHI (match_dup 1)))
982    (set (match_dup 2)
983         (compare:CC (match_dup 0)
984                     (const_int 0)))]
985   ""
986   [(set_attr "type" "exts")
987    (set_attr "dot" "yes")
988    (set_attr "length" "4,8")])
989
990
991 (define_insn "extendsi<mode>2"
992   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
993                      "=r, r,   wl,    wu,    wj,    wK,     wH,    wr")
994
995         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
996                      "Y,  r,   Z,     Z,     r,     wK,     wH,    ?wIwH")))]
997   ""
998   "@
999    lwa%U1%X1 %0,%1
1000    extsw %0,%1
1001    lfiwax %0,%y1
1002    lxsiwax %x0,%y1
1003    mtvsrwa %x0,%1
1004    vextsw2d %0,%1
1005    #
1006    #"
1007   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1008    (set_attr "sign_extend" "yes")
1009    (set_attr "length" "4,4,4,4,4,4,8,8")])
1010
1011 (define_split
1012   [(set (match_operand:EXTSI 0 "int_reg_operand")
1013         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1014   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1015   [(set (match_dup 2)
1016         (match_dup 1))
1017    (set (match_dup 0)
1018         (sign_extend:DI (match_dup 2)))]
1019 {
1020   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1021 })
1022
1023 (define_split
1024   [(set (match_operand:DI 0 "altivec_register_operand")
1025         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1026   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1027   [(const_int 0)]
1028 {
1029   rtx dest = operands[0];
1030   rtx src = operands[1];
1031   int dest_regno = REGNO (dest);
1032   int src_regno = REGNO (src);
1033   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1034   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1035
1036   if (VECTOR_ELT_ORDER_BIG)
1037     {
1038       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1039       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1040     }
1041   else
1042     {
1043       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1044       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1045     }
1046   DONE;
1047 })
1048
1049 (define_insn_and_split "*extendsi<mode>2_dot"
1050   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1051         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1052                     (const_int 0)))
1053    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1054   ""
1055   "@
1056    extsw. %0,%1
1057    #"
1058   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1059   [(set (match_dup 0)
1060         (sign_extend:EXTSI (match_dup 1)))
1061    (set (match_dup 2)
1062         (compare:CC (match_dup 0)
1063                     (const_int 0)))]
1064   ""
1065   [(set_attr "type" "exts")
1066    (set_attr "dot" "yes")
1067    (set_attr "length" "4,8")])
1068
1069 (define_insn_and_split "*extendsi<mode>2_dot2"
1070   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1071         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1072                     (const_int 0)))
1073    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1074         (sign_extend:EXTSI (match_dup 1)))]
1075   ""
1076   "@
1077    extsw. %0,%1
1078    #"
1079   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1080   [(set (match_dup 0)
1081         (sign_extend:EXTSI (match_dup 1)))
1082    (set (match_dup 2)
1083         (compare:CC (match_dup 0)
1084                     (const_int 0)))]
1085   ""
1086   [(set_attr "type" "exts")
1087    (set_attr "dot" "yes")
1088    (set_attr "length" "4,8")])
1089 \f
1090 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1091
1092 (define_insn "*macchwc"
1093   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1094         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1095                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1096                                        (const_int 16))
1097                                       (sign_extend:SI
1098                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1099                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1100                     (const_int 0)))
1101    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1102         (plus:SI (mult:SI (ashiftrt:SI
1103                            (match_dup 2)
1104                            (const_int 16))
1105                           (sign_extend:SI
1106                            (match_dup 1)))
1107                  (match_dup 4)))]
1108   "TARGET_MULHW"
1109   "macchw. %0,%1,%2"
1110   [(set_attr "type" "halfmul")])
1111
1112 (define_insn "*macchw"
1113   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1114         (plus:SI (mult:SI (ashiftrt:SI
1115                            (match_operand:SI 2 "gpc_reg_operand" "r")
1116                            (const_int 16))
1117                           (sign_extend:SI
1118                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1119                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1120   "TARGET_MULHW"
1121   "macchw %0,%1,%2"
1122   [(set_attr "type" "halfmul")])
1123
1124 (define_insn "*macchwuc"
1125   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1126         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1127                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1128                                        (const_int 16))
1129                                       (zero_extend:SI
1130                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1131                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1132                     (const_int 0)))
1133    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1134         (plus:SI (mult:SI (lshiftrt:SI
1135                            (match_dup 2)
1136                            (const_int 16))
1137                           (zero_extend:SI
1138                            (match_dup 1)))
1139                  (match_dup 4)))]
1140   "TARGET_MULHW"
1141   "macchwu. %0,%1,%2"
1142   [(set_attr "type" "halfmul")])
1143
1144 (define_insn "*macchwu"
1145   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1146         (plus:SI (mult:SI (lshiftrt:SI
1147                            (match_operand:SI 2 "gpc_reg_operand" "r")
1148                            (const_int 16))
1149                           (zero_extend:SI
1150                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1151                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1152   "TARGET_MULHW"
1153   "macchwu %0,%1,%2"
1154   [(set_attr "type" "halfmul")])
1155
1156 (define_insn "*machhwc"
1157   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1158         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1159                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1160                                        (const_int 16))
1161                                       (ashiftrt:SI
1162                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1163                                        (const_int 16)))
1164                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1165                     (const_int 0)))
1166    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1167         (plus:SI (mult:SI (ashiftrt:SI
1168                            (match_dup 1)
1169                            (const_int 16))
1170                           (ashiftrt:SI
1171                            (match_dup 2)
1172                            (const_int 16)))
1173                  (match_dup 4)))]
1174   "TARGET_MULHW"
1175   "machhw. %0,%1,%2"
1176   [(set_attr "type" "halfmul")])
1177
1178 (define_insn "*machhw"
1179   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1180         (plus:SI (mult:SI (ashiftrt:SI
1181                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1182                            (const_int 16))
1183                           (ashiftrt:SI
1184                            (match_operand:SI 2 "gpc_reg_operand" "r")
1185                            (const_int 16)))
1186                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1187   "TARGET_MULHW"
1188   "machhw %0,%1,%2"
1189   [(set_attr "type" "halfmul")])
1190
1191 (define_insn "*machhwuc"
1192   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1193         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1194                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1195                                        (const_int 16))
1196                                       (lshiftrt:SI
1197                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1198                                        (const_int 16)))
1199                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1200                     (const_int 0)))
1201    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1202         (plus:SI (mult:SI (lshiftrt:SI
1203                            (match_dup 1)
1204                            (const_int 16))
1205                           (lshiftrt:SI
1206                            (match_dup 2)
1207                            (const_int 16)))
1208                  (match_dup 4)))]
1209   "TARGET_MULHW"
1210   "machhwu. %0,%1,%2"
1211   [(set_attr "type" "halfmul")])
1212
1213 (define_insn "*machhwu"
1214   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1215         (plus:SI (mult:SI (lshiftrt:SI
1216                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1217                            (const_int 16))
1218                           (lshiftrt:SI
1219                            (match_operand:SI 2 "gpc_reg_operand" "r")
1220                            (const_int 16)))
1221                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1222   "TARGET_MULHW"
1223   "machhwu %0,%1,%2"
1224   [(set_attr "type" "halfmul")])
1225
1226 (define_insn "*maclhwc"
1227   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1228         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1229                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1230                                       (sign_extend:SI
1231                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1232                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1233                     (const_int 0)))
1234    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1235         (plus:SI (mult:SI (sign_extend:SI
1236                            (match_dup 1))
1237                           (sign_extend:SI
1238                            (match_dup 2)))
1239                  (match_dup 4)))]
1240   "TARGET_MULHW"
1241   "maclhw. %0,%1,%2"
1242   [(set_attr "type" "halfmul")])
1243
1244 (define_insn "*maclhw"
1245   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1246         (plus:SI (mult:SI (sign_extend:SI
1247                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1248                           (sign_extend:SI
1249                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1250                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1251   "TARGET_MULHW"
1252   "maclhw %0,%1,%2"
1253   [(set_attr "type" "halfmul")])
1254
1255 (define_insn "*maclhwuc"
1256   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1257         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1258                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1259                                       (zero_extend:SI
1260                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1261                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1262                     (const_int 0)))
1263    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1264         (plus:SI (mult:SI (zero_extend:SI
1265                            (match_dup 1))
1266                           (zero_extend:SI
1267                            (match_dup 2)))
1268                  (match_dup 4)))]
1269   "TARGET_MULHW"
1270   "maclhwu. %0,%1,%2"
1271   [(set_attr "type" "halfmul")])
1272
1273 (define_insn "*maclhwu"
1274   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1275         (plus:SI (mult:SI (zero_extend:SI
1276                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1277                           (zero_extend:SI
1278                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1279                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1280   "TARGET_MULHW"
1281   "maclhwu %0,%1,%2"
1282   [(set_attr "type" "halfmul")])
1283
1284 (define_insn "*nmacchwc"
1285   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1286         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1287                               (mult:SI (ashiftrt:SI
1288                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1289                                         (const_int 16))
1290                                        (sign_extend:SI
1291                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1292                     (const_int 0)))
1293    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1294         (minus:SI (match_dup 4)
1295                   (mult:SI (ashiftrt:SI
1296                             (match_dup 2)
1297                             (const_int 16))
1298                            (sign_extend:SI
1299                             (match_dup 1)))))]
1300   "TARGET_MULHW"
1301   "nmacchw. %0,%1,%2"
1302   [(set_attr "type" "halfmul")])
1303
1304 (define_insn "*nmacchw"
1305   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1306         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1307                   (mult:SI (ashiftrt:SI
1308                             (match_operand:SI 2 "gpc_reg_operand" "r")
1309                             (const_int 16))
1310                            (sign_extend:SI
1311                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1312   "TARGET_MULHW"
1313   "nmacchw %0,%1,%2"
1314   [(set_attr "type" "halfmul")])
1315
1316 (define_insn "*nmachhwc"
1317   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1318         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1319                               (mult:SI (ashiftrt:SI
1320                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1321                                         (const_int 16))
1322                                        (ashiftrt:SI
1323                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1324                                         (const_int 16))))
1325                     (const_int 0)))
1326    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1327         (minus:SI (match_dup 4)
1328                   (mult:SI (ashiftrt:SI
1329                             (match_dup 1)
1330                             (const_int 16))
1331                            (ashiftrt:SI
1332                             (match_dup 2)
1333                             (const_int 16)))))]
1334   "TARGET_MULHW"
1335   "nmachhw. %0,%1,%2"
1336   [(set_attr "type" "halfmul")])
1337
1338 (define_insn "*nmachhw"
1339   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1340         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1341                   (mult:SI (ashiftrt:SI
1342                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1343                             (const_int 16))
1344                            (ashiftrt:SI
1345                             (match_operand:SI 2 "gpc_reg_operand" "r")
1346                             (const_int 16)))))]
1347   "TARGET_MULHW"
1348   "nmachhw %0,%1,%2"
1349   [(set_attr "type" "halfmul")])
1350
1351 (define_insn "*nmaclhwc"
1352   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1353         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1354                               (mult:SI (sign_extend:SI
1355                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1356                                        (sign_extend:SI
1357                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1358                     (const_int 0)))
1359    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1360         (minus:SI (match_dup 4)
1361                   (mult:SI (sign_extend:SI
1362                             (match_dup 1))
1363                            (sign_extend:SI
1364                             (match_dup 2)))))]
1365   "TARGET_MULHW"
1366   "nmaclhw. %0,%1,%2"
1367   [(set_attr "type" "halfmul")])
1368
1369 (define_insn "*nmaclhw"
1370   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1371         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1372                   (mult:SI (sign_extend:SI
1373                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1374                            (sign_extend:SI
1375                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1376   "TARGET_MULHW"
1377   "nmaclhw %0,%1,%2"
1378   [(set_attr "type" "halfmul")])
1379
1380 (define_insn "*mulchwc"
1381   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1382         (compare:CC (mult:SI (ashiftrt:SI
1383                               (match_operand:SI 2 "gpc_reg_operand" "r")
1384                               (const_int 16))
1385                              (sign_extend:SI
1386                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1387                     (const_int 0)))
1388    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1389         (mult:SI (ashiftrt:SI
1390                   (match_dup 2)
1391                   (const_int 16))
1392                  (sign_extend:SI
1393                   (match_dup 1))))]
1394   "TARGET_MULHW"
1395   "mulchw. %0,%1,%2"
1396   [(set_attr "type" "halfmul")])
1397
1398 (define_insn "*mulchw"
1399   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1400         (mult:SI (ashiftrt:SI
1401                   (match_operand:SI 2 "gpc_reg_operand" "r")
1402                   (const_int 16))
1403                  (sign_extend:SI
1404                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1405   "TARGET_MULHW"
1406   "mulchw %0,%1,%2"
1407   [(set_attr "type" "halfmul")])
1408
1409 (define_insn "*mulchwuc"
1410   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1411         (compare:CC (mult:SI (lshiftrt:SI
1412                               (match_operand:SI 2 "gpc_reg_operand" "r")
1413                               (const_int 16))
1414                              (zero_extend:SI
1415                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1416                     (const_int 0)))
1417    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1418         (mult:SI (lshiftrt:SI
1419                   (match_dup 2)
1420                   (const_int 16))
1421                  (zero_extend:SI
1422                   (match_dup 1))))]
1423   "TARGET_MULHW"
1424   "mulchwu. %0,%1,%2"
1425   [(set_attr "type" "halfmul")])
1426
1427 (define_insn "*mulchwu"
1428   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1429         (mult:SI (lshiftrt:SI
1430                   (match_operand:SI 2 "gpc_reg_operand" "r")
1431                   (const_int 16))
1432                  (zero_extend:SI
1433                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1434   "TARGET_MULHW"
1435   "mulchwu %0,%1,%2"
1436   [(set_attr "type" "halfmul")])
1437
1438 (define_insn "*mulhhwc"
1439   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1440         (compare:CC (mult:SI (ashiftrt:SI
1441                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1442                               (const_int 16))
1443                              (ashiftrt:SI
1444                               (match_operand:SI 2 "gpc_reg_operand" "r")
1445                               (const_int 16)))
1446                     (const_int 0)))
1447    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1448         (mult:SI (ashiftrt:SI
1449                   (match_dup 1)
1450                   (const_int 16))
1451                  (ashiftrt:SI
1452                   (match_dup 2)
1453                   (const_int 16))))]
1454   "TARGET_MULHW"
1455   "mulhhw. %0,%1,%2"
1456   [(set_attr "type" "halfmul")])
1457
1458 (define_insn "*mulhhw"
1459   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1460         (mult:SI (ashiftrt:SI
1461                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1462                   (const_int 16))
1463                  (ashiftrt:SI
1464                   (match_operand:SI 2 "gpc_reg_operand" "r")
1465                   (const_int 16))))]
1466   "TARGET_MULHW"
1467   "mulhhw %0,%1,%2"
1468   [(set_attr "type" "halfmul")])
1469
1470 (define_insn "*mulhhwuc"
1471   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1472         (compare:CC (mult:SI (lshiftrt:SI
1473                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1474                               (const_int 16))
1475                              (lshiftrt:SI
1476                               (match_operand:SI 2 "gpc_reg_operand" "r")
1477                               (const_int 16)))
1478                     (const_int 0)))
1479    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1480         (mult:SI (lshiftrt:SI
1481                   (match_dup 1)
1482                   (const_int 16))
1483                  (lshiftrt:SI
1484                   (match_dup 2)
1485                   (const_int 16))))]
1486   "TARGET_MULHW"
1487   "mulhhwu. %0,%1,%2"
1488   [(set_attr "type" "halfmul")])
1489
1490 (define_insn "*mulhhwu"
1491   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1492         (mult:SI (lshiftrt:SI
1493                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1494                   (const_int 16))
1495                  (lshiftrt:SI
1496                   (match_operand:SI 2 "gpc_reg_operand" "r")
1497                   (const_int 16))))]
1498   "TARGET_MULHW"
1499   "mulhhwu %0,%1,%2"
1500   [(set_attr "type" "halfmul")])
1501
1502 (define_insn "*mullhwc"
1503   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1504         (compare:CC (mult:SI (sign_extend:SI
1505                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1506                              (sign_extend:SI
1507                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1508                     (const_int 0)))
1509    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1510         (mult:SI (sign_extend:SI
1511                   (match_dup 1))
1512                  (sign_extend:SI
1513                   (match_dup 2))))]
1514   "TARGET_MULHW"
1515   "mullhw. %0,%1,%2"
1516   [(set_attr "type" "halfmul")])
1517
1518 (define_insn "*mullhw"
1519   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1520         (mult:SI (sign_extend:SI
1521                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1522                  (sign_extend:SI
1523                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1524   "TARGET_MULHW"
1525   "mullhw %0,%1,%2"
1526   [(set_attr "type" "halfmul")])
1527
1528 (define_insn "*mullhwuc"
1529   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1530         (compare:CC (mult:SI (zero_extend:SI
1531                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1532                              (zero_extend:SI
1533                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1534                     (const_int 0)))
1535    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1536         (mult:SI (zero_extend:SI
1537                   (match_dup 1))
1538                  (zero_extend:SI
1539                   (match_dup 2))))]
1540   "TARGET_MULHW"
1541   "mullhwu. %0,%1,%2"
1542   [(set_attr "type" "halfmul")])
1543
1544 (define_insn "*mullhwu"
1545   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1546         (mult:SI (zero_extend:SI
1547                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1548                  (zero_extend:SI
1549                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1550   "TARGET_MULHW"
1551   "mullhwu %0,%1,%2"
1552   [(set_attr "type" "halfmul")])
1553 \f
1554 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1555 (define_insn "dlmzb"
1556   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1557         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1558                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1559                    UNSPEC_DLMZB_CR))
1560    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1561         (unspec:SI [(match_dup 1)
1562                     (match_dup 2)]
1563                    UNSPEC_DLMZB))]
1564   "TARGET_DLMZB"
1565   "dlmzb. %0,%1,%2")
1566
1567 (define_expand "strlensi"
1568   [(set (match_operand:SI 0 "gpc_reg_operand")
1569         (unspec:SI [(match_operand:BLK 1 "general_operand")
1570                     (match_operand:QI 2 "const_int_operand")
1571                     (match_operand 3 "const_int_operand")]
1572                    UNSPEC_DLMZB_STRLEN))
1573    (clobber (match_scratch:CC 4))]
1574   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1575 {
1576   rtx result = operands[0];
1577   rtx src = operands[1];
1578   rtx search_char = operands[2];
1579   rtx align = operands[3];
1580   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1581   rtx loop_label, end_label, mem, cr0, cond;
1582   if (search_char != const0_rtx
1583       || GET_CODE (align) != CONST_INT
1584       || INTVAL (align) < 8)
1585         FAIL;
1586   word1 = gen_reg_rtx (SImode);
1587   word2 = gen_reg_rtx (SImode);
1588   scratch_dlmzb = gen_reg_rtx (SImode);
1589   scratch_string = gen_reg_rtx (Pmode);
1590   loop_label = gen_label_rtx ();
1591   end_label = gen_label_rtx ();
1592   addr = force_reg (Pmode, XEXP (src, 0));
1593   emit_move_insn (scratch_string, addr);
1594   emit_label (loop_label);
1595   mem = change_address (src, SImode, scratch_string);
1596   emit_move_insn (word1, mem);
1597   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1598   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1599   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1600   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1601   emit_jump_insn (gen_rtx_SET (pc_rtx,
1602                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1603                                                      cond,
1604                                                      gen_rtx_LABEL_REF
1605                                                        (VOIDmode,
1606                                                         end_label),
1607                                                      pc_rtx)));
1608   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1609   emit_jump_insn (gen_rtx_SET (pc_rtx,
1610                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1611   emit_barrier ();
1612   emit_label (end_label);
1613   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1614   emit_insn (gen_subsi3 (result, scratch_string, addr));
1615   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1616   DONE;
1617 })
1618 \f
1619 ;; Fixed-point arithmetic insns.
1620
1621 (define_expand "add<mode>3"
1622   [(set (match_operand:SDI 0 "gpc_reg_operand")
1623         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1624                   (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1625   ""
1626 {
1627   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1628     {
1629       rtx lo0 = gen_lowpart (SImode, operands[0]);
1630       rtx lo1 = gen_lowpart (SImode, operands[1]);
1631       rtx lo2 = gen_lowpart (SImode, operands[2]);
1632       rtx hi0 = gen_highpart (SImode, operands[0]);
1633       rtx hi1 = gen_highpart (SImode, operands[1]);
1634       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1635
1636       if (!reg_or_short_operand (lo2, SImode))
1637         lo2 = force_reg (SImode, lo2);
1638       if (!adde_operand (hi2, SImode))
1639         hi2 = force_reg (SImode, hi2);
1640
1641       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1642       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1643       DONE;
1644     }
1645
1646   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1647     {
1648       rtx tmp = ((!can_create_pseudo_p ()
1649                   || rtx_equal_p (operands[0], operands[1]))
1650                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1651
1652       /* Adding a constant to r0 is not a valid insn, so use a different
1653          strategy in that case.  */
1654       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1655         {
1656           if (operands[0] == operands[1])
1657             FAIL;
1658           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1659           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1660           DONE;
1661         }
1662
1663       HOST_WIDE_INT val = INTVAL (operands[2]);
1664       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1665       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1666
1667       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1668         FAIL;
1669
1670       /* The ordering here is important for the prolog expander.
1671          When space is allocated from the stack, adding 'low' first may
1672          produce a temporary deallocation (which would be bad).  */
1673       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1674       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1675       DONE;
1676     }
1677 })
1678
1679 (define_insn "*add<mode>3"
1680   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1681         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1682                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1683   ""
1684   "@
1685    add %0,%1,%2
1686    addi %0,%1,%2
1687    addis %0,%1,%v2"
1688   [(set_attr "type" "add")])
1689
1690 (define_insn "addsi3_high"
1691   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1692         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1693                  (high:SI (match_operand 2 "" ""))))]
1694   "TARGET_MACHO && !TARGET_64BIT"
1695   "addis %0,%1,ha16(%2)"
1696   [(set_attr "type" "add")])
1697
1698 (define_insn_and_split "*add<mode>3_dot"
1699   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1700         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1701                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1702                     (const_int 0)))
1703    (clobber (match_scratch:GPR 0 "=r,r"))]
1704   "<MODE>mode == Pmode"
1705   "@
1706    add. %0,%1,%2
1707    #"
1708   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1709   [(set (match_dup 0)
1710         (plus:GPR (match_dup 1)
1711                  (match_dup 2)))
1712    (set (match_dup 3)
1713         (compare:CC (match_dup 0)
1714                     (const_int 0)))]
1715   ""
1716   [(set_attr "type" "add")
1717    (set_attr "dot" "yes")
1718    (set_attr "length" "4,8")])
1719
1720 (define_insn_and_split "*add<mode>3_dot2"
1721   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1722         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1723                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1724                     (const_int 0)))
1725    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1726         (plus:GPR (match_dup 1)
1727                   (match_dup 2)))]
1728   "<MODE>mode == Pmode"
1729   "@
1730    add. %0,%1,%2
1731    #"
1732   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1733   [(set (match_dup 0)
1734         (plus:GPR (match_dup 1)
1735                   (match_dup 2)))
1736    (set (match_dup 3)
1737         (compare:CC (match_dup 0)
1738                     (const_int 0)))]
1739   ""
1740   [(set_attr "type" "add")
1741    (set_attr "dot" "yes")
1742    (set_attr "length" "4,8")])
1743
1744 (define_insn_and_split "*add<mode>3_imm_dot"
1745   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1746         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1747                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1748                     (const_int 0)))
1749    (clobber (match_scratch:GPR 0 "=r,r"))
1750    (clobber (reg:GPR CA_REGNO))]
1751   "<MODE>mode == Pmode"
1752   "@
1753    addic. %0,%1,%2
1754    #"
1755   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1756   [(set (match_dup 0)
1757         (plus:GPR (match_dup 1)
1758                   (match_dup 2)))
1759    (set (match_dup 3)
1760         (compare:CC (match_dup 0)
1761                     (const_int 0)))]
1762   ""
1763   [(set_attr "type" "add")
1764    (set_attr "dot" "yes")
1765    (set_attr "length" "4,8")])
1766
1767 (define_insn_and_split "*add<mode>3_imm_dot2"
1768   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1769         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1770                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1771                     (const_int 0)))
1772    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1773         (plus:GPR (match_dup 1)
1774                   (match_dup 2)))
1775    (clobber (reg:GPR CA_REGNO))]
1776   "<MODE>mode == Pmode"
1777   "@
1778    addic. %0,%1,%2
1779    #"
1780   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1781   [(set (match_dup 0)
1782         (plus:GPR (match_dup 1)
1783                   (match_dup 2)))
1784    (set (match_dup 3)
1785         (compare:CC (match_dup 0)
1786                     (const_int 0)))]
1787   ""
1788   [(set_attr "type" "add")
1789    (set_attr "dot" "yes")
1790    (set_attr "length" "4,8")])
1791
1792 ;; Split an add that we can't do in one insn into two insns, each of which
1793 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1794 ;; add should be last in case the result gets used in an address.
1795
1796 (define_split
1797   [(set (match_operand:GPR 0 "gpc_reg_operand")
1798         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1799                   (match_operand:GPR 2 "non_add_cint_operand")))]
1800   ""
1801   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1802    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1803 {
1804   HOST_WIDE_INT val = INTVAL (operands[2]);
1805   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1806   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1807
1808   operands[4] = GEN_INT (low);
1809   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1810     operands[3] = GEN_INT (rest);
1811   else if (can_create_pseudo_p ())
1812     {
1813       operands[3] = gen_reg_rtx (DImode);
1814       emit_move_insn (operands[3], operands[2]);
1815       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1816       DONE;
1817     }
1818   else
1819     FAIL;
1820 })
1821
1822
1823 (define_insn "add<mode>3_carry"
1824   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1825         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1826                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1827    (set (reg:P CA_REGNO)
1828         (ltu:P (plus:P (match_dup 1)
1829                        (match_dup 2))
1830                (match_dup 1)))]
1831   ""
1832   "add%I2c %0,%1,%2"
1833   [(set_attr "type" "add")])
1834
1835 (define_insn "*add<mode>3_imm_carry_pos"
1836   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1837         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1838                 (match_operand:P 2 "short_cint_operand" "n")))
1839    (set (reg:P CA_REGNO)
1840         (geu:P (match_dup 1)
1841                (match_operand:P 3 "const_int_operand" "n")))]
1842   "INTVAL (operands[2]) > 0
1843    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1844   "addic %0,%1,%2"
1845   [(set_attr "type" "add")])
1846
1847 (define_insn "*add<mode>3_imm_carry_0"
1848   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1849         (match_operand:P 1 "gpc_reg_operand" "r"))
1850    (set (reg:P CA_REGNO)
1851         (const_int 0))]
1852   ""
1853   "addic %0,%1,0"
1854   [(set_attr "type" "add")])
1855
1856 (define_insn "*add<mode>3_imm_carry_m1"
1857   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1858         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1859                 (const_int -1)))
1860    (set (reg:P CA_REGNO)
1861         (ne:P (match_dup 1)
1862               (const_int 0)))]
1863   ""
1864   "addic %0,%1,-1"
1865   [(set_attr "type" "add")])
1866
1867 (define_insn "*add<mode>3_imm_carry_neg"
1868   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1869         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1870                 (match_operand:P 2 "short_cint_operand" "n")))
1871    (set (reg:P CA_REGNO)
1872         (gtu:P (match_dup 1)
1873                (match_operand:P 3 "const_int_operand" "n")))]
1874   "INTVAL (operands[2]) < 0
1875    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1876   "addic %0,%1,%2"
1877   [(set_attr "type" "add")])
1878
1879
1880 (define_expand "add<mode>3_carry_in"
1881   [(parallel [
1882      (set (match_operand:GPR 0 "gpc_reg_operand")
1883           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1884                               (match_operand:GPR 2 "adde_operand"))
1885                     (reg:GPR CA_REGNO)))
1886      (clobber (reg:GPR CA_REGNO))])]
1887   ""
1888 {
1889   if (operands[2] == const0_rtx)
1890     {
1891       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1892       DONE;
1893     }
1894   if (operands[2] == constm1_rtx)
1895     {
1896       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1897       DONE;
1898     }
1899 })
1900
1901 (define_insn "*add<mode>3_carry_in_internal"
1902   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1903         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1904                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1905                   (reg:GPR CA_REGNO)))
1906    (clobber (reg:GPR CA_REGNO))]
1907   ""
1908   "adde %0,%1,%2"
1909   [(set_attr "type" "add")])
1910
1911 (define_insn "*add<mode>3_carry_in_internal2"
1912   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1913         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1914                             (reg:GPR CA_REGNO))
1915                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
1916    (clobber (reg:GPR CA_REGNO))]
1917   ""
1918   "adde %0,%1,%2"
1919   [(set_attr "type" "add")])
1920
1921 (define_insn "add<mode>3_carry_in_0"
1922   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1923         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1924                   (reg:GPR CA_REGNO)))
1925    (clobber (reg:GPR CA_REGNO))]
1926   ""
1927   "addze %0,%1"
1928   [(set_attr "type" "add")])
1929
1930 (define_insn "add<mode>3_carry_in_m1"
1931   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1932         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1933                             (reg:GPR CA_REGNO))
1934                   (const_int -1)))
1935    (clobber (reg:GPR CA_REGNO))]
1936   ""
1937   "addme %0,%1"
1938   [(set_attr "type" "add")])
1939
1940
1941 (define_expand "one_cmpl<mode>2"
1942   [(set (match_operand:SDI 0 "gpc_reg_operand")
1943         (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1944   ""
1945 {
1946   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1947     {
1948       rs6000_split_logical (operands, NOT, false, false, false);
1949       DONE;
1950     }
1951 })
1952
1953 (define_insn "*one_cmpl<mode>2"
1954   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1955         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1956   ""
1957   "not %0,%1")
1958
1959 (define_insn_and_split "*one_cmpl<mode>2_dot"
1960   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1961         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1962                     (const_int 0)))
1963    (clobber (match_scratch:GPR 0 "=r,r"))]
1964   "<MODE>mode == Pmode"
1965   "@
1966    not. %0,%1
1967    #"
1968   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1969   [(set (match_dup 0)
1970         (not:GPR (match_dup 1)))
1971    (set (match_dup 2)
1972         (compare:CC (match_dup 0)
1973                     (const_int 0)))]
1974   ""
1975   [(set_attr "type" "logical")
1976    (set_attr "dot" "yes")
1977    (set_attr "length" "4,8")])
1978
1979 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1980   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1981         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1982                     (const_int 0)))
1983    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1984         (not:GPR (match_dup 1)))]
1985   "<MODE>mode == Pmode"
1986   "@
1987    not. %0,%1
1988    #"
1989   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1990   [(set (match_dup 0)
1991         (not:GPR (match_dup 1)))
1992    (set (match_dup 2)
1993         (compare:CC (match_dup 0)
1994                     (const_int 0)))]
1995   ""
1996   [(set_attr "type" "logical")
1997    (set_attr "dot" "yes")
1998    (set_attr "length" "4,8")])
1999
2000
2001 (define_expand "sub<mode>3"
2002   [(set (match_operand:SDI 0 "gpc_reg_operand")
2003         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2004                    (match_operand:SDI 2 "gpc_reg_operand")))]
2005   ""
2006 {
2007   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2008     {
2009       rtx lo0 = gen_lowpart (SImode, operands[0]);
2010       rtx lo1 = gen_lowpart (SImode, operands[1]);
2011       rtx lo2 = gen_lowpart (SImode, operands[2]);
2012       rtx hi0 = gen_highpart (SImode, operands[0]);
2013       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2014       rtx hi2 = gen_highpart (SImode, operands[2]);
2015
2016       if (!reg_or_short_operand (lo1, SImode))
2017         lo1 = force_reg (SImode, lo1);
2018       if (!adde_operand (hi1, SImode))
2019         hi1 = force_reg (SImode, hi1);
2020
2021       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2022       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2023       DONE;
2024     }
2025
2026   if (short_cint_operand (operands[1], <MODE>mode))
2027     {
2028       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2029       DONE;
2030     }
2031 })
2032
2033 (define_insn "*subf<mode>3"
2034   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2035         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2036                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2037   ""
2038   "subf %0,%1,%2"
2039   [(set_attr "type" "add")])
2040
2041 (define_insn_and_split "*subf<mode>3_dot"
2042   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2043         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2044                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2045                     (const_int 0)))
2046    (clobber (match_scratch:GPR 0 "=r,r"))]
2047   "<MODE>mode == Pmode"
2048   "@
2049    subf. %0,%1,%2
2050    #"
2051   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2052   [(set (match_dup 0)
2053         (minus:GPR (match_dup 2)
2054                    (match_dup 1)))
2055    (set (match_dup 3)
2056         (compare:CC (match_dup 0)
2057                     (const_int 0)))]
2058   ""
2059   [(set_attr "type" "add")
2060    (set_attr "dot" "yes")
2061    (set_attr "length" "4,8")])
2062
2063 (define_insn_and_split "*subf<mode>3_dot2"
2064   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2065         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2066                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2067                     (const_int 0)))
2068    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2069         (minus:GPR (match_dup 2)
2070                    (match_dup 1)))]
2071   "<MODE>mode == Pmode"
2072   "@
2073    subf. %0,%1,%2
2074    #"
2075   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2076   [(set (match_dup 0)
2077         (minus:GPR (match_dup 2)
2078                    (match_dup 1)))
2079    (set (match_dup 3)
2080         (compare:CC (match_dup 0)
2081                     (const_int 0)))]
2082   ""
2083   [(set_attr "type" "add")
2084    (set_attr "dot" "yes")
2085    (set_attr "length" "4,8")])
2086
2087 (define_insn "subf<mode>3_imm"
2088   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2089         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2090                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2091    (clobber (reg:GPR CA_REGNO))]
2092   ""
2093   "subfic %0,%1,%2"
2094   [(set_attr "type" "add")])
2095
2096 (define_insn_and_split "subf<mode>3_carry_dot2"
2097   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2098         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2099                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2100                     (const_int 0)))
2101    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2102         (minus:P (match_dup 2)
2103                    (match_dup 1)))
2104    (set (reg:P CA_REGNO)
2105         (leu:P (match_dup 1)
2106                (match_dup 2)))]
2107   "<MODE>mode == Pmode"
2108   "@
2109    subfc. %0,%1,%2
2110    #"
2111   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2112   [(parallel [(set (match_dup 0)
2113                    (minus:P (match_dup 2)
2114                             (match_dup 1)))
2115               (set (reg:P CA_REGNO)
2116                    (leu:P (match_dup 1)
2117                           (match_dup 2)))])
2118    (set (match_dup 3)
2119         (compare:CC (match_dup 0)
2120                     (const_int 0)))]
2121   ""
2122   [(set_attr "type" "add")
2123    (set_attr "dot" "yes")
2124    (set_attr "length" "4,8")])
2125
2126 (define_insn "subf<mode>3_carry"
2127   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2128         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2129                  (match_operand:P 1 "gpc_reg_operand" "r")))
2130    (set (reg:P CA_REGNO)
2131         (leu:P (match_dup 1)
2132                (match_dup 2)))]
2133   ""
2134   "subf%I2c %0,%1,%2"
2135   [(set_attr "type" "add")])
2136
2137 (define_insn "*subf<mode>3_imm_carry_0"
2138   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2139         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2140    (set (reg:P CA_REGNO)
2141         (eq:P (match_dup 1)
2142               (const_int 0)))]
2143   ""
2144   "subfic %0,%1,0"
2145   [(set_attr "type" "add")])
2146
2147 (define_insn "*subf<mode>3_imm_carry_m1"
2148   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2149         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2150    (set (reg:P CA_REGNO)
2151         (const_int 1))]
2152   ""
2153   "subfic %0,%1,-1"
2154   [(set_attr "type" "add")])
2155
2156
2157 (define_expand "subf<mode>3_carry_in"
2158   [(parallel [
2159      (set (match_operand:GPR 0 "gpc_reg_operand")
2160           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2161                               (reg:GPR CA_REGNO))
2162                     (match_operand:GPR 2 "adde_operand")))
2163      (clobber (reg:GPR CA_REGNO))])]
2164   ""
2165 {
2166   if (operands[2] == const0_rtx)
2167     {
2168       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2169       DONE;
2170     }
2171   if (operands[2] == constm1_rtx)
2172     {
2173       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2174       DONE;
2175     }
2176 })
2177
2178 (define_insn "*subf<mode>3_carry_in_internal"
2179   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2180         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2181                             (reg:GPR CA_REGNO))
2182                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2183    (clobber (reg:GPR CA_REGNO))]
2184   ""
2185   "subfe %0,%1,%2"
2186   [(set_attr "type" "add")])
2187
2188 (define_insn "subf<mode>3_carry_in_0"
2189   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2190         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2191                   (reg:GPR CA_REGNO)))
2192    (clobber (reg:GPR CA_REGNO))]
2193   ""
2194   "subfze %0,%1"
2195   [(set_attr "type" "add")])
2196
2197 (define_insn "subf<mode>3_carry_in_m1"
2198   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2199         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2200                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2201                   (const_int -2)))
2202    (clobber (reg:GPR CA_REGNO))]
2203   ""
2204   "subfme %0,%1"
2205   [(set_attr "type" "add")])
2206
2207 (define_insn "subf<mode>3_carry_in_xx"
2208   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2209         (plus:GPR (reg:GPR CA_REGNO)
2210                   (const_int -1)))
2211    (clobber (reg:GPR CA_REGNO))]
2212   ""
2213   "subfe %0,%0,%0"
2214   [(set_attr "type" "add")])
2215
2216
2217 (define_insn "neg<mode>2"
2218   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2219         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2220   ""
2221   "neg %0,%1"
2222   [(set_attr "type" "add")])
2223
2224 (define_insn_and_split "*neg<mode>2_dot"
2225   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2226         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2227                     (const_int 0)))
2228    (clobber (match_scratch:GPR 0 "=r,r"))]
2229   "<MODE>mode == Pmode"
2230   "@
2231    neg. %0,%1
2232    #"
2233   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2234   [(set (match_dup 0)
2235         (neg:GPR (match_dup 1)))
2236    (set (match_dup 2)
2237         (compare:CC (match_dup 0)
2238                     (const_int 0)))]
2239   ""
2240   [(set_attr "type" "add")
2241    (set_attr "dot" "yes")
2242    (set_attr "length" "4,8")])
2243
2244 (define_insn_and_split "*neg<mode>2_dot2"
2245   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2246         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2247                     (const_int 0)))
2248    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2249         (neg:GPR (match_dup 1)))]
2250   "<MODE>mode == Pmode"
2251   "@
2252    neg. %0,%1
2253    #"
2254   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2255   [(set (match_dup 0)
2256         (neg:GPR (match_dup 1)))
2257    (set (match_dup 2)
2258         (compare:CC (match_dup 0)
2259                     (const_int 0)))]
2260   ""
2261   [(set_attr "type" "add")
2262    (set_attr "dot" "yes")
2263    (set_attr "length" "4,8")])
2264
2265
2266 (define_insn "clz<mode>2"
2267   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2268         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2269   ""
2270   "cntlz<wd> %0,%1"
2271   [(set_attr "type" "cntlz")])
2272
2273 (define_expand "ctz<mode>2"
2274    [(set (match_operand:GPR 0 "gpc_reg_operand")
2275          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2276   ""
2277 {
2278   if (TARGET_CTZ)
2279     {
2280       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2281       DONE;
2282     }
2283
2284   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2285   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2286   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2287
2288   if (TARGET_POPCNTD)
2289     {
2290       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2291       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2292       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2293       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2294     }
2295   else
2296     {
2297       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2298       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2299       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2300       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2301     }
2302
2303   DONE;
2304 })
2305
2306 (define_insn "ctz<mode>2_hw"
2307   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2308         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2309   "TARGET_CTZ"
2310   "cnttz<wd> %0,%1"
2311   [(set_attr "type" "cntlz")])
2312
2313 (define_expand "ffs<mode>2"
2314   [(set (match_operand:GPR 0 "gpc_reg_operand")
2315         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2316   ""
2317 {
2318   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2319   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2320   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2321   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2322   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2323   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2324   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2325   DONE;
2326 })
2327
2328
2329 (define_expand "popcount<mode>2"
2330   [(set (match_operand:GPR 0 "gpc_reg_operand")
2331         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2332   "TARGET_POPCNTB || TARGET_POPCNTD"
2333 {
2334   rs6000_emit_popcount (operands[0], operands[1]);
2335   DONE;
2336 })
2337
2338 (define_insn "popcntb<mode>2"
2339   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2340         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2341                     UNSPEC_POPCNTB))]
2342   "TARGET_POPCNTB"
2343   "popcntb %0,%1"
2344   [(set_attr "type" "popcnt")])
2345
2346 (define_insn "popcntd<mode>2"
2347   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2348         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2349   "TARGET_POPCNTD"
2350   "popcnt<wd> %0,%1"
2351   [(set_attr "type" "popcnt")])
2352
2353
2354 (define_expand "parity<mode>2"
2355   [(set (match_operand:GPR 0 "gpc_reg_operand")
2356         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2357   "TARGET_POPCNTB"
2358 {
2359   rs6000_emit_parity (operands[0], operands[1]);
2360   DONE;
2361 })
2362
2363 (define_insn "parity<mode>2_cmpb"
2364   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2365         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2366   "TARGET_CMPB && TARGET_POPCNTB"
2367   "prty<wd> %0,%1"
2368   [(set_attr "type" "popcnt")])
2369
2370 (define_insn "cmpb<mode>3"
2371   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2372         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2373                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2374   "TARGET_CMPB"
2375   "cmpb %0,%1,%2"
2376   [(set_attr "type" "cmp")])
2377
2378 ;; Since the hardware zeros the upper part of the register, save generating the
2379 ;; AND immediate if we are converting to unsigned
2380 (define_insn "*bswap<mode>2_extenddi"
2381   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2382         (zero_extend:DI
2383          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2384   "TARGET_POWERPC64"
2385   "l<wd>brx %0,%y1"
2386   [(set_attr "length" "4")
2387    (set_attr "type" "load")])
2388
2389 (define_insn "*bswaphi2_extendsi"
2390   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2391         (zero_extend:SI
2392          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2393   ""
2394   "lhbrx %0,%y1"
2395   [(set_attr "length" "4")
2396    (set_attr "type" "load")])
2397
2398 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2399 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2400 ;; load with byte swap, which can be slower than doing it in the registers.  It
2401 ;; also prevents certain failures with the RELOAD register allocator.
2402
2403 (define_expand "bswap<mode>2"
2404   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2405    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2406   ""
2407 {
2408   rtx dest = operands[0];
2409   rtx src = operands[1];
2410
2411   if (!REG_P (dest) && !REG_P (src))
2412     src = force_reg (<MODE>mode, src);
2413
2414   if (MEM_P (src))
2415     emit_insn (gen_bswap<mode>2_load (dest, src));
2416   else if (MEM_P (dest))
2417     emit_insn (gen_bswap<mode>2_store (dest, src));
2418   else
2419     emit_insn (gen_bswap<mode>2_reg (dest, src));
2420   DONE;
2421 })
2422
2423 (define_insn "bswap<mode>2_load"
2424   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2425         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2426   ""
2427   "l<wd>brx %0,%y1"
2428   [(set_attr "type" "load")])
2429
2430 (define_insn "bswap<mode>2_store"
2431   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2432         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2433   ""
2434   "st<wd>brx %1,%y0"
2435   [(set_attr "type" "store")])
2436
2437 (define_insn_and_split "bswaphi2_reg"
2438   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2439         (bswap:HI
2440          (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2441    (clobber (match_scratch:SI 2 "=&r,X"))]
2442   ""
2443   "@
2444    #
2445    xxbrh %x0,%x1"
2446   "reload_completed && int_reg_operand (operands[0], HImode)"
2447   [(set (match_dup 3)
2448         (and:SI (lshiftrt:SI (match_dup 4)
2449                              (const_int 8))
2450                 (const_int 255)))
2451    (set (match_dup 2)
2452         (and:SI (ashift:SI (match_dup 4)
2453                            (const_int 8))
2454                 (const_int 65280)))             ;; 0xff00
2455    (set (match_dup 3)
2456         (ior:SI (match_dup 3)
2457                 (match_dup 2)))]
2458 {
2459   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2460   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2461 }
2462   [(set_attr "length" "12,4")
2463    (set_attr "type" "*,vecperm")])
2464
2465 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2466 ;; zero_extract insns do not change for -mlittle.
2467 (define_insn_and_split "bswapsi2_reg"
2468   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2469         (bswap:SI
2470          (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2471   ""
2472   "@
2473    #
2474    xxbrw %x0,%x1"
2475   "reload_completed && int_reg_operand (operands[0], SImode)"
2476   [(set (match_dup 0)                                   ; DABC
2477         (rotate:SI (match_dup 1)
2478                    (const_int 24)))
2479    (set (match_dup 0)                                   ; DCBC
2480         (ior:SI (and:SI (ashift:SI (match_dup 1)
2481                                    (const_int 8))
2482                         (const_int 16711680))
2483                 (and:SI (match_dup 0)
2484                         (const_int -16711681))))
2485    (set (match_dup 0)                                   ; DCBA
2486         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2487                                      (const_int 24))
2488                         (const_int 255))
2489                 (and:SI (match_dup 0)
2490                         (const_int -256))))]
2491   ""
2492   [(set_attr "length" "12,4")
2493    (set_attr "type" "*,vecperm")])
2494
2495 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2496 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2497 ;; complex code.
2498
2499 (define_expand "bswapdi2"
2500   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2501                    (bswap:DI
2502                     (match_operand:DI 1 "reg_or_mem_operand")))
2503               (clobber (match_scratch:DI 2))
2504               (clobber (match_scratch:DI 3))])]
2505   ""
2506 {
2507   rtx dest = operands[0];
2508   rtx src = operands[1];
2509
2510   if (!REG_P (dest) && !REG_P (src))
2511     operands[1] = src = force_reg (DImode, src);
2512
2513   if (TARGET_POWERPC64 && TARGET_LDBRX)
2514     {
2515       if (MEM_P (src))
2516         emit_insn (gen_bswapdi2_load (dest, src));
2517       else if (MEM_P (dest))
2518         emit_insn (gen_bswapdi2_store (dest, src));
2519       else if (TARGET_P9_VECTOR)
2520         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2521       else
2522         emit_insn (gen_bswapdi2_reg (dest, src));
2523       DONE;
2524     }
2525
2526   if (!TARGET_POWERPC64)
2527     {
2528       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2529          that uses 64-bit registers needs the same scratch registers as 64-bit
2530          mode.  */
2531       emit_insn (gen_bswapdi2_32bit (dest, src));
2532       DONE;
2533     }
2534 })
2535
2536 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2537 (define_insn "bswapdi2_load"
2538   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2539         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2540   "TARGET_POWERPC64 && TARGET_LDBRX"
2541   "ldbrx %0,%y1"
2542   [(set_attr "type" "load")])
2543
2544 (define_insn "bswapdi2_store"
2545   [(set (match_operand:DI 0 "memory_operand" "=Z")
2546         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2547   "TARGET_POWERPC64 && TARGET_LDBRX"
2548   "stdbrx %1,%y0"
2549   [(set_attr "type" "store")])
2550
2551 (define_insn "bswapdi2_xxbrd"
2552   [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2553         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2554   "TARGET_P9_VECTOR"
2555   "xxbrd %x0,%x1"
2556   [(set_attr "type" "vecperm")])
2557
2558 (define_insn "bswapdi2_reg"
2559   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2560         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2561    (clobber (match_scratch:DI 2 "=&r"))
2562    (clobber (match_scratch:DI 3 "=&r"))]
2563   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2564   "#"
2565   [(set_attr "length" "36")])
2566
2567 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2568 (define_insn "*bswapdi2_64bit"
2569   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2570         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2571    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2572    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2573   "TARGET_POWERPC64 && !TARGET_LDBRX
2574    && (REG_P (operands[0]) || REG_P (operands[1]))
2575    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2576    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2577   "#"
2578   [(set_attr "length" "16,12,36")])
2579
2580 (define_split
2581   [(set (match_operand:DI 0 "gpc_reg_operand")
2582         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2583    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2584    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2585   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2586   [(const_int 0)]
2587 {
2588   rtx dest   = operands[0];
2589   rtx src    = operands[1];
2590   rtx op2    = operands[2];
2591   rtx op3    = operands[3];
2592   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2593                                     BYTES_BIG_ENDIAN ? 4 : 0);
2594   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2595                                      BYTES_BIG_ENDIAN ? 4 : 0);
2596   rtx addr1;
2597   rtx addr2;
2598   rtx word1;
2599   rtx word2;
2600
2601   addr1 = XEXP (src, 0);
2602   if (GET_CODE (addr1) == PLUS)
2603     {
2604       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2605       if (TARGET_AVOID_XFORM)
2606         {
2607           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2608           addr2 = op2;
2609         }
2610       else
2611         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2612     }
2613   else if (TARGET_AVOID_XFORM)
2614     {
2615       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2616       addr2 = op2;
2617     }
2618   else
2619     {
2620       emit_move_insn (op2, GEN_INT (4));
2621       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2622     }
2623
2624   word1 = change_address (src, SImode, addr1);
2625   word2 = change_address (src, SImode, addr2);
2626
2627   if (BYTES_BIG_ENDIAN)
2628     {
2629       emit_insn (gen_bswapsi2 (op3_32, word2));
2630       emit_insn (gen_bswapsi2 (dest_32, word1));
2631     }
2632   else
2633     {
2634       emit_insn (gen_bswapsi2 (op3_32, word1));
2635       emit_insn (gen_bswapsi2 (dest_32, word2));
2636     }
2637
2638   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2639   emit_insn (gen_iordi3 (dest, dest, op3));
2640   DONE;
2641 })
2642
2643 (define_split
2644   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2645         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2646    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2647    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2648   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2649   [(const_int 0)]
2650 {
2651   rtx dest   = operands[0];
2652   rtx src    = operands[1];
2653   rtx op2    = operands[2];
2654   rtx op3    = operands[3];
2655   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2656                                     BYTES_BIG_ENDIAN ? 4 : 0);
2657   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2658                                     BYTES_BIG_ENDIAN ? 4 : 0);
2659   rtx addr1;
2660   rtx addr2;
2661   rtx word1;
2662   rtx word2;
2663
2664   addr1 = XEXP (dest, 0);
2665   if (GET_CODE (addr1) == PLUS)
2666     {
2667       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2668       if (TARGET_AVOID_XFORM)
2669         {
2670           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2671           addr2 = op2;
2672         }
2673       else
2674         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2675     }
2676   else if (TARGET_AVOID_XFORM)
2677     {
2678       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2679       addr2 = op2;
2680     }
2681   else
2682     {
2683       emit_move_insn (op2, GEN_INT (4));
2684       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2685     }
2686
2687   word1 = change_address (dest, SImode, addr1);
2688   word2 = change_address (dest, SImode, addr2);
2689
2690   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2691
2692   if (BYTES_BIG_ENDIAN)
2693     {
2694       emit_insn (gen_bswapsi2 (word1, src_si));
2695       emit_insn (gen_bswapsi2 (word2, op3_si));
2696     }
2697   else
2698     {
2699       emit_insn (gen_bswapsi2 (word2, src_si));
2700       emit_insn (gen_bswapsi2 (word1, op3_si));
2701     }
2702   DONE;
2703 })
2704
2705 (define_split
2706   [(set (match_operand:DI 0 "gpc_reg_operand")
2707         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2708    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2709    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2710   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2711   [(const_int 0)]
2712 {
2713   rtx dest    = operands[0];
2714   rtx src     = operands[1];
2715   rtx op2     = operands[2];
2716   rtx op3     = operands[3];
2717   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2718   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2719   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2720   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2721   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2722
2723   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2724   emit_insn (gen_bswapsi2 (dest_si, src_si));
2725   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2726   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2727   emit_insn (gen_iordi3 (dest, dest, op3));
2728   DONE;
2729 })
2730
2731 (define_insn "bswapdi2_32bit"
2732   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2733         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2734    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2735   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2736   "#"
2737   [(set_attr "length" "16,12,36")])
2738
2739 (define_split
2740   [(set (match_operand:DI 0 "gpc_reg_operand")
2741         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2742    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2743   "!TARGET_POWERPC64 && reload_completed"
2744   [(const_int 0)]
2745 {
2746   rtx dest  = operands[0];
2747   rtx src   = operands[1];
2748   rtx op2   = operands[2];
2749   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2750   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2751   rtx addr1;
2752   rtx addr2;
2753   rtx word1;
2754   rtx word2;
2755
2756   addr1 = XEXP (src, 0);
2757   if (GET_CODE (addr1) == PLUS)
2758     {
2759       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2760       if (TARGET_AVOID_XFORM
2761           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2762         {
2763           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2764           addr2 = op2;
2765         }
2766       else
2767         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2768     }
2769   else if (TARGET_AVOID_XFORM
2770            || REGNO (addr1) == REGNO (dest2))
2771     {
2772       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2773       addr2 = op2;
2774     }
2775   else
2776     {
2777       emit_move_insn (op2, GEN_INT (4));
2778       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2779     }
2780
2781   word1 = change_address (src, SImode, addr1);
2782   word2 = change_address (src, SImode, addr2);
2783
2784   emit_insn (gen_bswapsi2 (dest2, word1));
2785   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2786      thus allowing us to omit an early clobber on the output.  */
2787   emit_insn (gen_bswapsi2 (dest1, word2));
2788   DONE;
2789 })
2790
2791 (define_split
2792   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2793         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2794    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2795   "!TARGET_POWERPC64 && reload_completed"
2796   [(const_int 0)]
2797 {
2798   rtx dest = operands[0];
2799   rtx src  = operands[1];
2800   rtx op2  = operands[2];
2801   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2802   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2803   rtx addr1;
2804   rtx addr2;
2805   rtx word1;
2806   rtx word2;
2807
2808   addr1 = XEXP (dest, 0);
2809   if (GET_CODE (addr1) == PLUS)
2810     {
2811       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2812       if (TARGET_AVOID_XFORM)
2813         {
2814           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2815           addr2 = op2;
2816         }
2817       else
2818         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2819     }
2820   else if (TARGET_AVOID_XFORM)
2821     {
2822       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2823       addr2 = op2;
2824     }
2825   else
2826     {
2827       emit_move_insn (op2, GEN_INT (4));
2828       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2829     }
2830
2831   word1 = change_address (dest, SImode, addr1);
2832   word2 = change_address (dest, SImode, addr2);
2833
2834   emit_insn (gen_bswapsi2 (word2, src1));
2835   emit_insn (gen_bswapsi2 (word1, src2));
2836   DONE;
2837 })
2838
2839 (define_split
2840   [(set (match_operand:DI 0 "gpc_reg_operand")
2841         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2842    (clobber (match_operand:SI 2 ""))]
2843   "!TARGET_POWERPC64 && reload_completed"
2844   [(const_int 0)]
2845 {
2846   rtx dest  = operands[0];
2847   rtx src   = operands[1];
2848   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2849   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2850   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2851   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2852
2853   emit_insn (gen_bswapsi2 (dest1, src2));
2854   emit_insn (gen_bswapsi2 (dest2, src1));
2855   DONE;
2856 })
2857
2858
2859 (define_insn "mul<mode>3"
2860   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2861         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2862                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2863   ""
2864   "@
2865    mull<wd> %0,%1,%2
2866    mulli %0,%1,%2"
2867    [(set_attr "type" "mul")
2868     (set (attr "size")
2869       (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2870                 (const_string "8")
2871              (match_operand:GPR 2 "short_cint_operand")
2872                 (const_string "16")]
2873         (const_string "<bits>")))])
2874
2875 (define_insn_and_split "*mul<mode>3_dot"
2876   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2877         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2878                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2879                     (const_int 0)))
2880    (clobber (match_scratch:GPR 0 "=r,r"))]
2881   "<MODE>mode == Pmode"
2882   "@
2883    mull<wd>. %0,%1,%2
2884    #"
2885   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2886   [(set (match_dup 0)
2887         (mult:GPR (match_dup 1)
2888                   (match_dup 2)))
2889    (set (match_dup 3)
2890         (compare:CC (match_dup 0)
2891                     (const_int 0)))]
2892   ""
2893   [(set_attr "type" "mul")
2894    (set_attr "size" "<bits>")
2895    (set_attr "dot" "yes")
2896    (set_attr "length" "4,8")])
2897
2898 (define_insn_and_split "*mul<mode>3_dot2"
2899   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2900         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2901                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2902                     (const_int 0)))
2903    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2904         (mult:GPR (match_dup 1)
2905                   (match_dup 2)))]
2906   "<MODE>mode == Pmode"
2907   "@
2908    mull<wd>. %0,%1,%2
2909    #"
2910   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2911   [(set (match_dup 0)
2912         (mult:GPR (match_dup 1)
2913                   (match_dup 2)))
2914    (set (match_dup 3)
2915         (compare:CC (match_dup 0)
2916                     (const_int 0)))]
2917   ""
2918   [(set_attr "type" "mul")
2919    (set_attr "size" "<bits>")
2920    (set_attr "dot" "yes")
2921    (set_attr "length" "4,8")])
2922
2923
2924 (define_expand "<su>mul<mode>3_highpart"
2925   [(set (match_operand:GPR 0 "gpc_reg_operand")
2926         (subreg:GPR
2927           (mult:<DMODE> (any_extend:<DMODE>
2928                           (match_operand:GPR 1 "gpc_reg_operand"))
2929                         (any_extend:<DMODE>
2930                           (match_operand:GPR 2 "gpc_reg_operand")))
2931          0))]
2932   ""
2933 {
2934   if (<MODE>mode == SImode && TARGET_POWERPC64)
2935     {
2936       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2937                                              operands[2]));
2938       DONE;
2939     }
2940
2941   if (!WORDS_BIG_ENDIAN)
2942     {
2943       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2944                                                  operands[2]));
2945       DONE;
2946     }
2947 })
2948
2949 (define_insn "*<su>mul<mode>3_highpart"
2950   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2951         (subreg:GPR
2952           (mult:<DMODE> (any_extend:<DMODE>
2953                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2954                         (any_extend:<DMODE>
2955                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2956          0))]
2957   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2958   "mulh<wd><u> %0,%1,%2"
2959   [(set_attr "type" "mul")
2960    (set_attr "size" "<bits>")])
2961
2962 (define_insn "<su>mulsi3_highpart_le"
2963   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2964         (subreg:SI
2965           (mult:DI (any_extend:DI
2966                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2967                    (any_extend:DI
2968                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2969          4))]
2970   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2971   "mulhw<u> %0,%1,%2"
2972   [(set_attr "type" "mul")])
2973
2974 (define_insn "<su>muldi3_highpart_le"
2975   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2976         (subreg:DI
2977           (mult:TI (any_extend:TI
2978                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2979                    (any_extend:TI
2980                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2981          8))]
2982   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2983   "mulhd<u> %0,%1,%2"
2984   [(set_attr "type" "mul")
2985    (set_attr "size" "64")])
2986
2987 (define_insn "<su>mulsi3_highpart_64"
2988   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2989         (truncate:SI
2990           (lshiftrt:DI
2991             (mult:DI (any_extend:DI
2992                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2993                      (any_extend:DI
2994                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2995             (const_int 32))))]
2996   "TARGET_POWERPC64"
2997   "mulhw<u> %0,%1,%2"
2998   [(set_attr "type" "mul")])
2999
3000 (define_expand "<u>mul<mode><dmode>3"
3001   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3002         (mult:<DMODE> (any_extend:<DMODE>
3003                         (match_operand:GPR 1 "gpc_reg_operand"))
3004                       (any_extend:<DMODE>
3005                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3006   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3007 {
3008   rtx l = gen_reg_rtx (<MODE>mode);
3009   rtx h = gen_reg_rtx (<MODE>mode);
3010   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3011   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3012   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3013   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3014   DONE;
3015 })
3016
3017 (define_insn "*maddld4"
3018   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3019         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3020                           (match_operand:DI 2 "gpc_reg_operand" "r"))
3021                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
3022   "TARGET_MADDLD"
3023   "maddld %0,%1,%2,%3"
3024   [(set_attr "type" "mul")])
3025
3026 (define_insn "udiv<mode>3"
3027   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3028         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3029                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3030   ""
3031   "div<wd>u %0,%1,%2"
3032   [(set_attr "type" "div")
3033    (set_attr "size" "<bits>")])
3034
3035
3036 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3037 ;; modulus.  If it isn't a power of two, force operands into register and do
3038 ;; a normal divide.
3039 (define_expand "div<mode>3"
3040   [(set (match_operand:GPR 0 "gpc_reg_operand")
3041         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3042                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3043   ""
3044 {
3045   if (CONST_INT_P (operands[2])
3046       && INTVAL (operands[2]) > 0
3047       && exact_log2 (INTVAL (operands[2])) >= 0)
3048     {
3049       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3050       DONE;
3051     }
3052
3053   operands[2] = force_reg (<MODE>mode, operands[2]);
3054 })
3055
3056 (define_insn "*div<mode>3"
3057   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3058         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3059                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3060   ""
3061   "div<wd> %0,%1,%2"
3062   [(set_attr "type" "div")
3063    (set_attr "size" "<bits>")])
3064
3065 (define_insn "div<mode>3_sra"
3066   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3067         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3068                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3069    (clobber (reg:GPR CA_REGNO))]
3070   ""
3071   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3072   [(set_attr "type" "two")
3073    (set_attr "length" "8")])
3074
3075 (define_insn_and_split "*div<mode>3_sra_dot"
3076   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3077         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3078                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3079                     (const_int 0)))
3080    (clobber (match_scratch:GPR 0 "=r,r"))
3081    (clobber (reg:GPR CA_REGNO))]
3082   "<MODE>mode == Pmode"
3083   "@
3084    sra<wd>i %0,%1,%p2\;addze. %0,%0
3085    #"
3086   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3087   [(parallel [(set (match_dup 0)
3088                    (div:GPR (match_dup 1)
3089                             (match_dup 2)))
3090               (clobber (reg:GPR CA_REGNO))])
3091    (set (match_dup 3)
3092         (compare:CC (match_dup 0)
3093                     (const_int 0)))]
3094   ""
3095   [(set_attr "type" "two")
3096    (set_attr "length" "8,12")
3097    (set_attr "cell_micro" "not")])
3098
3099 (define_insn_and_split "*div<mode>3_sra_dot2"
3100   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3101         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3102                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3103                     (const_int 0)))
3104    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3105         (div:GPR (match_dup 1)
3106                  (match_dup 2)))
3107    (clobber (reg:GPR CA_REGNO))]
3108   "<MODE>mode == Pmode"
3109   "@
3110    sra<wd>i %0,%1,%p2\;addze. %0,%0
3111    #"
3112   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3113   [(parallel [(set (match_dup 0)
3114                    (div:GPR (match_dup 1)
3115                             (match_dup 2)))
3116               (clobber (reg:GPR CA_REGNO))])
3117    (set (match_dup 3)
3118         (compare:CC (match_dup 0)
3119                     (const_int 0)))]
3120   ""
3121   [(set_attr "type" "two")
3122    (set_attr "length" "8,12")
3123    (set_attr "cell_micro" "not")])
3124
3125 (define_expand "mod<mode>3"
3126   [(set (match_operand:GPR 0 "gpc_reg_operand")
3127         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3128                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3129   ""
3130 {
3131   int i;
3132   rtx temp1;
3133   rtx temp2;
3134
3135   if (GET_CODE (operands[2]) != CONST_INT
3136       || INTVAL (operands[2]) <= 0
3137       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3138     {
3139       if (!TARGET_MODULO)
3140         FAIL;
3141
3142       operands[2] = force_reg (<MODE>mode, operands[2]);
3143     }
3144   else
3145     {
3146       temp1 = gen_reg_rtx (<MODE>mode);
3147       temp2 = gen_reg_rtx (<MODE>mode);
3148
3149       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3150       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3151       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3152       DONE;
3153     }
3154 })
3155
3156 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3157 ;; mod, prefer putting the result of mod into a different register
3158 (define_insn "*mod<mode>3"
3159   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3160         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3161                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3162   "TARGET_MODULO"
3163   "mods<wd> %0,%1,%2"
3164   [(set_attr "type" "div")
3165    (set_attr "size" "<bits>")])
3166
3167
3168 (define_insn "umod<mode>3"
3169   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3170         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3171                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3172   "TARGET_MODULO"
3173   "modu<wd> %0,%1,%2"
3174   [(set_attr "type" "div")
3175    (set_attr "size" "<bits>")])
3176
3177 ;; On machines with modulo support, do a combined div/mod the old fashioned
3178 ;; method, since the multiply/subtract is faster than doing the mod instruction
3179 ;; after a divide.
3180
3181 (define_peephole2
3182   [(set (match_operand:GPR 0 "gpc_reg_operand")
3183         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3184                  (match_operand:GPR 2 "gpc_reg_operand")))
3185    (set (match_operand:GPR 3 "gpc_reg_operand")
3186         (mod:GPR (match_dup 1)
3187                  (match_dup 2)))]
3188   "TARGET_MODULO
3189    && ! reg_mentioned_p (operands[0], operands[1])
3190    && ! reg_mentioned_p (operands[0], operands[2])
3191    && ! reg_mentioned_p (operands[3], operands[1])
3192    && ! reg_mentioned_p (operands[3], operands[2])"
3193   [(set (match_dup 0)
3194         (div:GPR (match_dup 1)
3195                  (match_dup 2)))
3196    (set (match_dup 3)
3197         (mult:GPR (match_dup 0)
3198                   (match_dup 2)))
3199    (set (match_dup 3)
3200         (minus:GPR (match_dup 1)
3201                    (match_dup 3)))])
3202
3203 (define_peephole2
3204   [(set (match_operand:GPR 0 "gpc_reg_operand")
3205         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3206                   (match_operand:GPR 2 "gpc_reg_operand")))
3207    (set (match_operand:GPR 3 "gpc_reg_operand")
3208         (umod:GPR (match_dup 1)
3209                   (match_dup 2)))]
3210   "TARGET_MODULO
3211    && ! reg_mentioned_p (operands[0], operands[1])
3212    && ! reg_mentioned_p (operands[0], operands[2])
3213    && ! reg_mentioned_p (operands[3], operands[1])
3214    && ! reg_mentioned_p (operands[3], operands[2])"
3215   [(set (match_dup 0)
3216         (udiv:GPR (match_dup 1)
3217                   (match_dup 2)))
3218    (set (match_dup 3)
3219         (mult:GPR (match_dup 0)
3220                   (match_dup 2)))
3221    (set (match_dup 3)
3222         (minus:GPR (match_dup 1)
3223                    (match_dup 3)))])
3224
3225 \f
3226 ;; Logical instructions
3227 ;; The logical instructions are mostly combined by using match_operator,
3228 ;; but the plain AND insns are somewhat different because there is no
3229 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3230 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3231
3232 (define_expand "and<mode>3"
3233   [(set (match_operand:SDI 0 "gpc_reg_operand")
3234         (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3235                  (match_operand:SDI 2 "reg_or_cint_operand")))]
3236   ""
3237 {
3238   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3239     {
3240       rs6000_split_logical (operands, AND, false, false, false);
3241       DONE;
3242     }
3243
3244   if (CONST_INT_P (operands[2]))
3245     {
3246       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3247         {
3248           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3249           DONE;
3250         }
3251
3252       if (logical_const_operand (operands[2], <MODE>mode))
3253         {
3254           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3255           DONE;
3256         }
3257
3258       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3259         {
3260           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3261           DONE;
3262         }
3263
3264       operands[2] = force_reg (<MODE>mode, operands[2]);
3265     }
3266 })
3267
3268
3269 (define_insn "and<mode>3_imm"
3270   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3271         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3272                  (match_operand:GPR 2 "logical_const_operand" "n")))
3273    (clobber (match_scratch:CC 3 "=x"))]
3274   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3275   "andi%e2. %0,%1,%u2"
3276   [(set_attr "type" "logical")
3277    (set_attr "dot" "yes")])
3278
3279 (define_insn_and_split "*and<mode>3_imm_dot"
3280   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3281         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3282                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3283                     (const_int 0)))
3284    (clobber (match_scratch:GPR 0 "=r,r"))
3285    (clobber (match_scratch:CC 4 "=X,x"))]
3286   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3287    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3288   "@
3289    andi%e2. %0,%1,%u2
3290    #"
3291   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3292   [(parallel [(set (match_dup 0)
3293                    (and:GPR (match_dup 1)
3294                             (match_dup 2)))
3295               (clobber (match_dup 4))])
3296    (set (match_dup 3)
3297         (compare:CC (match_dup 0)
3298                     (const_int 0)))]
3299   ""
3300   [(set_attr "type" "logical")
3301    (set_attr "dot" "yes")
3302    (set_attr "length" "4,8")])
3303
3304 (define_insn_and_split "*and<mode>3_imm_dot2"
3305   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3306         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3307                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3308                     (const_int 0)))
3309    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3310         (and:GPR (match_dup 1)
3311                  (match_dup 2)))
3312    (clobber (match_scratch:CC 4 "=X,x"))]
3313   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3314    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3315   "@
3316    andi%e2. %0,%1,%u2
3317    #"
3318   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3319   [(parallel [(set (match_dup 0)
3320                    (and:GPR (match_dup 1)
3321                             (match_dup 2)))
3322               (clobber (match_dup 4))])
3323    (set (match_dup 3)
3324         (compare:CC (match_dup 0)
3325                     (const_int 0)))]
3326   ""
3327   [(set_attr "type" "logical")
3328    (set_attr "dot" "yes")
3329    (set_attr "length" "4,8")])
3330
3331 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3332   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3333         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3334                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3335                     (const_int 0)))
3336    (clobber (match_scratch:GPR 0 "=r,r"))]
3337   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3338    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3339   "@
3340    andi%e2. %0,%1,%u2
3341    #"
3342   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3343   [(set (match_dup 0)
3344         (and:GPR (match_dup 1)
3345                  (match_dup 2)))
3346    (set (match_dup 3)
3347         (compare:CC (match_dup 0)
3348                     (const_int 0)))]
3349   ""
3350   [(set_attr "type" "logical")
3351    (set_attr "dot" "yes")
3352    (set_attr "length" "4,8")])
3353
3354 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3355   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3356         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3357                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3358                     (const_int 0)))
3359    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3360         (and:GPR (match_dup 1)
3361                  (match_dup 2)))]
3362   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3363    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3364   "@
3365    andi%e2. %0,%1,%u2
3366    #"
3367   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3368   [(set (match_dup 0)
3369         (and:GPR (match_dup 1)
3370                  (match_dup 2)))
3371    (set (match_dup 3)
3372         (compare:CC (match_dup 0)
3373                     (const_int 0)))]
3374   ""
3375   [(set_attr "type" "logical")
3376    (set_attr "dot" "yes")
3377    (set_attr "length" "4,8")])
3378
3379 (define_insn "*and<mode>3_imm_dot_shifted"
3380   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3381         (compare:CC
3382           (and:GPR
3383             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3384                           (match_operand:SI 4 "const_int_operand" "n"))
3385             (match_operand:GPR 2 "const_int_operand" "n"))
3386           (const_int 0)))
3387    (clobber (match_scratch:GPR 0 "=r"))]
3388   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3389                                    << INTVAL (operands[4])),
3390                           DImode)
3391    && (<MODE>mode == Pmode
3392        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3393 {
3394   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3395   return "andi%e2. %0,%1,%u2";
3396 }
3397   [(set_attr "type" "logical")
3398    (set_attr "dot" "yes")])
3399
3400
3401 (define_insn "and<mode>3_mask"
3402   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3403         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3404                  (match_operand:GPR 2 "const_int_operand" "n")))]
3405   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3406 {
3407   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3408 }
3409   [(set_attr "type" "shift")])
3410
3411 (define_insn_and_split "*and<mode>3_mask_dot"
3412   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3413         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3414                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3415                     (const_int 0)))
3416    (clobber (match_scratch:GPR 0 "=r,r"))]
3417   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3418    && !logical_const_operand (operands[2], <MODE>mode)
3419    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3420 {
3421   if (which_alternative == 0)
3422     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3423   else
3424     return "#";
3425 }
3426   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3427   [(set (match_dup 0)
3428         (and:GPR (match_dup 1)
3429                  (match_dup 2)))
3430    (set (match_dup 3)
3431         (compare:CC (match_dup 0)
3432                     (const_int 0)))]
3433   ""
3434   [(set_attr "type" "shift")
3435    (set_attr "dot" "yes")
3436    (set_attr "length" "4,8")])
3437
3438 (define_insn_and_split "*and<mode>3_mask_dot2"
3439   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3440         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3441                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3442                     (const_int 0)))
3443    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3444         (and:GPR (match_dup 1)
3445                  (match_dup 2)))]
3446   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3447    && !logical_const_operand (operands[2], <MODE>mode)
3448    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3449 {
3450   if (which_alternative == 0)
3451     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3452   else
3453     return "#";
3454 }
3455   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3456   [(set (match_dup 0)
3457         (and:GPR (match_dup 1)
3458                  (match_dup 2)))
3459    (set (match_dup 3)
3460         (compare:CC (match_dup 0)
3461                     (const_int 0)))]
3462   ""
3463   [(set_attr "type" "shift")
3464    (set_attr "dot" "yes")
3465    (set_attr "length" "4,8")])
3466
3467
3468 (define_insn_and_split "*and<mode>3_2insn"
3469   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3470         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3471                  (match_operand:GPR 2 "const_int_operand" "n")))]
3472   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3473    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3474         || logical_const_operand (operands[2], <MODE>mode))"
3475   "#"
3476   "&& 1"
3477   [(pc)]
3478 {
3479   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3480   DONE;
3481 }
3482   [(set_attr "type" "shift")
3483    (set_attr "length" "8")])
3484
3485 (define_insn_and_split "*and<mode>3_2insn_dot"
3486   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3487         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3488                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3489                     (const_int 0)))
3490    (clobber (match_scratch:GPR 0 "=r,r"))]
3491   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3492    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3493    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3494         || logical_const_operand (operands[2], <MODE>mode))"
3495   "#"
3496   "&& reload_completed"
3497   [(pc)]
3498 {
3499   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3500   DONE;
3501 }
3502   [(set_attr "type" "shift")
3503    (set_attr "dot" "yes")
3504    (set_attr "length" "8,12")])
3505
3506 (define_insn_and_split "*and<mode>3_2insn_dot2"
3507   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3508         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3509                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3510                     (const_int 0)))
3511    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3512         (and:GPR (match_dup 1)
3513                  (match_dup 2)))]
3514   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3515    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3516    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3517         || logical_const_operand (operands[2], <MODE>mode))"
3518   "#"
3519   "&& reload_completed"
3520   [(pc)]
3521 {
3522   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3523   DONE;
3524 }
3525   [(set_attr "type" "shift")
3526    (set_attr "dot" "yes")
3527    (set_attr "length" "8,12")])
3528
3529
3530 (define_expand "<code><mode>3"
3531   [(set (match_operand:SDI 0 "gpc_reg_operand")
3532         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3533                     (match_operand:SDI 2 "reg_or_cint_operand")))]
3534   ""
3535 {
3536   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3537     {
3538       rs6000_split_logical (operands, <CODE>, false, false, false);
3539       DONE;
3540     }
3541
3542   if (non_logical_cint_operand (operands[2], <MODE>mode))
3543     {
3544       rtx tmp = ((!can_create_pseudo_p ()
3545                   || rtx_equal_p (operands[0], operands[1]))
3546                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3547
3548       HOST_WIDE_INT value = INTVAL (operands[2]);
3549       HOST_WIDE_INT lo = value & 0xffff;
3550       HOST_WIDE_INT hi = value - lo;
3551
3552       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3553       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3554       DONE;
3555     }
3556
3557   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3558     operands[2] = force_reg (<MODE>mode, operands[2]);
3559 })
3560
3561 (define_split
3562   [(set (match_operand:GPR 0 "gpc_reg_operand")
3563         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3564                     (match_operand:GPR 2 "non_logical_cint_operand")))]
3565   ""
3566   [(set (match_dup 3)
3567         (iorxor:GPR (match_dup 1)
3568                     (match_dup 4)))
3569    (set (match_dup 0)
3570         (iorxor:GPR (match_dup 3)
3571                     (match_dup 5)))]
3572 {
3573   operands[3] = ((!can_create_pseudo_p ()
3574                   || rtx_equal_p (operands[0], operands[1]))
3575                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3576
3577   HOST_WIDE_INT value = INTVAL (operands[2]);
3578   HOST_WIDE_INT lo = value & 0xffff;
3579   HOST_WIDE_INT hi = value - lo;
3580
3581   operands[4] = GEN_INT (hi);
3582   operands[5] = GEN_INT (lo);
3583 })
3584
3585 (define_insn "*bool<mode>3_imm"
3586   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3587         (match_operator:GPR 3 "boolean_or_operator"
3588          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3589           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3590   ""
3591   "%q3i%e2 %0,%1,%u2"
3592   [(set_attr "type" "logical")])
3593
3594 (define_insn "*bool<mode>3"
3595   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3596         (match_operator:GPR 3 "boolean_operator"
3597          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3598           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3599   ""
3600   "%q3 %0,%1,%2"
3601   [(set_attr "type" "logical")])
3602
3603 (define_insn_and_split "*bool<mode>3_dot"
3604   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3605         (compare:CC (match_operator:GPR 3 "boolean_operator"
3606          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3607           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3608          (const_int 0)))
3609    (clobber (match_scratch:GPR 0 "=r,r"))]
3610   "<MODE>mode == Pmode"
3611   "@
3612    %q3. %0,%1,%2
3613    #"
3614   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3615   [(set (match_dup 0)
3616         (match_dup 3))
3617    (set (match_dup 4)
3618         (compare:CC (match_dup 0)
3619                     (const_int 0)))]
3620   ""
3621   [(set_attr "type" "logical")
3622    (set_attr "dot" "yes")
3623    (set_attr "length" "4,8")])
3624
3625 (define_insn_and_split "*bool<mode>3_dot2"
3626   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3627         (compare:CC (match_operator:GPR 3 "boolean_operator"
3628          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3629           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3630          (const_int 0)))
3631    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3632         (match_dup 3))]
3633   "<MODE>mode == Pmode"
3634   "@
3635    %q3. %0,%1,%2
3636    #"
3637   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3638   [(set (match_dup 0)
3639         (match_dup 3))
3640    (set (match_dup 4)
3641         (compare:CC (match_dup 0)
3642                     (const_int 0)))]
3643   ""
3644   [(set_attr "type" "logical")
3645    (set_attr "dot" "yes")
3646    (set_attr "length" "4,8")])
3647
3648
3649 (define_insn "*boolc<mode>3"
3650   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3651         (match_operator:GPR 3 "boolean_operator"
3652          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3653           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3654   ""
3655   "%q3 %0,%1,%2"
3656   [(set_attr "type" "logical")])
3657
3658 (define_insn_and_split "*boolc<mode>3_dot"
3659   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3660         (compare:CC (match_operator:GPR 3 "boolean_operator"
3661          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3662           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3663          (const_int 0)))
3664    (clobber (match_scratch:GPR 0 "=r,r"))]
3665   "<MODE>mode == Pmode"
3666   "@
3667    %q3. %0,%1,%2
3668    #"
3669   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3670   [(set (match_dup 0)
3671         (match_dup 3))
3672    (set (match_dup 4)
3673         (compare:CC (match_dup 0)
3674                     (const_int 0)))]
3675   ""
3676   [(set_attr "type" "logical")
3677    (set_attr "dot" "yes")
3678    (set_attr "length" "4,8")])
3679
3680 (define_insn_and_split "*boolc<mode>3_dot2"
3681   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3682         (compare:CC (match_operator:GPR 3 "boolean_operator"
3683          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3684           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3685          (const_int 0)))
3686    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3687         (match_dup 3))]
3688   "<MODE>mode == Pmode"
3689   "@
3690    %q3. %0,%1,%2
3691    #"
3692   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3693   [(set (match_dup 0)
3694         (match_dup 3))
3695    (set (match_dup 4)
3696         (compare:CC (match_dup 0)
3697                     (const_int 0)))]
3698   ""
3699   [(set_attr "type" "logical")
3700    (set_attr "dot" "yes")
3701    (set_attr "length" "4,8")])
3702
3703
3704 (define_insn "*boolcc<mode>3"
3705   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3706         (match_operator:GPR 3 "boolean_operator"
3707          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3708           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3709   ""
3710   "%q3 %0,%1,%2"
3711   [(set_attr "type" "logical")])
3712
3713 (define_insn_and_split "*boolcc<mode>3_dot"
3714   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3715         (compare:CC (match_operator:GPR 3 "boolean_operator"
3716          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3717           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3718          (const_int 0)))
3719    (clobber (match_scratch:GPR 0 "=r,r"))]
3720   "<MODE>mode == Pmode"
3721   "@
3722    %q3. %0,%1,%2
3723    #"
3724   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3725   [(set (match_dup 0)
3726         (match_dup 3))
3727    (set (match_dup 4)
3728         (compare:CC (match_dup 0)
3729                     (const_int 0)))]
3730   ""
3731   [(set_attr "type" "logical")
3732    (set_attr "dot" "yes")
3733    (set_attr "length" "4,8")])
3734
3735 (define_insn_and_split "*boolcc<mode>3_dot2"
3736   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3737         (compare:CC (match_operator:GPR 3 "boolean_operator"
3738          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3739           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3740          (const_int 0)))
3741    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3742         (match_dup 3))]
3743   "<MODE>mode == Pmode"
3744   "@
3745    %q3. %0,%1,%2
3746    #"
3747   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3748   [(set (match_dup 0)
3749         (match_dup 3))
3750    (set (match_dup 4)
3751         (compare:CC (match_dup 0)
3752                     (const_int 0)))]
3753   ""
3754   [(set_attr "type" "logical")
3755    (set_attr "dot" "yes")
3756    (set_attr "length" "4,8")])
3757
3758
3759 ;; TODO: Should have dots of this as well.
3760 (define_insn "*eqv<mode>3"
3761   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3762         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3763                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3764   ""
3765   "eqv %0,%1,%2"
3766   [(set_attr "type" "logical")])
3767 \f
3768 ;; Rotate-and-mask and insert.
3769
3770 (define_insn "*rotl<mode>3_mask"
3771   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3772         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3773                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3774                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3775                  (match_operand:GPR 3 "const_int_operand" "n")))]
3776   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3777 {
3778   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3779 }
3780   [(set_attr "type" "shift")
3781    (set_attr "maybe_var_shift" "yes")])
3782
3783 (define_insn_and_split "*rotl<mode>3_mask_dot"
3784   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3785         (compare:CC
3786           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3787                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3788                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3789                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3790           (const_int 0)))
3791    (clobber (match_scratch:GPR 0 "=r,r"))]
3792   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3793    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3794 {
3795   if (which_alternative == 0)
3796     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3797   else
3798     return "#";
3799 }
3800   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3801   [(set (match_dup 0)
3802         (and:GPR (match_dup 4)
3803                  (match_dup 3)))
3804    (set (match_dup 5)
3805         (compare:CC (match_dup 0)
3806                     (const_int 0)))]
3807   ""
3808   [(set_attr "type" "shift")
3809    (set_attr "maybe_var_shift" "yes")
3810    (set_attr "dot" "yes")
3811    (set_attr "length" "4,8")])
3812
3813 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3814   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3815         (compare:CC
3816           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3817                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3818                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3819                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3820           (const_int 0)))
3821    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3822         (and:GPR (match_dup 4)
3823                  (match_dup 3)))]
3824   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3825    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3826 {
3827   if (which_alternative == 0)
3828     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3829   else
3830     return "#";
3831 }
3832   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3833   [(set (match_dup 0)
3834         (and:GPR (match_dup 4)
3835                  (match_dup 3)))
3836    (set (match_dup 5)
3837         (compare:CC (match_dup 0)
3838                     (const_int 0)))]
3839   ""
3840   [(set_attr "type" "shift")
3841    (set_attr "maybe_var_shift" "yes")
3842    (set_attr "dot" "yes")
3843    (set_attr "length" "4,8")])
3844
3845 ; Special case for less-than-0.  We can do it with just one machine
3846 ; instruction, but the generic optimizers do not realise it is cheap.
3847 (define_insn "*lt0_<mode>di"
3848   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3849         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3850                 (const_int 0)))]
3851   "TARGET_POWERPC64"
3852   "srdi %0,%1,63"
3853   [(set_attr "type" "shift")])
3854
3855 (define_insn "*lt0_<mode>si"
3856   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3857         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3858                 (const_int 0)))]
3859   ""
3860   "rlwinm %0,%1,1,31,31"
3861   [(set_attr "type" "shift")])
3862
3863
3864
3865 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3866 ; both are an AND so are the same precedence).
3867 (define_insn "*rotl<mode>3_insert"
3868   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3869         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3870                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3871                             (match_operand:SI 2 "const_int_operand" "n")])
3872                           (match_operand:GPR 3 "const_int_operand" "n"))
3873                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3874                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3875   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3876    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3877 {
3878   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3879 }
3880   [(set_attr "type" "insert")])
3881 ; FIXME: this needs an attr "size", so that the scheduler can see the
3882 ; difference between rlwimi and rldimi.  We also might want dot forms,
3883 ; but not for rlwimi on POWER4 and similar processors.
3884
3885 (define_insn "*rotl<mode>3_insert_2"
3886   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3887         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3888                           (match_operand:GPR 6 "const_int_operand" "n"))
3889                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3890                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3891                             (match_operand:SI 2 "const_int_operand" "n")])
3892                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3893   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3894    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3895 {
3896   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3897 }
3898   [(set_attr "type" "insert")])
3899
3900 ; There are also some forms without one of the ANDs.
3901 (define_insn "*rotl<mode>3_insert_3"
3902   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3903         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3904                           (match_operand:GPR 4 "const_int_operand" "n"))
3905                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3906                              (match_operand:SI 2 "const_int_operand" "n"))))]
3907   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3908 {
3909   if (<MODE>mode == SImode)
3910     return "rlwimi %0,%1,%h2,0,31-%h2";
3911   else
3912     return "rldimi %0,%1,%H2,0";
3913 }
3914   [(set_attr "type" "insert")])
3915
3916 (define_insn "*rotl<mode>3_insert_4"
3917   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3918         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3919                           (match_operand:GPR 4 "const_int_operand" "n"))
3920                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3921                                (match_operand:SI 2 "const_int_operand" "n"))))]
3922   "<MODE>mode == SImode &&
3923    GET_MODE_PRECISION (<MODE>mode)
3924    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3925 {
3926   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3927                          - INTVAL (operands[2]));
3928   if (<MODE>mode == SImode)
3929     return "rlwimi %0,%1,%h2,32-%h2,31";
3930   else
3931     return "rldimi %0,%1,%H2,64-%H2";
3932 }
3933   [(set_attr "type" "insert")])
3934
3935 (define_insn "*rotlsi3_insert_5"
3936   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3937         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3938                         (match_operand:SI 2 "const_int_operand" "n,n"))
3939                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3940                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3941   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3942    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3943    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3944   "@
3945    rlwimi %0,%3,0,%4
3946    rlwimi %0,%1,0,%2"
3947   [(set_attr "type" "insert")])
3948
3949 (define_insn "*rotldi3_insert_6"
3950   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3951         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3952                         (match_operand:DI 2 "const_int_operand" "n"))
3953                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3954                         (match_operand:DI 4 "const_int_operand" "n"))))]
3955   "exact_log2 (-UINTVAL (operands[2])) > 0
3956    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3957 {
3958   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3959   return "rldimi %0,%3,0,%5";
3960 }
3961   [(set_attr "type" "insert")
3962    (set_attr "size" "64")])
3963
3964 (define_insn "*rotldi3_insert_7"
3965   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3966         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3967                         (match_operand:DI 4 "const_int_operand" "n"))
3968                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3969                         (match_operand:DI 2 "const_int_operand" "n"))))]
3970   "exact_log2 (-UINTVAL (operands[2])) > 0
3971    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3972 {
3973   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3974   return "rldimi %0,%3,0,%5";
3975 }
3976   [(set_attr "type" "insert")
3977    (set_attr "size" "64")])
3978
3979
3980 ; This handles the important case of multiple-precision shifts.  There is
3981 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3982 (define_split
3983   [(set (match_operand:GPR 0 "gpc_reg_operand")
3984         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3985                              (match_operand:SI 3 "const_int_operand"))
3986                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3987                                (match_operand:SI 4 "const_int_operand"))))]
3988   "can_create_pseudo_p ()
3989    && INTVAL (operands[3]) + INTVAL (operands[4])
3990       >= GET_MODE_PRECISION (<MODE>mode)"
3991   [(set (match_dup 5)
3992         (lshiftrt:GPR (match_dup 2)
3993                       (match_dup 4)))
3994    (set (match_dup 0)
3995         (ior:GPR (and:GPR (match_dup 5)
3996                           (match_dup 6))
3997                  (ashift:GPR (match_dup 1)
3998                              (match_dup 3))))]
3999 {
4000   unsigned HOST_WIDE_INT mask = 1;
4001   mask = (mask << INTVAL (operands[3])) - 1;
4002   operands[5] = gen_reg_rtx (<MODE>mode);
4003   operands[6] = GEN_INT (mask);
4004 })
4005
4006 (define_split
4007   [(set (match_operand:GPR 0 "gpc_reg_operand")
4008         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4009                                (match_operand:SI 4 "const_int_operand"))
4010                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4011                              (match_operand:SI 3 "const_int_operand"))))]
4012   "can_create_pseudo_p ()
4013    && INTVAL (operands[3]) + INTVAL (operands[4])
4014       >= GET_MODE_PRECISION (<MODE>mode)"
4015   [(set (match_dup 5)
4016         (lshiftrt:GPR (match_dup 2)
4017                       (match_dup 4)))
4018    (set (match_dup 0)
4019         (ior:GPR (and:GPR (match_dup 5)
4020                           (match_dup 6))
4021                  (ashift:GPR (match_dup 1)
4022                              (match_dup 3))))]
4023 {
4024   unsigned HOST_WIDE_INT mask = 1;
4025   mask = (mask << INTVAL (operands[3])) - 1;
4026   operands[5] = gen_reg_rtx (<MODE>mode);
4027   operands[6] = GEN_INT (mask);
4028 })
4029
4030
4031 ; Another important case is setting some bits to 1; we can do that with
4032 ; an insert instruction, in many cases.
4033 (define_insn_and_split "*ior<mode>_mask"
4034   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4035         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4036                  (match_operand:GPR 2 "const_int_operand" "n")))
4037    (clobber (match_scratch:GPR 3 "=r"))]
4038   "!logical_const_operand (operands[2], <MODE>mode)
4039    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4040   "#"
4041   "&& 1"
4042   [(set (match_dup 3)
4043         (const_int -1))
4044    (set (match_dup 0)
4045         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4046                                       (match_dup 4))
4047                           (match_dup 2))
4048                  (and:GPR (match_dup 1)
4049                           (match_dup 5))))]
4050 {
4051   int nb, ne;
4052   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4053   if (GET_CODE (operands[3]) == SCRATCH)
4054     operands[3] = gen_reg_rtx (<MODE>mode);
4055   operands[4] = GEN_INT (ne);
4056   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4057 }
4058   [(set_attr "type" "two")
4059    (set_attr "length" "8")])
4060
4061
4062 ;; Now the simple shifts.
4063
4064 (define_insn "rotl<mode>3"
4065   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4066         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4067                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4068   ""
4069   "rotl<wd>%I2 %0,%1,%<hH>2"
4070   [(set_attr "type" "shift")
4071    (set_attr "maybe_var_shift" "yes")])
4072
4073 (define_insn "*rotlsi3_64"
4074   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4075         (zero_extend:DI
4076             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4077                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4078   "TARGET_POWERPC64"
4079   "rotlw%I2 %0,%1,%h2"
4080   [(set_attr "type" "shift")
4081    (set_attr "maybe_var_shift" "yes")])
4082
4083 (define_insn_and_split "*rotl<mode>3_dot"
4084   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4085         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4086                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4087                     (const_int 0)))
4088    (clobber (match_scratch:GPR 0 "=r,r"))]
4089   "<MODE>mode == Pmode"
4090   "@
4091    rotl<wd>%I2. %0,%1,%<hH>2
4092    #"
4093   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4094   [(set (match_dup 0)
4095         (rotate:GPR (match_dup 1)
4096                     (match_dup 2)))
4097    (set (match_dup 3)
4098         (compare:CC (match_dup 0)
4099                     (const_int 0)))]
4100   ""
4101   [(set_attr "type" "shift")
4102    (set_attr "maybe_var_shift" "yes")
4103    (set_attr "dot" "yes")
4104    (set_attr "length" "4,8")])
4105
4106 (define_insn_and_split "*rotl<mode>3_dot2"
4107   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4108         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4109                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4110                     (const_int 0)))
4111    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4112         (rotate:GPR (match_dup 1)
4113                     (match_dup 2)))]
4114   "<MODE>mode == Pmode"
4115   "@
4116    rotl<wd>%I2. %0,%1,%<hH>2
4117    #"
4118   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4119   [(set (match_dup 0)
4120         (rotate:GPR (match_dup 1)
4121                     (match_dup 2)))
4122    (set (match_dup 3)
4123         (compare:CC (match_dup 0)
4124                     (const_int 0)))]
4125   ""
4126   [(set_attr "type" "shift")
4127    (set_attr "maybe_var_shift" "yes")
4128    (set_attr "dot" "yes")
4129    (set_attr "length" "4,8")])
4130
4131
4132 (define_insn "ashl<mode>3"
4133   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4134         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4135                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4136   ""
4137   "sl<wd>%I2 %0,%1,%<hH>2"
4138   [(set_attr "type" "shift")
4139    (set_attr "maybe_var_shift" "yes")])
4140
4141 (define_insn "*ashlsi3_64"
4142   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4143         (zero_extend:DI
4144             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4145                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4146   "TARGET_POWERPC64"
4147   "slw%I2 %0,%1,%h2"
4148   [(set_attr "type" "shift")
4149    (set_attr "maybe_var_shift" "yes")])
4150
4151 (define_insn_and_split "*ashl<mode>3_dot"
4152   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4153         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4154                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4155                     (const_int 0)))
4156    (clobber (match_scratch:GPR 0 "=r,r"))]
4157   "<MODE>mode == Pmode"
4158   "@
4159    sl<wd>%I2. %0,%1,%<hH>2
4160    #"
4161   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4162   [(set (match_dup 0)
4163         (ashift:GPR (match_dup 1)
4164                     (match_dup 2)))
4165    (set (match_dup 3)
4166         (compare:CC (match_dup 0)
4167                     (const_int 0)))]
4168   ""
4169   [(set_attr "type" "shift")
4170    (set_attr "maybe_var_shift" "yes")
4171    (set_attr "dot" "yes")
4172    (set_attr "length" "4,8")])
4173
4174 (define_insn_and_split "*ashl<mode>3_dot2"
4175   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4176         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4177                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4178                     (const_int 0)))
4179    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4180         (ashift:GPR (match_dup 1)
4181                     (match_dup 2)))]
4182   "<MODE>mode == Pmode"
4183   "@
4184    sl<wd>%I2. %0,%1,%<hH>2
4185    #"
4186   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4187   [(set (match_dup 0)
4188         (ashift:GPR (match_dup 1)
4189                     (match_dup 2)))
4190    (set (match_dup 3)
4191         (compare:CC (match_dup 0)
4192                     (const_int 0)))]
4193   ""
4194   [(set_attr "type" "shift")
4195    (set_attr "maybe_var_shift" "yes")
4196    (set_attr "dot" "yes")
4197    (set_attr "length" "4,8")])
4198
4199 ;; Pretend we have a memory form of extswsli until register allocation is done
4200 ;; so that we use LWZ to load the value from memory, instead of LWA.
4201 (define_insn_and_split "ashdi3_extswsli"
4202   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4203         (ashift:DI
4204          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4205          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4206   "TARGET_EXTSWSLI"
4207   "@
4208    extswsli %0,%1,%2
4209    #"
4210   "&& reload_completed && MEM_P (operands[1])"
4211   [(set (match_dup 3)
4212         (match_dup 1))
4213    (set (match_dup 0)
4214         (ashift:DI (sign_extend:DI (match_dup 3))
4215                    (match_dup 2)))]
4216 {
4217   operands[3] = gen_lowpart (SImode, operands[0]);
4218 }
4219   [(set_attr "type" "shift")
4220    (set_attr "maybe_var_shift" "no")])
4221
4222
4223 (define_insn_and_split "ashdi3_extswsli_dot"
4224   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4225         (compare:CC
4226          (ashift:DI
4227           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4228           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4229          (const_int 0)))
4230    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4231   "TARGET_EXTSWSLI"
4232   "@
4233    extswsli. %0,%1,%2
4234    #
4235    #
4236    #"
4237   "&& reload_completed
4238    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4239        || memory_operand (operands[1], SImode))"
4240   [(pc)]
4241 {
4242   rtx dest = operands[0];
4243   rtx src = operands[1];
4244   rtx shift = operands[2];
4245   rtx cr = operands[3];
4246   rtx src2;
4247
4248   if (!MEM_P (src))
4249     src2 = src;
4250   else
4251     {
4252       src2 = gen_lowpart (SImode, dest);
4253       emit_move_insn (src2, src);
4254     }
4255
4256   if (REGNO (cr) == CR0_REGNO)
4257     {
4258       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4259       DONE;
4260     }
4261
4262   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4263   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4264   DONE;
4265 }
4266   [(set_attr "type" "shift")
4267    (set_attr "maybe_var_shift" "no")
4268    (set_attr "dot" "yes")
4269    (set_attr "length" "4,8,8,12")])
4270
4271 (define_insn_and_split "ashdi3_extswsli_dot2"
4272   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4273         (compare:CC
4274          (ashift:DI
4275           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4276           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4277          (const_int 0)))
4278    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4279         (ashift:DI (sign_extend:DI (match_dup 1))
4280                    (match_dup 2)))]
4281   "TARGET_EXTSWSLI"
4282   "@
4283    extswsli. %0,%1,%2
4284    #
4285    #
4286    #"
4287   "&& reload_completed
4288    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4289        || memory_operand (operands[1], SImode))"
4290   [(pc)]
4291 {
4292   rtx dest = operands[0];
4293   rtx src = operands[1];
4294   rtx shift = operands[2];
4295   rtx cr = operands[3];
4296   rtx src2;
4297
4298   if (!MEM_P (src))
4299     src2 = src;
4300   else
4301     {
4302       src2 = gen_lowpart (SImode, dest);
4303       emit_move_insn (src2, src);
4304     }
4305
4306   if (REGNO (cr) == CR0_REGNO)
4307     {
4308       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4309       DONE;
4310     }
4311
4312   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4313   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4314   DONE;
4315 }
4316   [(set_attr "type" "shift")
4317    (set_attr "maybe_var_shift" "no")
4318    (set_attr "dot" "yes")
4319    (set_attr "length" "4,8,8,12")])
4320
4321 (define_insn "lshr<mode>3"
4322   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4323         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4324                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4325   ""
4326   "sr<wd>%I2 %0,%1,%<hH>2"
4327   [(set_attr "type" "shift")
4328    (set_attr "maybe_var_shift" "yes")])
4329
4330 (define_insn "*lshrsi3_64"
4331   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4332         (zero_extend:DI
4333             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4334                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4335   "TARGET_POWERPC64"
4336   "srw%I2 %0,%1,%h2"
4337   [(set_attr "type" "shift")
4338    (set_attr "maybe_var_shift" "yes")])
4339
4340 (define_insn_and_split "*lshr<mode>3_dot"
4341   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4342         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4343                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4344                     (const_int 0)))
4345    (clobber (match_scratch:GPR 0 "=r,r"))]
4346   "<MODE>mode == Pmode"
4347   "@
4348    sr<wd>%I2. %0,%1,%<hH>2
4349    #"
4350   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4351   [(set (match_dup 0)
4352         (lshiftrt:GPR (match_dup 1)
4353                       (match_dup 2)))
4354    (set (match_dup 3)
4355         (compare:CC (match_dup 0)
4356                     (const_int 0)))]
4357   ""
4358   [(set_attr "type" "shift")
4359    (set_attr "maybe_var_shift" "yes")
4360    (set_attr "dot" "yes")
4361    (set_attr "length" "4,8")])
4362
4363 (define_insn_and_split "*lshr<mode>3_dot2"
4364   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4365         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4366                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4367                     (const_int 0)))
4368    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4369         (lshiftrt:GPR (match_dup 1)
4370                       (match_dup 2)))]
4371   "<MODE>mode == Pmode"
4372   "@
4373    sr<wd>%I2. %0,%1,%<hH>2
4374    #"
4375   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4376   [(set (match_dup 0)
4377         (lshiftrt:GPR (match_dup 1)
4378                       (match_dup 2)))
4379    (set (match_dup 3)
4380         (compare:CC (match_dup 0)
4381                     (const_int 0)))]
4382   ""
4383   [(set_attr "type" "shift")
4384    (set_attr "maybe_var_shift" "yes")
4385    (set_attr "dot" "yes")
4386    (set_attr "length" "4,8")])
4387
4388
4389 (define_insn "ashr<mode>3"
4390   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4391         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4392                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4393    (clobber (reg:GPR CA_REGNO))]
4394   ""
4395   "sra<wd>%I2 %0,%1,%<hH>2"
4396   [(set_attr "type" "shift")
4397    (set_attr "maybe_var_shift" "yes")])
4398
4399 (define_insn "*ashrsi3_64"
4400   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4401         (sign_extend:DI
4402             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4403                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4404    (clobber (reg:SI CA_REGNO))]
4405   "TARGET_POWERPC64"
4406   "sraw%I2 %0,%1,%h2"
4407   [(set_attr "type" "shift")
4408    (set_attr "maybe_var_shift" "yes")])
4409
4410 (define_insn_and_split "*ashr<mode>3_dot"
4411   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4412         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4413                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4414                     (const_int 0)))
4415    (clobber (match_scratch:GPR 0 "=r,r"))
4416    (clobber (reg:GPR CA_REGNO))]
4417   "<MODE>mode == Pmode"
4418   "@
4419    sra<wd>%I2. %0,%1,%<hH>2
4420    #"
4421   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4422   [(parallel [(set (match_dup 0)
4423                    (ashiftrt:GPR (match_dup 1)
4424                                  (match_dup 2)))
4425               (clobber (reg:GPR CA_REGNO))])
4426    (set (match_dup 3)
4427         (compare:CC (match_dup 0)
4428                     (const_int 0)))]
4429   ""
4430   [(set_attr "type" "shift")
4431    (set_attr "maybe_var_shift" "yes")
4432    (set_attr "dot" "yes")
4433    (set_attr "length" "4,8")])
4434
4435 (define_insn_and_split "*ashr<mode>3_dot2"
4436   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4437         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4438                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4439                     (const_int 0)))
4440    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4441         (ashiftrt:GPR (match_dup 1)
4442                       (match_dup 2)))
4443    (clobber (reg:GPR CA_REGNO))]
4444   "<MODE>mode == Pmode"
4445   "@
4446    sra<wd>%I2. %0,%1,%<hH>2
4447    #"
4448   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4449   [(parallel [(set (match_dup 0)
4450                    (ashiftrt:GPR (match_dup 1)
4451                                  (match_dup 2)))
4452               (clobber (reg:GPR CA_REGNO))])
4453    (set (match_dup 3)
4454         (compare:CC (match_dup 0)
4455                     (const_int 0)))]
4456   ""
4457   [(set_attr "type" "shift")
4458    (set_attr "maybe_var_shift" "yes")
4459    (set_attr "dot" "yes")
4460    (set_attr "length" "4,8")])
4461 \f
4462 ;; Builtins to replace a division to generate FRE reciprocal estimate
4463 ;; instructions and the necessary fixup instructions
4464 (define_expand "recip<mode>3"
4465   [(match_operand:RECIPF 0 "gpc_reg_operand")
4466    (match_operand:RECIPF 1 "gpc_reg_operand")
4467    (match_operand:RECIPF 2 "gpc_reg_operand")]
4468   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4469 {
4470    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4471    DONE;
4472 })
4473
4474 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4475 ;; hardware division.  This is only done before register allocation and with
4476 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4477 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4478 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4479 (define_split
4480   [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4481         (div:RECIPF (match_operand 1 "gpc_reg_operand")
4482                     (match_operand 2 "gpc_reg_operand")))]
4483   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4484    && can_create_pseudo_p () && flag_finite_math_only
4485    && !flag_trapping_math && flag_reciprocal_math"
4486   [(const_int 0)]
4487 {
4488   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4489   DONE;
4490 })
4491
4492 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4493 ;; appropriate fixup.
4494 (define_expand "rsqrt<mode>2"
4495   [(match_operand:RECIPF 0 "gpc_reg_operand")
4496    (match_operand:RECIPF 1 "gpc_reg_operand")]
4497   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4498 {
4499   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4500   DONE;
4501 })
4502 \f
4503 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4504 ;; modes here, and also add in conditional vsx/power8-vector support to access
4505 ;; values in the traditional Altivec registers if the appropriate
4506 ;; -mupper-regs-{df,sf} option is enabled.
4507
4508 (define_expand "abs<mode>2"
4509   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4510         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4511   "TARGET_HARD_FLOAT"
4512   "")
4513
4514 (define_insn "*abs<mode>2_fpr"
4515   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4516         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4517   "TARGET_HARD_FLOAT"
4518   "@
4519    fabs %0,%1
4520    xsabsdp %x0,%x1"
4521   [(set_attr "type" "fpsimple")])
4522
4523 (define_insn "*nabs<mode>2_fpr"
4524   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4525         (neg:SFDF
4526          (abs:SFDF
4527           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4528   "TARGET_HARD_FLOAT"
4529   "@
4530    fnabs %0,%1
4531    xsnabsdp %x0,%x1"
4532   [(set_attr "type" "fpsimple")])
4533
4534 (define_expand "neg<mode>2"
4535   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4536         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4537   "TARGET_HARD_FLOAT"
4538   "")
4539
4540 (define_insn "*neg<mode>2_fpr"
4541   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4542         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4543   "TARGET_HARD_FLOAT"
4544   "@
4545    fneg %0,%1
4546    xsnegdp %x0,%x1"
4547   [(set_attr "type" "fpsimple")])
4548
4549 (define_expand "add<mode>3"
4550   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4551         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4552                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4553   "TARGET_HARD_FLOAT"
4554   "")
4555
4556 (define_insn "*add<mode>3_fpr"
4557   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4558         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4559                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4560   "TARGET_HARD_FLOAT"
4561   "@
4562    fadd<Ftrad> %0,%1,%2
4563    xsadd<Fvsx> %x0,%x1,%x2"
4564   [(set_attr "type" "fp")])
4565
4566 (define_expand "sub<mode>3"
4567   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4568         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4569                     (match_operand:SFDF 2 "gpc_reg_operand")))]
4570   "TARGET_HARD_FLOAT"
4571   "")
4572
4573 (define_insn "*sub<mode>3_fpr"
4574   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4575         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4576                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4577   "TARGET_HARD_FLOAT"
4578   "@
4579    fsub<Ftrad> %0,%1,%2
4580    xssub<Fvsx> %x0,%x1,%x2"
4581   [(set_attr "type" "fp")])
4582
4583 (define_expand "mul<mode>3"
4584   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4585         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4586                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4587   "TARGET_HARD_FLOAT"
4588   "")
4589
4590 (define_insn "*mul<mode>3_fpr"
4591   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4592         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4593                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4594   "TARGET_HARD_FLOAT"
4595   "@
4596    fmul<Ftrad> %0,%1,%2
4597    xsmul<Fvsx> %x0,%x1,%x2"
4598   [(set_attr "type" "dmul")])
4599
4600 (define_expand "div<mode>3"
4601   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4602         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4603                   (match_operand:SFDF 2 "gpc_reg_operand")))]
4604   "TARGET_HARD_FLOAT"
4605 {
4606   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4607       && can_create_pseudo_p () && flag_finite_math_only
4608       && !flag_trapping_math && flag_reciprocal_math)
4609     {
4610       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4611       DONE;
4612     }
4613 })
4614
4615 (define_insn "*div<mode>3_fpr"
4616   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4617         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4618                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4619   "TARGET_HARD_FLOAT"
4620   "@
4621    fdiv<Ftrad> %0,%1,%2
4622    xsdiv<Fvsx> %x0,%x1,%x2"
4623   [(set_attr "type" "<Fs>div")])
4624
4625 (define_insn "*sqrt<mode>2_internal"
4626   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4627         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4628   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4629   "@
4630    fsqrt<Ftrad> %0,%1
4631    xssqrt<Fvsx> %x0,%x1"
4632   [(set_attr "type" "<Fs>sqrt")])
4633
4634 (define_expand "sqrt<mode>2"
4635   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4636         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4637   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4638 {
4639   if (<MODE>mode == SFmode
4640       && TARGET_RECIP_PRECISION
4641       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4642       && !optimize_function_for_size_p (cfun)
4643       && flag_finite_math_only && !flag_trapping_math
4644       && flag_unsafe_math_optimizations)
4645     {
4646       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4647       DONE;
4648     }
4649 })
4650
4651 ;; Floating point reciprocal approximation
4652 (define_insn "fre<Fs>"
4653   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4654         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4655                      UNSPEC_FRES))]
4656   "TARGET_<FFRE>"
4657   "@
4658    fre<Ftrad> %0,%1
4659    xsre<Fvsx> %x0,%x1"
4660   [(set_attr "type" "fp")])
4661
4662 (define_insn "*rsqrt<mode>2"
4663   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4664         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4665                      UNSPEC_RSQRT))]
4666   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4667   "@
4668    frsqrte<Ftrad> %0,%1
4669    xsrsqrte<Fvsx> %x0,%x1"
4670   [(set_attr "type" "fp")])
4671
4672 ;; Floating point comparisons
4673 (define_insn "*cmp<mode>_fpr"
4674   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4675         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4676                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4677   "TARGET_HARD_FLOAT"
4678   "@
4679    fcmpu %0,%1,%2
4680    xscmpudp %0,%x1,%x2"
4681   [(set_attr "type" "fpcompare")])
4682
4683 ;; Floating point conversions
4684 (define_expand "extendsfdf2"
4685   [(set (match_operand:DF 0 "gpc_reg_operand")
4686         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4687   "TARGET_HARD_FLOAT"
4688 {
4689   if (HONOR_SNANS (SFmode))
4690     operands[1] = force_reg (SFmode, operands[1]);
4691 })
4692
4693 (define_insn_and_split "*extendsfdf2_fpr"
4694   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4695         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4696   "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4697   "@
4698    #
4699    fmr %0,%1
4700    lfs%U1%X1 %0,%1
4701    #
4702    xscpsgndp %x0,%x1,%x1
4703    lxsspx %x0,%y1
4704    lxssp %0,%1"
4705   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4706   [(const_int 0)]
4707 {
4708   emit_note (NOTE_INSN_DELETED);
4709   DONE;
4710 }
4711   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4712
4713 (define_insn "*extendsfdf2_snan"
4714   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4715         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4716   "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4717   "@
4718    frsp %0,%1
4719    xsrsp %x0,%x1"
4720   [(set_attr "type" "fp")])
4721
4722 (define_expand "truncdfsf2"
4723   [(set (match_operand:SF 0 "gpc_reg_operand")
4724         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4725   "TARGET_HARD_FLOAT"
4726   "")
4727
4728 (define_insn "*truncdfsf2_fpr"
4729   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4730         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4731   "TARGET_HARD_FLOAT"
4732   "@
4733    frsp %0,%1
4734    xsrsp %x0,%x1"
4735   [(set_attr "type" "fp")])
4736
4737 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4738 ;; builtins.c and optabs.c that are not correct for IBM long double
4739 ;; when little-endian.
4740 (define_expand "signbit<mode>2"
4741   [(set (match_dup 2)
4742         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4743    (set (match_dup 3)
4744         (subreg:DI (match_dup 2) 0))
4745    (set (match_dup 4)
4746         (match_dup 5))
4747    (set (match_operand:SI 0 "gpc_reg_operand")
4748         (match_dup 6))]
4749   "TARGET_HARD_FLOAT
4750    && (!FLOAT128_IEEE_P (<MODE>mode)
4751        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4752 {
4753   if (FLOAT128_IEEE_P (<MODE>mode))
4754     {
4755       rtx dest = operands[0];
4756       rtx src = operands[1];
4757       rtx tmp = gen_reg_rtx (DImode);
4758       rtx dest_di = gen_lowpart (DImode, dest);
4759
4760       if (<MODE>mode == KFmode)
4761         emit_insn (gen_signbitkf2_dm (tmp, src));
4762       else if (<MODE>mode == TFmode)
4763         emit_insn (gen_signbittf2_dm (tmp, src));
4764       else
4765         gcc_unreachable ();
4766
4767       emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4768       DONE;
4769     }
4770   operands[2] = gen_reg_rtx (DFmode);
4771   operands[3] = gen_reg_rtx (DImode);
4772   if (TARGET_POWERPC64)
4773     {
4774       operands[4] = gen_reg_rtx (DImode);
4775       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4776       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4777                                     WORDS_BIG_ENDIAN ? 4 : 0);
4778     }
4779   else
4780     {
4781       operands[4] = gen_reg_rtx (SImode);
4782       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4783                                     WORDS_BIG_ENDIAN ? 0 : 4);
4784       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4785     }
4786 })
4787
4788 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4789 ;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4790 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4791 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4792 ;;
4793 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4794 ;; split allows the post reload phases to eliminate the move, and do the shift
4795 ;; directly with the register that contains the signbit.
4796 (define_insn_and_split "signbit<mode>2_dm"
4797   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4798         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4799                    UNSPEC_SIGNBIT))]
4800   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4801   "@
4802    mfvsrd %0,%x1
4803    #"
4804   "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4805   [(set (match_dup 0)
4806         (match_dup 2))]
4807 {
4808   operands[2] = gen_highpart (DImode, operands[1]);
4809 }
4810  [(set_attr "type" "mftgpr,*")])
4811
4812 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4813 ;; register and then doing a direct move if the value comes from memory.  On
4814 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4815 (define_insn_and_split "*signbit<mode>2_dm_mem"
4816   [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4817         (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4818                    UNSPEC_SIGNBIT))]
4819   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4820   "#"
4821   "&& 1"
4822   [(set (match_dup 0)
4823         (match_dup 2))]
4824 {
4825   rtx dest = operands[0];
4826   rtx src = operands[1];
4827   rtx addr = XEXP (src, 0);
4828
4829   if (WORDS_BIG_ENDIAN)
4830     operands[2] = adjust_address (src, DImode, 0);
4831
4832   else if (REG_P (addr) || SUBREG_P (addr))
4833     operands[2] = adjust_address (src, DImode, 8);
4834
4835   else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4836            && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4837     operands[2] = adjust_address (src, DImode, 8);
4838
4839   else
4840     {
4841       rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4842       emit_insn (gen_rtx_SET (tmp, addr));
4843       operands[2] = change_address (src, DImode,
4844                                     gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4845     }
4846 })
4847
4848 (define_expand "copysign<mode>3"
4849   [(set (match_dup 3)
4850         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4851    (set (match_dup 4)
4852         (neg:SFDF (abs:SFDF (match_dup 1))))
4853    (set (match_operand:SFDF 0 "gpc_reg_operand")
4854         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4855                                (match_dup 5))
4856                          (match_dup 3)
4857                          (match_dup 4)))]
4858   "TARGET_HARD_FLOAT
4859    && ((TARGET_PPC_GFXOPT
4860         && !HONOR_NANS (<MODE>mode)
4861         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4862        || TARGET_CMPB
4863        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4864 {
4865   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4866     {
4867       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4868                                              operands[2]));
4869       DONE;
4870     }
4871
4872    operands[3] = gen_reg_rtx (<MODE>mode);
4873    operands[4] = gen_reg_rtx (<MODE>mode);
4874    operands[5] = CONST0_RTX (<MODE>mode);
4875   })
4876
4877 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4878 ;; compiler from optimizing -0.0
4879 (define_insn "copysign<mode>3_fcpsgn"
4880   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4881         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4882                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4883                      UNSPEC_COPYSIGN))]
4884   "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4885   "@
4886    fcpsgn %0,%2,%1
4887    xscpsgndp %x0,%x2,%x1"
4888   [(set_attr "type" "fpsimple")])
4889
4890 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4891 ;; fsel instruction and some auxiliary computations.  Then we just have a
4892 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4893 ;; combine.
4894 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4895 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4896 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4897 ;; define_splits to make them if made by combine.  On VSX machines we have the
4898 ;; min/max instructions.
4899 ;;
4900 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4901 ;; to allow either DF/SF to use only traditional registers.
4902
4903 (define_expand "s<minmax><mode>3"
4904   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4905         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4906                         (match_operand:SFDF 2 "gpc_reg_operand")))]
4907   "TARGET_MINMAX"
4908 {
4909   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4910   DONE;
4911 })
4912
4913 (define_insn "*s<minmax><mode>3_vsx"
4914   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4915         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4916                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4917   "TARGET_VSX && TARGET_HARD_FLOAT"
4918 {
4919   return (TARGET_P9_MINMAX
4920           ? "xs<minmax>cdp %x0,%x1,%x2"
4921           : "xs<minmax>dp %x0,%x1,%x2");
4922 }
4923   [(set_attr "type" "fp")])
4924
4925 ;; The conditional move instructions allow us to perform max and min operations
4926 ;; even when we don't have the appropriate max/min instruction using the FSEL
4927 ;; instruction.
4928
4929 (define_insn_and_split "*s<minmax><mode>3_fpr"
4930   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4931         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4932                         (match_operand:SFDF 2 "gpc_reg_operand")))]
4933   "!TARGET_VSX && TARGET_MINMAX"
4934   "#"
4935   "&& 1"
4936   [(const_int 0)]
4937 {
4938   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4939   DONE;
4940 })
4941
4942 (define_expand "mov<mode>cc"
4943    [(set (match_operand:GPR 0 "gpc_reg_operand")
4944          (if_then_else:GPR (match_operand 1 "comparison_operator")
4945                            (match_operand:GPR 2 "gpc_reg_operand")
4946                            (match_operand:GPR 3 "gpc_reg_operand")))]
4947   "TARGET_ISEL"
4948 {
4949   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4950     DONE;
4951   else
4952     FAIL;
4953 })
4954
4955 ;; We use the BASE_REGS for the isel input operands because, if rA is
4956 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4957 ;; because we may switch the operands and rB may end up being rA.
4958 ;;
4959 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4960 ;; leave out the mode in operand 4 and use one pattern, but reload can
4961 ;; change the mode underneath our feet and then gets confused trying
4962 ;; to reload the value.
4963 (define_insn "isel_signed_<mode>"
4964   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4965         (if_then_else:GPR
4966          (match_operator 1 "scc_comparison_operator"
4967                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4968                           (const_int 0)])
4969          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4970          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4971   "TARGET_ISEL"
4972   "isel %0,%2,%3,%j1"
4973   [(set_attr "type" "isel")])
4974
4975 (define_insn "isel_unsigned_<mode>"
4976   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4977         (if_then_else:GPR
4978          (match_operator 1 "scc_comparison_operator"
4979                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4980                           (const_int 0)])
4981          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4982          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4983   "TARGET_ISEL"
4984   "isel %0,%2,%3,%j1"
4985   [(set_attr "type" "isel")])
4986
4987 ;; These patterns can be useful for combine; they let combine know that
4988 ;; isel can handle reversed comparisons so long as the operands are
4989 ;; registers.
4990
4991 (define_insn "*isel_reversed_signed_<mode>"
4992   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4993         (if_then_else:GPR
4994          (match_operator 1 "scc_rev_comparison_operator"
4995                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4996                           (const_int 0)])
4997          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
4998          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
4999   "TARGET_ISEL"
5000 {
5001   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5002   return "isel %0,%3,%2,%j1";
5003 }
5004   [(set_attr "type" "isel")])
5005
5006 (define_insn "*isel_reversed_unsigned_<mode>"
5007   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5008         (if_then_else:GPR
5009          (match_operator 1 "scc_rev_comparison_operator"
5010                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5011                           (const_int 0)])
5012          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5013          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5014   "TARGET_ISEL"
5015 {
5016   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5017   return "isel %0,%3,%2,%j1";
5018 }
5019   [(set_attr "type" "isel")])
5020
5021 ;; Floating point conditional move
5022 (define_expand "mov<mode>cc"
5023    [(set (match_operand:SFDF 0 "gpc_reg_operand")
5024          (if_then_else:SFDF (match_operand 1 "comparison_operator")
5025                             (match_operand:SFDF 2 "gpc_reg_operand")
5026                             (match_operand:SFDF 3 "gpc_reg_operand")))]
5027   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5028 {
5029   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5030     DONE;
5031   else
5032     FAIL;
5033 })
5034
5035 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5036   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5037         (if_then_else:SFDF
5038          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5039              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5040          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5041          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5042   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5043   "fsel %0,%1,%2,%3"
5044   [(set_attr "type" "fp")])
5045
5046 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5047   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5048         (if_then_else:SFDF
5049          (match_operator:CCFP 1 "fpmask_comparison_operator"
5050                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5051                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5052          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5053          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5054    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5055   "TARGET_P9_MINMAX"
5056   "#"
5057   ""
5058   [(set (match_dup 6)
5059         (if_then_else:V2DI (match_dup 1)
5060                            (match_dup 7)
5061                            (match_dup 8)))
5062    (set (match_dup 0)
5063         (if_then_else:SFDF (ne (match_dup 6)
5064                                (match_dup 8))
5065                            (match_dup 4)
5066                            (match_dup 5)))]
5067 {
5068   if (GET_CODE (operands[6]) == SCRATCH)
5069     operands[6] = gen_reg_rtx (V2DImode);
5070
5071   operands[7] = CONSTM1_RTX (V2DImode);
5072   operands[8] = CONST0_RTX (V2DImode);
5073 }
5074  [(set_attr "length" "8")
5075   (set_attr "type" "vecperm")])
5076
5077 ;; Handle inverting the fpmask comparisons.
5078 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5079   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5080         (if_then_else:SFDF
5081          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5082                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5083                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5084          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5085          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5086    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5087   "TARGET_P9_MINMAX"
5088   "#"
5089   "&& 1"
5090   [(set (match_dup 6)
5091         (if_then_else:V2DI (match_dup 9)
5092                            (match_dup 7)
5093                            (match_dup 8)))
5094    (set (match_dup 0)
5095         (if_then_else:SFDF (ne (match_dup 6)
5096                                (match_dup 8))
5097                            (match_dup 5)
5098                            (match_dup 4)))]
5099 {
5100   rtx op1 = operands[1];
5101   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5102
5103   if (GET_CODE (operands[6]) == SCRATCH)
5104     operands[6] = gen_reg_rtx (V2DImode);
5105
5106   operands[7] = CONSTM1_RTX (V2DImode);
5107   operands[8] = CONST0_RTX (V2DImode);
5108
5109   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5110 }
5111  [(set_attr "length" "8")
5112   (set_attr "type" "vecperm")])
5113
5114 (define_insn "*fpmask<mode>"
5115   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5116         (if_then_else:V2DI
5117          (match_operator:CCFP 1 "fpmask_comparison_operator"
5118                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5119                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5120          (match_operand:V2DI 4 "all_ones_constant" "")
5121          (match_operand:V2DI 5 "zero_constant" "")))]
5122   "TARGET_P9_MINMAX"
5123   "xscmp%V1dp %x0,%x2,%x3"
5124   [(set_attr "type" "fpcompare")])
5125
5126 (define_insn "*xxsel<mode>"
5127   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5128         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5129                                (match_operand:V2DI 2 "zero_constant" ""))
5130                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5131                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5132   "TARGET_P9_MINMAX"
5133   "xxsel %x0,%x4,%x3,%x1"
5134   [(set_attr "type" "vecmove")])
5135
5136 \f
5137 ;; Conversions to and from floating-point.
5138
5139 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5140 ; don't want to support putting SImode in FPR registers.
5141 (define_insn "lfiwax"
5142   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5143         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5144                    UNSPEC_LFIWAX))]
5145   "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5146   "@
5147    lfiwax %0,%y1
5148    lxsiwax %x0,%y1
5149    mtvsrwa %x0,%1
5150    vextsw2d %0,%1"
5151   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5152
5153 ; This split must be run before register allocation because it allocates the
5154 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5155 ; it earlier to allow for the combiner to merge insns together where it might
5156 ; not be needed and also in case the insns are deleted as dead code.
5157
5158 (define_insn_and_split "floatsi<mode>2_lfiwax"
5159   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5160         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5161    (clobber (match_scratch:DI 2 "=wi"))]
5162   "TARGET_HARD_FLOAT && TARGET_LFIWAX
5163    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5164   "#"
5165   ""
5166   [(pc)]
5167 {
5168   rtx dest = operands[0];
5169   rtx src = operands[1];
5170   rtx tmp;
5171
5172   if (!MEM_P (src) && TARGET_POWERPC64
5173       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5174     tmp = convert_to_mode (DImode, src, false);
5175   else
5176     {
5177       tmp = operands[2];
5178       if (GET_CODE (tmp) == SCRATCH)
5179         tmp = gen_reg_rtx (DImode);
5180       if (MEM_P (src))
5181         {
5182           src = rs6000_address_for_fpconvert (src);
5183           emit_insn (gen_lfiwax (tmp, src));
5184         }
5185       else
5186         {
5187           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5188           emit_move_insn (stack, src);
5189           emit_insn (gen_lfiwax (tmp, stack));
5190         }
5191     }
5192   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5193   DONE;
5194 }
5195   [(set_attr "length" "12")
5196    (set_attr "type" "fpload")])
5197
5198 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5199   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5200         (float:SFDF
5201          (sign_extend:DI
5202           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5203    (clobber (match_scratch:DI 2 "=wi"))]
5204   "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5205   "#"
5206   ""
5207   [(pc)]
5208 {
5209   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5210   if (GET_CODE (operands[2]) == SCRATCH)
5211     operands[2] = gen_reg_rtx (DImode);
5212   if (TARGET_P8_VECTOR)
5213     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5214   else
5215     emit_insn (gen_lfiwax (operands[2], operands[1]));
5216   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5217   DONE;
5218 }
5219   [(set_attr "length" "8")
5220    (set_attr "type" "fpload")])
5221
5222 (define_insn "lfiwzx"
5223   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5224         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5225                    UNSPEC_LFIWZX))]
5226   "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5227   "@
5228    lfiwzx %0,%y1
5229    lxsiwzx %x0,%y1
5230    mtvsrwz %x0,%1
5231    xxextractuw %x0,%x1,4"
5232   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5233
5234 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5235   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5236         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5237    (clobber (match_scratch:DI 2 "=wi"))]
5238   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5239   "#"
5240   ""
5241   [(pc)]
5242 {
5243   rtx dest = operands[0];
5244   rtx src = operands[1];
5245   rtx tmp;
5246
5247   if (!MEM_P (src) && TARGET_POWERPC64
5248       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5249     tmp = convert_to_mode (DImode, src, true);
5250   else
5251     {
5252       tmp = operands[2];
5253       if (GET_CODE (tmp) == SCRATCH)
5254         tmp = gen_reg_rtx (DImode);
5255       if (MEM_P (src))
5256         {
5257           src = rs6000_address_for_fpconvert (src);
5258           emit_insn (gen_lfiwzx (tmp, src));
5259         }
5260       else
5261         {
5262           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5263           emit_move_insn (stack, src);
5264           emit_insn (gen_lfiwzx (tmp, stack));
5265         }
5266     }
5267   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5268   DONE;
5269 }
5270   [(set_attr "length" "12")
5271    (set_attr "type" "fpload")])
5272
5273 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5274   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5275         (unsigned_float:SFDF
5276          (zero_extend:DI
5277           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5278    (clobber (match_scratch:DI 2 "=wi"))]
5279   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5280   "#"
5281   ""
5282   [(pc)]
5283 {
5284   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5285   if (GET_CODE (operands[2]) == SCRATCH)
5286     operands[2] = gen_reg_rtx (DImode);
5287   if (TARGET_P8_VECTOR)
5288     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5289   else
5290     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5291   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5292   DONE;
5293 }
5294   [(set_attr "length" "8")
5295    (set_attr "type" "fpload")])
5296
5297 ; For each of these conversions, there is a define_expand, a define_insn
5298 ; with a '#' template, and a define_split (with C code).  The idea is
5299 ; to allow constant folding with the template of the define_insn,
5300 ; then to have the insns split later (between sched1 and final).
5301
5302 (define_expand "floatsidf2"
5303   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5304                    (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5305               (use (match_dup 2))
5306               (use (match_dup 3))
5307               (clobber (match_dup 4))
5308               (clobber (match_dup 5))
5309               (clobber (match_dup 6))])]
5310   "TARGET_HARD_FLOAT"
5311 {
5312   if (TARGET_LFIWAX && TARGET_FCFID)
5313     {
5314       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5315       DONE;
5316     }
5317   else if (TARGET_FCFID)
5318     {
5319       rtx dreg = operands[1];
5320       if (!REG_P (dreg))
5321         dreg = force_reg (SImode, dreg);
5322       dreg = convert_to_mode (DImode, dreg, false);
5323       emit_insn (gen_floatdidf2 (operands[0], dreg));
5324       DONE;
5325     }
5326
5327   if (!REG_P (operands[1]))
5328     operands[1] = force_reg (SImode, operands[1]);
5329   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5330   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5331   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5332   operands[5] = gen_reg_rtx (DFmode);
5333   operands[6] = gen_reg_rtx (SImode);
5334 })
5335
5336 (define_insn_and_split "*floatsidf2_internal"
5337   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5338         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5339    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5340    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5341    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5342    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5343    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5344   "!TARGET_FCFID && TARGET_HARD_FLOAT"
5345   "#"
5346   ""
5347   [(pc)]
5348 {
5349   rtx lowword, highword;
5350   gcc_assert (MEM_P (operands[4]));
5351   highword = adjust_address (operands[4], SImode, 0);
5352   lowword = adjust_address (operands[4], SImode, 4);
5353   if (! WORDS_BIG_ENDIAN)
5354     std::swap (lowword, highword);
5355
5356   emit_insn (gen_xorsi3 (operands[6], operands[1],
5357                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5358   emit_move_insn (lowword, operands[6]);
5359   emit_move_insn (highword, operands[2]);
5360   emit_move_insn (operands[5], operands[4]);
5361   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5362   DONE;
5363 }
5364   [(set_attr "length" "24")
5365    (set_attr "type" "fp")])
5366
5367 ;; If we don't have a direct conversion to single precision, don't enable this
5368 ;; conversion for 32-bit without fast math, because we don't have the insn to
5369 ;; generate the fixup swizzle to avoid double rounding problems.
5370 (define_expand "floatunssisf2"
5371   [(set (match_operand:SF 0 "gpc_reg_operand")
5372         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5373   "TARGET_HARD_FLOAT
5374    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5375        || (TARGET_FCFID
5376            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5377 {
5378   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5379     {
5380       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5381       DONE;
5382     }
5383   else
5384     {
5385       rtx dreg = operands[1];
5386       if (!REG_P (dreg))
5387         dreg = force_reg (SImode, dreg);
5388       dreg = convert_to_mode (DImode, dreg, true);
5389       emit_insn (gen_floatdisf2 (operands[0], dreg));
5390       DONE;
5391     }
5392 })
5393
5394 (define_expand "floatunssidf2"
5395   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5396                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5397               (use (match_dup 2))
5398               (use (match_dup 3))
5399               (clobber (match_dup 4))
5400               (clobber (match_dup 5))])]
5401   "TARGET_HARD_FLOAT"
5402 {
5403   if (TARGET_LFIWZX && TARGET_FCFID)
5404     {
5405       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5406       DONE;
5407     }
5408   else if (TARGET_FCFID)
5409     {
5410       rtx dreg = operands[1];
5411       if (!REG_P (dreg))
5412         dreg = force_reg (SImode, dreg);
5413       dreg = convert_to_mode (DImode, dreg, true);
5414       emit_insn (gen_floatdidf2 (operands[0], dreg));
5415       DONE;
5416     }
5417
5418   if (!REG_P (operands[1]))
5419     operands[1] = force_reg (SImode, operands[1]);
5420   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5421   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5422   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5423   operands[5] = gen_reg_rtx (DFmode);
5424 })
5425
5426 (define_insn_and_split "*floatunssidf2_internal"
5427   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5428         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5429    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5430    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5431    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5432    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5433   "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5434    && !(TARGET_FCFID && TARGET_POWERPC64)"
5435   "#"
5436   ""
5437   [(pc)]
5438 {
5439   rtx lowword, highword;
5440   gcc_assert (MEM_P (operands[4]));
5441   highword = adjust_address (operands[4], SImode, 0);
5442   lowword = adjust_address (operands[4], SImode, 4);
5443   if (! WORDS_BIG_ENDIAN)
5444     std::swap (lowword, highword);
5445
5446   emit_move_insn (lowword, operands[1]);
5447   emit_move_insn (highword, operands[2]);
5448   emit_move_insn (operands[5], operands[4]);
5449   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5450   DONE;
5451 }
5452   [(set_attr "length" "20")
5453    (set_attr "type" "fp")])
5454
5455 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5456 ;; vector registers.  These insns favor doing the sign/zero extension in
5457 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5458 ;; extension and then a direct move.
5459
5460 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5461   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5462                    (float:FP_ISA3
5463                     (match_operand:QHI 1 "input_operand")))
5464               (clobber (match_scratch:DI 2))
5465               (clobber (match_scratch:DI 3))
5466               (clobber (match_scratch:<QHI:MODE> 4))])]
5467   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5468 {
5469   if (MEM_P (operands[1]))
5470     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5471 })
5472
5473 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5474   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5475         (float:FP_ISA3
5476          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5477    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5478    (clobber (match_scratch:DI 3 "=X,r,X"))
5479    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5480   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5481   "#"
5482   "&& reload_completed"
5483   [(const_int 0)]
5484 {
5485   rtx result = operands[0];
5486   rtx input = operands[1];
5487   rtx di = operands[2];
5488
5489   if (!MEM_P (input))
5490     {
5491       rtx tmp = operands[3];
5492       if (altivec_register_operand (input, <QHI:MODE>mode))
5493         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5494       else if (GET_CODE (tmp) == SCRATCH)
5495         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5496       else
5497         {
5498           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5499           emit_move_insn (di, tmp);
5500         }
5501     }
5502   else
5503     {
5504       rtx tmp = operands[4];
5505       emit_move_insn (tmp, input);
5506       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5507     }
5508
5509   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5510   DONE;
5511 })
5512
5513 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5514   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5515                    (unsigned_float:FP_ISA3
5516                     (match_operand:QHI 1 "input_operand")))
5517               (clobber (match_scratch:DI 2))
5518               (clobber (match_scratch:DI 3))])]
5519   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5520 {
5521   if (MEM_P (operands[1]))
5522     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5523 })
5524
5525 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5526   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5527         (unsigned_float:FP_ISA3
5528          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5529    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5530    (clobber (match_scratch:DI 3 "=X,r,X"))]
5531   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5532   "#"
5533   "&& reload_completed"
5534   [(const_int 0)]
5535 {
5536   rtx result = operands[0];
5537   rtx input = operands[1];
5538   rtx di = operands[2];
5539
5540   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5541     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5542   else
5543     {
5544       rtx tmp = operands[3];
5545       if (GET_CODE (tmp) == SCRATCH)
5546         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5547       else
5548         {
5549           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5550           emit_move_insn (di, tmp);
5551         }
5552     }
5553
5554   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5555   DONE;
5556 })
5557
5558 (define_expand "fix_trunc<mode>si2"
5559   [(set (match_operand:SI 0 "gpc_reg_operand")
5560         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5561   "TARGET_HARD_FLOAT"
5562 {
5563   if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5564     {
5565       rtx src = force_reg (<MODE>mode, operands[1]);
5566
5567       if (TARGET_STFIWX)
5568         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5569       else
5570         {
5571           rtx tmp = gen_reg_rtx (DImode);
5572           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5573           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5574                                                       tmp, stack));
5575         }
5576       DONE;
5577     }
5578 })
5579
5580 ; Like the convert to float patterns, this insn must be split before
5581 ; register allocation so that it can allocate the memory slot if it
5582 ; needed
5583 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5584   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5585         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5586    (clobber (match_scratch:DI 2 "=d"))]
5587   "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5588    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5589   "#"
5590   ""
5591   [(pc)]
5592 {
5593   rtx dest = operands[0];
5594   rtx src = operands[1];
5595   rtx tmp = operands[2];
5596
5597   if (GET_CODE (tmp) == SCRATCH)
5598     tmp = gen_reg_rtx (DImode);
5599
5600   emit_insn (gen_fctiwz_<mode> (tmp, src));
5601   if (MEM_P (dest))
5602     {
5603       dest = rs6000_address_for_fpconvert (dest);
5604       emit_insn (gen_stfiwx (dest, tmp));
5605       DONE;
5606     }
5607   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5608     {
5609       dest = gen_lowpart (DImode, dest);
5610       emit_move_insn (dest, tmp);
5611       DONE;
5612     }
5613   else
5614     {
5615       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5616       emit_insn (gen_stfiwx (stack, tmp));
5617       emit_move_insn (dest, stack);
5618       DONE;
5619     }
5620 }
5621   [(set_attr "length" "12")
5622    (set_attr "type" "fp")])
5623
5624 (define_insn_and_split "fix_trunc<mode>si2_internal"
5625   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5626         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5627    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5628    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5629   "TARGET_HARD_FLOAT
5630    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5631   "#"
5632   ""
5633   [(pc)]
5634 {
5635   rtx lowword;
5636   gcc_assert (MEM_P (operands[3]));
5637   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5638
5639   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5640   emit_move_insn (operands[3], operands[2]);
5641   emit_move_insn (operands[0], lowword);
5642   DONE;
5643 }
5644   [(set_attr "length" "16")
5645    (set_attr "type" "fp")])
5646
5647 (define_expand "fix_trunc<mode>di2"
5648   [(set (match_operand:DI 0 "gpc_reg_operand")
5649         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5650   "TARGET_HARD_FLOAT && TARGET_FCFID"
5651   "")
5652
5653 (define_insn "*fix_trunc<mode>di2_fctidz"
5654   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5655         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5656   "TARGET_HARD_FLOAT && TARGET_FCFID"
5657   "@
5658    fctidz %0,%1
5659    xscvdpsxds %x0,%x1"
5660   [(set_attr "type" "fp")])
5661
5662 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5663 ;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5664 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5665 ;; values can go in VSX registers.  Keeping the direct move part through
5666 ;; register allocation prevents the register allocator from doing a direct move
5667 ;; of the SImode value to a GPR, and then a store/load.
5668 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5669   [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5670         (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5671    (clobber (match_scratch:SI 2 "=X,X,wi"))]
5672   "TARGET_DIRECT_MOVE"
5673   "@
5674    fctiw<u>z %0,%1
5675    xscvdp<su>xws %x0,%x1
5676    #"
5677   "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5678   [(set (match_dup 2)
5679         (any_fix:SI (match_dup 1)))
5680    (set (match_dup 3)
5681         (match_dup 2))]
5682 {
5683   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5684 }
5685   [(set_attr "length" "4,4,8")
5686    (set_attr "type" "fp")])
5687
5688 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5689   [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5690         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5691   "TARGET_DIRECT_MOVE"
5692   "@
5693    fctiw<u>z %0,%1
5694    xscvdp<su>xws %x0,%x1"
5695   [(set_attr "type" "fp")])
5696
5697 ;; Keep the convert and store together through register allocation to prevent
5698 ;; the register allocator from getting clever and doing a direct move to a GPR
5699 ;; and then store for reg+offset stores.
5700 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5701   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5702         (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5703    (clobber (match_scratch:SI 2 "=wa"))]
5704     "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5705   "#"
5706   "&& reload_completed"
5707   [(set (match_dup 2)
5708         (any_fix:SI (match_dup 1)))
5709    (set (match_dup 0)
5710         (match_dup 3))]
5711 {
5712   operands[3] = (<QHSI:MODE>mode == SImode
5713                  ? operands[2]
5714                  : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5715 })
5716
5717 (define_expand "fixuns_trunc<mode>si2"
5718   [(set (match_operand:SI 0 "gpc_reg_operand")
5719         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5720   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5721 {
5722   if (!TARGET_P8_VECTOR)
5723     {
5724       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5725       DONE;
5726     }
5727 })
5728
5729 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5730   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5731         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5732    (clobber (match_scratch:DI 2 "=d"))]
5733   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5734    && TARGET_STFIWX && can_create_pseudo_p ()
5735    && !TARGET_P8_VECTOR"
5736   "#"
5737   ""
5738   [(pc)]
5739 {
5740   rtx dest = operands[0];
5741   rtx src = operands[1];
5742   rtx tmp = operands[2];
5743
5744   if (GET_CODE (tmp) == SCRATCH)
5745     tmp = gen_reg_rtx (DImode);
5746
5747   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5748   if (MEM_P (dest))
5749     {
5750       dest = rs6000_address_for_fpconvert (dest);
5751       emit_insn (gen_stfiwx (dest, tmp));
5752       DONE;
5753     }
5754   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5755     {
5756       dest = gen_lowpart (DImode, dest);
5757       emit_move_insn (dest, tmp);
5758       DONE;
5759     }
5760   else
5761     {
5762       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5763       emit_insn (gen_stfiwx (stack, tmp));
5764       emit_move_insn (dest, stack);
5765       DONE;
5766     }
5767 }
5768   [(set_attr "length" "12")
5769    (set_attr "type" "fp")])
5770
5771 (define_insn "fixuns_trunc<mode>di2"
5772   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5773         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5774   "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5775   "@
5776    fctiduz %0,%1
5777    xscvdpuxds %x0,%x1"
5778   [(set_attr "type" "fp")])
5779
5780 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5781 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5782 ;; because the first makes it clear that operand 0 is not live
5783 ;; before the instruction.
5784 (define_insn "fctiwz_<mode>"
5785   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5786         (unspec:DI [(fix:SI
5787                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5788                    UNSPEC_FCTIWZ))]
5789   "TARGET_HARD_FLOAT"
5790   "@
5791    fctiwz %0,%1
5792    xscvdpsxws %x0,%x1"
5793   [(set_attr "type" "fp")])
5794
5795 (define_insn "fctiwuz_<mode>"
5796   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5797         (unspec:DI [(unsigned_fix:SI
5798                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5799                    UNSPEC_FCTIWUZ))]
5800   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
5801   "@
5802    fctiwuz %0,%1
5803    xscvdpuxws %x0,%x1"
5804   [(set_attr "type" "fp")])
5805
5806 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5807 ;; since the friz instruction does not truncate the value if the floating
5808 ;; point value is < LONG_MIN or > LONG_MAX.
5809 (define_insn "*friz"
5810   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5811         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5812   "TARGET_HARD_FLOAT && TARGET_FPRND
5813    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5814   "@
5815    friz %0,%1
5816    xsrdpiz %x0,%x1"
5817   [(set_attr "type" "fp")])
5818
5819 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5820 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5821 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5822 ;; extend it, store it back on the stack from the GPR, load it back into the
5823 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5824 ;; disable using store and load to sign/zero extend the value.
5825 (define_insn_and_split "*round32<mode>2_fprs"
5826   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5827         (float:SFDF
5828          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5829    (clobber (match_scratch:DI 2 "=d"))
5830    (clobber (match_scratch:DI 3 "=d"))]
5831   "TARGET_HARD_FLOAT
5832    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5833    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5834   "#"
5835   ""
5836   [(pc)]
5837 {
5838   rtx dest = operands[0];
5839   rtx src = operands[1];
5840   rtx tmp1 = operands[2];
5841   rtx tmp2 = operands[3];
5842   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5843
5844   if (GET_CODE (tmp1) == SCRATCH)
5845     tmp1 = gen_reg_rtx (DImode);
5846   if (GET_CODE (tmp2) == SCRATCH)
5847     tmp2 = gen_reg_rtx (DImode);
5848
5849   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5850   emit_insn (gen_stfiwx (stack, tmp1));
5851   emit_insn (gen_lfiwax (tmp2, stack));
5852   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5853   DONE;
5854 }
5855   [(set_attr "type" "fpload")
5856    (set_attr "length" "16")])
5857
5858 (define_insn_and_split "*roundu32<mode>2_fprs"
5859   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5860         (unsigned_float:SFDF
5861          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5862    (clobber (match_scratch:DI 2 "=d"))
5863    (clobber (match_scratch:DI 3 "=d"))]
5864   "TARGET_HARD_FLOAT
5865    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5866    && can_create_pseudo_p ()"
5867   "#"
5868   ""
5869   [(pc)]
5870 {
5871   rtx dest = operands[0];
5872   rtx src = operands[1];
5873   rtx tmp1 = operands[2];
5874   rtx tmp2 = operands[3];
5875   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5876
5877   if (GET_CODE (tmp1) == SCRATCH)
5878     tmp1 = gen_reg_rtx (DImode);
5879   if (GET_CODE (tmp2) == SCRATCH)
5880     tmp2 = gen_reg_rtx (DImode);
5881
5882   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5883   emit_insn (gen_stfiwx (stack, tmp1));
5884   emit_insn (gen_lfiwzx (tmp2, stack));
5885   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5886   DONE;
5887 }
5888   [(set_attr "type" "fpload")
5889    (set_attr "length" "16")])
5890
5891 ;; No VSX equivalent to fctid
5892 (define_insn "lrint<mode>di2"
5893   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5894         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5895                    UNSPEC_FCTID))]
5896   "TARGET_HARD_FLOAT && TARGET_FPRND"
5897   "fctid %0,%1"
5898   [(set_attr "type" "fp")])
5899
5900 (define_insn "btrunc<mode>2"
5901   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5902         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5903                      UNSPEC_FRIZ))]
5904   "TARGET_HARD_FLOAT && TARGET_FPRND"
5905   "@
5906    friz %0,%1
5907    xsrdpiz %x0,%x1"
5908   [(set_attr "type" "fp")])
5909
5910 (define_insn "ceil<mode>2"
5911   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5912         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5913                      UNSPEC_FRIP))]
5914   "TARGET_HARD_FLOAT && TARGET_FPRND"
5915   "@
5916    frip %0,%1
5917    xsrdpip %x0,%x1"
5918   [(set_attr "type" "fp")])
5919
5920 (define_insn "floor<mode>2"
5921   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5922         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5923                      UNSPEC_FRIM))]
5924   "TARGET_HARD_FLOAT && TARGET_FPRND"
5925   "@
5926    frim %0,%1
5927    xsrdpim %x0,%x1"
5928   [(set_attr "type" "fp")])
5929
5930 ;; No VSX equivalent to frin
5931 (define_insn "round<mode>2"
5932   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5933         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5934                      UNSPEC_FRIN))]
5935   "TARGET_HARD_FLOAT && TARGET_FPRND"
5936   "frin %0,%1"
5937   [(set_attr "type" "fp")])
5938
5939 (define_insn "*xsrdpi<mode>2"
5940   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5941         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5942                      UNSPEC_XSRDPI))]
5943   "TARGET_HARD_FLOAT && TARGET_VSX"
5944   "xsrdpi %x0,%x1"
5945   [(set_attr "type" "fp")])
5946
5947 (define_expand "lround<mode>di2"
5948   [(set (match_dup 2)
5949         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
5950                      UNSPEC_XSRDPI))
5951    (set (match_operand:DI 0 "gpc_reg_operand")
5952         (unspec:DI [(match_dup 2)]
5953                    UNSPEC_FCTID))]
5954   "TARGET_HARD_FLOAT && TARGET_VSX"
5955 {
5956   operands[2] = gen_reg_rtx (<MODE>mode);
5957 })
5958
5959 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5960 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5961 ; is only generated for Power8 or later.
5962 (define_insn "stfiwx"
5963   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5964         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5965                    UNSPEC_STFIWX))]
5966   "TARGET_PPC_GFXOPT"
5967   "@
5968    stfiwx %1,%y0
5969    stxsiwx %x1,%y0"
5970   [(set_attr "type" "fpstore")])
5971
5972 ;; If we don't have a direct conversion to single precision, don't enable this
5973 ;; conversion for 32-bit without fast math, because we don't have the insn to
5974 ;; generate the fixup swizzle to avoid double rounding problems.
5975 (define_expand "floatsisf2"
5976   [(set (match_operand:SF 0 "gpc_reg_operand")
5977         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5978   "TARGET_HARD_FLOAT
5979    && ((TARGET_FCFIDS && TARGET_LFIWAX)
5980        || (TARGET_FCFID
5981            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5982 {
5983   if (TARGET_FCFIDS && TARGET_LFIWAX)
5984     {
5985       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5986       DONE;
5987     }
5988   else if (TARGET_FCFID && TARGET_LFIWAX)
5989     {
5990       rtx dfreg = gen_reg_rtx (DFmode);
5991       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5992       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5993       DONE;
5994     }
5995   else
5996     {
5997       rtx dreg = operands[1];
5998       if (!REG_P (dreg))
5999         dreg = force_reg (SImode, dreg);
6000       dreg = convert_to_mode (DImode, dreg, false);
6001       emit_insn (gen_floatdisf2 (operands[0], dreg));
6002       DONE;
6003     }
6004 })
6005
6006 (define_insn "floatdidf2"
6007   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6008         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6009   "TARGET_FCFID && TARGET_HARD_FLOAT"
6010   "@
6011    fcfid %0,%1
6012    xscvsxddp %x0,%x1"
6013   [(set_attr "type" "fp")])
6014
6015 ; Allow the combiner to merge source memory operands to the conversion so that
6016 ; the optimizer/register allocator doesn't try to load the value too early in a
6017 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6018 ; hit.  We will split after reload to avoid the trip through the GPRs
6019
6020 (define_insn_and_split "*floatdidf2_mem"
6021   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6022         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6023    (clobber (match_scratch:DI 2 "=d,wi"))]
6024   "TARGET_HARD_FLOAT && TARGET_FCFID"
6025   "#"
6026   "&& reload_completed"
6027   [(set (match_dup 2) (match_dup 1))
6028    (set (match_dup 0) (float:DF (match_dup 2)))]
6029   ""
6030   [(set_attr "length" "8")
6031    (set_attr "type" "fpload")])
6032
6033 (define_expand "floatunsdidf2"
6034   [(set (match_operand:DF 0 "gpc_reg_operand")
6035         (unsigned_float:DF
6036          (match_operand:DI 1 "gpc_reg_operand")))]
6037   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6038   "")
6039
6040 (define_insn "*floatunsdidf2_fcfidu"
6041   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6042         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6043   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6044   "@
6045    fcfidu %0,%1
6046    xscvuxddp %x0,%x1"
6047   [(set_attr "type" "fp")
6048    (set_attr "length" "4")])
6049
6050 (define_insn_and_split "*floatunsdidf2_mem"
6051   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6052         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6053    (clobber (match_scratch:DI 2 "=d,wi"))]
6054   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6055   "#"
6056   "&& reload_completed"
6057   [(set (match_dup 2) (match_dup 1))
6058    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6059   ""
6060   [(set_attr "length" "8")
6061    (set_attr "type" "fpload")])
6062
6063 (define_expand "floatdisf2"
6064   [(set (match_operand:SF 0 "gpc_reg_operand")
6065         (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6066   "TARGET_FCFID && TARGET_HARD_FLOAT
6067    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6068 {
6069   if (!TARGET_FCFIDS)
6070     {
6071       rtx val = operands[1];
6072       if (!flag_unsafe_math_optimizations)
6073         {
6074           rtx label = gen_label_rtx ();
6075           val = gen_reg_rtx (DImode);
6076           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6077           emit_label (label);
6078         }
6079       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6080       DONE;
6081     }
6082 })
6083
6084 (define_insn "floatdisf2_fcfids"
6085   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6086         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6087   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6088   "@
6089    fcfids %0,%1
6090    xscvsxdsp %x0,%x1"
6091   [(set_attr "type" "fp")])
6092
6093 (define_insn_and_split "*floatdisf2_mem"
6094   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6095         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6096    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6097   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6098   "#"
6099   "&& reload_completed"
6100   [(pc)]
6101 {
6102   emit_move_insn (operands[2], operands[1]);
6103   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6104   DONE;
6105 }
6106   [(set_attr "length" "8")])
6107
6108 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6109 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6110 ;; from double rounding.
6111 ;; Instead of creating a new cpu type for two FP operations, just use fp
6112 (define_insn_and_split "floatdisf2_internal1"
6113   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6114         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6115    (clobber (match_scratch:DF 2 "=d"))]
6116   "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6117   "#"
6118   "&& reload_completed"
6119   [(set (match_dup 2)
6120         (float:DF (match_dup 1)))
6121    (set (match_dup 0)
6122         (float_truncate:SF (match_dup 2)))]
6123   ""
6124   [(set_attr "length" "8")
6125    (set_attr "type" "fp")])
6126
6127 ;; Twiddles bits to avoid double rounding.
6128 ;; Bits that might be truncated when converting to DFmode are replaced
6129 ;; by a bit that won't be lost at that stage, but is below the SFmode
6130 ;; rounding position.
6131 (define_expand "floatdisf2_internal2"
6132   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6133                                               (const_int 53)))
6134               (clobber (reg:DI CA_REGNO))])
6135    (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6136                                         (const_int 2047)))
6137    (set (match_dup 3) (plus:DI (match_dup 3)
6138                                (const_int 1)))
6139    (set (match_dup 0) (plus:DI (match_dup 0)
6140                                (const_int 2047)))
6141    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6142                                      (const_int 2)))
6143    (set (match_dup 0) (ior:DI (match_dup 0)
6144                               (match_dup 1)))
6145    (set (match_dup 0) (and:DI (match_dup 0)
6146                               (const_int -2048)))
6147    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6148                            (label_ref (match_operand:DI 2 ""))
6149                            (pc)))
6150    (set (match_dup 0) (match_dup 1))]
6151   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6152 {
6153   operands[3] = gen_reg_rtx (DImode);
6154   operands[4] = gen_reg_rtx (CCUNSmode);
6155 })
6156
6157 (define_expand "floatunsdisf2"
6158   [(set (match_operand:SF 0 "gpc_reg_operand")
6159         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6160   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6161   "")
6162
6163 (define_insn "floatunsdisf2_fcfidus"
6164   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6165         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6166   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6167   "@
6168    fcfidus %0,%1
6169    xscvuxdsp %x0,%x1"
6170   [(set_attr "type" "fp")])
6171
6172 (define_insn_and_split "*floatunsdisf2_mem"
6173   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6174         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6175    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6176   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6177   "#"
6178   "&& reload_completed"
6179   [(pc)]
6180 {
6181   emit_move_insn (operands[2], operands[1]);
6182   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6183   DONE;
6184 }
6185   [(set_attr "length" "8")
6186    (set_attr "type" "fpload")])
6187 \f
6188 ;; Define the TImode operations that can be done in a small number
6189 ;; of instructions.  The & constraints are to prevent the register
6190 ;; allocator from allocating registers that overlap with the inputs
6191 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6192 ;; also allow for the output being the same as one of the inputs.
6193
6194 (define_expand "addti3"
6195   [(set (match_operand:TI 0 "gpc_reg_operand")
6196         (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6197                  (match_operand:TI 2 "reg_or_short_operand")))]
6198   "TARGET_64BIT"
6199 {
6200   rtx lo0 = gen_lowpart (DImode, operands[0]);
6201   rtx lo1 = gen_lowpart (DImode, operands[1]);
6202   rtx lo2 = gen_lowpart (DImode, operands[2]);
6203   rtx hi0 = gen_highpart (DImode, operands[0]);
6204   rtx hi1 = gen_highpart (DImode, operands[1]);
6205   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6206
6207   if (!reg_or_short_operand (lo2, DImode))
6208     lo2 = force_reg (DImode, lo2);
6209   if (!adde_operand (hi2, DImode))
6210     hi2 = force_reg (DImode, hi2);
6211
6212   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6213   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6214   DONE;
6215 })
6216
6217 (define_expand "subti3"
6218   [(set (match_operand:TI 0 "gpc_reg_operand")
6219         (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6220                   (match_operand:TI 2 "gpc_reg_operand")))]
6221   "TARGET_64BIT"
6222 {
6223   rtx lo0 = gen_lowpart (DImode, operands[0]);
6224   rtx lo1 = gen_lowpart (DImode, operands[1]);
6225   rtx lo2 = gen_lowpart (DImode, operands[2]);
6226   rtx hi0 = gen_highpart (DImode, operands[0]);
6227   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6228   rtx hi2 = gen_highpart (DImode, operands[2]);
6229
6230   if (!reg_or_short_operand (lo1, DImode))
6231     lo1 = force_reg (DImode, lo1);
6232   if (!adde_operand (hi1, DImode))
6233     hi1 = force_reg (DImode, hi1);
6234
6235   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6236   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6237   DONE;
6238 })
6239 \f
6240 ;; 128-bit logical operations expanders
6241
6242 (define_expand "and<mode>3"
6243   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6244         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6245                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6246   ""
6247   "")
6248
6249 (define_expand "ior<mode>3"
6250   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6251         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6252                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6253   ""
6254   "")
6255
6256 (define_expand "xor<mode>3"
6257   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6258         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6259                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6260   ""
6261   "")
6262
6263 (define_expand "one_cmpl<mode>2"
6264   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6265         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6266   ""
6267   "")
6268
6269 (define_expand "nor<mode>3"
6270   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6271         (and:BOOL_128
6272          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6273          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6274   ""
6275   "")
6276
6277 (define_expand "andc<mode>3"
6278   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6279         (and:BOOL_128
6280          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6281          (match_operand:BOOL_128 1 "vlogical_operand")))]
6282   ""
6283   "")
6284
6285 ;; Power8 vector logical instructions.
6286 (define_expand "eqv<mode>3"
6287   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6288         (not:BOOL_128
6289          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6290                        (match_operand:BOOL_128 2 "vlogical_operand"))))]
6291   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6292   "")
6293
6294 ;; Rewrite nand into canonical form
6295 (define_expand "nand<mode>3"
6296   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6297         (ior:BOOL_128
6298          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6299          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6300   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6301   "")
6302
6303 ;; The canonical form is to have the negated element first, so we need to
6304 ;; reverse arguments.
6305 (define_expand "orc<mode>3"
6306   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6307         (ior:BOOL_128
6308          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6309          (match_operand:BOOL_128 1 "vlogical_operand")))]
6310   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6311   "")
6312
6313 ;; 128-bit logical operations insns and split operations
6314 (define_insn_and_split "*and<mode>3_internal"
6315   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6316         (and:BOOL_128
6317          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6318          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6319   ""
6320 {
6321   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6322     return "xxland %x0,%x1,%x2";
6323
6324   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6325     return "vand %0,%1,%2";
6326
6327   return "#";
6328 }
6329   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6330   [(const_int 0)]
6331 {
6332   rs6000_split_logical (operands, AND, false, false, false);
6333   DONE;
6334 }
6335   [(set (attr "type")
6336       (if_then_else
6337         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6338         (const_string "veclogical")
6339         (const_string "integer")))
6340    (set (attr "length")
6341       (if_then_else
6342         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6343         (const_string "4")
6344         (if_then_else
6345          (match_test "TARGET_POWERPC64")
6346          (const_string "8")
6347          (const_string "16"))))])
6348
6349 ;; 128-bit IOR/XOR
6350 (define_insn_and_split "*bool<mode>3_internal"
6351   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6352         (match_operator:BOOL_128 3 "boolean_or_operator"
6353          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6354           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6355   ""
6356 {
6357   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6358     return "xxl%q3 %x0,%x1,%x2";
6359
6360   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6361     return "v%q3 %0,%1,%2";
6362
6363   return "#";
6364 }
6365   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6366   [(const_int 0)]
6367 {
6368   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6369   DONE;
6370 }
6371   [(set (attr "type")
6372       (if_then_else
6373         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6374         (const_string "veclogical")
6375         (const_string "integer")))
6376    (set (attr "length")
6377       (if_then_else
6378         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6379         (const_string "4")
6380         (if_then_else
6381          (match_test "TARGET_POWERPC64")
6382          (const_string "8")
6383          (const_string "16"))))])
6384
6385 ;; 128-bit ANDC/ORC
6386 (define_insn_and_split "*boolc<mode>3_internal1"
6387   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6388         (match_operator:BOOL_128 3 "boolean_operator"
6389          [(not:BOOL_128
6390            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6391           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6392   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6393 {
6394   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6395     return "xxl%q3 %x0,%x1,%x2";
6396
6397   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6398     return "v%q3 %0,%1,%2";
6399
6400   return "#";
6401 }
6402   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6403    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6404   [(const_int 0)]
6405 {
6406   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6407   DONE;
6408 }
6409   [(set (attr "type")
6410       (if_then_else
6411         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6412         (const_string "veclogical")
6413         (const_string "integer")))
6414    (set (attr "length")
6415       (if_then_else
6416         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6417         (const_string "4")
6418         (if_then_else
6419          (match_test "TARGET_POWERPC64")
6420          (const_string "8")
6421          (const_string "16"))))])
6422
6423 (define_insn_and_split "*boolc<mode>3_internal2"
6424   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6425         (match_operator:TI2 3 "boolean_operator"
6426          [(not:TI2
6427            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6428           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6429   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6430   "#"
6431   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6432   [(const_int 0)]
6433 {
6434   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6435   DONE;
6436 }
6437   [(set_attr "type" "integer")
6438    (set (attr "length")
6439         (if_then_else
6440          (match_test "TARGET_POWERPC64")
6441          (const_string "8")
6442          (const_string "16")))])
6443
6444 ;; 128-bit NAND/NOR
6445 (define_insn_and_split "*boolcc<mode>3_internal1"
6446   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6447         (match_operator:BOOL_128 3 "boolean_operator"
6448          [(not:BOOL_128
6449            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6450           (not:BOOL_128
6451            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6452   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6453 {
6454   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6455     return "xxl%q3 %x0,%x1,%x2";
6456
6457   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6458     return "v%q3 %0,%1,%2";
6459
6460   return "#";
6461 }
6462   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6463    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6464   [(const_int 0)]
6465 {
6466   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6467   DONE;
6468 }
6469   [(set (attr "type")
6470       (if_then_else
6471         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6472         (const_string "veclogical")
6473         (const_string "integer")))
6474    (set (attr "length")
6475       (if_then_else
6476         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6477         (const_string "4")
6478         (if_then_else
6479          (match_test "TARGET_POWERPC64")
6480          (const_string "8")
6481          (const_string "16"))))])
6482
6483 (define_insn_and_split "*boolcc<mode>3_internal2"
6484   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6485         (match_operator:TI2 3 "boolean_operator"
6486          [(not:TI2
6487            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6488           (not:TI2
6489            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6490   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6491   "#"
6492   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6493   [(const_int 0)]
6494 {
6495   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6496   DONE;
6497 }
6498   [(set_attr "type" "integer")
6499    (set (attr "length")
6500         (if_then_else
6501          (match_test "TARGET_POWERPC64")
6502          (const_string "8")
6503          (const_string "16")))])
6504
6505
6506 ;; 128-bit EQV
6507 (define_insn_and_split "*eqv<mode>3_internal1"
6508   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6509         (not:BOOL_128
6510          (xor:BOOL_128
6511           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6512           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6513   "TARGET_P8_VECTOR"
6514 {
6515   if (vsx_register_operand (operands[0], <MODE>mode))
6516     return "xxleqv %x0,%x1,%x2";
6517
6518   return "#";
6519 }
6520   "TARGET_P8_VECTOR && reload_completed
6521    && int_reg_operand (operands[0], <MODE>mode)"
6522   [(const_int 0)]
6523 {
6524   rs6000_split_logical (operands, XOR, true, false, false);
6525   DONE;
6526 }
6527   [(set (attr "type")
6528       (if_then_else
6529         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6530         (const_string "veclogical")
6531         (const_string "integer")))
6532    (set (attr "length")
6533       (if_then_else
6534         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6535         (const_string "4")
6536         (if_then_else
6537          (match_test "TARGET_POWERPC64")
6538          (const_string "8")
6539          (const_string "16"))))])
6540
6541 (define_insn_and_split "*eqv<mode>3_internal2"
6542   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6543         (not:TI2
6544          (xor:TI2
6545           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6546           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6547   "!TARGET_P8_VECTOR"
6548   "#"
6549   "reload_completed && !TARGET_P8_VECTOR"
6550   [(const_int 0)]
6551 {
6552   rs6000_split_logical (operands, XOR, true, false, false);
6553   DONE;
6554 }
6555   [(set_attr "type" "integer")
6556    (set (attr "length")
6557         (if_then_else
6558          (match_test "TARGET_POWERPC64")
6559          (const_string "8")
6560          (const_string "16")))])
6561
6562 ;; 128-bit one's complement
6563 (define_insn_and_split "*one_cmpl<mode>3_internal"
6564   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6565         (not:BOOL_128
6566           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6567   ""
6568 {
6569   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6570     return "xxlnor %x0,%x1,%x1";
6571
6572   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6573     return "vnor %0,%1,%1";
6574
6575   return "#";
6576 }
6577   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6578   [(const_int 0)]
6579 {
6580   rs6000_split_logical (operands, NOT, false, false, false);
6581   DONE;
6582 }
6583   [(set (attr "type")
6584       (if_then_else
6585         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6586         (const_string "veclogical")
6587         (const_string "integer")))
6588    (set (attr "length")
6589       (if_then_else
6590         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6591         (const_string "4")
6592         (if_then_else
6593          (match_test "TARGET_POWERPC64")
6594          (const_string "8")
6595          (const_string "16"))))])
6596
6597 \f
6598 ;; Now define ways of moving data around.
6599
6600 ;; Set up a register with a value from the GOT table
6601
6602 (define_expand "movsi_got"
6603   [(set (match_operand:SI 0 "gpc_reg_operand")
6604         (unspec:SI [(match_operand:SI 1 "got_operand")
6605                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6606   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6607 {
6608   if (GET_CODE (operands[1]) == CONST)
6609     {
6610       rtx offset = const0_rtx;
6611       HOST_WIDE_INT value;
6612
6613       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6614       value = INTVAL (offset);
6615       if (value != 0)
6616         {
6617           rtx tmp = (!can_create_pseudo_p ()
6618                      ? operands[0]
6619                      : gen_reg_rtx (Pmode));
6620           emit_insn (gen_movsi_got (tmp, operands[1]));
6621           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6622           DONE;
6623         }
6624     }
6625
6626   operands[2] = rs6000_got_register (operands[1]);
6627 })
6628
6629 (define_insn "*movsi_got_internal"
6630   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6631         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6632                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6633                    UNSPEC_MOVSI_GOT))]
6634   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6635   "lwz %0,%a1@got(%2)"
6636   [(set_attr "type" "load")])
6637
6638 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6639 ;; didn't get allocated to a hard register.
6640 (define_split
6641   [(set (match_operand:SI 0 "gpc_reg_operand")
6642         (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6643                     (match_operand:SI 2 "memory_operand")]
6644                    UNSPEC_MOVSI_GOT))]
6645   "DEFAULT_ABI == ABI_V4
6646     && flag_pic == 1
6647     && reload_completed"
6648   [(set (match_dup 0) (match_dup 2))
6649    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6650                                  UNSPEC_MOVSI_GOT))]
6651   "")
6652
6653 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6654 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6655 ;; and this is even supposed to be faster, but it is simpler not to get
6656 ;; integers in the TOC.
6657 (define_insn "movsi_low"
6658   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6659         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6660                            (match_operand 2 "" ""))))]
6661   "TARGET_MACHO && ! TARGET_64BIT"
6662   "lwz %0,lo16(%2)(%1)"
6663   [(set_attr "type" "load")
6664    (set_attr "length" "4")])
6665
6666 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6667 ;;              STW          STFIWX       STXSIWX      LI           LIS
6668 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6669 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6670 ;;              MF%1         MT%0         MT%0         NOP
6671 (define_insn "*movsi_internal1"
6672   [(set (match_operand:SI 0 "nonimmediate_operand"
6673                 "=r,         r,           r,           ?*wI,        ?*wH,
6674                  m,          ?Z,          ?Z,          r,           r,
6675                  r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6676                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6677                  r,          *c*l,        *h,          *h")
6678
6679         (match_operand:SI 1 "input_operand"
6680                 "r,          U,           m,           Z,           Z,
6681                  r,          wI,          wH,          I,           L,
6682                  n,          wIwH,        O,           wM,          wB,
6683                  O,          wM,          wS,          r,           wIwH,
6684                  *h,         r,           r,           0"))]
6685
6686   "gpc_reg_operand (operands[0], SImode)
6687    || gpc_reg_operand (operands[1], SImode)"
6688   "@
6689    mr %0,%1
6690    la %0,%a1
6691    lwz%U1%X1 %0,%1
6692    lfiwzx %0,%y1
6693    lxsiwzx %x0,%y1
6694    stw%U0%X0 %1,%0
6695    stfiwx %1,%y0
6696    stxsiwx %x1,%y0
6697    li %0,%1
6698    lis %0,%v1
6699    #
6700    xxlor %x0,%x1,%x1
6701    xxspltib %x0,0
6702    xxspltib %x0,255
6703    vspltisw %0,%1
6704    xxlxor %x0,%x0,%x0
6705    xxlorc %x0,%x0,%x0
6706    #
6707    mtvsrwz %x0,%1
6708    mfvsrwz %0,%x1
6709    mf%1 %0
6710    mt%0 %1
6711    mt%0 %1
6712    nop"
6713   [(set_attr "type"
6714                 "*,          *,           load,        fpload,      fpload,
6715                  store,      fpstore,     fpstore,     *,           *,
6716                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6717                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6718                  *,           *,           *,           *")
6719
6720    (set_attr "length"
6721                 "4,          4,           4,           4,           4,
6722                  4,          4,           4,           4,           4,
6723                  8,          4,           4,           4,           4,
6724                  4,          4,           8,           4,           4,
6725                  4,          4,           4,           4")])
6726
6727 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6728 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6729 ;;
6730 ;; Because SF values are actually stored as DF values within the vector
6731 ;; registers, we need to convert the value to the vector SF format when
6732 ;; we need to use the bits in a union or similar cases.  We only need
6733 ;; to do this transformation when the value is a vector register.  Loads,
6734 ;; stores, and transfers within GPRs are assumed to be safe.
6735 ;;
6736 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6737 ;; no alternatives, because the call is created as part of secondary_reload,
6738 ;; and operand #2's register class is used to allocate the temporary register.
6739 ;; This function is called before reload, and it creates the temporary as
6740 ;; needed.
6741
6742 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6743 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6744 ;;              MTVSRWZ
6745
6746 (define_insn_and_split "movsi_from_sf"
6747   [(set (match_operand:SI 0 "nonimmediate_operand"
6748                 "=r,         r,           ?*wI,        ?*wH,     m,
6749                  m,          wY,          Z,           r,        ?*wIwH,
6750                  wIwH")
6751
6752         (unspec:SI [(match_operand:SF 1 "input_operand"
6753                 "r,          m,           Z,           Z,        r,
6754                  f,          wb,          wu,          wIwH,     wIwH,
6755                  r")]
6756                     UNSPEC_SI_FROM_SF))
6757
6758    (clobber (match_scratch:V4SF 2
6759                 "=X,         X,           X,           X,        X,
6760                  X,          X,           X,           wIwH,     X,
6761                  X"))]
6762
6763   "TARGET_NO_SF_SUBREG
6764    && (register_operand (operands[0], SImode)
6765        || register_operand (operands[1], SFmode))"
6766   "@
6767    mr %0,%1
6768    lwz%U1%X1 %0,%1
6769    lfiwzx %0,%y1
6770    lxsiwzx %x0,%y1
6771    stw%U0%X0 %1,%0
6772    stfs%U0%X0 %1,%0
6773    stxssp %1,%0
6774    stxsspx %x1,%y0
6775    #
6776    xscvdpspn %x0,%x1
6777    mtvsrwz %x0,%1"
6778   "&& reload_completed
6779    && int_reg_operand (operands[0], SImode)
6780    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6781   [(const_int 0)]
6782 {
6783   rtx op0 = operands[0];
6784   rtx op1 = operands[1];
6785   rtx op2 = operands[2];
6786   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6787   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6788
6789   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6790   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6791   DONE;
6792 }
6793   [(set_attr "type"
6794                 "*,          load,        fpload,      fpload,   store,
6795                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
6796                  mffgpr")
6797
6798    (set_attr "length"
6799                 "4,          4,           4,           4,        4,
6800                  4,          4,           4,           8,        4,
6801                  4")])
6802
6803 ;; movsi_from_sf with zero extension
6804 ;;
6805 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6806 ;;              VSX->VSX     MTVSRWZ
6807
6808 (define_insn_and_split "*movdi_from_sf_zero_ext"
6809   [(set (match_operand:DI 0 "gpc_reg_operand"
6810                 "=r,         r,           ?*wI,        ?*wH,     r,
6811                  ?wK,        wIwH")
6812
6813         (zero_extend:DI
6814          (unspec:SI [(match_operand:SF 1 "input_operand"
6815                 "r,          m,           Z,           Z,        wIwH,
6816                  wIwH,       r")]
6817                     UNSPEC_SI_FROM_SF)))
6818
6819    (clobber (match_scratch:V4SF 2
6820                 "=X,         X,           X,           X,        wa,
6821                  wIwH,       X"))]
6822
6823   "TARGET_DIRECT_MOVE_64BIT
6824    && (register_operand (operands[0], DImode)
6825        || register_operand (operands[1], SImode))"
6826   "@
6827    rldicl %0,%1,0,32
6828    lwz%U1%X1 %0,%1
6829    lfiwzx %0,%y1
6830    lxsiwzx %x0,%y1
6831    #
6832    #
6833    mtvsrwz %x0,%1"
6834   "&& reload_completed
6835    && register_operand (operands[0], DImode)
6836    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6837   [(const_int 0)]
6838 {
6839   rtx op0 = operands[0];
6840   rtx op1 = operands[1];
6841   rtx op2 = operands[2];
6842   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6843
6844   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6845   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6846   DONE;
6847 }
6848   [(set_attr "type"
6849                 "*,          load,        fpload,      fpload,   two,
6850                  two,        mffgpr")
6851
6852    (set_attr "length"
6853                 "4,          4,           4,           4,        8,
6854                  8,          4")])
6855
6856 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6857 ;; moving it to SImode.  We can do a SFmode store without having to do the
6858 ;; conversion explicitly.  If we are doing a register->register conversion, use
6859 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6860 ;; input will not fit in a SFmode, and the later assumes the value has already
6861 ;; been rounded.
6862 (define_insn "*movsi_from_df"
6863   [(set (match_operand:SI 0 "nonimmediate_operand"         "=wa,m,wY,Z")
6864         (unspec:SI [(float_truncate:SF
6865                      (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6866                     UNSPEC_SI_FROM_SF))]
6867
6868   "TARGET_NO_SF_SUBREG"
6869   "@
6870    xscvdpsp %x0,%x1
6871    stfs%U0%X0 %1,%0
6872    stxssp %1,%0
6873    stxsspx %x1,%y0"
6874   [(set_attr "type"   "fp,fpstore,fpstore,fpstore")])
6875
6876 ;; Split a load of a large constant into the appropriate two-insn
6877 ;; sequence.
6878
6879 (define_split
6880   [(set (match_operand:SI 0 "gpc_reg_operand")
6881         (match_operand:SI 1 "const_int_operand"))]
6882   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6883    && (INTVAL (operands[1]) & 0xffff) != 0"
6884   [(set (match_dup 0)
6885         (match_dup 2))
6886    (set (match_dup 0)
6887         (ior:SI (match_dup 0)
6888                 (match_dup 3)))]
6889 {
6890   if (rs6000_emit_set_const (operands[0], operands[1]))
6891     DONE;
6892   else
6893     FAIL;
6894 })
6895
6896 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6897 (define_split
6898   [(set (match_operand:DI 0 "altivec_register_operand")
6899         (match_operand:DI 1 "xxspltib_constant_split"))]
6900   "TARGET_P9_VECTOR && reload_completed"
6901   [(const_int 0)]
6902 {
6903   rtx op0 = operands[0];
6904   rtx op1 = operands[1];
6905   int r = REGNO (op0);
6906   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6907
6908   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6909   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6910   DONE;
6911 })
6912
6913 (define_insn "*mov<mode>_internal2"
6914   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6915         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6916                     (const_int 0)))
6917    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6918   ""
6919   "@
6920    cmp<wd>i %2,%0,0
6921    mr. %0,%1
6922    #"
6923   [(set_attr "type" "cmp,logical,cmp")
6924    (set_attr "dot" "yes")
6925    (set_attr "length" "4,4,8")])
6926
6927 (define_split
6928   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
6929         (compare:CC (match_operand:P 1 "gpc_reg_operand")
6930                     (const_int 0)))
6931    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
6932   "reload_completed"
6933   [(set (match_dup 0) (match_dup 1))
6934    (set (match_dup 2)
6935         (compare:CC (match_dup 0)
6936                     (const_int 0)))]
6937   "")
6938 \f
6939 (define_expand "mov<mode>"
6940   [(set (match_operand:INT 0 "general_operand")
6941         (match_operand:INT 1 "any_operand"))]
6942   ""
6943 {
6944   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
6945   DONE;
6946 })
6947
6948 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
6949 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
6950 ;;              MTVSRWZ     MF%1       MT%1       NOP
6951 (define_insn "*mov<mode>_internal"
6952   [(set (match_operand:QHI 0 "nonimmediate_operand"
6953                 "=r,        r,         ?*wJwK,    m,         Z,         r,
6954                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
6955                  ?*wJwK,    r,         *c*l,      *h")
6956
6957         (match_operand:QHI 1 "input_operand"
6958                 "r,         m,         Z,         r,         wJwK,      i,
6959                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
6960                  r,         *h,        r,         0"))]
6961
6962   "gpc_reg_operand (operands[0], <MODE>mode)
6963    || gpc_reg_operand (operands[1], <MODE>mode)"
6964   "@
6965    mr %0,%1
6966    l<wd>z%U1%X1 %0,%1
6967    lxsi<wd>zx %x0,%y1
6968    st<wd>%U0%X0 %1,%0
6969    stxsi<wd>x %x1,%y0
6970    li %0,%1
6971    xxlor %x0,%x1,%x1
6972    xxspltib %x0,0
6973    xxspltib %x0,255
6974    vspltis<wd> %0,%1
6975    #
6976    mfvsrwz %0,%x1
6977    mtvsrwz %x0,%1
6978    mf%1 %0
6979    mt%0 %1
6980    nop"
6981   [(set_attr "type"
6982                 "*,         load,      fpload,    store,     fpstore,   *,
6983                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
6984                  mffgpr,    mfjmpr,    mtjmpr,    *")
6985
6986    (set_attr "length"
6987                 "4,         4,         4,         4,         4,         4,
6988                  4,         4,         4,         4,         8,         4,
6989                  4,         4,         4,         4")])
6990
6991 \f
6992 ;; Here is how to move condition codes around.  When we store CC data in
6993 ;; an integer register or memory, we store just the high-order 4 bits.
6994 ;; This lets us not shift in the most common case of CR0.
6995 (define_expand "movcc"
6996   [(set (match_operand:CC 0 "nonimmediate_operand")
6997         (match_operand:CC 1 "nonimmediate_operand"))]
6998   ""
6999   "")
7000
7001 (define_insn "*movcc_internal1"
7002   [(set (match_operand:CC 0 "nonimmediate_operand"
7003                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7004         (match_operand:CC 1 "general_operand"
7005                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7006   "register_operand (operands[0], CCmode)
7007    || register_operand (operands[1], CCmode)"
7008   "@
7009    mcrf %0,%1
7010    mtcrf 128,%1
7011    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7012    crxor %0,%0,%0
7013    mfcr %0%Q1
7014    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7015    mr %0,%1
7016    li %0,%1
7017    mf%1 %0
7018    mt%0 %1
7019    lwz%U1%X1 %0,%1
7020    stw%U0%X0 %1,%0"
7021   [(set (attr "type")
7022      (cond [(eq_attr "alternative" "0,3")
7023                 (const_string "cr_logical")
7024             (eq_attr "alternative" "1,2")
7025                 (const_string "mtcr")
7026             (eq_attr "alternative" "6,7")
7027                 (const_string "integer")
7028             (eq_attr "alternative" "8")
7029                 (const_string "mfjmpr")
7030             (eq_attr "alternative" "9")
7031                 (const_string "mtjmpr")
7032             (eq_attr "alternative" "10")
7033                 (const_string "load")
7034             (eq_attr "alternative" "11")
7035                 (const_string "store")
7036             (match_test "TARGET_MFCRF")
7037                 (const_string "mfcrf")
7038            ]
7039         (const_string "mfcr")))
7040    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7041 \f
7042 ;; For floating-point, we normally deal with the floating-point registers
7043 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7044 ;; can produce floating-point values in fixed-point registers.  Unless the
7045 ;; value is a simple constant or already in memory, we deal with this by
7046 ;; allocating memory and copying the value explicitly via that memory location.
7047
7048 ;; Move 32-bit binary/decimal floating point
7049 (define_expand "mov<mode>"
7050   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7051         (match_operand:FMOVE32 1 "any_operand"))]
7052   "<fmove_ok>"
7053 {
7054   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7055   DONE;
7056 })
7057
7058 (define_split
7059   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7060         (match_operand:FMOVE32 1 "const_double_operand"))]
7061   "reload_completed
7062    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7063        || (GET_CODE (operands[0]) == SUBREG
7064            && GET_CODE (SUBREG_REG (operands[0])) == REG
7065            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7066   [(set (match_dup 2) (match_dup 3))]
7067 {
7068   long l;
7069
7070   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7071
7072   if (! TARGET_POWERPC64)
7073     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7074   else
7075     operands[2] = gen_lowpart (SImode, operands[0]);
7076
7077   operands[3] = gen_int_mode (l, SImode);
7078 })
7079
7080 ;; Originally, we tried to keep movsf and movsd common, but the differences
7081 ;; addressing was making it rather difficult to hide with mode attributes.  In
7082 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7083 ;; before the VSX stores meant that the register allocator would tend to do a
7084 ;; direct move to the GPR (which involves conversion from scalar to
7085 ;; vector/memory formats) to save values in the traditional Altivec registers,
7086 ;; while SDmode had problems on power6 if the GPR store was not first due to
7087 ;; the power6 not having an integer store operation.
7088 ;;
7089 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7090 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7091 ;;      MR           MT<x>      MF<x>       NOP
7092
7093 (define_insn "movsf_hardfloat"
7094   [(set (match_operand:SF 0 "nonimmediate_operand"
7095          "=!r,       f,         wb,         wu,        m,         wY,
7096           Z,         m,         ww,         !r,        f,         ww,
7097           !r,        *c*l,      !r,         *h")
7098         (match_operand:SF 1 "input_operand"
7099          "m,         m,         wY,         Z,         f,         wb,
7100           wu,        r,         j,          j,         f,         ww,
7101           r,         r,         *h,         0"))]
7102   "(register_operand (operands[0], SFmode)
7103    || register_operand (operands[1], SFmode))
7104    && TARGET_HARD_FLOAT
7105    && (TARGET_ALLOW_SF_SUBREG
7106        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7107   "@
7108    lwz%U1%X1 %0,%1
7109    lfs%U1%X1 %0,%1
7110    lxssp %0,%1
7111    lxsspx %x0,%y1
7112    stfs%U0%X0 %1,%0
7113    stxssp %1,%0
7114    stxsspx %x1,%y0
7115    stw%U0%X0 %1,%0
7116    xxlxor %x0,%x0,%x0
7117    li %0,0
7118    fmr %0,%1
7119    xscpsgndp %x0,%x1,%x1
7120    mr %0,%1
7121    mt%0 %1
7122    mf%1 %0
7123    nop"
7124   [(set_attr "type"
7125         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7126          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7127          *,          mtjmpr,    mfjmpr,     *")])
7128
7129 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7130 ;;      FMR          MR         MT%0       MF%1       NOP
7131 (define_insn "movsd_hardfloat"
7132   [(set (match_operand:SD 0 "nonimmediate_operand"
7133          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7134           f,         !r,        *c*l,      !r,        *h")
7135         (match_operand:SD 1 "input_operand"
7136          "m,         Z,         r,         wx,        r,         wh,
7137           f,         r,         r,         *h,        0"))]
7138   "(register_operand (operands[0], SDmode)
7139    || register_operand (operands[1], SDmode))
7140    && TARGET_HARD_FLOAT"
7141   "@
7142    lwz%U1%X1 %0,%1
7143    lfiwzx %0,%y1
7144    stw%U0%X0 %1,%0
7145    stfiwx %1,%y0
7146    mtvsrwz %x0,%1
7147    mfvsrwz %0,%x1
7148    fmr %0,%1
7149    mr %0,%1
7150    mt%0 %1
7151    mf%1 %0
7152    nop"
7153   [(set_attr "type"
7154         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7155          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7156
7157 (define_insn "*mov<mode>_softfloat"
7158   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7159         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7160   "(gpc_reg_operand (operands[0], <MODE>mode)
7161    || gpc_reg_operand (operands[1], <MODE>mode))
7162    && TARGET_SOFT_FLOAT"
7163   "@
7164    mr %0,%1
7165    mt%0 %1
7166    mf%1 %0
7167    lwz%U1%X1 %0,%1
7168    stw%U0%X0 %1,%0
7169    li %0,%1
7170    lis %0,%v1
7171    #
7172    #
7173    nop"
7174   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7175    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7176
7177 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7178 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7179 ;;
7180 ;; Because SF values are actually stored as DF values within the vector
7181 ;; registers, we need to convert the value to the vector SF format when
7182 ;; we need to use the bits in a union or similar cases.  We only need
7183 ;; to do this transformation when the value is a vector register.  Loads,
7184 ;; stores, and transfers within GPRs are assumed to be safe.
7185 ;;
7186 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7187 ;; no alternatives, because the call is created as part of secondary_reload,
7188 ;; and operand #2's register class is used to allocate the temporary register.
7189 ;; This function is called before reload, and it creates the temporary as
7190 ;; needed.
7191
7192 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7193 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7194 (define_insn_and_split "movsf_from_si"
7195   [(set (match_operand:SF 0 "nonimmediate_operand"
7196             "=!r,       f,         wb,        wu,        m,         Z,
7197              Z,         wy,        ?r,        !r")
7198
7199         (unspec:SF [(match_operand:SI 1 "input_operand" 
7200             "m,         m,         wY,        Z,         r,         f,
7201              wu,        r,         wy,        r")]
7202                    UNSPEC_SF_FROM_SI))
7203
7204    (clobber (match_scratch:DI 2
7205             "=X,        X,         X,         X,         X,         X,
7206              X,         r,         X,         X"))]
7207
7208   "TARGET_NO_SF_SUBREG
7209    && (register_operand (operands[0], SFmode)
7210        || register_operand (operands[1], SImode))"
7211   "@
7212    lwz%U1%X1 %0,%1
7213    lfs%U1%X1 %0,%1
7214    lxssp %0,%1
7215    lxsspx %x0,%y1
7216    stw%U0%X0 %1,%0
7217    stfiwx %1,%y0
7218    stxsiwx %x1,%y0
7219    #
7220    mfvsrwz %0,%x1
7221    mr %0,%1"
7222
7223   "&& reload_completed
7224    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7225    && int_reg_operand_not_pseudo (operands[1], SImode)"
7226   [(const_int 0)]
7227 {
7228   rtx op0 = operands[0];
7229   rtx op1 = operands[1];
7230   rtx op2 = operands[2];
7231   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7232
7233   /* Move SF value to upper 32-bits for xscvspdpn.  */
7234   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7235   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7236   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7237   DONE;
7238 }
7239   [(set_attr "length"
7240             "4,          4,         4,         4,         4,         4,
7241              4,          12,        4,         4")
7242    (set_attr "type"
7243             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7244              fpstore,    vecfloat,  mffgpr,    *")])
7245
7246 \f
7247 ;; Move 64-bit binary/decimal floating point
7248 (define_expand "mov<mode>"
7249   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7250         (match_operand:FMOVE64 1 "any_operand"))]
7251   ""
7252 {
7253   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7254   DONE;
7255 })
7256
7257 (define_split
7258   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7259         (match_operand:FMOVE64 1 "const_int_operand"))]
7260   "! TARGET_POWERPC64 && reload_completed
7261    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7262        || (GET_CODE (operands[0]) == SUBREG
7263            && GET_CODE (SUBREG_REG (operands[0])) == REG
7264            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7265   [(set (match_dup 2) (match_dup 4))
7266    (set (match_dup 3) (match_dup 1))]
7267 {
7268   int endian = (WORDS_BIG_ENDIAN == 0);
7269   HOST_WIDE_INT value = INTVAL (operands[1]);
7270
7271   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7272   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7273   operands[4] = GEN_INT (value >> 32);
7274   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7275 })
7276
7277 (define_split
7278   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7279         (match_operand:FMOVE64 1 "const_double_operand"))]
7280   "! TARGET_POWERPC64 && reload_completed
7281    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7282        || (GET_CODE (operands[0]) == SUBREG
7283            && GET_CODE (SUBREG_REG (operands[0])) == REG
7284            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7285   [(set (match_dup 2) (match_dup 4))
7286    (set (match_dup 3) (match_dup 5))]
7287 {
7288   int endian = (WORDS_BIG_ENDIAN == 0);
7289   long l[2];
7290
7291   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7292
7293   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7294   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7295   operands[4] = gen_int_mode (l[endian], SImode);
7296   operands[5] = gen_int_mode (l[1 - endian], SImode);
7297 })
7298
7299 (define_split
7300   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7301         (match_operand:FMOVE64 1 "const_double_operand"))]
7302   "TARGET_POWERPC64 && reload_completed
7303    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7304        || (GET_CODE (operands[0]) == SUBREG
7305            && GET_CODE (SUBREG_REG (operands[0])) == REG
7306            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7307   [(set (match_dup 2) (match_dup 3))]
7308 {
7309   int endian = (WORDS_BIG_ENDIAN == 0);
7310   long l[2];
7311   HOST_WIDE_INT val;
7312
7313   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7314
7315   operands[2] = gen_lowpart (DImode, operands[0]);
7316   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7317   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7318          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7319
7320   operands[3] = gen_int_mode (val, DImode);
7321 })
7322
7323 ;; Don't have reload use general registers to load a constant.  It is
7324 ;; less efficient than loading the constant into an FP register, since
7325 ;; it will probably be used there.
7326
7327 ;; The move constraints are ordered to prefer floating point registers before
7328 ;; general purpose registers to avoid doing a store and a load to get the value
7329 ;; into a floating point register when it is needed for a floating point
7330 ;; operation.  Prefer traditional floating point registers over VSX registers,
7331 ;; since the D-form version of the memory instructions does not need a GPR for
7332 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7333 ;; registers.
7334
7335 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7336 ;; except for 0.0 which can be created on VSX with an xor instruction.
7337
7338 (define_insn "*mov<mode>_hardfloat32"
7339   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7340         (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7341   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7342    && (gpc_reg_operand (operands[0], <MODE>mode)
7343        || gpc_reg_operand (operands[1], <MODE>mode))"
7344   "@
7345    stfd%U0%X0 %1,%0
7346    lfd%U1%X1 %0,%1
7347    fmr %0,%1
7348    lxsd %0,%1
7349    stxsd %1,%0
7350    lxsd%U1x %x0,%y1
7351    stxsd%U0x %x1,%y0
7352    xxlor %x0,%x1,%x1
7353    xxlxor %x0,%x0,%x0
7354    #
7355    #
7356    #
7357    #"
7358   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7359    (set_attr "size" "64")
7360    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7361
7362 (define_insn "*mov<mode>_softfloat32"
7363   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7364         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7365   "!TARGET_POWERPC64
7366    && (gpc_reg_operand (operands[0], <MODE>mode)
7367        || gpc_reg_operand (operands[1], <MODE>mode))"
7368   "#"
7369   [(set_attr "type" "store,load,two,*,*,*")
7370    (set_attr "length" "8,8,8,8,12,16")])
7371
7372 ; ld/std require word-aligned displacements -> 'Y' constraint.
7373 ; List Y->r and r->Y before r->r for reload.
7374 (define_insn "*mov<mode>_hardfloat64"
7375   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
7376         (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
7377   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7378    && (gpc_reg_operand (operands[0], <MODE>mode)
7379        || gpc_reg_operand (operands[1], <MODE>mode))"
7380   "@
7381    stfd%U0%X0 %1,%0
7382    lfd%U1%X1 %0,%1
7383    fmr %0,%1
7384    lxsd %0,%1
7385    stxsd %1,%0
7386    lxsd%U1x %x0,%y1
7387    stxsd%U0x %x1,%y0
7388    xxlor %x0,%x1,%x1
7389    xxlxor %x0,%x0,%x0
7390    li %0,0
7391    std%U0%X0 %1,%0
7392    ld%U1%X1 %0,%1
7393    mr %0,%1
7394    mt%0 %1
7395    mf%1 %0
7396    nop
7397    mftgpr %0,%1
7398    mffgpr %0,%1
7399    mfvsrd %0,%x1
7400    mtvsrd %x0,%1"
7401   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7402    (set_attr "size" "64")
7403    (set_attr "length" "4")])
7404
7405 (define_insn "*mov<mode>_softfloat64"
7406   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7407         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7408   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7409    && (gpc_reg_operand (operands[0], <MODE>mode)
7410        || gpc_reg_operand (operands[1], <MODE>mode))"
7411   "@
7412    std%U0%X0 %1,%0
7413    ld%U1%X1 %0,%1
7414    mr %0,%1
7415    mt%0 %1
7416    mf%1 %0
7417    #
7418    #
7419    #
7420    nop"
7421   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7422    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7423 \f
7424 (define_expand "mov<mode>"
7425   [(set (match_operand:FMOVE128 0 "general_operand")
7426         (match_operand:FMOVE128 1 "any_operand"))]
7427   ""
7428 {
7429   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7430   DONE;
7431 })
7432
7433 ;; It's important to list Y->r and r->Y before r->r because otherwise
7434 ;; reload, given m->r, will try to pick r->r and reload it, which
7435 ;; doesn't make progress.
7436
7437 ;; We can't split little endian direct moves of TDmode, because the words are
7438 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7439 ;; problematical.  Don't allow direct move for this case.
7440
7441 (define_insn_and_split "*mov<mode>_64bit_dm"
7442   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7443         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7444   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7445    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7446    && (gpc_reg_operand (operands[0], <MODE>mode)
7447        || gpc_reg_operand (operands[1], <MODE>mode))"
7448   "#"
7449   "&& reload_completed"
7450   [(pc)]
7451 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7452   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7453
7454 (define_insn_and_split "*movtd_64bit_nodm"
7455   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7456         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7457   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7458    && (gpc_reg_operand (operands[0], TDmode)
7459        || gpc_reg_operand (operands[1], TDmode))"
7460   "#"
7461   "&& reload_completed"
7462   [(pc)]
7463 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7464   [(set_attr "length" "8,8,8,12,12,8")])
7465
7466 (define_insn_and_split "*mov<mode>_32bit"
7467   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7468         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7469   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7470    && (FLOAT128_2REG_P (<MODE>mode)
7471        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7472        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7473    && (gpc_reg_operand (operands[0], <MODE>mode)
7474        || gpc_reg_operand (operands[1], <MODE>mode))"
7475   "#"
7476   "&& reload_completed"
7477   [(pc)]
7478 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7479   [(set_attr "length" "8,8,8,8,20,20,16")])
7480
7481 (define_insn_and_split "*mov<mode>_softfloat"
7482   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7483         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7484   "TARGET_SOFT_FLOAT
7485    && (gpc_reg_operand (operands[0], <MODE>mode)
7486        || gpc_reg_operand (operands[1], <MODE>mode))"
7487   "#"
7488   "&& reload_completed"
7489   [(pc)]
7490 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7491   [(set_attr "length" "20,20,16")])
7492
7493 (define_expand "extenddf<mode>2"
7494   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7495         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7496   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7497 {
7498   if (FLOAT128_IEEE_P (<MODE>mode))
7499     rs6000_expand_float128_convert (operands[0], operands[1], false);
7500   else if (TARGET_VSX)
7501     {
7502       if (<MODE>mode == TFmode)
7503         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7504       else if (<MODE>mode == IFmode)
7505         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7506       else
7507         gcc_unreachable ();
7508     }
7509    else
7510     {
7511       rtx zero = gen_reg_rtx (DFmode);
7512       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7513
7514       if (<MODE>mode == TFmode)
7515         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7516       else if (<MODE>mode == IFmode)
7517         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7518       else
7519         gcc_unreachable ();
7520     }
7521   DONE;
7522 })
7523
7524 ;; Allow memory operands for the source to be created by the combiner.
7525 (define_insn_and_split "extenddf<mode>2_fprs"
7526   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7527         (float_extend:IBM128
7528          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7529    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7530   "!TARGET_VSX && TARGET_HARD_FLOAT
7531    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7532   "#"
7533   "&& reload_completed"
7534   [(set (match_dup 3) (match_dup 1))
7535    (set (match_dup 4) (match_dup 2))]
7536 {
7537   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7538   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7539
7540   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7541   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7542 })
7543
7544 (define_insn_and_split "extenddf<mode>2_vsx"
7545   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7546         (float_extend:IBM128
7547          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7548   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7549   "#"
7550   "&& reload_completed"
7551   [(set (match_dup 2) (match_dup 1))
7552    (set (match_dup 3) (match_dup 4))]
7553 {
7554   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7555   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7556
7557   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7558   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7559   operands[4] = CONST0_RTX (DFmode);
7560 })
7561
7562 (define_expand "extendsf<mode>2"
7563   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7564         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7565   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7566 {
7567   if (FLOAT128_IEEE_P (<MODE>mode))
7568     rs6000_expand_float128_convert (operands[0], operands[1], false);
7569   else
7570     {
7571       rtx tmp = gen_reg_rtx (DFmode);
7572       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7573       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7574     }
7575   DONE;
7576 })
7577
7578 (define_expand "trunc<mode>df2"
7579   [(set (match_operand:DF 0 "gpc_reg_operand")
7580         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7581   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7582 {
7583   if (FLOAT128_IEEE_P (<MODE>mode))
7584     {
7585       rs6000_expand_float128_convert (operands[0], operands[1], false);
7586       DONE;
7587     }
7588 })
7589
7590 (define_insn_and_split "trunc<mode>df2_internal1"
7591   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7592         (float_truncate:DF
7593          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7594   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7595    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7596   "@
7597    #
7598    fmr %0,%1"
7599   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7600   [(const_int 0)]
7601 {
7602   emit_note (NOTE_INSN_DELETED);
7603   DONE;
7604 }
7605   [(set_attr "type" "fpsimple")])
7606
7607 (define_insn "trunc<mode>df2_internal2"
7608   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7609         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7610   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7611    && TARGET_LONG_DOUBLE_128"
7612   "fadd %0,%1,%L1"
7613   [(set_attr "type" "fp")])
7614
7615 (define_expand "trunc<mode>sf2"
7616   [(set (match_operand:SF 0 "gpc_reg_operand")
7617         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7618   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7619 {
7620   if (FLOAT128_IEEE_P (<MODE>mode))
7621     rs6000_expand_float128_convert (operands[0], operands[1], false);
7622   else if (<MODE>mode == TFmode)
7623     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7624   else if (<MODE>mode == IFmode)
7625     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7626   else
7627     gcc_unreachable ();
7628   DONE;
7629 })
7630
7631 (define_insn_and_split "trunc<mode>sf2_fprs"
7632   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7633         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7634    (clobber (match_scratch:DF 2 "=d"))]
7635   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7636   "#"
7637   "&& reload_completed"
7638   [(set (match_dup 2)
7639         (float_truncate:DF (match_dup 1)))
7640    (set (match_dup 0)
7641         (float_truncate:SF (match_dup 2)))]
7642   "")
7643
7644 (define_expand "floatsi<mode>2"
7645   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7646                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7647               (clobber (match_scratch:DI 2))])]
7648   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7649 {
7650   rtx op0 = operands[0];
7651   rtx op1 = operands[1];
7652
7653   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7654     ;
7655   else if (FLOAT128_IEEE_P (<MODE>mode))
7656     {
7657       rs6000_expand_float128_convert (op0, op1, false);
7658       DONE;
7659     }
7660   else
7661     {
7662       rtx tmp = gen_reg_rtx (DFmode);
7663       expand_float (tmp, op1, false);
7664       if (<MODE>mode == TFmode)
7665         emit_insn (gen_extenddftf2 (op0, tmp));
7666       else if (<MODE>mode == IFmode)
7667         emit_insn (gen_extenddfif2 (op0, tmp));
7668       else
7669         gcc_unreachable ();
7670       DONE;
7671     }
7672 })
7673
7674 ; fadd, but rounding towards zero.
7675 ; This is probably not the optimal code sequence.
7676 (define_insn "fix_trunc_helper<mode>"
7677   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7678         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7679                    UNSPEC_FIX_TRUNC_TF))
7680    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7681   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7682   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7683   [(set_attr "type" "fp")
7684    (set_attr "length" "20")])
7685
7686 (define_expand "fix_trunc<mode>si2"
7687   [(set (match_operand:SI 0 "gpc_reg_operand")
7688         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7689   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7690 {
7691   rtx op0 = operands[0];
7692   rtx op1 = operands[1];
7693
7694   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7695     ;
7696   else
7697     {
7698       if (FLOAT128_IEEE_P (<MODE>mode))
7699         rs6000_expand_float128_convert (op0, op1, false);
7700       else if (<MODE>mode == TFmode)
7701         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7702       else if (<MODE>mode == IFmode)
7703         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7704       else
7705         gcc_unreachable ();
7706       DONE;
7707     }
7708 })
7709
7710 (define_expand "fix_trunc<mode>si2_fprs"
7711   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7712                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7713               (clobber (match_dup 2))
7714               (clobber (match_dup 3))
7715               (clobber (match_dup 4))
7716               (clobber (match_dup 5))])]
7717   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7718 {
7719   operands[2] = gen_reg_rtx (DFmode);
7720   operands[3] = gen_reg_rtx (DFmode);
7721   operands[4] = gen_reg_rtx (DImode);
7722   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7723 })
7724
7725 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7726   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7727         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7728    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7729    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7730    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7731    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7732   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7733   "#"
7734   ""
7735   [(pc)]
7736 {
7737   rtx lowword;
7738   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7739                                          operands[3]));
7740
7741   gcc_assert (MEM_P (operands[5]));
7742   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7743
7744   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7745   emit_move_insn (operands[5], operands[4]);
7746   emit_move_insn (operands[0], lowword);
7747   DONE;
7748 })
7749
7750 (define_expand "fix_trunc<mode>di2"
7751   [(set (match_operand:DI 0 "gpc_reg_operand")
7752         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7753   "TARGET_FLOAT128_TYPE"
7754 {
7755   if (!TARGET_FLOAT128_HW)
7756     {
7757       rs6000_expand_float128_convert (operands[0], operands[1], false);
7758       DONE;
7759     }
7760 })
7761
7762 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7763   [(set (match_operand:SDI 0 "gpc_reg_operand")
7764         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7765   "TARGET_FLOAT128_TYPE"
7766 {
7767   rs6000_expand_float128_convert (operands[0], operands[1], true);
7768   DONE;
7769 })
7770
7771 (define_expand "floatdi<mode>2"
7772   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7773         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7774   "TARGET_FLOAT128_TYPE"
7775 {
7776   if (!TARGET_FLOAT128_HW)
7777     {
7778       rs6000_expand_float128_convert (operands[0], operands[1], false);
7779       DONE;
7780     }
7781 })
7782
7783 (define_expand "floatunsdi<IEEE128:mode>2"
7784   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7785         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7786   "TARGET_FLOAT128_TYPE"
7787 {
7788   if (!TARGET_FLOAT128_HW)
7789     {
7790       rs6000_expand_float128_convert (operands[0], operands[1], true);
7791       DONE;
7792     }
7793 })
7794
7795 (define_expand "floatuns<IEEE128:mode>2"
7796   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7797         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
7798   "TARGET_FLOAT128_TYPE"
7799 {
7800   rtx op0 = operands[0];
7801   rtx op1 = operands[1];
7802
7803   if (TARGET_FLOAT128_HW)
7804     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7805   else
7806     rs6000_expand_float128_convert (op0, op1, true);
7807   DONE;
7808 })
7809
7810 (define_expand "neg<mode>2"
7811   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7812         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7813   "FLOAT128_IEEE_P (<MODE>mode)
7814    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7815 {
7816   if (FLOAT128_IEEE_P (<MODE>mode))
7817     {
7818       if (TARGET_FLOAT128_HW)
7819         {
7820           if (<MODE>mode == TFmode)
7821             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7822           else if (<MODE>mode == KFmode)
7823             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7824           else
7825             gcc_unreachable ();
7826         }
7827       else if (TARGET_FLOAT128_TYPE)
7828         {
7829           if (<MODE>mode == TFmode)
7830             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7831           else if (<MODE>mode == KFmode)
7832             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7833           else
7834             gcc_unreachable ();
7835         }
7836       else
7837         {
7838           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7839           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7840                                                 <MODE>mode,
7841                                                 operands[1], <MODE>mode);
7842
7843           if (target && !rtx_equal_p (target, operands[0]))
7844             emit_move_insn (operands[0], target);
7845         }
7846       DONE;
7847     }
7848 })
7849
7850 (define_insn "neg<mode>2_internal"
7851   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7852         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7853   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7854 {
7855   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7856     return "fneg %L0,%L1\;fneg %0,%1";
7857   else
7858     return "fneg %0,%1\;fneg %L0,%L1";
7859 }
7860   [(set_attr "type" "fpsimple")
7861    (set_attr "length" "8")])
7862
7863 (define_expand "abs<mode>2"
7864   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7865         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7866   "FLOAT128_IEEE_P (<MODE>mode)
7867    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7868 {
7869   rtx label;
7870
7871   if (FLOAT128_IEEE_P (<MODE>mode))
7872     {
7873       if (TARGET_FLOAT128_HW)
7874         {
7875           if (<MODE>mode == TFmode)
7876             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7877           else if (<MODE>mode == KFmode)
7878             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7879           else
7880             FAIL;
7881           DONE;
7882         }
7883       else if (TARGET_FLOAT128_TYPE)
7884         {
7885           if (<MODE>mode == TFmode)
7886             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7887           else if (<MODE>mode == KFmode)
7888             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7889           else
7890             FAIL;
7891           DONE;
7892         }
7893       else
7894         FAIL;
7895     }
7896
7897   label = gen_label_rtx ();
7898   if (<MODE>mode == TFmode)
7899     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7900   else if (<MODE>mode == TFmode)
7901     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7902   else
7903     FAIL;
7904   emit_label (label);
7905   DONE;
7906 })
7907
7908 (define_expand "abs<mode>2_internal"
7909   [(set (match_operand:IBM128 0 "gpc_reg_operand")
7910         (match_operand:IBM128 1 "gpc_reg_operand"))
7911    (set (match_dup 3) (match_dup 5))
7912    (set (match_dup 5) (abs:DF (match_dup 5)))
7913    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7914    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7915                            (label_ref (match_operand 2 ""))
7916                            (pc)))
7917    (set (match_dup 6) (neg:DF (match_dup 6)))]
7918   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7919 {
7920   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7921   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7922   operands[3] = gen_reg_rtx (DFmode);
7923   operands[4] = gen_reg_rtx (CCFPmode);
7924   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7925   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7926 })
7927
7928 \f
7929 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7930 ;; register
7931
7932 (define_expand "ieee_128bit_negative_zero"
7933   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
7934   "TARGET_FLOAT128_TYPE"
7935 {
7936   rtvec v = rtvec_alloc (16);
7937   int i, high;
7938
7939   for (i = 0; i < 16; i++)
7940     RTVEC_ELT (v, i) = const0_rtx;
7941
7942   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7943   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
7944
7945   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7946   DONE;
7947 })
7948
7949 ;; IEEE 128-bit negate
7950
7951 ;; We have 2 insns here for negate and absolute value.  The first uses
7952 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7953 ;; insns, and second insn after the first split pass loads up the bit to
7954 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
7955 ;; neg/abs to create the constant just once.
7956
7957 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7958   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7959         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7960    (clobber (match_scratch:V16QI 2 "=v"))]
7961   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7962   "#"
7963   "&& 1"
7964   [(parallel [(set (match_dup 0)
7965                    (neg:IEEE128 (match_dup 1)))
7966               (use (match_dup 2))])]
7967 {
7968   if (GET_CODE (operands[2]) == SCRATCH)
7969     operands[2] = gen_reg_rtx (V16QImode);
7970
7971   operands[3] = gen_reg_rtx (V16QImode);
7972   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7973 }
7974   [(set_attr "length" "8")
7975    (set_attr "type" "vecsimple")])
7976
7977 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7978   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7979         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7980    (use (match_operand:V16QI 2 "register_operand" "v"))]
7981   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7982   "xxlxor %x0,%x1,%x2"
7983   [(set_attr "type" "veclogical")])
7984
7985 ;; IEEE 128-bit absolute value
7986 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7987   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7988         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7989    (clobber (match_scratch:V16QI 2 "=v"))]
7990   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7991   "#"
7992   "&& 1"
7993   [(parallel [(set (match_dup 0)
7994                    (abs:IEEE128 (match_dup 1)))
7995               (use (match_dup 2))])]
7996 {
7997   if (GET_CODE (operands[2]) == SCRATCH)
7998     operands[2] = gen_reg_rtx (V16QImode);
7999
8000   operands[3] = gen_reg_rtx (V16QImode);
8001   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8002 }
8003   [(set_attr "length" "8")
8004    (set_attr "type" "vecsimple")])
8005
8006 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8007   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8008         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8009    (use (match_operand:V16QI 2 "register_operand" "v"))]
8010   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8011   "xxlandc %x0,%x1,%x2"
8012   [(set_attr "type" "veclogical")])
8013
8014 ;; IEEE 128-bit negative absolute value
8015 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8016   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8017         (neg:IEEE128
8018          (abs:IEEE128
8019           (match_operand:IEEE128 1 "register_operand" "wa"))))
8020    (clobber (match_scratch:V16QI 2 "=v"))]
8021   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8022    && FLOAT128_IEEE_P (<MODE>mode)"
8023   "#"
8024   "&& 1"
8025   [(parallel [(set (match_dup 0)
8026                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8027               (use (match_dup 2))])]
8028 {
8029   if (GET_CODE (operands[2]) == SCRATCH)
8030     operands[2] = gen_reg_rtx (V16QImode);
8031
8032   operands[3] = gen_reg_rtx (V16QImode);
8033   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8034 }
8035   [(set_attr "length" "8")
8036    (set_attr "type" "vecsimple")])
8037
8038 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8039   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8040         (neg:IEEE128
8041          (abs:IEEE128
8042           (match_operand:IEEE128 1 "register_operand" "wa"))))
8043    (use (match_operand:V16QI 2 "register_operand" "v"))]
8044   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8045   "xxlor %x0,%x1,%x2"
8046   [(set_attr "type" "veclogical")])
8047
8048 ;; Float128 conversion functions.  These expand to library function calls.
8049 ;; We use expand to convert from IBM double double to IEEE 128-bit
8050 ;; and trunc for the opposite.
8051 (define_expand "extendiftf2"
8052   [(set (match_operand:TF 0 "gpc_reg_operand")
8053         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8054   "TARGET_FLOAT128_TYPE"
8055 {
8056   rs6000_expand_float128_convert (operands[0], operands[1], false);
8057   DONE;
8058 })
8059
8060 (define_expand "extendifkf2"
8061   [(set (match_operand:KF 0 "gpc_reg_operand")
8062         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8063   "TARGET_FLOAT128_TYPE"
8064 {
8065   rs6000_expand_float128_convert (operands[0], operands[1], false);
8066   DONE;
8067 })
8068
8069 (define_expand "extendtfkf2"
8070   [(set (match_operand:KF 0 "gpc_reg_operand")
8071         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8072   "TARGET_FLOAT128_TYPE"
8073 {
8074   rs6000_expand_float128_convert (operands[0], operands[1], false);
8075   DONE;
8076 })
8077
8078 (define_expand "trunciftf2"
8079   [(set (match_operand:IF 0 "gpc_reg_operand")
8080         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8081   "TARGET_FLOAT128_TYPE"
8082 {
8083   rs6000_expand_float128_convert (operands[0], operands[1], false);
8084   DONE;
8085 })
8086
8087 (define_expand "truncifkf2"
8088   [(set (match_operand:IF 0 "gpc_reg_operand")
8089         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand")))]
8090   "TARGET_FLOAT128_TYPE"
8091 {
8092   rs6000_expand_float128_convert (operands[0], operands[1], false);
8093   DONE;
8094 })
8095
8096 (define_expand "trunckftf2"
8097   [(set (match_operand:TF 0 "gpc_reg_operand")
8098         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8099   "TARGET_FLOAT128_TYPE"
8100 {
8101   rs6000_expand_float128_convert (operands[0], operands[1], false);
8102   DONE;
8103 })
8104
8105 (define_expand "trunctfif2"
8106   [(set (match_operand:IF 0 "gpc_reg_operand")
8107         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8108   "TARGET_FLOAT128_TYPE"
8109 {
8110   rs6000_expand_float128_convert (operands[0], operands[1], false);
8111   DONE;
8112 })
8113
8114 \f
8115 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8116 ;; must have 3 arguments, and scratch register constraint must be a single
8117 ;; constraint.
8118
8119 ;; Reload patterns to support gpr load/store with misaligned mem.
8120 ;; and multiple gpr load/store at offset >= 0xfffc
8121 (define_expand "reload_<mode>_store"
8122   [(parallel [(match_operand 0 "memory_operand" "=m")
8123               (match_operand 1 "gpc_reg_operand" "r")
8124               (match_operand:GPR 2 "register_operand" "=&b")])]
8125   ""
8126 {
8127   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8128   DONE;
8129 })
8130
8131 (define_expand "reload_<mode>_load"
8132   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8133               (match_operand 1 "memory_operand" "m")
8134               (match_operand:GPR 2 "register_operand" "=b")])]
8135   ""
8136 {
8137   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8138   DONE;
8139 })
8140
8141 \f
8142 ;; Reload patterns for various types using the vector registers.  We may need
8143 ;; an additional base register to convert the reg+offset addressing to reg+reg
8144 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8145 ;; index register for gpr registers.
8146 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8147   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8148               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8149               (match_operand:P 2 "register_operand" "=b")])]
8150   "<P:tptrsize>"
8151 {
8152   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8153   DONE;
8154 })
8155
8156 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8157   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8158               (match_operand:RELOAD 1 "memory_operand" "m")
8159               (match_operand:P 2 "register_operand" "=b")])]
8160   "<P:tptrsize>"
8161 {
8162   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8163   DONE;
8164 })
8165
8166
8167 ;; Reload sometimes tries to move the address to a GPR, and can generate
8168 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8169 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8170
8171 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8172   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8173         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8174                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8175                (const_int -16)))]
8176   "TARGET_ALTIVEC && reload_completed"
8177   "#"
8178   "&& reload_completed"
8179   [(set (match_dup 0)
8180         (plus:P (match_dup 1)
8181                 (match_dup 2)))
8182    (set (match_dup 0)
8183         (and:P (match_dup 0)
8184                (const_int -16)))])
8185 \f
8186 ;; Power8 merge instructions to allow direct move to/from floating point
8187 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8188 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8189 ;; value, since it is allocated in reload and not all of the flow information
8190 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8191 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8192 ;; schedule other instructions between the two instructions.
8193
8194 (define_insn "p8_fmrgow_<mode>"
8195   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8196         (unspec:FMOVE64X [
8197                 (match_operand:DF 1 "register_operand" "d")
8198                 (match_operand:DF 2 "register_operand" "d")]
8199                          UNSPEC_P8V_FMRGOW))]
8200   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8201   "fmrgow %0,%1,%2"
8202   [(set_attr "type" "fpsimple")])
8203
8204 (define_insn "p8_mtvsrwz"
8205   [(set (match_operand:DF 0 "register_operand" "=d")
8206         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8207                    UNSPEC_P8V_MTVSRWZ))]
8208   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8209   "mtvsrwz %x0,%1"
8210   [(set_attr "type" "mftgpr")])
8211
8212 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8213   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8214         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8215                          UNSPEC_P8V_RELOAD_FROM_GPR))
8216    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8217   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8218   "#"
8219   "&& reload_completed"
8220   [(const_int 0)]
8221 {
8222   rtx dest = operands[0];
8223   rtx src = operands[1];
8224   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8225   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8226   rtx gpr_hi_reg = gen_highpart (SImode, src);
8227   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8228
8229   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8230   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8231   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8232   DONE;
8233 }
8234   [(set_attr "length" "12")
8235    (set_attr "type" "three")])
8236
8237 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8238 (define_insn "p8_mtvsrd_df"
8239   [(set (match_operand:DF 0 "register_operand" "=wa")
8240         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8241                    UNSPEC_P8V_MTVSRD))]
8242   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8243   "mtvsrd %x0,%1"
8244   [(set_attr "type" "mftgpr")])
8245
8246 (define_insn "p8_xxpermdi_<mode>"
8247   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8248         (unspec:FMOVE128_GPR [
8249                 (match_operand:DF 1 "register_operand" "wa")
8250                 (match_operand:DF 2 "register_operand" "wa")]
8251                 UNSPEC_P8V_XXPERMDI))]
8252   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8253   "xxpermdi %x0,%x1,%x2,0"
8254   [(set_attr "type" "vecperm")])
8255
8256 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8257   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8258         (unspec:FMOVE128_GPR
8259          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8260          UNSPEC_P8V_RELOAD_FROM_GPR))
8261    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8262   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8263   "#"
8264   "&& reload_completed"
8265   [(const_int 0)]
8266 {
8267   rtx dest = operands[0];
8268   rtx src = operands[1];
8269   /* You might think that we could use op0 as one temp and a DF clobber
8270      as op2, but you'd be wrong.  Secondary reload move patterns don't
8271      check for overlap of the clobber and the destination.  */
8272   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8273   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8274   rtx gpr_hi_reg = gen_highpart (DImode, src);
8275   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8276
8277   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8278   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8279   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8280   DONE;
8281 }
8282   [(set_attr "length" "12")
8283    (set_attr "type" "three")])
8284
8285 (define_split
8286   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8287         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8288   "reload_completed
8289    && (int_reg_operand (operands[0], <MODE>mode)
8290        || int_reg_operand (operands[1], <MODE>mode))
8291    && (!TARGET_DIRECT_MOVE_128
8292        || (!vsx_register_operand (operands[0], <MODE>mode)
8293            && !vsx_register_operand (operands[1], <MODE>mode)))"
8294   [(pc)]
8295 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8296
8297 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8298 ;; type is stored internally as double precision in the VSX registers, we have
8299 ;; to convert it from the vector format.
8300 (define_insn "p8_mtvsrd_sf"
8301   [(set (match_operand:SF 0 "register_operand" "=wa")
8302         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8303                    UNSPEC_P8V_MTVSRD))]
8304   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8305   "mtvsrd %x0,%1"
8306   [(set_attr "type" "mftgpr")])
8307
8308 (define_insn_and_split "reload_vsx_from_gprsf"
8309   [(set (match_operand:SF 0 "register_operand" "=wa")
8310         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8311                    UNSPEC_P8V_RELOAD_FROM_GPR))
8312    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8313   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8314   "#"
8315   "&& reload_completed"
8316   [(const_int 0)]
8317 {
8318   rtx op0 = operands[0];
8319   rtx op1 = operands[1];
8320   rtx op2 = operands[2];
8321   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8322
8323   /* Move SF value to upper 32-bits for xscvspdpn.  */
8324   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8325   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8326   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8327   DONE;
8328 }
8329   [(set_attr "length" "8")
8330    (set_attr "type" "two")])
8331
8332 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8333 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8334 ;; and then doing a move of that.
8335 (define_insn "p8_mfvsrd_3_<mode>"
8336   [(set (match_operand:DF 0 "register_operand" "=r")
8337         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8338                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8339   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8340   "mfvsrd %0,%x1"
8341   [(set_attr "type" "mftgpr")])
8342
8343 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8344   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8345         (unspec:FMOVE128_GPR
8346          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8347          UNSPEC_P8V_RELOAD_FROM_VSX))
8348    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8349   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8350   "#"
8351   "&& reload_completed"
8352   [(const_int 0)]
8353 {
8354   rtx dest = operands[0];
8355   rtx src = operands[1];
8356   rtx tmp = operands[2];
8357   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8358   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8359
8360   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8361   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8362   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8363   DONE;
8364 }
8365   [(set_attr "length" "12")
8366    (set_attr "type" "three")])
8367
8368 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8369 ;; type is stored internally as double precision, we have to convert it to the
8370 ;; vector format.
8371
8372 (define_insn_and_split "reload_gpr_from_vsxsf"
8373   [(set (match_operand:SF 0 "register_operand" "=r")
8374         (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8375                    UNSPEC_P8V_RELOAD_FROM_VSX))
8376    (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8377   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8378   "#"
8379   "&& reload_completed"
8380   [(const_int 0)]
8381 {
8382   rtx op0 = operands[0];
8383   rtx op1 = operands[1];
8384   rtx op2 = operands[2];
8385   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8386   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8387
8388   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8389   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8390   DONE;
8391 }
8392   [(set_attr "length" "8")
8393    (set_attr "type" "two")])
8394
8395 \f
8396 ;; Next come the multi-word integer load and store and the load and store
8397 ;; multiple insns.
8398
8399 ;; List r->r after r->Y, otherwise reload will try to reload a
8400 ;; non-offsettable address by using r->r which won't make progress.
8401 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8402 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8403
8404 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8405 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8406 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8407 ;;        AVX const  
8408
8409 (define_insn "*movdi_internal32"
8410   [(set (match_operand:DI 0 "nonimmediate_operand"
8411          "=Y,        r,         r,         ^m,        ^d,         ^d,
8412           r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8413           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8414           *wv")
8415
8416         (match_operand:DI 1 "input_operand"
8417           "r,        Y,         r,         d,         m,          d,
8418            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8419            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8420            wB"))]
8421
8422   "! TARGET_POWERPC64
8423    && (gpc_reg_operand (operands[0], DImode)
8424        || gpc_reg_operand (operands[1], DImode))"
8425   "@
8426    #
8427    #
8428    #
8429    stfd%U0%X0 %1,%0
8430    lfd%U1%X1 %0,%1
8431    fmr %0,%1
8432    #
8433    stxsd %1,%0
8434    stxsdx %x1,%y0
8435    lxsd %0,%1
8436    lxsdx %x0,%y1
8437    xxlor %x0,%x1,%x1
8438    xxspltib %x0,0
8439    xxspltib %x0,255
8440    vspltisw %0,%1
8441    xxlxor %x0,%x0,%x0
8442    xxlorc %x0,%x0,%x0
8443    #
8444    #"
8445   [(set_attr "type"
8446                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8447                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8448                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8449                 vecsimple")
8450    (set_attr "size" "64")])
8451
8452 (define_split
8453   [(set (match_operand:DI 0 "gpc_reg_operand")
8454         (match_operand:DI 1 "const_int_operand"))]
8455   "! TARGET_POWERPC64 && reload_completed
8456    && gpr_or_gpr_p (operands[0], operands[1])
8457    && !direct_move_p (operands[0], operands[1])"
8458   [(set (match_dup 2) (match_dup 4))
8459    (set (match_dup 3) (match_dup 1))]
8460 {
8461   HOST_WIDE_INT value = INTVAL (operands[1]);
8462   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8463                                        DImode);
8464   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8465                                        DImode);
8466   operands[4] = GEN_INT (value >> 32);
8467   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8468 })
8469
8470 (define_split
8471   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8472         (match_operand:DIFD 1 "input_operand"))]
8473   "reload_completed && !TARGET_POWERPC64
8474    && gpr_or_gpr_p (operands[0], operands[1])
8475    && !direct_move_p (operands[0], operands[1])"
8476   [(pc)]
8477 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8478
8479 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8480 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8481 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8482 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8483 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8484 (define_insn "*movdi_internal64"
8485   [(set (match_operand:DI 0 "nonimmediate_operand"
8486                "=YZ,       r,         r,         r,         r,          r,
8487                 ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
8488                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8489                 *wi,       *wv,       *wv,       r,         *h,         *h,
8490                 ?*r,       ?*wg,      ?*r,       ?*wj")
8491
8492         (match_operand:DI 1 "input_operand"
8493                 "r,        YZ,        r,         I,         L,          nF,
8494                  d,        m,         d,         wb,        wv,         wY,
8495                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8496                  wM,       wS,        wB,        *h,        r,          0,
8497                  wg,       r,         wj,        r"))]
8498
8499   "TARGET_POWERPC64
8500    && (gpc_reg_operand (operands[0], DImode)
8501        || gpc_reg_operand (operands[1], DImode))"
8502   "@
8503    std%U0%X0 %1,%0
8504    ld%U1%X1 %0,%1
8505    mr %0,%1
8506    li %0,%1
8507    lis %0,%v1
8508    #
8509    stfd%U0%X0 %1,%0
8510    lfd%U1%X1 %0,%1
8511    fmr %0,%1
8512    stxsd %1,%0
8513    stxsdx %x1,%y0
8514    lxsd %0,%1
8515    lxsdx %x0,%y1
8516    xxlor %x0,%x1,%x1
8517    xxspltib %x0,0
8518    xxspltib %x0,255
8519    #
8520    xxlxor %x0,%x0,%x0
8521    xxlorc %x0,%x0,%x0
8522    #
8523    #
8524    mf%1 %0
8525    mt%0 %1
8526    nop
8527    mftgpr %0,%1
8528    mffgpr %0,%1
8529    mfvsrd %0,%x1
8530    mtvsrd %x0,%1"
8531   [(set_attr "type"
8532                "store,      load,       *,         *,         *,         *,
8533                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8534                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8535                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8536                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8537
8538    (set_attr "size" "64")
8539    (set_attr "length"
8540                "4,         4,         4,         4,         4,          20,
8541                 4,         4,         4,         4,         4,          4,
8542                 4,         4,         4,         4,         4,          8,
8543                 8,         4,         4,         4,         4,          4,
8544                 4,         4,         4,         4")])
8545
8546 ; Some DImode loads are best done as a load of -1 followed by a mask
8547 ; instruction.
8548 (define_split
8549   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8550         (match_operand:DI 1 "const_int_operand"))]
8551   "TARGET_POWERPC64
8552    && num_insns_constant (operands[1], DImode) > 1
8553    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8554    && rs6000_is_valid_and_mask (operands[1], DImode)"
8555   [(set (match_dup 0)
8556         (const_int -1))
8557    (set (match_dup 0)
8558         (and:DI (match_dup 0)
8559                 (match_dup 1)))]
8560   "")
8561
8562 ;; Split a load of a large constant into the appropriate five-instruction
8563 ;; sequence.  Handle anything in a constant number of insns.
8564 ;; When non-easy constants can go in the TOC, this should use
8565 ;; easy_fp_constant predicate.
8566 (define_split
8567   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8568         (match_operand:DI 1 "const_int_operand"))]
8569   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8570   [(set (match_dup 0) (match_dup 2))
8571    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8572 {
8573   if (rs6000_emit_set_const (operands[0], operands[1]))
8574     DONE;
8575   else
8576     FAIL;
8577 })
8578
8579 (define_split
8580   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8581         (match_operand:DI 1 "const_scalar_int_operand"))]
8582   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8583   [(set (match_dup 0) (match_dup 2))
8584    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8585 {
8586   if (rs6000_emit_set_const (operands[0], operands[1]))
8587     DONE;
8588   else
8589     FAIL;
8590 })
8591
8592 (define_split
8593   [(set (match_operand:DI 0 "altivec_register_operand")
8594         (match_operand:DI 1 "s5bit_cint_operand"))]
8595   "TARGET_VSX && reload_completed"
8596   [(const_int 0)]
8597 {
8598   rtx op0 = operands[0];
8599   rtx op1 = operands[1];
8600   int r = REGNO (op0);
8601   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8602
8603   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8604   if (op1 != const0_rtx && op1 != constm1_rtx)
8605     {
8606       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8607       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8608     }
8609   DONE;
8610 })
8611
8612 ;; Split integer constants that can be loaded with XXSPLTIB and a
8613 ;; sign extend operation.
8614 (define_split
8615   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8616         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8617   "TARGET_P9_VECTOR && reload_completed"
8618   [(const_int 0)]
8619 {
8620   rtx op0 = operands[0];
8621   rtx op1 = operands[1];
8622   int r = REGNO (op0);
8623   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8624
8625   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8626   if (<MODE>mode == DImode)
8627     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8628   else if (<MODE>mode == SImode)
8629     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8630   else if (<MODE>mode == HImode)
8631     {
8632       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8633       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8634     }
8635   DONE;
8636 })
8637
8638 \f
8639 ;; TImode/PTImode is similar, except that we usually want to compute the
8640 ;; address into a register and use lsi/stsi (the exception is during reload).
8641
8642 (define_insn "*mov<mode>_string"
8643   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8644         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8645   "! TARGET_POWERPC64
8646    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8647    && (gpc_reg_operand (operands[0], <MODE>mode)
8648        || gpc_reg_operand (operands[1], <MODE>mode))"
8649   "#"
8650   [(set_attr "type" "store,store,load,load,*,*")
8651    (set_attr "update" "yes")
8652    (set_attr "indexed" "yes")
8653    (set_attr "cell_micro" "conditional")])
8654
8655 (define_insn "*mov<mode>_ppc64"
8656   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8657         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8658   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8659    && (gpc_reg_operand (operands[0], <MODE>mode)
8660        || gpc_reg_operand (operands[1], <MODE>mode)))"
8661 {
8662   return rs6000_output_move_128bit (operands);
8663 }
8664   [(set_attr "type" "store,store,load,load,*,*")
8665    (set_attr "length" "8")])
8666
8667 (define_split
8668   [(set (match_operand:TI2 0 "int_reg_operand")
8669         (match_operand:TI2 1 "const_scalar_int_operand"))]
8670   "TARGET_POWERPC64
8671    && (VECTOR_MEM_NONE_P (<MODE>mode)
8672        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8673   [(set (match_dup 2) (match_dup 4))
8674    (set (match_dup 3) (match_dup 5))]
8675 {
8676   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8677                                        <MODE>mode);
8678   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8679                                        <MODE>mode);
8680   if (CONST_WIDE_INT_P (operands[1]))
8681     {
8682       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8683       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8684     }
8685   else if (CONST_INT_P (operands[1]))
8686     {
8687       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8688       operands[5] = operands[1];
8689     }
8690   else
8691     FAIL;
8692 })
8693
8694 (define_split
8695   [(set (match_operand:TI2 0 "nonimmediate_operand")
8696         (match_operand:TI2 1 "input_operand"))]
8697   "reload_completed
8698    && gpr_or_gpr_p (operands[0], operands[1])
8699    && !direct_move_p (operands[0], operands[1])
8700    && !quad_load_store_p (operands[0], operands[1])"
8701   [(pc)]
8702 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8703 \f
8704 (define_expand "setmemsi"
8705   [(parallel [(set (match_operand:BLK 0 "")
8706                    (match_operand 2 "const_int_operand"))
8707               (use (match_operand:SI 1 ""))
8708               (use (match_operand:SI 3 ""))])]
8709   ""
8710 {
8711   /* If value to set is not zero, use the library routine.  */
8712   if (operands[2] != const0_rtx)
8713     FAIL;
8714
8715   if (expand_block_clear (operands))
8716     DONE;
8717   else
8718     FAIL;
8719 })
8720
8721 ;; String compare N insn.
8722 ;; Argument 0 is the target (result)
8723 ;; Argument 1 is the destination
8724 ;; Argument 2 is the source
8725 ;; Argument 3 is the length
8726 ;; Argument 4 is the alignment
8727
8728 (define_expand "cmpstrnsi"
8729   [(parallel [(set (match_operand:SI 0)
8730                (compare:SI (match_operand:BLK 1)
8731                            (match_operand:BLK 2)))
8732               (use (match_operand:SI 3))
8733               (use (match_operand:SI 4))])]
8734   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8735 {
8736   if (optimize_insn_for_size_p ())
8737     FAIL;
8738
8739   if (expand_strn_compare (operands, 0))
8740     DONE;
8741   else  
8742     FAIL;
8743 })
8744
8745 ;; String compare insn.
8746 ;; Argument 0 is the target (result)
8747 ;; Argument 1 is the destination
8748 ;; Argument 2 is the source
8749 ;; Argument 3 is the alignment
8750
8751 (define_expand "cmpstrsi"
8752   [(parallel [(set (match_operand:SI 0)
8753                (compare:SI (match_operand:BLK 1)
8754                            (match_operand:BLK 2)))
8755               (use (match_operand:SI 3))])]
8756   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8757 {
8758   if (optimize_insn_for_size_p ())
8759     FAIL;
8760
8761   if (expand_strn_compare (operands, 1))
8762     DONE;
8763   else  
8764     FAIL;
8765 })
8766
8767 ;; Block compare insn.
8768 ;; Argument 0 is the target (result)
8769 ;; Argument 1 is the destination
8770 ;; Argument 2 is the source
8771 ;; Argument 3 is the length
8772 ;; Argument 4 is the alignment
8773
8774 (define_expand "cmpmemsi"
8775   [(parallel [(set (match_operand:SI 0)
8776                (compare:SI (match_operand:BLK 1)
8777                            (match_operand:BLK 2)))
8778               (use (match_operand:SI 3))
8779               (use (match_operand:SI 4))])]
8780   "TARGET_POPCNTD"
8781 {
8782   if (expand_block_compare (operands))
8783     DONE;
8784   else
8785     FAIL;
8786 })
8787
8788 ;; String/block move insn.
8789 ;; Argument 0 is the destination
8790 ;; Argument 1 is the source
8791 ;; Argument 2 is the length
8792 ;; Argument 3 is the alignment
8793
8794 (define_expand "movmemsi"
8795   [(parallel [(set (match_operand:BLK 0 "")
8796                    (match_operand:BLK 1 ""))
8797               (use (match_operand:SI 2 ""))
8798               (use (match_operand:SI 3 ""))])]
8799   ""
8800 {
8801   if (expand_block_move (operands))
8802     DONE;
8803   else
8804     FAIL;
8805 })
8806 \f
8807 ;; Define insns that do load or store with update.  Some of these we can
8808 ;; get by using pre-decrement or pre-increment, but the hardware can also
8809 ;; do cases where the increment is not the size of the object.
8810 ;;
8811 ;; In all these cases, we use operands 0 and 1 for the register being
8812 ;; incremented because those are the operands that local-alloc will
8813 ;; tie and these are the pair most likely to be tieable (and the ones
8814 ;; that will benefit the most).
8815
8816 (define_insn "*movdi_update1"
8817   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8818         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8819                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8820    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8821         (plus:DI (match_dup 1) (match_dup 2)))]
8822   "TARGET_POWERPC64 && TARGET_UPDATE
8823    && (!avoiding_indexed_address_p (DImode)
8824        || !gpc_reg_operand (operands[2], DImode))"
8825   "@
8826    ldux %3,%0,%2
8827    ldu %3,%2(%0)"
8828   [(set_attr "type" "load")
8829    (set_attr "update" "yes")
8830    (set_attr "indexed" "yes,no")])
8831
8832 (define_insn "movdi_<mode>_update"
8833   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8834                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8835         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8836    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8837         (plus:P (match_dup 1) (match_dup 2)))]
8838   "TARGET_POWERPC64 && TARGET_UPDATE
8839    && (!avoiding_indexed_address_p (Pmode)
8840        || !gpc_reg_operand (operands[2], Pmode)
8841        || (REG_P (operands[0])
8842            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8843   "@
8844    stdux %3,%0,%2
8845    stdu %3,%2(%0)"
8846   [(set_attr "type" "store")
8847    (set_attr "update" "yes")
8848    (set_attr "indexed" "yes,no")])
8849
8850 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8851 ;; needed for stack allocation, even if the user passes -mno-update.
8852 (define_insn "movdi_<mode>_update_stack"
8853   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8854                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8855         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8856    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8857         (plus:P (match_dup 1) (match_dup 2)))]
8858   "TARGET_POWERPC64"
8859   "@
8860    stdux %3,%0,%2
8861    stdu %3,%2(%0)"
8862   [(set_attr "type" "store")
8863    (set_attr "update" "yes")
8864    (set_attr "indexed" "yes,no")])
8865
8866 (define_insn "*movsi_update1"
8867   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8868         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8869                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8870    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8871         (plus:SI (match_dup 1) (match_dup 2)))]
8872   "TARGET_UPDATE
8873    && (!avoiding_indexed_address_p (SImode)
8874        || !gpc_reg_operand (operands[2], SImode))"
8875   "@
8876    lwzux %3,%0,%2
8877    lwzu %3,%2(%0)"
8878   [(set_attr "type" "load")
8879    (set_attr "update" "yes")
8880    (set_attr "indexed" "yes,no")])
8881
8882 (define_insn "*movsi_update2"
8883   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8884         (sign_extend:DI
8885          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8886                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
8887    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8888         (plus:DI (match_dup 1) (match_dup 2)))]
8889   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
8890   "lwaux %3,%0,%2"
8891   [(set_attr "type" "load")
8892    (set_attr "sign_extend" "yes")
8893    (set_attr "update" "yes")
8894    (set_attr "indexed" "yes")])
8895
8896 (define_insn "movsi_update"
8897   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8898                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8899         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8900    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8901         (plus:SI (match_dup 1) (match_dup 2)))]
8902   "TARGET_UPDATE
8903    && (!avoiding_indexed_address_p (SImode)
8904        || !gpc_reg_operand (operands[2], SImode)
8905        || (REG_P (operands[0])
8906            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8907   "@
8908    stwux %3,%0,%2
8909    stwu %3,%2(%0)"
8910   [(set_attr "type" "store")
8911    (set_attr "update" "yes")
8912    (set_attr "indexed" "yes,no")])
8913
8914 ;; This is an unconditional pattern; needed for stack allocation, even
8915 ;; if the user passes -mno-update.
8916 (define_insn "movsi_update_stack"
8917   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8918                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8919         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8920    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8921         (plus:SI (match_dup 1) (match_dup 2)))]
8922   ""
8923   "@
8924    stwux %3,%0,%2
8925    stwu %3,%2(%0)"
8926   [(set_attr "type" "store")
8927    (set_attr "update" "yes")
8928    (set_attr "indexed" "yes,no")])
8929
8930 (define_insn "*movhi_update1"
8931   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8932         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8933                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8934    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8935         (plus:SI (match_dup 1) (match_dup 2)))]
8936   "TARGET_UPDATE
8937    && (!avoiding_indexed_address_p (SImode)
8938        || !gpc_reg_operand (operands[2], SImode))"
8939   "@
8940    lhzux %3,%0,%2
8941    lhzu %3,%2(%0)"
8942   [(set_attr "type" "load")
8943    (set_attr "update" "yes")
8944    (set_attr "indexed" "yes,no")])
8945
8946 (define_insn "*movhi_update2"
8947   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8948         (zero_extend:SI
8949          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8950                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8951    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8952         (plus:SI (match_dup 1) (match_dup 2)))]
8953   "TARGET_UPDATE
8954    && (!avoiding_indexed_address_p (SImode)
8955        || !gpc_reg_operand (operands[2], SImode))"
8956   "@
8957    lhzux %3,%0,%2
8958    lhzu %3,%2(%0)"
8959   [(set_attr "type" "load")
8960    (set_attr "update" "yes")
8961    (set_attr "indexed" "yes,no")])
8962
8963 (define_insn "*movhi_update3"
8964   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8965         (sign_extend:SI
8966          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8967                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8968    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8969         (plus:SI (match_dup 1) (match_dup 2)))]
8970   "TARGET_UPDATE
8971    && !(avoiding_indexed_address_p (SImode)
8972         && gpc_reg_operand (operands[2], SImode))"
8973   "@
8974    lhaux %3,%0,%2
8975    lhau %3,%2(%0)"
8976   [(set_attr "type" "load")
8977    (set_attr "sign_extend" "yes")
8978    (set_attr "update" "yes")
8979    (set_attr "indexed" "yes,no")])
8980
8981 (define_insn "*movhi_update4"
8982   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8983                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8984         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8985    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8986         (plus:SI (match_dup 1) (match_dup 2)))]
8987   "TARGET_UPDATE
8988    && (!avoiding_indexed_address_p (SImode)
8989        || !gpc_reg_operand (operands[2], SImode))"
8990   "@
8991    sthux %3,%0,%2
8992    sthu %3,%2(%0)"
8993   [(set_attr "type" "store")
8994    (set_attr "update" "yes")
8995    (set_attr "indexed" "yes,no")])
8996
8997 (define_insn "*movqi_update1"
8998   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8999         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9000                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9001    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9002         (plus:SI (match_dup 1) (match_dup 2)))]
9003   "TARGET_UPDATE
9004    && (!avoiding_indexed_address_p (SImode)
9005        || !gpc_reg_operand (operands[2], SImode))"
9006   "@
9007    lbzux %3,%0,%2
9008    lbzu %3,%2(%0)"
9009   [(set_attr "type" "load")
9010    (set_attr "update" "yes")
9011    (set_attr "indexed" "yes,no")])
9012
9013 (define_insn "*movqi_update2"
9014   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9015         (zero_extend:SI
9016          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9017                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9018    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9019         (plus:SI (match_dup 1) (match_dup 2)))]
9020   "TARGET_UPDATE
9021    && (!avoiding_indexed_address_p (SImode)
9022        || !gpc_reg_operand (operands[2], SImode))"
9023   "@
9024    lbzux %3,%0,%2
9025    lbzu %3,%2(%0)"
9026   [(set_attr "type" "load")
9027    (set_attr "update" "yes")
9028    (set_attr "indexed" "yes,no")])
9029
9030 (define_insn "*movqi_update3"
9031   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9032                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9033         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9034    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9035         (plus:SI (match_dup 1) (match_dup 2)))]
9036   "TARGET_UPDATE
9037    && (!avoiding_indexed_address_p (SImode)
9038        || !gpc_reg_operand (operands[2], SImode))"
9039   "@
9040    stbux %3,%0,%2
9041    stbu %3,%2(%0)"
9042   [(set_attr "type" "store")
9043    (set_attr "update" "yes")
9044    (set_attr "indexed" "yes,no")])
9045
9046 (define_insn "*movsf_update1"
9047   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9048         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9049                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9050    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9051         (plus:SI (match_dup 1) (match_dup 2)))]
9052   "TARGET_HARD_FLOAT && TARGET_UPDATE
9053    && (!avoiding_indexed_address_p (SImode)
9054        || !gpc_reg_operand (operands[2], SImode))"
9055   "@
9056    lfsux %3,%0,%2
9057    lfsu %3,%2(%0)"
9058   [(set_attr "type" "fpload")
9059    (set_attr "update" "yes")
9060    (set_attr "indexed" "yes,no")])
9061
9062 (define_insn "*movsf_update2"
9063   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9064                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9065         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9066    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9067         (plus:SI (match_dup 1) (match_dup 2)))]
9068   "TARGET_HARD_FLOAT && TARGET_UPDATE
9069    && (!avoiding_indexed_address_p (SImode)
9070        || !gpc_reg_operand (operands[2], SImode))"
9071   "@
9072    stfsux %3,%0,%2
9073    stfsu %3,%2(%0)"
9074   [(set_attr "type" "fpstore")
9075    (set_attr "update" "yes")
9076    (set_attr "indexed" "yes,no")])
9077
9078 (define_insn "*movsf_update3"
9079   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9080         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9081                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9082    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9083         (plus:SI (match_dup 1) (match_dup 2)))]
9084   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9085    && (!avoiding_indexed_address_p (SImode)
9086        || !gpc_reg_operand (operands[2], SImode))"
9087   "@
9088    lwzux %3,%0,%2
9089    lwzu %3,%2(%0)"
9090   [(set_attr "type" "load")
9091    (set_attr "update" "yes")
9092    (set_attr "indexed" "yes,no")])
9093
9094 (define_insn "*movsf_update4"
9095   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9096                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9097         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9098    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9099         (plus:SI (match_dup 1) (match_dup 2)))]
9100   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9101    && (!avoiding_indexed_address_p (SImode)
9102        || !gpc_reg_operand (operands[2], SImode))"
9103   "@
9104    stwux %3,%0,%2
9105    stwu %3,%2(%0)"
9106   [(set_attr "type" "store")
9107    (set_attr "update" "yes")
9108    (set_attr "indexed" "yes,no")])
9109
9110 (define_insn "*movdf_update1"
9111   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9112         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9113                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9114    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9115         (plus:SI (match_dup 1) (match_dup 2)))]
9116   "TARGET_HARD_FLOAT && TARGET_UPDATE
9117    && (!avoiding_indexed_address_p (SImode)
9118        || !gpc_reg_operand (operands[2], SImode))"
9119   "@
9120    lfdux %3,%0,%2
9121    lfdu %3,%2(%0)"
9122   [(set_attr "type" "fpload")
9123    (set_attr "update" "yes")
9124    (set_attr "indexed" "yes,no")
9125    (set_attr "size" "64")])
9126
9127 (define_insn "*movdf_update2"
9128   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9129                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9130         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9131    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9132         (plus:SI (match_dup 1) (match_dup 2)))]
9133   "TARGET_HARD_FLOAT && TARGET_UPDATE
9134    && (!avoiding_indexed_address_p (SImode)
9135        || !gpc_reg_operand (operands[2], SImode))"
9136   "@
9137    stfdux %3,%0,%2
9138    stfdu %3,%2(%0)"
9139   [(set_attr "type" "fpstore")
9140    (set_attr "update" "yes")
9141    (set_attr "indexed" "yes,no")])
9142
9143
9144 ;; After inserting conditional returns we can sometimes have
9145 ;; unnecessary register moves.  Unfortunately we cannot have a
9146 ;; modeless peephole here, because some single SImode sets have early
9147 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9148 ;; sequences, using get_attr_length here will smash the operands
9149 ;; array.  Neither is there an early_cobbler_p predicate.
9150 ;; Also this optimization interferes with scalars going into
9151 ;; altivec registers (the code does reloading through the FPRs).
9152 (define_peephole2
9153   [(set (match_operand:DF 0 "gpc_reg_operand")
9154         (match_operand:DF 1 "any_operand"))
9155    (set (match_operand:DF 2 "gpc_reg_operand")
9156         (match_dup 0))]
9157   "!TARGET_VSX
9158    && peep2_reg_dead_p (2, operands[0])"
9159   [(set (match_dup 2) (match_dup 1))])
9160
9161 (define_peephole2
9162   [(set (match_operand:SF 0 "gpc_reg_operand")
9163         (match_operand:SF 1 "any_operand"))
9164    (set (match_operand:SF 2 "gpc_reg_operand")
9165         (match_dup 0))]
9166   "!TARGET_P8_VECTOR
9167    && peep2_reg_dead_p (2, operands[0])"
9168   [(set (match_dup 2) (match_dup 1))])
9169
9170 \f
9171 ;; TLS support.
9172
9173 ;; Mode attributes for different ABIs.
9174 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9175 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9176 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9177 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9178
9179 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9180   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9181         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9182               (match_operand 4 "" "g")))
9183    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9184                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9185                    UNSPEC_TLSGD)
9186    (clobber (reg:SI LR_REGNO))]
9187   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9188 {
9189   if (TARGET_CMODEL != CMODEL_SMALL)
9190     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9191            "bl %z3\;nop";
9192   else
9193     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9194 }
9195   "&& TARGET_TLS_MARKERS"
9196   [(set (match_dup 0)
9197         (unspec:TLSmode [(match_dup 1)
9198                          (match_dup 2)]
9199                         UNSPEC_TLSGD))
9200    (parallel [(set (match_dup 0)
9201                    (call (mem:TLSmode (match_dup 3))
9202                          (match_dup 4)))
9203               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9204               (clobber (reg:SI LR_REGNO))])]
9205   ""
9206   [(set_attr "type" "two")
9207    (set (attr "length")
9208      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9209                    (const_int 16)
9210                    (const_int 12)))])
9211
9212 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9213   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9214         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9215               (match_operand 4 "" "g")))
9216    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9217                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9218                    UNSPEC_TLSGD)
9219    (clobber (reg:SI LR_REGNO))]
9220   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9221 {
9222   if (flag_pic)
9223     {
9224       if (TARGET_SECURE_PLT && flag_pic == 2)
9225         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9226       else
9227         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9228     }
9229   else
9230     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9231 }
9232   "&& TARGET_TLS_MARKERS"
9233   [(set (match_dup 0)
9234         (unspec:TLSmode [(match_dup 1)
9235                          (match_dup 2)]
9236                         UNSPEC_TLSGD))
9237    (parallel [(set (match_dup 0)
9238                    (call (mem:TLSmode (match_dup 3))
9239                          (match_dup 4)))
9240               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9241               (clobber (reg:SI LR_REGNO))])]
9242   ""
9243   [(set_attr "type" "two")
9244    (set_attr "length" "8")])
9245
9246 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9247   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9248         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9249                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9250                         UNSPEC_TLSGD))]
9251   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9252   "addi %0,%1,%2@got@tlsgd"
9253   "&& TARGET_CMODEL != CMODEL_SMALL"
9254   [(set (match_dup 3)
9255         (high:TLSmode
9256             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9257    (set (match_dup 0)
9258         (lo_sum:TLSmode (match_dup 3)
9259             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9260 {
9261   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9262 }
9263   [(set (attr "length")
9264      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9265                    (const_int 8)
9266                    (const_int 4)))])
9267
9268 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9269   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9270      (high:TLSmode
9271        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9272                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9273                        UNSPEC_TLSGD)))]
9274   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9275   "addis %0,%1,%2@got@tlsgd@ha"
9276   [(set_attr "length" "4")])
9277
9278 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9279   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9280      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9281        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9282                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9283                        UNSPEC_TLSGD)))]
9284   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9285   "addi %0,%1,%2@got@tlsgd@l"
9286   [(set_attr "length" "4")])
9287
9288 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9289   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9290         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9291               (match_operand 2 "" "g")))
9292    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9293                    UNSPEC_TLSGD)
9294    (clobber (reg:SI LR_REGNO))]
9295   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9296    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9297   "bl %z1(%3@tlsgd)\;nop"
9298   [(set_attr "type" "branch")
9299    (set_attr "length" "8")])
9300
9301 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9302   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9303         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9304               (match_operand 2 "" "g")))
9305    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9306                    UNSPEC_TLSGD)
9307    (clobber (reg:SI LR_REGNO))]
9308   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9309 {
9310   if (flag_pic)
9311     {
9312       if (TARGET_SECURE_PLT && flag_pic == 2)
9313         return "bl %z1+32768(%3@tlsgd)@plt";
9314       return "bl %z1(%3@tlsgd)@plt";
9315     }
9316   return "bl %z1(%3@tlsgd)";
9317 }
9318   [(set_attr "type" "branch")
9319    (set_attr "length" "4")])
9320
9321 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9322   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9323         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9324               (match_operand 3 "" "g")))
9325    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9326                    UNSPEC_TLSLD)
9327    (clobber (reg:SI LR_REGNO))]
9328   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9329 {
9330   if (TARGET_CMODEL != CMODEL_SMALL)
9331     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9332            "bl %z2\;nop";
9333   else
9334     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9335 }
9336   "&& TARGET_TLS_MARKERS"
9337   [(set (match_dup 0)
9338         (unspec:TLSmode [(match_dup 1)]
9339                         UNSPEC_TLSLD))
9340    (parallel [(set (match_dup 0)
9341                    (call (mem:TLSmode (match_dup 2))
9342                          (match_dup 3)))
9343               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9344               (clobber (reg:SI LR_REGNO))])]
9345   ""
9346   [(set_attr "type" "two")
9347    (set (attr "length")
9348      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9349                    (const_int 16)
9350                    (const_int 12)))])
9351
9352 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9353   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9354         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9355               (match_operand 3 "" "g")))
9356    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9357                    UNSPEC_TLSLD)
9358    (clobber (reg:SI LR_REGNO))]
9359   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9360 {
9361   if (flag_pic)
9362     {
9363       if (TARGET_SECURE_PLT && flag_pic == 2)
9364         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9365       else
9366         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9367     }
9368   else
9369     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9370 }
9371   "&& TARGET_TLS_MARKERS"
9372   [(set (match_dup 0)
9373         (unspec:TLSmode [(match_dup 1)]
9374                         UNSPEC_TLSLD))
9375    (parallel [(set (match_dup 0)
9376                    (call (mem:TLSmode (match_dup 2))
9377                          (match_dup 3)))
9378               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9379               (clobber (reg:SI LR_REGNO))])]
9380   ""
9381   [(set_attr "length" "8")])
9382
9383 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9384   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9385         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9386                         UNSPEC_TLSLD))]
9387   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9388   "addi %0,%1,%&@got@tlsld"
9389   "&& TARGET_CMODEL != CMODEL_SMALL"
9390   [(set (match_dup 2)
9391         (high:TLSmode
9392             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9393    (set (match_dup 0)
9394         (lo_sum:TLSmode (match_dup 2)
9395             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9396 {
9397   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9398 }
9399   [(set (attr "length")
9400      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9401                    (const_int 8)
9402                    (const_int 4)))])
9403
9404 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9405   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9406      (high:TLSmode
9407        (unspec:TLSmode [(const_int 0)
9408                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9409                        UNSPEC_TLSLD)))]
9410   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9411   "addis %0,%1,%&@got@tlsld@ha"
9412   [(set_attr "length" "4")])
9413
9414 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9415   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9416      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9417        (unspec:TLSmode [(const_int 0)
9418                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9419                        UNSPEC_TLSLD)))]
9420   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9421   "addi %0,%1,%&@got@tlsld@l"
9422   [(set_attr "length" "4")])
9423
9424 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9425   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9426         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9427               (match_operand 2 "" "g")))
9428    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9429    (clobber (reg:SI LR_REGNO))]
9430   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9431    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9432   "bl %z1(%&@tlsld)\;nop"
9433   [(set_attr "type" "branch")
9434    (set_attr "length" "8")])
9435
9436 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9437   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9438         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9439               (match_operand 2 "" "g")))
9440    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9441    (clobber (reg:SI LR_REGNO))]
9442   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9443 {
9444   if (flag_pic)
9445     {
9446       if (TARGET_SECURE_PLT && flag_pic == 2)
9447         return "bl %z1+32768(%&@tlsld)@plt";
9448       return "bl %z1(%&@tlsld)@plt";
9449     }
9450   return "bl %z1(%&@tlsld)";
9451 }
9452   [(set_attr "type" "branch")
9453    (set_attr "length" "4")])
9454
9455 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9456   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9457         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9458                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9459                         UNSPEC_TLSDTPREL))]
9460   "HAVE_AS_TLS"
9461   "addi %0,%1,%2@dtprel")
9462
9463 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9464   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9465         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9466                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9467                         UNSPEC_TLSDTPRELHA))]
9468   "HAVE_AS_TLS"
9469   "addis %0,%1,%2@dtprel@ha")
9470
9471 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9472   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9473         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9474                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9475                         UNSPEC_TLSDTPRELLO))]
9476   "HAVE_AS_TLS"
9477   "addi %0,%1,%2@dtprel@l")
9478
9479 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9480   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9481         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9482                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9483                         UNSPEC_TLSGOTDTPREL))]
9484   "HAVE_AS_TLS"
9485   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9486   "&& TARGET_CMODEL != CMODEL_SMALL"
9487   [(set (match_dup 3)
9488         (high:TLSmode
9489             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9490    (set (match_dup 0)
9491         (lo_sum:TLSmode (match_dup 3)
9492             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9493 {
9494   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9495 }
9496   [(set (attr "length")
9497      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9498                    (const_int 8)
9499                    (const_int 4)))])
9500
9501 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9502   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9503      (high:TLSmode
9504        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9505                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9506                        UNSPEC_TLSGOTDTPREL)))]
9507   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9508   "addis %0,%1,%2@got@dtprel@ha"
9509   [(set_attr "length" "4")])
9510
9511 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9512   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9513      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9514          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9515                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9516                          UNSPEC_TLSGOTDTPREL)))]
9517   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9518   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9519   [(set_attr "length" "4")])
9520
9521 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9522   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9523         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9524                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9525                         UNSPEC_TLSTPREL))]
9526   "HAVE_AS_TLS"
9527   "addi %0,%1,%2@tprel")
9528
9529 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9530   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9531         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9532                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9533                         UNSPEC_TLSTPRELHA))]
9534   "HAVE_AS_TLS"
9535   "addis %0,%1,%2@tprel@ha")
9536
9537 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9538   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9539         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9540                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9541                         UNSPEC_TLSTPRELLO))]
9542   "HAVE_AS_TLS"
9543   "addi %0,%1,%2@tprel@l")
9544
9545 ;; "b" output constraint here and on tls_tls input to support linker tls
9546 ;; optimization.  The linker may edit the instructions emitted by a
9547 ;; tls_got_tprel/tls_tls pair to addis,addi.
9548 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9549   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9550         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9551                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9552                         UNSPEC_TLSGOTTPREL))]
9553   "HAVE_AS_TLS"
9554   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9555   "&& TARGET_CMODEL != CMODEL_SMALL"
9556   [(set (match_dup 3)
9557         (high:TLSmode
9558             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9559    (set (match_dup 0)
9560         (lo_sum:TLSmode (match_dup 3)
9561             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9562 {
9563   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9564 }
9565   [(set (attr "length")
9566      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9567                    (const_int 8)
9568                    (const_int 4)))])
9569
9570 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9571   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9572      (high:TLSmode
9573        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9574                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9575                        UNSPEC_TLSGOTTPREL)))]
9576   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9577   "addis %0,%1,%2@got@tprel@ha"
9578   [(set_attr "length" "4")])
9579
9580 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9581   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9582      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9583          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9584                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9585                          UNSPEC_TLSGOTTPREL)))]
9586   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9587   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9588   [(set_attr "length" "4")])
9589
9590 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9591   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9592         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9593                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9594                         UNSPEC_TLSTLS))]
9595   "TARGET_ELF && HAVE_AS_TLS"
9596   "add %0,%1,%2@tls")
9597
9598 (define_expand "tls_get_tpointer"
9599   [(set (match_operand:SI 0 "gpc_reg_operand")
9600         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9601   "TARGET_XCOFF && HAVE_AS_TLS"
9602 {
9603   emit_insn (gen_tls_get_tpointer_internal ());
9604   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9605   DONE;
9606 })
9607
9608 (define_insn "tls_get_tpointer_internal"
9609   [(set (reg:SI 3)
9610         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9611    (clobber (reg:SI LR_REGNO))]
9612   "TARGET_XCOFF && HAVE_AS_TLS"
9613   "bla __get_tpointer")
9614
9615 (define_expand "tls_get_addr<mode>"
9616   [(set (match_operand:P 0 "gpc_reg_operand")
9617         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9618                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9619   "TARGET_XCOFF && HAVE_AS_TLS"
9620 {
9621   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9622   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9623   emit_insn (gen_tls_get_addr_internal<mode> ());
9624   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9625   DONE;
9626 })
9627
9628 (define_insn "tls_get_addr_internal<mode>"
9629   [(set (reg:P 3)
9630         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9631    (clobber (reg:P 0))
9632    (clobber (reg:P 4))
9633    (clobber (reg:P 5))
9634    (clobber (reg:P 11))
9635    (clobber (reg:CC CR0_REGNO))
9636    (clobber (reg:P LR_REGNO))]
9637   "TARGET_XCOFF && HAVE_AS_TLS"
9638   "bla __tls_get_addr")
9639 \f
9640 ;; Next come insns related to the calling sequence.
9641 ;;
9642 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9643 ;; We move the back-chain and decrement the stack pointer.
9644 ;;
9645 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9646 ;; constant alloca, using that predicate will force the generic code to put
9647 ;; the constant size into a register before calling the expander.
9648 ;;
9649 ;; As a result the expander would not have the constant size information
9650 ;; in those cases and would have to generate less efficient code.
9651 ;;
9652 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9653 ;; the constant size.  The value is forced into a register if necessary.
9654 ;;
9655 (define_expand "allocate_stack"
9656   [(set (match_operand 0 "gpc_reg_operand")
9657         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9658    (set (reg 1)
9659         (minus (reg 1) (match_dup 1)))]
9660   ""
9661 {
9662   rtx chain = gen_reg_rtx (Pmode);
9663   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9664   rtx neg_op0;
9665   rtx insn, par, set, mem;
9666
9667   /* By allowing reg_or_cint_operand as the predicate we can get
9668      better code for stack-clash-protection because we do not lose
9669      size information.  But the rest of the code expects the operand
9670      to be reg_or_short_operand.  If it isn't, then force it into
9671      a register.  */
9672   rtx orig_op1 = operands[1];
9673   if (!reg_or_short_operand (operands[1], Pmode))
9674     operands[1] = force_reg (Pmode, operands[1]);
9675
9676   emit_move_insn (chain, stack_bot);
9677
9678   /* Check stack bounds if necessary.  */
9679   if (crtl->limit_stack)
9680     {
9681       rtx available;
9682       available = expand_binop (Pmode, sub_optab,
9683                                 stack_pointer_rtx, stack_limit_rtx,
9684                                 NULL_RTX, 1, OPTAB_WIDEN);
9685       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9686     }
9687
9688   /* Allocate and probe if requested.
9689      This may look similar to the loop we use for prologue allocations,
9690      but it is critically different.  For the former we know the loop
9691      will iterate, but do not know that generally here.  The former
9692      uses that knowledge to rotate the loop.  Combining them would be
9693      possible with some performance cost.  */
9694   if (flag_stack_clash_protection)
9695     {
9696       rtx rounded_size, last_addr, residual;
9697       HOST_WIDE_INT probe_interval;
9698       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9699                                                 &residual, &probe_interval,
9700                                                 orig_op1);
9701       
9702       /* We do occasionally get in here with constant sizes, we might
9703          as well do a reasonable job when we obviously can.  */
9704       if (rounded_size != const0_rtx)
9705         {
9706           rtx loop_lab, end_loop;
9707           bool rotated = CONST_INT_P (rounded_size);
9708           rtx update = GEN_INT (-probe_interval);
9709           if (probe_interval > 32768)
9710             update = force_reg (Pmode, update);
9711
9712           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9713                                                         last_addr, rotated);
9714
9715           if (Pmode == SImode)
9716             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9717                                                stack_pointer_rtx,
9718                                                update, chain));
9719           else
9720             emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9721                                                   stack_pointer_rtx,
9722                                                   update, chain));
9723           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9724                                                       last_addr, rotated);
9725         }
9726
9727       /* Now handle residuals.  We just have to set operands[1] correctly
9728          and let the rest of the expander run.  */
9729       operands[1] = residual;
9730     }
9731
9732   if (!(CONST_INT_P (operands[1])
9733         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9734     {
9735       operands[1] = force_reg (Pmode, operands[1]);
9736       neg_op0 = gen_reg_rtx (Pmode);
9737       if (TARGET_32BIT)
9738         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9739       else
9740         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9741     }
9742   else
9743     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9744
9745   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9746                                        : gen_movdi_di_update_stack))
9747                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9748                          chain));
9749   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9750      it now and set the alias set/attributes. The above gen_*_update
9751      calls will generate a PARALLEL with the MEM set being the first
9752      operation. */
9753   par = PATTERN (insn);
9754   gcc_assert (GET_CODE (par) == PARALLEL);
9755   set = XVECEXP (par, 0, 0);
9756   gcc_assert (GET_CODE (set) == SET);
9757   mem = SET_DEST (set);
9758   gcc_assert (MEM_P (mem));
9759   MEM_NOTRAP_P (mem) = 1;
9760   set_mem_alias_set (mem, get_frame_alias_set ());
9761
9762   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9763   DONE;
9764 })
9765
9766 ;; These patterns say how to save and restore the stack pointer.  We need not
9767 ;; save the stack pointer at function level since we are careful to
9768 ;; preserve the backchain.  At block level, we have to restore the backchain
9769 ;; when we restore the stack pointer.
9770 ;;
9771 ;; For nonlocal gotos, we must save both the stack pointer and its
9772 ;; backchain and restore both.  Note that in the nonlocal case, the
9773 ;; save area is a memory location.
9774
9775 (define_expand "save_stack_function"
9776   [(match_operand 0 "any_operand")
9777    (match_operand 1 "any_operand")]
9778   ""
9779   "DONE;")
9780
9781 (define_expand "restore_stack_function"
9782   [(match_operand 0 "any_operand")
9783    (match_operand 1 "any_operand")]
9784   ""
9785   "DONE;")
9786
9787 ;; Adjust stack pointer (op0) to a new value (op1).
9788 ;; First copy old stack backchain to new location, and ensure that the
9789 ;; scheduler won't reorder the sp assignment before the backchain write.
9790 (define_expand "restore_stack_block"
9791   [(set (match_dup 2) (match_dup 3))
9792    (set (match_dup 4) (match_dup 2))
9793    (match_dup 5)
9794    (set (match_operand 0 "register_operand")
9795         (match_operand 1 "register_operand"))]
9796   ""
9797 {
9798   rtvec p;
9799
9800   operands[1] = force_reg (Pmode, operands[1]);
9801   operands[2] = gen_reg_rtx (Pmode);
9802   operands[3] = gen_frame_mem (Pmode, operands[0]);
9803   operands[4] = gen_frame_mem (Pmode, operands[1]);
9804   p = rtvec_alloc (1);
9805   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9806                                   const0_rtx);
9807   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9808 })
9809
9810 (define_expand "save_stack_nonlocal"
9811   [(set (match_dup 3) (match_dup 4))
9812    (set (match_operand 0 "memory_operand") (match_dup 3))
9813    (set (match_dup 2) (match_operand 1 "register_operand"))]
9814   ""
9815 {
9816   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9817
9818   /* Copy the backchain to the first word, sp to the second.  */
9819   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9820   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9821   operands[3] = gen_reg_rtx (Pmode);
9822   operands[4] = gen_frame_mem (Pmode, operands[1]);
9823 })
9824
9825 (define_expand "restore_stack_nonlocal"
9826   [(set (match_dup 2) (match_operand 1 "memory_operand"))
9827    (set (match_dup 3) (match_dup 4))
9828    (set (match_dup 5) (match_dup 2))
9829    (match_dup 6)
9830    (set (match_operand 0 "register_operand") (match_dup 3))]
9831   ""
9832 {
9833   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9834   rtvec p;
9835
9836   /* Restore the backchain from the first word, sp from the second.  */
9837   operands[2] = gen_reg_rtx (Pmode);
9838   operands[3] = gen_reg_rtx (Pmode);
9839   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9840   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9841   operands[5] = gen_frame_mem (Pmode, operands[3]);
9842   p = rtvec_alloc (1);
9843   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9844                                   const0_rtx);
9845   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9846 })
9847 \f
9848 ;; TOC register handling.
9849
9850 ;; Code to initialize the TOC register...
9851
9852 (define_insn "load_toc_aix_si"
9853   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9854                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9855               (use (reg:SI 2))])]
9856   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9857 {
9858   char buf[30];
9859   extern int need_toc_init;
9860   need_toc_init = 1;
9861   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9862   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9863   operands[2] = gen_rtx_REG (Pmode, 2);
9864   return "lwz %0,%1(%2)";
9865 }
9866   [(set_attr "type" "load")
9867    (set_attr "update" "no")
9868    (set_attr "indexed" "no")])
9869
9870 (define_insn "load_toc_aix_di"
9871   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9872                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9873               (use (reg:DI 2))])]
9874   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9875 {
9876   char buf[30];
9877   extern int need_toc_init;
9878   need_toc_init = 1;
9879   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9880                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
9881   if (TARGET_ELF)
9882     strcat (buf, "@toc");
9883   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9884   operands[2] = gen_rtx_REG (Pmode, 2);
9885   return "ld %0,%1(%2)";
9886 }
9887   [(set_attr "type" "load")
9888    (set_attr "update" "no")
9889    (set_attr "indexed" "no")])
9890
9891 (define_insn "load_toc_v4_pic_si"
9892   [(set (reg:SI LR_REGNO)
9893         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9894   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9895   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9896   [(set_attr "type" "branch")
9897    (set_attr "length" "4")])
9898
9899 (define_expand "load_toc_v4_PIC_1"
9900   [(parallel [(set (reg:SI LR_REGNO)
9901                    (match_operand:SI 0 "immediate_operand" "s"))
9902               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9903   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9904    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9905   "")
9906
9907 (define_insn "load_toc_v4_PIC_1_normal"
9908   [(set (reg:SI LR_REGNO)
9909         (match_operand:SI 0 "immediate_operand" "s"))
9910    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9911   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9912    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9913   "bcl 20,31,%0\n%0:"
9914   [(set_attr "type" "branch")
9915    (set_attr "length" "4")
9916    (set_attr "cannot_copy" "yes")])
9917
9918 (define_insn "load_toc_v4_PIC_1_476"
9919   [(set (reg:SI LR_REGNO)
9920         (match_operand:SI 0 "immediate_operand" "s"))
9921    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9922   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9923    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9924 {
9925   char name[32];
9926   static char templ[32];
9927
9928   get_ppc476_thunk_name (name);
9929   sprintf (templ, "bl %s\n%%0:", name);
9930   return templ;
9931 }
9932   [(set_attr "type" "branch")
9933    (set_attr "length" "4")
9934    (set_attr "cannot_copy" "yes")])
9935
9936 (define_expand "load_toc_v4_PIC_1b"
9937   [(parallel [(set (reg:SI LR_REGNO)
9938                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9939                                (label_ref (match_operand 1 ""))]
9940                            UNSPEC_TOCPTR))
9941               (match_dup 1)])]
9942   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9943   "")
9944
9945 (define_insn "load_toc_v4_PIC_1b_normal"
9946   [(set (reg:SI LR_REGNO)
9947         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9948                     (label_ref (match_operand 1 "" ""))]
9949                 UNSPEC_TOCPTR))
9950    (match_dup 1)]
9951   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9952   "bcl 20,31,$+8\;.long %0-$"
9953   [(set_attr "type" "branch")
9954    (set_attr "length" "8")])
9955
9956 (define_insn "load_toc_v4_PIC_1b_476"
9957   [(set (reg:SI LR_REGNO)
9958         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9959                     (label_ref (match_operand 1 "" ""))]
9960                 UNSPEC_TOCPTR))
9961    (match_dup 1)]
9962   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9963 {
9964   char name[32];
9965   static char templ[32];
9966
9967   get_ppc476_thunk_name (name);
9968   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
9969   return templ;
9970 }
9971   [(set_attr "type" "branch")
9972    (set_attr "length" "16")])
9973
9974 (define_insn "load_toc_v4_PIC_2"
9975   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9976         (mem:SI (plus:SI
9977                   (match_operand:SI 1 "gpc_reg_operand" "b")
9978                   (const
9979                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9980                               (match_operand:SI 3 "immediate_operand" "s"))))))]
9981   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9982   "lwz %0,%2-%3(%1)"
9983   [(set_attr "type" "load")])
9984
9985 (define_insn "load_toc_v4_PIC_3b"
9986   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9987         (plus:SI
9988           (match_operand:SI 1 "gpc_reg_operand" "b")
9989           (high:SI
9990             (const
9991               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9992                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
9993   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9994   "addis %0,%1,%2-%3@ha")
9995
9996 (define_insn "load_toc_v4_PIC_3c"
9997   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9998         (lo_sum:SI
9999           (match_operand:SI 1 "gpc_reg_operand" "b")
10000           (const
10001             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10002                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10003   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10004   "addi %0,%1,%2-%3@l")
10005
10006 ;; If the TOC is shared over a translation unit, as happens with all
10007 ;; the kinds of PIC that we support, we need to restore the TOC
10008 ;; pointer only when jumping over units of translation.
10009 ;; On Darwin, we need to reload the picbase.
10010
10011 (define_expand "builtin_setjmp_receiver"
10012   [(use (label_ref (match_operand 0 "")))]
10013   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10014    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10015    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10016 {
10017 #if TARGET_MACHO
10018   if (DEFAULT_ABI == ABI_DARWIN)
10019     {
10020       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10021       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10022       rtx tmplabrtx;
10023       char tmplab[20];
10024
10025       crtl->uses_pic_offset_table = 1;
10026       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10027                                   CODE_LABEL_NUMBER (operands[0]));
10028       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10029
10030       emit_insn (gen_load_macho_picbase (tmplabrtx));
10031       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10032       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10033     }
10034   else
10035 #endif
10036     rs6000_emit_load_toc_table (FALSE);
10037   DONE;
10038 })
10039
10040 ;; Largetoc support
10041 (define_insn "*largetoc_high"
10042   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10043         (high:DI
10044           (unspec [(match_operand:DI 1 "" "")
10045                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10046                   UNSPEC_TOCREL)))]
10047    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10048    "addis %0,%2,%1@toc@ha")
10049
10050 (define_insn "*largetoc_high_aix<mode>"
10051   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10052         (high:P
10053           (unspec [(match_operand:P 1 "" "")
10054                    (match_operand:P 2 "gpc_reg_operand" "b")]
10055                   UNSPEC_TOCREL)))]
10056    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10057    "addis %0,%1@u(%2)")
10058
10059 (define_insn "*largetoc_high_plus"
10060   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10061         (high:DI
10062           (plus:DI
10063             (unspec [(match_operand:DI 1 "" "")
10064                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10065                     UNSPEC_TOCREL)
10066             (match_operand:DI 3 "add_cint_operand" "n"))))]
10067    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10068    "addis %0,%2,%1+%3@toc@ha")
10069
10070 (define_insn "*largetoc_high_plus_aix<mode>"
10071   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10072         (high:P
10073           (plus:P
10074             (unspec [(match_operand:P 1 "" "")
10075                      (match_operand:P 2 "gpc_reg_operand" "b")]
10076                     UNSPEC_TOCREL)
10077             (match_operand:P 3 "add_cint_operand" "n"))))]
10078    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10079    "addis %0,%1+%3@u(%2)")
10080
10081 (define_insn "*largetoc_low"
10082   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10083         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10084                    (match_operand:DI 2 "" "")))]
10085    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10086    "addi %0,%1,%2@l")
10087
10088 (define_insn "*largetoc_low_aix<mode>"
10089   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10090         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10091                    (match_operand:P 2 "" "")))]
10092    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10093    "la %0,%2@l(%1)")
10094
10095 (define_insn_and_split "*tocref<mode>"
10096   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10097         (match_operand:P 1 "small_toc_ref" "R"))]
10098    "TARGET_TOC"
10099    "la %0,%a1"
10100    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10101   [(set (match_dup 0) (high:P (match_dup 1)))
10102    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10103
10104 ;; Elf specific ways of loading addresses for non-PIC code.
10105 ;; The output of this could be r0, but we make a very strong
10106 ;; preference for a base register because it will usually
10107 ;; be needed there.
10108 (define_insn "elf_high"
10109   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10110         (high:SI (match_operand 1 "" "")))]
10111   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10112   "lis %0,%1@ha")
10113
10114 (define_insn "elf_low"
10115   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10116         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10117                    (match_operand 2 "" "")))]
10118    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10119    "la %0,%2@l(%1)")
10120 \f
10121 ;; Call and call_value insns
10122 (define_expand "call"
10123   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10124                     (match_operand 1 ""))
10125               (use (match_operand 2 ""))
10126               (clobber (reg:SI LR_REGNO))])]
10127   ""
10128 {
10129 #if TARGET_MACHO
10130   if (MACHOPIC_INDIRECT)
10131     operands[0] = machopic_indirect_call_target (operands[0]);
10132 #endif
10133
10134   gcc_assert (GET_CODE (operands[0]) == MEM);
10135   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10136
10137   operands[0] = XEXP (operands[0], 0);
10138
10139   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10140     {
10141       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10142       DONE;
10143     }
10144
10145   if (GET_CODE (operands[0]) != SYMBOL_REF
10146       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10147     {
10148       if (INTVAL (operands[2]) & CALL_LONG)
10149         operands[0] = rs6000_longcall_ref (operands[0]);
10150
10151       switch (DEFAULT_ABI)
10152         {
10153         case ABI_V4:
10154         case ABI_DARWIN:
10155           operands[0] = force_reg (Pmode, operands[0]);
10156           break;
10157
10158         default:
10159           gcc_unreachable ();
10160         }
10161     }
10162 })
10163
10164 (define_expand "call_value"
10165   [(parallel [(set (match_operand 0 "")
10166                    (call (mem:SI (match_operand 1 "address_operand"))
10167                          (match_operand 2 "")))
10168               (use (match_operand 3 ""))
10169               (clobber (reg:SI LR_REGNO))])]
10170   ""
10171 {
10172 #if TARGET_MACHO
10173   if (MACHOPIC_INDIRECT)
10174     operands[1] = machopic_indirect_call_target (operands[1]);
10175 #endif
10176
10177   gcc_assert (GET_CODE (operands[1]) == MEM);
10178   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10179
10180   operands[1] = XEXP (operands[1], 0);
10181
10182   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10183     {
10184       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10185       DONE;
10186     }
10187
10188   if (GET_CODE (operands[1]) != SYMBOL_REF
10189       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10190     {
10191       if (INTVAL (operands[3]) & CALL_LONG)
10192         operands[1] = rs6000_longcall_ref (operands[1]);
10193
10194       switch (DEFAULT_ABI)
10195         {
10196         case ABI_V4:
10197         case ABI_DARWIN:
10198           operands[1] = force_reg (Pmode, operands[1]);
10199           break;
10200
10201         default:
10202           gcc_unreachable ();
10203         }
10204     }
10205 })
10206
10207 ;; Call to function in current module.  No TOC pointer reload needed.
10208 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10209 ;; either the function was not prototyped, or it was prototyped as a
10210 ;; variable argument function.  It is > 0 if FP registers were passed
10211 ;; and < 0 if they were not.
10212
10213 (define_insn "*call_local32"
10214   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10215          (match_operand 1 "" "g,g"))
10216    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10217    (clobber (reg:SI LR_REGNO))]
10218   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10219 {
10220   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10221     output_asm_insn ("crxor 6,6,6", operands);
10222
10223   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10224     output_asm_insn ("creqv 6,6,6", operands);
10225
10226   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10227 }
10228   [(set_attr "type" "branch")
10229    (set_attr "length" "4,8")])
10230
10231 (define_insn "*call_local64"
10232   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10233          (match_operand 1 "" "g,g"))
10234    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10235    (clobber (reg:SI LR_REGNO))]
10236   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10237 {
10238   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10239     output_asm_insn ("crxor 6,6,6", operands);
10240
10241   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10242     output_asm_insn ("creqv 6,6,6", operands);
10243
10244   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10245 }
10246   [(set_attr "type" "branch")
10247    (set_attr "length" "4,8")])
10248
10249 (define_insn "*call_value_local32"
10250   [(set (match_operand 0 "" "")
10251         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10252               (match_operand 2 "" "g,g")))
10253    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10254    (clobber (reg:SI LR_REGNO))]
10255   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10256 {
10257   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10258     output_asm_insn ("crxor 6,6,6", operands);
10259
10260   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10261     output_asm_insn ("creqv 6,6,6", operands);
10262
10263   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10264 }
10265   [(set_attr "type" "branch")
10266    (set_attr "length" "4,8")])
10267
10268
10269 (define_insn "*call_value_local64"
10270   [(set (match_operand 0 "" "")
10271         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10272               (match_operand 2 "" "g,g")))
10273    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10274    (clobber (reg:SI LR_REGNO))]
10275   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10276 {
10277   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10278     output_asm_insn ("crxor 6,6,6", operands);
10279
10280   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10281     output_asm_insn ("creqv 6,6,6", operands);
10282
10283   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10284 }
10285   [(set_attr "type" "branch")
10286    (set_attr "length" "4,8")])
10287
10288
10289 ;; A function pointer under System V is just a normal pointer
10290 ;; operands[0] is the function pointer
10291 ;; operands[1] is the stack size to clean up
10292 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10293 ;; which indicates how to set cr1
10294
10295 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10296   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10297          (match_operand 1 "" "g,g,g,g"))
10298    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10299    (clobber (reg:SI LR_REGNO))]
10300   "DEFAULT_ABI == ABI_V4
10301    || DEFAULT_ABI == ABI_DARWIN"
10302 {
10303   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10304     output_asm_insn ("crxor 6,6,6", operands);
10305
10306   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10307     output_asm_insn ("creqv 6,6,6", operands);
10308
10309   if (rs6000_speculate_indirect_jumps
10310       || which_alternative == 1 || which_alternative == 3)
10311     return "b%T0l";
10312   else
10313     return "crset 2\;beq%T0l-";
10314 }
10315   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10316    (set (attr "length")
10317         (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10318                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10319                         (const_int 0)))
10320                   (const_string "8")
10321                (and (eq (symbol_ref "which_alternative") (const_int 2))
10322                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10323                         (const_int 0)))
10324                   (const_string "8")
10325                (and (eq (symbol_ref "which_alternative") (const_int 2))
10326                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10327                         (const_int 0)))
10328                   (const_string "12")
10329                (eq (symbol_ref "which_alternative") (const_int 3))
10330                   (const_string "8")]
10331               (const_string "4")))])
10332
10333 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10334   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10335          (match_operand 1 "" "g,g"))
10336    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10337    (clobber (reg:SI LR_REGNO))]
10338   "(DEFAULT_ABI == ABI_DARWIN
10339    || (DEFAULT_ABI == ABI_V4
10340        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10341 {
10342   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10343     output_asm_insn ("crxor 6,6,6", operands);
10344
10345   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10346     output_asm_insn ("creqv 6,6,6", operands);
10347
10348 #if TARGET_MACHO
10349   return output_call(insn, operands, 0, 2);
10350 #else
10351   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10352     {
10353       gcc_assert (!TARGET_SECURE_PLT);
10354       return "bl %z0@plt";
10355     }
10356   else
10357     return "bl %z0";
10358 #endif
10359 }
10360   "DEFAULT_ABI == ABI_V4
10361    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10362    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10363   [(parallel [(call (mem:SI (match_dup 0))
10364                     (match_dup 1))
10365               (use (match_dup 2))
10366               (use (match_dup 3))
10367               (clobber (reg:SI LR_REGNO))])]
10368 {
10369   operands[3] = pic_offset_table_rtx;
10370 }
10371   [(set_attr "type" "branch,branch")
10372    (set_attr "length" "4,8")])
10373
10374 (define_insn "*call_nonlocal_sysv_secure<mode>"
10375   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10376          (match_operand 1 "" "g,g"))
10377    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10378    (use (match_operand:SI 3 "register_operand" "r,r"))
10379    (clobber (reg:SI LR_REGNO))]
10380   "(DEFAULT_ABI == ABI_V4
10381     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10382     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10383 {
10384   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10385     output_asm_insn ("crxor 6,6,6", operands);
10386
10387   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10388     output_asm_insn ("creqv 6,6,6", operands);
10389
10390   if (flag_pic == 2)
10391     /* The magic 32768 offset here and in the other sysv call insns
10392        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10393        See sysv4.h:toc_section.  */
10394     return "bl %z0+32768@plt";
10395   else
10396     return "bl %z0@plt";
10397 }
10398   [(set_attr "type" "branch,branch")
10399    (set_attr "length" "4,8")])
10400
10401 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10402   [(set (match_operand 0 "" "")
10403         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10404               (match_operand 2 "" "g,g,g,g")))
10405    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10406    (clobber (reg:SI LR_REGNO))]
10407   "DEFAULT_ABI == ABI_V4
10408    || DEFAULT_ABI == ABI_DARWIN"
10409 {
10410   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10411     output_asm_insn ("crxor 6,6,6", operands);
10412
10413   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10414     output_asm_insn ("creqv 6,6,6", operands);
10415
10416   if (rs6000_speculate_indirect_jumps
10417       || which_alternative == 1 || which_alternative == 3)
10418     return "b%T1l";
10419   else
10420     return "crset 2\;beq%T1l-";
10421 }
10422   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10423    (set (attr "length")
10424         (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10425                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10426                         (const_int 0)))
10427                   (const_string "8")
10428                (and (eq (symbol_ref "which_alternative") (const_int 2))
10429                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10430                         (const_int 0)))
10431                   (const_string "8")
10432                (and (eq (symbol_ref "which_alternative") (const_int 2))
10433                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10434                         (const_int 0)))
10435                   (const_string "12")
10436                (eq (symbol_ref "which_alternative") (const_int 3))
10437                   (const_string "8")]
10438               (const_string "4")))])
10439
10440 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10441   [(set (match_operand 0 "" "")
10442         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10443               (match_operand 2 "" "g,g")))
10444    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10445    (clobber (reg:SI LR_REGNO))]
10446   "(DEFAULT_ABI == ABI_DARWIN
10447    || (DEFAULT_ABI == ABI_V4
10448        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10449 {
10450   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10451     output_asm_insn ("crxor 6,6,6", operands);
10452
10453   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10454     output_asm_insn ("creqv 6,6,6", operands);
10455
10456 #if TARGET_MACHO
10457   return output_call(insn, operands, 1, 3);
10458 #else
10459   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10460     {
10461       gcc_assert (!TARGET_SECURE_PLT);
10462       return "bl %z1@plt";
10463     }
10464   else
10465     return "bl %z1";
10466 #endif
10467 }
10468   "DEFAULT_ABI == ABI_V4
10469    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10470    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10471   [(parallel [(set (match_dup 0)
10472                    (call (mem:SI (match_dup 1))
10473                          (match_dup 2)))
10474               (use (match_dup 3))
10475               (use (match_dup 4))
10476               (clobber (reg:SI LR_REGNO))])]
10477 {
10478   operands[4] = pic_offset_table_rtx;
10479 }
10480   [(set_attr "type" "branch,branch")
10481    (set_attr "length" "4,8")])
10482
10483 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10484   [(set (match_operand 0 "" "")
10485         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10486               (match_operand 2 "" "g,g")))
10487    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10488    (use (match_operand:SI 4 "register_operand" "r,r"))
10489    (clobber (reg:SI LR_REGNO))]
10490   "(DEFAULT_ABI == ABI_V4
10491     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10492     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10493 {
10494   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10495     output_asm_insn ("crxor 6,6,6", operands);
10496
10497   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10498     output_asm_insn ("creqv 6,6,6", operands);
10499
10500   if (flag_pic == 2)
10501     return "bl %z1+32768@plt";
10502   else
10503     return "bl %z1@plt";
10504 }
10505   [(set_attr "type" "branch,branch")
10506    (set_attr "length" "4,8")])
10507
10508
10509 ;; Call to AIX abi function in the same module.
10510
10511 (define_insn "*call_local_aix<mode>"
10512   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10513          (match_operand 1 "" "g"))
10514    (clobber (reg:P LR_REGNO))]
10515   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10516   "bl %z0"
10517   [(set_attr "type" "branch")
10518    (set_attr "length" "4")])
10519
10520 (define_insn "*call_value_local_aix<mode>"
10521   [(set (match_operand 0 "" "")
10522         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10523               (match_operand 2 "" "g")))
10524    (clobber (reg:P LR_REGNO))]
10525   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10526   "bl %z1"
10527   [(set_attr "type" "branch")
10528    (set_attr "length" "4")])
10529
10530 ;; Call to AIX abi function which may be in another module.
10531 ;; Restore the TOC pointer (r2) after the call.
10532
10533 (define_insn "*call_nonlocal_aix<mode>"
10534   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10535          (match_operand 1 "" "g"))
10536    (clobber (reg:P LR_REGNO))]
10537   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10538   "bl %z0\;nop"
10539   [(set_attr "type" "branch")
10540    (set_attr "length" "8")])
10541
10542 (define_insn "*call_value_nonlocal_aix<mode>"
10543   [(set (match_operand 0 "" "")
10544         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10545               (match_operand 2 "" "g")))
10546    (clobber (reg:P LR_REGNO))]
10547   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10548   "bl %z1\;nop"
10549   [(set_attr "type" "branch")
10550    (set_attr "length" "8")])
10551
10552 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10553 ;; Operand0 is the addresss of the function to call
10554 ;; Operand2 is the location in the function descriptor to load r2 from
10555 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10556
10557 (define_insn "*call_indirect_aix<mode>"
10558   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10559          (match_operand 1 "" "g,g"))
10560    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10561    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10562    (clobber (reg:P LR_REGNO))]
10563   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10564   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10565   [(set_attr "type" "jmpreg")
10566    (set_attr "length" "12")])
10567
10568 (define_insn "*call_indirect_aix<mode>_nospec"
10569   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10570          (match_operand 1 "" "g,g"))
10571    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10572    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10573    (clobber (reg:P LR_REGNO))]
10574   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10575   "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10576   [(set_attr "type" "jmpreg")
10577    (set_attr "length" "16")])
10578
10579 (define_insn "*call_value_indirect_aix<mode>"
10580   [(set (match_operand 0 "" "")
10581         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10582               (match_operand 2 "" "g,g")))
10583    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10584    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10585    (clobber (reg:P LR_REGNO))]
10586   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10587   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10588   [(set_attr "type" "jmpreg")
10589    (set_attr "length" "12")])
10590
10591 (define_insn "*call_value_indirect_aix<mode>_nospec"
10592   [(set (match_operand 0 "" "")
10593         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10594               (match_operand 2 "" "g,g")))
10595    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10596    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10597    (clobber (reg:P LR_REGNO))]
10598   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10599   "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10600   [(set_attr "type" "jmpreg")
10601    (set_attr "length" "16")])
10602
10603 ;; Call to indirect functions with the ELFv2 ABI.
10604 ;; Operand0 is the addresss of the function to call
10605 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10606
10607 (define_insn "*call_indirect_elfv2<mode>"
10608   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10609          (match_operand 1 "" "g,g"))
10610    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10611    (clobber (reg:P LR_REGNO))]
10612   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10613   "b%T0l\;<ptrload> 2,%2(1)"
10614   [(set_attr "type" "jmpreg")
10615    (set_attr "length" "8")])
10616
10617 ;; Variant with deliberate misprediction.
10618 (define_insn "*call_indirect_elfv2<mode>_nospec"
10619   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10620          (match_operand 1 "" "g,g"))
10621    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10622    (clobber (reg:P LR_REGNO))]
10623   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10624   "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10625   [(set_attr "type" "jmpreg")
10626    (set_attr "length" "12")])
10627
10628 (define_insn "*call_value_indirect_elfv2<mode>"
10629   [(set (match_operand 0 "" "")
10630         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10631               (match_operand 2 "" "g,g")))
10632    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10633    (clobber (reg:P LR_REGNO))]
10634   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10635   "b%T1l\;<ptrload> 2,%3(1)"
10636   [(set_attr "type" "jmpreg")
10637    (set_attr "length" "8")])
10638
10639 ; Variant with deliberate misprediction.
10640 (define_insn "*call_value_indirect_elfv2<mode>_nospec"
10641   [(set (match_operand 0 "" "")
10642         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10643               (match_operand 2 "" "g,g")))
10644    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10645    (clobber (reg:P LR_REGNO))]
10646   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10647   "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10648   [(set_attr "type" "jmpreg")
10649    (set_attr "length" "12")])
10650
10651 ;; Call subroutine returning any type.
10652 (define_expand "untyped_call"
10653   [(parallel [(call (match_operand 0 "")
10654                     (const_int 0))
10655               (match_operand 1 "")
10656               (match_operand 2 "")])]
10657   ""
10658 {
10659   int i;
10660
10661   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10662
10663   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10664     {
10665       rtx set = XVECEXP (operands[2], 0, i);
10666       emit_move_insn (SET_DEST (set), SET_SRC (set));
10667     }
10668
10669   /* The optimizer does not know that the call sets the function value
10670      registers we stored in the result block.  We avoid problems by
10671      claiming that all hard registers are used and clobbered at this
10672      point.  */
10673   emit_insn (gen_blockage ());
10674
10675   DONE;
10676 })
10677
10678 ;; sibling call patterns
10679 (define_expand "sibcall"
10680   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10681                     (match_operand 1 ""))
10682               (use (match_operand 2 ""))
10683               (simple_return)])]
10684   ""
10685 {
10686 #if TARGET_MACHO
10687   if (MACHOPIC_INDIRECT)
10688     operands[0] = machopic_indirect_call_target (operands[0]);
10689 #endif
10690
10691   gcc_assert (GET_CODE (operands[0]) == MEM);
10692   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10693
10694   operands[0] = XEXP (operands[0], 0);
10695
10696   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10697     {
10698       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10699       DONE;
10700     }
10701 })
10702
10703 (define_expand "sibcall_value"
10704   [(parallel [(set (match_operand 0 "register_operand")
10705                 (call (mem:SI (match_operand 1 "address_operand"))
10706                       (match_operand 2 "")))
10707               (use (match_operand 3 ""))
10708               (simple_return)])]
10709   ""
10710 {
10711 #if TARGET_MACHO
10712   if (MACHOPIC_INDIRECT)
10713     operands[1] = machopic_indirect_call_target (operands[1]);
10714 #endif
10715
10716   gcc_assert (GET_CODE (operands[1]) == MEM);
10717   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10718
10719   operands[1] = XEXP (operands[1], 0);
10720
10721   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10722     {
10723       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10724       DONE;
10725     }
10726 })
10727
10728 (define_insn "*sibcall_local32"
10729   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10730          (match_operand 1 "" "g,g"))
10731    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10732    (simple_return)]
10733   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10734 {
10735   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10736     output_asm_insn ("crxor 6,6,6", operands);
10737
10738   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10739     output_asm_insn ("creqv 6,6,6", operands);
10740
10741   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10742 }
10743   [(set_attr "type" "branch")
10744    (set_attr "length" "4,8")])
10745
10746 (define_insn "*sibcall_local64"
10747   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10748          (match_operand 1 "" "g,g"))
10749    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10750    (simple_return)]
10751   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10752 {
10753   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10754     output_asm_insn ("crxor 6,6,6", operands);
10755
10756   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10757     output_asm_insn ("creqv 6,6,6", operands);
10758
10759   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10760 }
10761   [(set_attr "type" "branch")
10762    (set_attr "length" "4,8")])
10763
10764 (define_insn "*sibcall_value_local32"
10765   [(set (match_operand 0 "" "")
10766         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10767               (match_operand 2 "" "g,g")))
10768    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10769    (simple_return)]
10770   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10771 {
10772   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10773     output_asm_insn ("crxor 6,6,6", operands);
10774
10775   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10776     output_asm_insn ("creqv 6,6,6", operands);
10777
10778   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10779 }
10780   [(set_attr "type" "branch")
10781    (set_attr "length" "4,8")])
10782
10783 (define_insn "*sibcall_value_local64"
10784   [(set (match_operand 0 "" "")
10785         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10786               (match_operand 2 "" "g,g")))
10787    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10788    (simple_return)]
10789   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10790 {
10791   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10792     output_asm_insn ("crxor 6,6,6", operands);
10793
10794   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10795     output_asm_insn ("creqv 6,6,6", operands);
10796
10797   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10798 }
10799   [(set_attr "type" "branch")
10800    (set_attr "length" "4,8")])
10801
10802 (define_insn "*sibcall_nonlocal_sysv<mode>"
10803   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10804          (match_operand 1 "" ""))
10805    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10806    (simple_return)]
10807   "(DEFAULT_ABI == ABI_DARWIN
10808     || DEFAULT_ABI == ABI_V4)
10809    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10810 {
10811   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10812     output_asm_insn ("crxor 6,6,6", operands);
10813
10814   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10815     output_asm_insn ("creqv 6,6,6", operands);
10816
10817   if (which_alternative >= 2)
10818     {
10819       if (rs6000_speculate_indirect_jumps)
10820         return "b%T0";
10821       else
10822         /* Can use CR0 since it is volatile across sibcalls.  */
10823         return "crset 2\;beq%T0-\;b $";
10824     }
10825   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10826     {
10827       gcc_assert (!TARGET_SECURE_PLT);
10828       return "b %z0@plt";
10829     }
10830   else
10831     return "b %z0";
10832 }
10833   [(set_attr "type" "branch")
10834    (set (attr "length")
10835         (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10836                   (const_string "8")
10837                (and (eq (symbol_ref "which_alternative") (const_int 2))
10838                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10839                         (const_int 0)))
10840                   (const_string "12")
10841                (and (eq (symbol_ref "which_alternative") (const_int 3))
10842                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10843                         (const_int 0)))
10844                   (const_string "8")
10845                (and (eq (symbol_ref "which_alternative") (const_int 3))
10846                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10847                         (const_int 0)))
10848                   (const_string "16")]
10849               (const_string "4")))])
10850
10851 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10852   [(set (match_operand 0 "" "")
10853         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10854               (match_operand 2 "" "")))
10855    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10856    (simple_return)]
10857   "(DEFAULT_ABI == ABI_DARWIN
10858     || DEFAULT_ABI == ABI_V4)
10859    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10860 {
10861   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10862     output_asm_insn ("crxor 6,6,6", operands);
10863
10864   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10865     output_asm_insn ("creqv 6,6,6", operands);
10866
10867   if (which_alternative >= 2)
10868     {
10869       if (rs6000_speculate_indirect_jumps)
10870         return "b%T1";
10871       else
10872         /* Can use CR0 since it is volatile across sibcalls.  */
10873         return "crset 2\;beq%T1-\;b $";
10874     }
10875   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10876     {
10877       gcc_assert (!TARGET_SECURE_PLT);
10878       return "b %z1@plt";
10879     }
10880   else
10881     return "b %z1";
10882 }
10883   [(set_attr "type" "branch")
10884    (set (attr "length")
10885         (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10886                   (const_string "8")
10887                (and (eq (symbol_ref "which_alternative") (const_int 2))
10888                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10889                         (const_int 0)))
10890                   (const_string "12")
10891                (and (eq (symbol_ref "which_alternative") (const_int 3))
10892                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10893                         (const_int 0)))
10894                   (const_string "8")
10895                (and (eq (symbol_ref "which_alternative") (const_int 3))
10896                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10897                         (const_int 0)))
10898                   (const_string "16")]
10899               (const_string "4")))])
10900
10901 ;; AIX ABI sibling call patterns.
10902
10903 (define_insn "*sibcall_aix<mode>"
10904   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10905          (match_operand 1 "" "g,g"))
10906    (simple_return)]
10907   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10908   "@
10909    b %z0
10910    b%T0"
10911   [(set_attr "type" "branch")
10912    (set_attr "length" "4")])
10913
10914 (define_insn "*sibcall_value_aix<mode>"
10915   [(set (match_operand 0 "" "")
10916         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10917               (match_operand 2 "" "g,g")))
10918    (simple_return)]
10919   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10920   "@
10921    b %z1
10922    b%T1"
10923   [(set_attr "type" "branch")
10924    (set_attr "length" "4")])
10925
10926 (define_expand "sibcall_epilogue"
10927   [(use (const_int 0))]
10928   ""
10929 {
10930   if (!TARGET_SCHED_PROLOG)
10931     emit_insn (gen_blockage ());
10932   rs6000_emit_epilogue (TRUE);
10933   DONE;
10934 })
10935
10936 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10937 ;; all of memory.  This blocks insns from being moved across this point.
10938
10939 (define_insn "blockage"
10940   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10941   ""
10942   ""
10943   [(set_attr "length" "0")])
10944
10945 (define_expand "probe_stack_address"
10946   [(use (match_operand 0 "address_operand"))]
10947   ""
10948 {
10949   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10950   MEM_VOLATILE_P (operands[0]) = 1;
10951
10952   if (TARGET_64BIT)
10953     emit_insn (gen_probe_stack_di (operands[0]));
10954   else
10955     emit_insn (gen_probe_stack_si (operands[0]));
10956   DONE;
10957 })
10958
10959 (define_insn "probe_stack_<mode>"
10960   [(set (match_operand:P 0 "memory_operand" "=m")
10961         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10962   ""
10963 {
10964   operands[1] = gen_rtx_REG (Pmode, 0);
10965   return "st<wd>%U0%X0 %1,%0";
10966 }
10967   [(set_attr "type" "store")
10968    (set (attr "update")
10969         (if_then_else (match_operand 0 "update_address_mem")
10970                       (const_string "yes")
10971                       (const_string "no")))
10972    (set (attr "indexed")
10973         (if_then_else (match_operand 0 "indexed_address_mem")
10974                       (const_string "yes")
10975                       (const_string "no")))
10976    (set_attr "length" "4")])
10977
10978 (define_insn "probe_stack_range<P:mode>"
10979   [(set (match_operand:P 0 "register_operand" "=&r")
10980         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10981                             (match_operand:P 2 "register_operand" "r")
10982                             (match_operand:P 3 "register_operand" "r")]
10983                            UNSPECV_PROBE_STACK_RANGE))]
10984   ""
10985   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
10986   [(set_attr "type" "three")])
10987 \f
10988 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
10989 ;; signed & unsigned, and one type of branch.
10990 ;;
10991 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10992 ;; insns, and branches.
10993
10994 (define_expand "cbranch<mode>4"
10995   [(use (match_operator 0 "comparison_operator"
10996          [(match_operand:GPR 1 "gpc_reg_operand")
10997           (match_operand:GPR 2 "reg_or_short_operand")]))
10998    (use (match_operand 3))]
10999   ""
11000 {
11001   /* Take care of the possibility that operands[2] might be negative but
11002      this might be a logical operation.  That insn doesn't exist.  */
11003   if (GET_CODE (operands[2]) == CONST_INT
11004       && INTVAL (operands[2]) < 0)
11005     {
11006       operands[2] = force_reg (<MODE>mode, operands[2]);
11007       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11008                                     GET_MODE (operands[0]),
11009                                     operands[1], operands[2]);
11010    }
11011
11012   rs6000_emit_cbranch (<MODE>mode, operands);
11013   DONE;
11014 })
11015
11016 (define_expand "cbranch<mode>4"
11017   [(use (match_operator 0 "comparison_operator"
11018          [(match_operand:FP 1 "gpc_reg_operand")
11019           (match_operand:FP 2 "gpc_reg_operand")]))
11020    (use (match_operand 3))]
11021   ""
11022 {
11023   rs6000_emit_cbranch (<MODE>mode, operands);
11024   DONE;
11025 })
11026
11027 (define_expand "cstore<mode>4_signed"
11028   [(use (match_operator 1 "signed_comparison_operator"
11029          [(match_operand:P 2 "gpc_reg_operand")
11030           (match_operand:P 3 "gpc_reg_operand")]))
11031    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11032   ""
11033 {
11034   enum rtx_code cond_code = GET_CODE (operands[1]);
11035
11036   rtx op0 = operands[0];
11037   rtx op1 = operands[2];
11038   rtx op2 = operands[3];
11039
11040   if (cond_code == GE || cond_code == LT)
11041     {
11042       cond_code = swap_condition (cond_code);
11043       std::swap (op1, op2);
11044     }
11045
11046   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11047   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11048   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11049
11050   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11051   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11052   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11053
11054   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11055
11056   if (cond_code == LE)
11057     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11058   else
11059     {
11060       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11061       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11062       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11063     }
11064
11065   DONE;
11066 })
11067
11068 (define_expand "cstore<mode>4_unsigned"
11069   [(use (match_operator 1 "unsigned_comparison_operator"
11070          [(match_operand:P 2 "gpc_reg_operand")
11071           (match_operand:P 3 "reg_or_short_operand")]))
11072    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11073   ""
11074 {
11075   enum rtx_code cond_code = GET_CODE (operands[1]);
11076
11077   rtx op0 = operands[0];
11078   rtx op1 = operands[2];
11079   rtx op2 = operands[3];
11080
11081   if (cond_code == GEU || cond_code == LTU)
11082     {
11083       cond_code = swap_condition (cond_code);
11084       std::swap (op1, op2);
11085     }
11086
11087   if (!gpc_reg_operand (op1, <MODE>mode))
11088     op1 = force_reg (<MODE>mode, op1);
11089   if (!reg_or_short_operand (op2, <MODE>mode))
11090     op2 = force_reg (<MODE>mode, op2);
11091
11092   rtx tmp = gen_reg_rtx (<MODE>mode);
11093   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11094
11095   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11096   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11097
11098   if (cond_code == LEU)
11099     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11100   else
11101     emit_insn (gen_neg<mode>2 (op0, tmp2));
11102
11103   DONE;
11104 })
11105
11106 (define_expand "cstore_si_as_di"
11107   [(use (match_operator 1 "unsigned_comparison_operator"
11108          [(match_operand:SI 2 "gpc_reg_operand")
11109           (match_operand:SI 3 "reg_or_short_operand")]))
11110    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11111   ""
11112 {
11113   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11114   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11115
11116   operands[2] = force_reg (SImode, operands[2]);
11117   operands[3] = force_reg (SImode, operands[3]);
11118   rtx op1 = gen_reg_rtx (DImode);
11119   rtx op2 = gen_reg_rtx (DImode);
11120   convert_move (op1, operands[2], uns_flag);
11121   convert_move (op2, operands[3], uns_flag);
11122
11123   if (cond_code == GT || cond_code == LE)
11124     {
11125       cond_code = swap_condition (cond_code);
11126       std::swap (op1, op2);
11127     }
11128
11129   rtx tmp = gen_reg_rtx (DImode);
11130   rtx tmp2 = gen_reg_rtx (DImode);
11131   emit_insn (gen_subdi3 (tmp, op1, op2));
11132   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11133
11134   rtx tmp3;
11135   switch (cond_code)
11136     {
11137     default:
11138       gcc_unreachable ();
11139     case LT:
11140       tmp3 = tmp2;
11141       break;
11142     case GE:
11143       tmp3 = gen_reg_rtx (DImode);
11144       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11145       break;
11146     }
11147
11148   convert_move (operands[0], tmp3, 1);
11149
11150   DONE;
11151 })
11152
11153 (define_expand "cstore<mode>4_signed_imm"
11154   [(use (match_operator 1 "signed_comparison_operator"
11155          [(match_operand:GPR 2 "gpc_reg_operand")
11156           (match_operand:GPR 3 "immediate_operand")]))
11157    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11158   ""
11159 {
11160   bool invert = false;
11161
11162   enum rtx_code cond_code = GET_CODE (operands[1]);
11163
11164   rtx op0 = operands[0];
11165   rtx op1 = operands[2];
11166   HOST_WIDE_INT val = INTVAL (operands[3]);
11167
11168   if (cond_code == GE || cond_code == GT)
11169     {
11170       cond_code = reverse_condition (cond_code);
11171       invert = true;
11172     }
11173
11174   if (cond_code == LE)
11175     val++;
11176
11177   rtx tmp = gen_reg_rtx (<MODE>mode);
11178   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11179   rtx x = gen_reg_rtx (<MODE>mode);
11180   if (val < 0)
11181     emit_insn (gen_and<mode>3 (x, op1, tmp));
11182   else
11183     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11184
11185   if (invert)
11186     {
11187       rtx tmp = gen_reg_rtx (<MODE>mode);
11188       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11189       x = tmp;
11190     }
11191
11192   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11193   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11194
11195   DONE;
11196 })
11197
11198 (define_expand "cstore<mode>4_unsigned_imm"
11199   [(use (match_operator 1 "unsigned_comparison_operator"
11200          [(match_operand:GPR 2 "gpc_reg_operand")
11201           (match_operand:GPR 3 "immediate_operand")]))
11202    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11203   ""
11204 {
11205   bool invert = false;
11206
11207   enum rtx_code cond_code = GET_CODE (operands[1]);
11208
11209   rtx op0 = operands[0];
11210   rtx op1 = operands[2];
11211   HOST_WIDE_INT val = INTVAL (operands[3]);
11212
11213   if (cond_code == GEU || cond_code == GTU)
11214     {
11215       cond_code = reverse_condition (cond_code);
11216       invert = true;
11217     }
11218
11219   if (cond_code == LEU)
11220     val++;
11221
11222   rtx tmp = gen_reg_rtx (<MODE>mode);
11223   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11224   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11225   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11226   rtx x = gen_reg_rtx (<MODE>mode);
11227   if (val < 0)
11228     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11229   else
11230     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11231
11232   if (invert)
11233     {
11234       rtx tmp = gen_reg_rtx (<MODE>mode);
11235       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11236       x = tmp;
11237     }
11238
11239   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11240   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11241
11242   DONE;
11243 })
11244
11245 (define_expand "cstore<mode>4"
11246   [(use (match_operator 1 "comparison_operator"
11247          [(match_operand:GPR 2 "gpc_reg_operand")
11248           (match_operand:GPR 3 "reg_or_short_operand")]))
11249    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11250   ""
11251 {
11252   /* Expanding EQ and NE directly to some machine instructions does not help
11253      but does hurt combine.  So don't.  */
11254   if (GET_CODE (operands[1]) == EQ)
11255     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11256   else if (<MODE>mode == Pmode
11257            && GET_CODE (operands[1]) == NE)
11258     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11259   else if (GET_CODE (operands[1]) == NE)
11260     {
11261       rtx tmp = gen_reg_rtx (<MODE>mode);
11262       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11263       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11264     }
11265
11266   /* If ISEL is fast, expand to it.  */
11267   else if (TARGET_ISEL)
11268     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11269
11270   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11271      etc. combinations magically work out just right.  */
11272   else if (<MODE>mode == Pmode
11273            && unsigned_comparison_operator (operands[1], VOIDmode))
11274     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11275                                            operands[2], operands[3]));
11276
11277   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11278   else if (<MODE>mode == SImode && Pmode == DImode)
11279     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11280                                     operands[2], operands[3]));
11281
11282   /* For signed comparisons against a constant, we can do some simple
11283      bit-twiddling.  */
11284   else if (signed_comparison_operator (operands[1], VOIDmode)
11285            && CONST_INT_P (operands[3]))
11286     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11287                                              operands[2], operands[3]));
11288
11289   /* And similarly for unsigned comparisons.  */
11290   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11291            && CONST_INT_P (operands[3]))
11292     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11293                                                operands[2], operands[3]));
11294
11295   /* We also do not want to use mfcr for signed comparisons.  */
11296   else if (<MODE>mode == Pmode
11297            && signed_comparison_operator (operands[1], VOIDmode))
11298     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11299                                          operands[2], operands[3]));
11300
11301   /* Everything else, use the mfcr brute force.  */
11302   else
11303     rs6000_emit_sCOND (<MODE>mode, operands);
11304
11305   DONE;
11306 })
11307
11308 (define_expand "cstore<mode>4"
11309   [(use (match_operator 1 "comparison_operator"
11310          [(match_operand:FP 2 "gpc_reg_operand")
11311           (match_operand:FP 3 "gpc_reg_operand")]))
11312    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11313   ""
11314 {
11315   rs6000_emit_sCOND (<MODE>mode, operands);
11316   DONE;
11317 })
11318
11319
11320 (define_expand "stack_protect_set"
11321   [(match_operand 0 "memory_operand")
11322    (match_operand 1 "memory_operand")]
11323   ""
11324 {
11325   if (rs6000_stack_protector_guard == SSP_TLS)
11326     {
11327       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11328       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11329       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11330       operands[1] = gen_rtx_MEM (Pmode, addr);
11331     }
11332
11333   if (TARGET_64BIT)
11334     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11335   else
11336     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11337
11338   DONE;
11339 })
11340
11341 (define_insn "stack_protect_setsi"
11342   [(set (match_operand:SI 0 "memory_operand" "=m")
11343         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11344    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11345   "TARGET_32BIT"
11346   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11347   [(set_attr "type" "three")
11348    (set_attr "length" "12")])
11349
11350 (define_insn "stack_protect_setdi"
11351   [(set (match_operand:DI 0 "memory_operand" "=Y")
11352         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11353    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11354   "TARGET_64BIT"
11355   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11356   [(set_attr "type" "three")
11357    (set_attr "length" "12")])
11358
11359 (define_expand "stack_protect_test"
11360   [(match_operand 0 "memory_operand")
11361    (match_operand 1 "memory_operand")
11362    (match_operand 2 "")]
11363   ""
11364 {
11365   rtx guard = operands[1];
11366
11367   if (rs6000_stack_protector_guard == SSP_TLS)
11368     {
11369       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11370       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11371       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11372       guard = gen_rtx_MEM (Pmode, addr);
11373     }
11374
11375   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11376   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11377   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11378   emit_jump_insn (jump);
11379
11380   DONE;
11381 })
11382
11383 (define_insn "stack_protect_testsi"
11384   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11385         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11386                       (match_operand:SI 2 "memory_operand" "m,m")]
11387                      UNSPEC_SP_TEST))
11388    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11389    (clobber (match_scratch:SI 3 "=&r,&r"))]
11390   "TARGET_32BIT"
11391   "@
11392    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11393    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11394   [(set_attr "length" "16,20")])
11395
11396 (define_insn "stack_protect_testdi"
11397   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11398         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11399                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11400                      UNSPEC_SP_TEST))
11401    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11402    (clobber (match_scratch:DI 3 "=&r,&r"))]
11403   "TARGET_64BIT"
11404   "@
11405    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11406    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11407   [(set_attr "length" "16,20")])
11408
11409 \f
11410 ;; Here are the actual compare insns.
11411 (define_insn "*cmp<mode>_signed"
11412   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11413         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11414                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11415   ""
11416   "cmp<wd>%I2 %0,%1,%2"
11417   [(set_attr "type" "cmp")])
11418
11419 (define_insn "*cmp<mode>_unsigned"
11420   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11421         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11422                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11423   ""
11424   "cmpl<wd>%I2 %0,%1,%2"
11425   [(set_attr "type" "cmp")])
11426
11427 ;; If we are comparing a register for equality with a large constant,
11428 ;; we can do this with an XOR followed by a compare.  But this is profitable
11429 ;; only if the large constant is only used for the comparison (and in this
11430 ;; case we already have a register to reuse as scratch).
11431 ;;
11432 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11433 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11434
11435 (define_peephole2
11436   [(set (match_operand:SI 0 "register_operand")
11437         (match_operand:SI 1 "logical_const_operand"))
11438    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11439                        [(match_dup 0)
11440                         (match_operand:SI 2 "logical_const_operand")]))
11441    (set (match_operand:CC 4 "cc_reg_operand")
11442         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11443                     (match_dup 0)))
11444    (set (pc)
11445         (if_then_else (match_operator 6 "equality_operator"
11446                        [(match_dup 4) (const_int 0)])
11447                       (match_operand 7 "")
11448                       (match_operand 8 "")))]
11449   "peep2_reg_dead_p (3, operands[0])
11450    && peep2_reg_dead_p (4, operands[4])
11451    && REGNO (operands[0]) != REGNO (operands[5])"
11452  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11453   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11454   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11455  
11456 {
11457   /* Get the constant we are comparing against, and see what it looks like
11458      when sign-extended from 16 to 32 bits.  Then see what constant we could
11459      XOR with SEXTC to get the sign-extended value.  */
11460   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11461                                               SImode,
11462                                               operands[1], operands[2]);
11463   HOST_WIDE_INT c = INTVAL (cnst);
11464   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11465   HOST_WIDE_INT xorv = c ^ sextc;
11466
11467   operands[9] = GEN_INT (xorv);
11468   operands[10] = GEN_INT (sextc);
11469 })
11470
11471 ;; The following two insns don't exist as single insns, but if we provide
11472 ;; them, we can swap an add and compare, which will enable us to overlap more
11473 ;; of the required delay between a compare and branch.  We generate code for
11474 ;; them by splitting.
11475
11476 (define_insn ""
11477   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11478         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11479                     (match_operand:SI 2 "short_cint_operand" "i")))
11480    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11481         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11482   ""
11483   "#"
11484   [(set_attr "length" "8")])
11485
11486 (define_insn ""
11487   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11488         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11489                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11490    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11491         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11492   ""
11493   "#"
11494   [(set_attr "length" "8")])
11495
11496 (define_split
11497   [(set (match_operand:CC 3 "cc_reg_operand")
11498         (compare:CC (match_operand:SI 1 "gpc_reg_operand")
11499                     (match_operand:SI 2 "short_cint_operand")))
11500    (set (match_operand:SI 0 "gpc_reg_operand")
11501         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11502   ""
11503   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11504    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11505
11506 (define_split
11507   [(set (match_operand:CCUNS 3 "cc_reg_operand")
11508         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand")
11509                        (match_operand:SI 2 "u_short_cint_operand")))
11510    (set (match_operand:SI 0 "gpc_reg_operand")
11511         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11512   ""
11513   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11514    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11515
11516 ;; Only need to compare second words if first words equal
11517 (define_insn "*cmp<mode>_internal1"
11518   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11519         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11520                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11521   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11522    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11523   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11524   [(set_attr "type" "fpcompare")
11525    (set_attr "length" "12")])
11526
11527 (define_insn_and_split "*cmp<mode>_internal2"
11528   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11529         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11530                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11531     (clobber (match_scratch:DF 3 "=d"))
11532     (clobber (match_scratch:DF 4 "=d"))
11533     (clobber (match_scratch:DF 5 "=d"))
11534     (clobber (match_scratch:DF 6 "=d"))
11535     (clobber (match_scratch:DF 7 "=d"))
11536     (clobber (match_scratch:DF 8 "=d"))
11537     (clobber (match_scratch:DF 9 "=d"))
11538     (clobber (match_scratch:DF 10 "=d"))
11539     (clobber (match_scratch:GPR 11 "=b"))]
11540   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11541    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11542   "#"
11543   "&& reload_completed"
11544   [(set (match_dup 3) (match_dup 14))
11545    (set (match_dup 4) (match_dup 15))
11546    (set (match_dup 9) (abs:DF (match_dup 5)))
11547    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11548    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11549                            (label_ref (match_dup 12))
11550                            (pc)))
11551    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11552    (set (pc) (label_ref (match_dup 13)))
11553    (match_dup 12)
11554    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11555    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11556    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11557    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11558    (match_dup 13)]
11559 {
11560   REAL_VALUE_TYPE rv;
11561   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11562   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11563
11564   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11565   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11566   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11567   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11568   operands[12] = gen_label_rtx ();
11569   operands[13] = gen_label_rtx ();
11570   real_inf (&rv);
11571   operands[14] = force_const_mem (DFmode,
11572                                   const_double_from_real_value (rv, DFmode));
11573   operands[15] = force_const_mem (DFmode,
11574                                   const_double_from_real_value (dconst0,
11575                                                                 DFmode));
11576   if (TARGET_TOC)
11577     {
11578       rtx tocref;
11579       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11580       operands[14] = gen_const_mem (DFmode, tocref);
11581       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11582       operands[15] = gen_const_mem (DFmode, tocref);
11583       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11584       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11585     }
11586 })
11587 \f
11588 ;; Now we have the scc insns.  We can do some combinations because of the
11589 ;; way the machine works.
11590 ;;
11591 ;; Note that this is probably faster if we can put an insn between the
11592 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11593 ;; cases the insns below which don't use an intermediate CR field will
11594 ;; be used instead.
11595 (define_insn ""
11596   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11597         (match_operator:SI 1 "scc_comparison_operator"
11598                            [(match_operand 2 "cc_reg_operand" "y")
11599                             (const_int 0)]))]
11600   ""
11601   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11602   [(set (attr "type")
11603      (cond [(match_test "TARGET_MFCRF")
11604                 (const_string "mfcrf")
11605            ]
11606         (const_string "mfcr")))
11607    (set_attr "length" "8")])
11608
11609 (define_insn ""
11610   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11611         (match_operator:DI 1 "scc_comparison_operator"
11612                            [(match_operand 2 "cc_reg_operand" "y")
11613                             (const_int 0)]))]
11614   "TARGET_POWERPC64"
11615   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11616   [(set (attr "type")
11617      (cond [(match_test "TARGET_MFCRF")
11618                 (const_string "mfcrf")
11619            ]
11620         (const_string "mfcr")))
11621    (set_attr "length" "8")])
11622
11623 (define_insn ""
11624   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11625         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11626                                        [(match_operand 2 "cc_reg_operand" "y,y")
11627                                         (const_int 0)])
11628                     (const_int 0)))
11629    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11630         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11631   "TARGET_32BIT"
11632   "@
11633    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11634    #"
11635   [(set_attr "type" "shift")
11636    (set_attr "dot" "yes")
11637    (set_attr "length" "8,16")])
11638
11639 (define_split
11640   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11641         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11642                                        [(match_operand 2 "cc_reg_operand")
11643                                         (const_int 0)])
11644                     (const_int 0)))
11645    (set (match_operand:SI 3 "gpc_reg_operand")
11646         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11647   "TARGET_32BIT && reload_completed"
11648   [(set (match_dup 3)
11649         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11650    (set (match_dup 0)
11651         (compare:CC (match_dup 3)
11652                     (const_int 0)))]
11653   "")
11654
11655 (define_insn ""
11656   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11657         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11658                                       [(match_operand 2 "cc_reg_operand" "y")
11659                                        (const_int 0)])
11660                    (match_operand:SI 3 "const_int_operand" "n")))]
11661   ""
11662 {
11663   int is_bit = ccr_bit (operands[1], 1);
11664   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11665   int count;
11666
11667   if (is_bit >= put_bit)
11668     count = is_bit - put_bit;
11669   else
11670     count = 32 - (put_bit - is_bit);
11671
11672   operands[4] = GEN_INT (count);
11673   operands[5] = GEN_INT (put_bit);
11674
11675   return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11676 }
11677   [(set (attr "type")
11678      (cond [(match_test "TARGET_MFCRF")
11679                 (const_string "mfcrf")
11680            ]
11681         (const_string "mfcr")))
11682    (set_attr "length" "8")])
11683
11684 (define_insn ""
11685   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11686         (compare:CC
11687          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11688                                        [(match_operand 2 "cc_reg_operand" "y,y")
11689                                         (const_int 0)])
11690                     (match_operand:SI 3 "const_int_operand" "n,n"))
11691          (const_int 0)))
11692    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11693         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11694                    (match_dup 3)))]
11695   ""
11696 {
11697   int is_bit = ccr_bit (operands[1], 1);
11698   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11699   int count;
11700
11701   /* Force split for non-cc0 compare.  */
11702   if (which_alternative == 1)
11703      return "#";
11704
11705   if (is_bit >= put_bit)
11706     count = is_bit - put_bit;
11707   else
11708     count = 32 - (put_bit - is_bit);
11709
11710   operands[5] = GEN_INT (count);
11711   operands[6] = GEN_INT (put_bit);
11712
11713   return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11714 }
11715   [(set_attr "type" "shift")
11716    (set_attr "dot" "yes")
11717    (set_attr "length" "8,16")])
11718
11719 (define_split
11720   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11721         (compare:CC
11722          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11723                                        [(match_operand 2 "cc_reg_operand")
11724                                         (const_int 0)])
11725                     (match_operand:SI 3 "const_int_operand"))
11726          (const_int 0)))
11727    (set (match_operand:SI 4 "gpc_reg_operand")
11728         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11729                    (match_dup 3)))]
11730   "reload_completed"
11731   [(set (match_dup 4)
11732         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11733                    (match_dup 3)))
11734    (set (match_dup 0)
11735         (compare:CC (match_dup 4)
11736                     (const_int 0)))]
11737   "")
11738
11739
11740 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11741 (define_code_attr UNS [(eq "CC")
11742                        (ne "CC")
11743                        (lt "CC") (ltu "CCUNS")
11744                        (gt "CC") (gtu "CCUNS")
11745                        (le "CC") (leu "CCUNS")
11746                        (ge "CC") (geu "CCUNS")])
11747 (define_code_attr UNSu_ [(eq "")
11748                          (ne "")
11749                          (lt "") (ltu "u_")
11750                          (gt "") (gtu "u_")
11751                          (le "") (leu "u_")
11752                          (ge "") (geu "u_")])
11753 (define_code_attr UNSIK [(eq "I")
11754                          (ne "I")
11755                          (lt "I") (ltu "K")
11756                          (gt "I") (gtu "K")
11757                          (le "I") (leu "K")
11758                          (ge "I") (geu "K")])
11759
11760 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11761   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11762         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11763                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11764    (clobber (match_scratch:GPR 3 "=r"))
11765    (clobber (match_scratch:GPR 4 "=r"))
11766    (clobber (match_scratch:<UNS> 5 "=y"))]
11767   "TARGET_ISEL
11768    && !(<CODE> == EQ && operands[2] == const0_rtx)
11769    && !(<CODE> == NE && operands[2] == const0_rtx
11770         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11771   "#"
11772   "&& 1"
11773   [(pc)]
11774 {
11775   rtx_code code = <CODE>;
11776   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11777     {
11778       HOST_WIDE_INT val = INTVAL (operands[2]);
11779       if (code == LT && val != -0x8000)
11780         {
11781           code = LE;
11782           val--;
11783         }
11784       if (code == GT && val != 0x7fff)
11785         {
11786           code = GE;
11787           val++;
11788         }
11789       if (code == LTU && val != 0)
11790         {
11791           code = LEU;
11792           val--;
11793         }
11794       if (code == GTU && val != 0xffff)
11795         {
11796           code = GEU;
11797           val++;
11798         }
11799       operands[2] = GEN_INT (val);
11800     }
11801
11802   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11803     operands[3] = const0_rtx;
11804   else
11805     {
11806       if (GET_CODE (operands[3]) == SCRATCH)
11807         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11808       emit_move_insn (operands[3], const0_rtx);
11809     }
11810
11811   if (GET_CODE (operands[4]) == SCRATCH)
11812     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11813   emit_move_insn (operands[4], const1_rtx);
11814
11815   if (GET_CODE (operands[5]) == SCRATCH)
11816     operands[5] = gen_reg_rtx (<UNS>mode);
11817
11818   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11819   emit_insn (gen_rtx_SET (operands[5], c1));
11820
11821   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11822   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11823   emit_move_insn (operands[0], x);
11824
11825   DONE;
11826 }
11827   [(set (attr "cost")
11828         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11829                                    || <CODE> == NE
11830                                    || <CODE> == LE || <CODE> == GE
11831                                    || <CODE> == LEU || <CODE> == GEU")
11832                       (const_string "9")
11833                       (const_string "10")))])
11834
11835 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11836                               (DI "rKJI")])
11837
11838 (define_expand "eq<mode>3"
11839   [(parallel [
11840      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11841           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11842                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11843      (clobber (match_scratch:GPR 3 "=r"))
11844      (clobber (match_scratch:GPR 4 "=r"))])]
11845   ""
11846 {
11847   if (TARGET_ISEL && operands[2] != const0_rtx)
11848     {
11849       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11850                                            operands[2]));
11851       DONE;
11852     }
11853 })
11854
11855 (define_insn_and_split "*eq<mode>3"
11856   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11857         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11858                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11859    (clobber (match_scratch:GPR 3 "=r"))
11860    (clobber (match_scratch:GPR 4 "=r"))]
11861   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11862   "#"
11863   "&& 1"
11864   [(set (match_dup 4)
11865         (clz:GPR (match_dup 3)))
11866    (set (match_dup 0)
11867         (lshiftrt:GPR (match_dup 4)
11868                       (match_dup 5)))]
11869 {
11870   operands[3] = rs6000_emit_eqne (<MODE>mode,
11871                                   operands[1], operands[2], operands[3]);
11872
11873   if (GET_CODE (operands[4]) == SCRATCH)
11874     operands[4] = gen_reg_rtx (<MODE>mode);
11875
11876   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11877 }
11878   [(set (attr "length")
11879         (if_then_else (match_test "operands[2] == const0_rtx")
11880                       (const_string "8")
11881                       (const_string "12")))])
11882
11883 (define_expand "ne<mode>3"
11884   [(parallel [
11885      (set (match_operand:P 0 "gpc_reg_operand" "=r")
11886           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11887                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11888      (clobber (match_scratch:P 3 "=r"))
11889      (clobber (match_scratch:P 4 "=r"))
11890      (clobber (reg:P CA_REGNO))])]
11891   ""
11892 {
11893   if (TARGET_ISEL && operands[2] != const0_rtx)
11894     {
11895       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11896                                            operands[2]));
11897       DONE;
11898     }
11899 })
11900
11901 (define_insn_and_split "*ne<mode>3"
11902   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11903         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11904               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11905    (clobber (match_scratch:P 3 "=r"))
11906    (clobber (match_scratch:P 4 "=r"))
11907    (clobber (reg:P CA_REGNO))]
11908   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11909   "#"
11910   "&& 1"
11911   [(parallel [(set (match_dup 4)
11912                    (plus:P (match_dup 3)
11913                            (const_int -1)))
11914               (set (reg:P CA_REGNO)
11915                    (ne:P (match_dup 3)
11916                          (const_int 0)))])
11917    (parallel [(set (match_dup 0)
11918                    (plus:P (plus:P (not:P (match_dup 4))
11919                                    (reg:P CA_REGNO))
11920                            (match_dup 3)))
11921               (clobber (reg:P CA_REGNO))])]
11922 {
11923   operands[3] = rs6000_emit_eqne (<MODE>mode,
11924                                   operands[1], operands[2], operands[3]);
11925
11926   if (GET_CODE (operands[4]) == SCRATCH)
11927     operands[4] = gen_reg_rtx (<MODE>mode);
11928 }
11929   [(set (attr "length")
11930         (if_then_else (match_test "operands[2] == const0_rtx")
11931                       (const_string "8")
11932                       (const_string "12")))])
11933
11934 (define_insn_and_split "*neg_eq_<mode>"
11935   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11936         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11937                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11938    (clobber (match_scratch:P 3 "=r"))
11939    (clobber (match_scratch:P 4 "=r"))
11940    (clobber (reg:P CA_REGNO))]
11941   ""
11942   "#"
11943   ""
11944   [(parallel [(set (match_dup 4)
11945                    (plus:P (match_dup 3)
11946                            (const_int -1)))
11947               (set (reg:P CA_REGNO)
11948                    (ne:P (match_dup 3)
11949                          (const_int 0)))])
11950    (parallel [(set (match_dup 0)
11951                    (plus:P (reg:P CA_REGNO)
11952                            (const_int -1)))
11953               (clobber (reg:P CA_REGNO))])]
11954 {
11955   operands[3] = rs6000_emit_eqne (<MODE>mode,
11956                                   operands[1], operands[2], operands[3]);
11957
11958   if (GET_CODE (operands[4]) == SCRATCH)
11959     operands[4] = gen_reg_rtx (<MODE>mode);
11960 }
11961   [(set (attr "length")
11962         (if_then_else (match_test "operands[2] == const0_rtx")
11963                       (const_string "8")
11964                       (const_string "12")))])
11965
11966 (define_insn_and_split "*neg_ne_<mode>"
11967   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11968         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11969                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11970    (clobber (match_scratch:P 3 "=r"))
11971    (clobber (match_scratch:P 4 "=r"))
11972    (clobber (reg:P CA_REGNO))]
11973   ""
11974   "#"
11975   ""
11976   [(parallel [(set (match_dup 4)
11977                    (neg:P (match_dup 3)))
11978               (set (reg:P CA_REGNO)
11979                    (eq:P (match_dup 3)
11980                          (const_int 0)))])
11981    (parallel [(set (match_dup 0)
11982                    (plus:P (reg:P CA_REGNO)
11983                            (const_int -1)))
11984               (clobber (reg:P CA_REGNO))])]
11985 {
11986   operands[3] = rs6000_emit_eqne (<MODE>mode,
11987                                   operands[1], operands[2], operands[3]);
11988
11989   if (GET_CODE (operands[4]) == SCRATCH)
11990     operands[4] = gen_reg_rtx (<MODE>mode);
11991 }
11992   [(set (attr "length")
11993         (if_then_else (match_test "operands[2] == const0_rtx")
11994                       (const_string "8")
11995                       (const_string "12")))])
11996
11997 (define_insn_and_split "*plus_eq_<mode>"
11998   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11999         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12000                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12001                 (match_operand:P 3 "gpc_reg_operand" "r")))
12002    (clobber (match_scratch:P 4 "=r"))
12003    (clobber (match_scratch:P 5 "=r"))
12004    (clobber (reg:P CA_REGNO))]
12005   ""
12006   "#"
12007   ""
12008   [(parallel [(set (match_dup 5)
12009                    (neg:P (match_dup 4)))
12010               (set (reg:P CA_REGNO)
12011                    (eq:P (match_dup 4)
12012                          (const_int 0)))])
12013    (parallel [(set (match_dup 0)
12014                    (plus:P (match_dup 3)
12015                            (reg:P CA_REGNO)))
12016               (clobber (reg:P CA_REGNO))])]
12017 {
12018   operands[4] = rs6000_emit_eqne (<MODE>mode,
12019                                   operands[1], operands[2], operands[4]);
12020
12021   if (GET_CODE (operands[5]) == SCRATCH)
12022     operands[5] = gen_reg_rtx (<MODE>mode);
12023 }
12024   [(set (attr "length")
12025         (if_then_else (match_test "operands[2] == const0_rtx")
12026                       (const_string "8")
12027                       (const_string "12")))])
12028
12029 (define_insn_and_split "*plus_ne_<mode>"
12030   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12031         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12032                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12033                 (match_operand:P 3 "gpc_reg_operand" "r")))
12034    (clobber (match_scratch:P 4 "=r"))
12035    (clobber (match_scratch:P 5 "=r"))
12036    (clobber (reg:P CA_REGNO))]
12037   ""
12038   "#"
12039   ""
12040   [(parallel [(set (match_dup 5)
12041                    (plus:P (match_dup 4)
12042                            (const_int -1)))
12043               (set (reg:P CA_REGNO)
12044                    (ne:P (match_dup 4)
12045                          (const_int 0)))])
12046    (parallel [(set (match_dup 0)
12047                    (plus:P (match_dup 3)
12048                            (reg:P CA_REGNO)))
12049               (clobber (reg:P CA_REGNO))])]
12050 {
12051   operands[4] = rs6000_emit_eqne (<MODE>mode,
12052                                   operands[1], operands[2], operands[4]);
12053
12054   if (GET_CODE (operands[5]) == SCRATCH)
12055     operands[5] = gen_reg_rtx (<MODE>mode);
12056 }
12057   [(set (attr "length")
12058         (if_then_else (match_test "operands[2] == const0_rtx")
12059                       (const_string "8")
12060                       (const_string "12")))])
12061
12062 (define_insn_and_split "*minus_eq_<mode>"
12063   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12064         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12065                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12066                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12067    (clobber (match_scratch:P 4 "=r"))
12068    (clobber (match_scratch:P 5 "=r"))
12069    (clobber (reg:P CA_REGNO))]
12070   ""
12071   "#"
12072   ""
12073   [(parallel [(set (match_dup 5)
12074                    (plus:P (match_dup 4)
12075                            (const_int -1)))
12076               (set (reg:P CA_REGNO)
12077                    (ne:P (match_dup 4)
12078                          (const_int 0)))])
12079    (parallel [(set (match_dup 0)
12080                    (plus:P (plus:P (match_dup 3)
12081                                    (reg:P CA_REGNO))
12082                            (const_int -1)))
12083               (clobber (reg:P CA_REGNO))])]
12084 {
12085   operands[4] = rs6000_emit_eqne (<MODE>mode,
12086                                   operands[1], operands[2], operands[4]);
12087
12088   if (GET_CODE (operands[5]) == SCRATCH)
12089     operands[5] = gen_reg_rtx (<MODE>mode);
12090 }
12091   [(set (attr "length")
12092         (if_then_else (match_test "operands[2] == const0_rtx")
12093                       (const_string "8")
12094                       (const_string "12")))])
12095
12096 (define_insn_and_split "*minus_ne_<mode>"
12097   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12098         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12099                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12100                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12101    (clobber (match_scratch:P 4 "=r"))
12102    (clobber (match_scratch:P 5 "=r"))
12103    (clobber (reg:P CA_REGNO))]
12104   ""
12105   "#"
12106   ""
12107   [(parallel [(set (match_dup 5)
12108                    (neg:P (match_dup 4)))
12109               (set (reg:P CA_REGNO)
12110                    (eq:P (match_dup 4)
12111                          (const_int 0)))])
12112    (parallel [(set (match_dup 0)
12113                    (plus:P (plus:P (match_dup 3)
12114                                    (reg:P CA_REGNO))
12115                            (const_int -1)))
12116               (clobber (reg:P CA_REGNO))])]
12117 {
12118   operands[4] = rs6000_emit_eqne (<MODE>mode,
12119                                   operands[1], operands[2], operands[4]);
12120
12121   if (GET_CODE (operands[5]) == SCRATCH)
12122     operands[5] = gen_reg_rtx (<MODE>mode);
12123 }
12124   [(set (attr "length")
12125         (if_then_else (match_test "operands[2] == const0_rtx")
12126                       (const_string "8")
12127                       (const_string "12")))])
12128
12129 (define_insn_and_split "*eqsi3_ext<mode>"
12130   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12131         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12132                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12133    (clobber (match_scratch:SI 3 "=r"))
12134    (clobber (match_scratch:SI 4 "=r"))]
12135   ""
12136   "#"
12137   ""
12138   [(set (match_dup 4)
12139         (clz:SI (match_dup 3)))
12140    (set (match_dup 0)
12141         (zero_extend:EXTSI
12142           (lshiftrt:SI (match_dup 4)
12143                        (const_int 5))))]
12144 {
12145   operands[3] = rs6000_emit_eqne (SImode,
12146                                   operands[1], operands[2], operands[3]);
12147
12148   if (GET_CODE (operands[4]) == SCRATCH)
12149     operands[4] = gen_reg_rtx (SImode);
12150 }
12151   [(set (attr "length")
12152         (if_then_else (match_test "operands[2] == const0_rtx")
12153                       (const_string "8")
12154                       (const_string "12")))])
12155
12156 (define_insn_and_split "*nesi3_ext<mode>"
12157   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12158         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12159                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12160    (clobber (match_scratch:SI 3 "=r"))
12161    (clobber (match_scratch:SI 4 "=r"))
12162    (clobber (match_scratch:EXTSI 5 "=r"))]
12163   "!TARGET_ISEL"
12164   "#"
12165   "&& 1"
12166   [(set (match_dup 4)
12167         (clz:SI (match_dup 3)))
12168    (set (match_dup 5)
12169         (zero_extend:EXTSI
12170           (lshiftrt:SI (match_dup 4)
12171                        (const_int 5))))
12172    (set (match_dup 0)
12173         (xor:EXTSI (match_dup 5)
12174                    (const_int 1)))]
12175 {
12176   operands[3] = rs6000_emit_eqne (SImode,
12177                                   operands[1], operands[2], operands[3]);
12178
12179   if (GET_CODE (operands[4]) == SCRATCH)
12180     operands[4] = gen_reg_rtx (SImode);
12181   if (GET_CODE (operands[5]) == SCRATCH)
12182     operands[5] = gen_reg_rtx (<MODE>mode);
12183 }
12184   [(set (attr "length")
12185         (if_then_else (match_test "operands[2] == const0_rtx")
12186                       (const_string "12")
12187                       (const_string "16")))])
12188 \f
12189 ;; Define both directions of branch and return.  If we need a reload
12190 ;; register, we'd rather use CR0 since it is much easier to copy a
12191 ;; register CC value to there.
12192
12193 (define_insn ""
12194   [(set (pc)
12195         (if_then_else (match_operator 1 "branch_comparison_operator"
12196                                       [(match_operand 2 "cc_reg_operand" "y")
12197                                        (const_int 0)])
12198                       (label_ref (match_operand 0))
12199                       (pc)))]
12200   ""
12201 {
12202   return output_cbranch (operands[1], "%l0", 0, insn);
12203 }
12204   [(set_attr "type" "branch")])
12205
12206 (define_insn ""
12207   [(set (pc)
12208         (if_then_else (match_operator 0 "branch_comparison_operator"
12209                                       [(match_operand 1 "cc_reg_operand" "y")
12210                                        (const_int 0)])
12211                       (any_return)
12212                       (pc)))]
12213   "<return_pred>"
12214 {
12215   return output_cbranch (operands[0], NULL, 0, insn);
12216 }
12217   [(set_attr "type" "jmpreg")
12218    (set_attr "length" "4")])
12219
12220 ;; Logic on condition register values.
12221
12222 ; This pattern matches things like
12223 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12224 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12225 ;                                  (const_int 1)))
12226 ; which are generated by the branch logic.
12227 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12228
12229 (define_insn "cceq_ior_compare"
12230   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12231         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12232                         [(match_operator:SI 2
12233                                       "branch_positive_comparison_operator"
12234                                       [(match_operand 3
12235                                                       "cc_reg_operand" "y,y")
12236                                        (const_int 0)])
12237                          (match_operator:SI 4
12238                                       "branch_positive_comparison_operator"
12239                                       [(match_operand 5
12240                                                       "cc_reg_operand" "0,y")
12241                                        (const_int 0)])])
12242                       (const_int 1)))]
12243   ""
12244   "cr%q1 %E0,%j2,%j4"
12245   [(set_attr "type" "cr_logical")
12246    (set_attr "cr_logical_3op" "no,yes")])
12247
12248 ; Why is the constant -1 here, but 1 in the previous pattern?
12249 ; Because ~1 has all but the low bit set.
12250 (define_insn "cceq_ior_compare_complement"
12251   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12252         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12253                         [(not:SI (match_operator:SI 2
12254                                       "branch_positive_comparison_operator"
12255                                       [(match_operand 3
12256                                                       "cc_reg_operand" "y,y")
12257                                        (const_int 0)]))
12258                          (match_operator:SI 4
12259                                 "branch_positive_comparison_operator"
12260                                 [(match_operand 5
12261                                                 "cc_reg_operand" "0,y")
12262                                  (const_int 0)])])
12263                       (const_int -1)))]
12264   ""
12265   "cr%q1 %E0,%j2,%j4"
12266   [(set_attr "type" "cr_logical")
12267    (set_attr "cr_logical_3op" "no,yes")])
12268
12269 (define_insn "*cceq_rev_compare"
12270   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12271         (compare:CCEQ (match_operator:SI 1
12272                                       "branch_positive_comparison_operator"
12273                                       [(match_operand 2
12274                                                       "cc_reg_operand" "0,y")
12275                                        (const_int 0)])
12276                       (const_int 0)))]
12277   ""
12278   "crnot %E0,%j1"
12279   [(set_attr "type" "cr_logical")
12280    (set_attr "cr_logical_3op" "no,yes")])
12281
12282 ;; If we are comparing the result of two comparisons, this can be done
12283 ;; using creqv or crxor.
12284
12285 (define_insn_and_split ""
12286   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12287         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12288                               [(match_operand 2 "cc_reg_operand" "y")
12289                                (const_int 0)])
12290                       (match_operator 3 "branch_comparison_operator"
12291                               [(match_operand 4 "cc_reg_operand" "y")
12292                                (const_int 0)])))]
12293   ""
12294   "#"
12295   ""
12296   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12297                                     (match_dup 5)))]
12298 {
12299   int positive_1, positive_2;
12300
12301   positive_1 = branch_positive_comparison_operator (operands[1],
12302                                                     GET_MODE (operands[1]));
12303   positive_2 = branch_positive_comparison_operator (operands[3],
12304                                                     GET_MODE (operands[3]));
12305
12306   if (! positive_1)
12307     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12308                                                             GET_CODE (operands[1])),
12309                                   SImode,
12310                                   operands[2], const0_rtx);
12311   else if (GET_MODE (operands[1]) != SImode)
12312     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12313                                   operands[2], const0_rtx);
12314
12315   if (! positive_2)
12316     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12317                                                             GET_CODE (operands[3])),
12318                                   SImode,
12319                                   operands[4], const0_rtx);
12320   else if (GET_MODE (operands[3]) != SImode)
12321     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12322                                   operands[4], const0_rtx);
12323
12324   if (positive_1 == positive_2)
12325     {
12326       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12327       operands[5] = constm1_rtx;
12328     }
12329   else
12330     {
12331       operands[5] = const1_rtx;
12332     }
12333 })
12334
12335 ;; Unconditional branch and return.
12336
12337 (define_insn "jump"
12338   [(set (pc)
12339         (label_ref (match_operand 0)))]
12340   ""
12341   "b %l0"
12342   [(set_attr "type" "branch")])
12343
12344 (define_insn "<return_str>return"
12345   [(any_return)]
12346   "<return_pred>"
12347   "blr"
12348   [(set_attr "type" "jmpreg")])
12349
12350 (define_expand "indirect_jump"
12351   [(set (pc) (match_operand 0 "register_operand"))]
12352  ""
12353 {
12354   if (!rs6000_speculate_indirect_jumps) {
12355     rtx ccreg = gen_reg_rtx (CCmode);
12356     if (Pmode == DImode)
12357       emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12358     else
12359       emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12360     DONE;
12361   }
12362 })
12363
12364 (define_insn "*indirect_jump<mode>"
12365   [(set (pc)
12366         (match_operand:P 0 "register_operand" "c,*l"))]
12367   "rs6000_speculate_indirect_jumps"
12368   "b%T0"
12369   [(set_attr "type" "jmpreg")])
12370
12371 (define_insn "indirect_jump<mode>_nospec"
12372   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12373    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12374   "!rs6000_speculate_indirect_jumps"
12375   "crset %E1\;beq%T0- %1\;b $"
12376   [(set_attr "type" "jmpreg")
12377    (set_attr "length" "12")])
12378
12379 ;; Table jump for switch statements:
12380 (define_expand "tablejump"
12381   [(use (match_operand 0))
12382    (use (label_ref (match_operand 1)))]
12383   ""
12384 {
12385   if (rs6000_speculate_indirect_jumps)
12386     {
12387       if (TARGET_32BIT)
12388         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12389       else
12390         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12391     }
12392   else
12393     {
12394       rtx ccreg = gen_reg_rtx (CCmode);
12395       rtx jump;
12396       if (TARGET_32BIT)
12397         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12398       else
12399         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12400       emit_jump_insn (jump);
12401     }
12402   DONE;
12403 })
12404
12405 (define_expand "tablejumpsi"
12406   [(set (match_dup 3)
12407         (plus:SI (match_operand:SI 0)
12408                  (match_dup 2)))
12409    (parallel [(set (pc)
12410                    (match_dup 3))
12411               (use (label_ref (match_operand 1)))])]
12412   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12413 {
12414   operands[0] = force_reg (SImode, operands[0]);
12415   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12416   operands[3] = gen_reg_rtx (SImode);
12417 })
12418
12419 (define_expand "tablejumpsi_nospec"
12420   [(set (match_dup 4)
12421         (plus:SI (match_operand:SI 0)
12422                  (match_dup 3)))
12423    (parallel [(set (pc)
12424                    (match_dup 4))
12425               (use (label_ref (match_operand 1)))
12426               (clobber (match_operand 2))])]
12427   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12428 {
12429   operands[0] = force_reg (SImode, operands[0]);
12430   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12431   operands[4] = gen_reg_rtx (SImode);
12432 })
12433
12434 (define_expand "tablejumpdi"
12435   [(set (match_dup 4)
12436         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12437    (set (match_dup 3)
12438         (plus:DI (match_dup 4)
12439                  (match_dup 2)))
12440    (parallel [(set (pc)
12441                    (match_dup 3))
12442               (use (label_ref (match_operand 1)))])]
12443   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12444 {
12445   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12446   operands[3] = gen_reg_rtx (DImode);
12447   operands[4] = gen_reg_rtx (DImode);
12448 })
12449
12450 (define_expand "tablejumpdi_nospec"
12451   [(set (match_dup 5)
12452         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12453    (set (match_dup 4)
12454         (plus:DI (match_dup 5)
12455                  (match_dup 3)))
12456    (parallel [(set (pc)
12457                    (match_dup 4))
12458               (use (label_ref (match_operand 1)))
12459               (clobber (match_operand 2))])]
12460   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12461 {
12462   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12463   operands[4] = gen_reg_rtx (DImode);
12464   operands[5] = gen_reg_rtx (DImode);
12465 })
12466
12467 (define_insn "*tablejump<mode>_internal1"
12468   [(set (pc)
12469         (match_operand:P 0 "register_operand" "c,*l"))
12470    (use (label_ref (match_operand 1)))]
12471   "rs6000_speculate_indirect_jumps"
12472   "b%T0"
12473   [(set_attr "type" "jmpreg")])
12474
12475 (define_insn "*tablejump<mode>_internal1_nospec"
12476   [(set (pc)
12477         (match_operand:P 0 "register_operand" "c,*l"))
12478    (use (label_ref (match_operand 1)))
12479    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12480   "!rs6000_speculate_indirect_jumps"
12481   "crset %E2\;beq%T0- %2\;b $"
12482   [(set_attr "type" "jmpreg")
12483    (set_attr "length" "12")])
12484
12485 (define_insn "nop"
12486   [(unspec [(const_int 0)] UNSPEC_NOP)]
12487   ""
12488   "nop")
12489
12490 (define_insn "group_ending_nop"
12491   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12492   ""
12493 {
12494   if (rs6000_tune == PROCESSOR_POWER6)
12495     return "ori 1,1,0";
12496   return "ori 2,2,0";
12497 })
12498
12499 (define_insn "rs6000_speculation_barrier"
12500   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12501   ""
12502   "ori 31,31,0")
12503 \f
12504 ;; Define the subtract-one-and-jump insns, starting with the template
12505 ;; so loop.c knows what to generate.
12506
12507 (define_expand "doloop_end"
12508   [(use (match_operand 0))      ; loop pseudo
12509    (use (match_operand 1))]     ; label
12510   ""
12511 {
12512   if (TARGET_64BIT)
12513     {
12514       if (GET_MODE (operands[0]) != DImode)
12515         FAIL;
12516       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12517     }
12518   else
12519     {
12520       if (GET_MODE (operands[0]) != SImode)
12521         FAIL;
12522       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12523     }
12524   DONE;
12525 })
12526
12527 (define_expand "ctr<mode>"
12528   [(parallel [(set (pc)
12529                    (if_then_else (ne (match_operand:P 0 "register_operand")
12530                                      (const_int 1))
12531                                  (label_ref (match_operand 1))
12532                                  (pc)))
12533               (set (match_dup 0)
12534                    (plus:P (match_dup 0)
12535                             (const_int -1)))
12536               (clobber (match_scratch:CC 2))
12537               (clobber (match_scratch:P 3))])]
12538   ""
12539   "")
12540
12541 ;; We need to be able to do this for any operand, including MEM, or we
12542 ;; will cause reload to blow up since we don't allow output reloads on
12543 ;; JUMP_INSNs.
12544 ;; For the length attribute to be calculated correctly, the
12545 ;; label MUST be operand 0.
12546 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12547 ;; the ctr<mode> insns.
12548
12549 (define_code_iterator eqne [eq ne])
12550 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12551 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12552
12553 (define_insn "<bd>_<mode>"
12554   [(set (pc)
12555         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12556                           (const_int 1))
12557                       (label_ref (match_operand 0))
12558                       (pc)))
12559    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12560         (plus:P (match_dup 1)
12561                 (const_int -1)))
12562    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12563    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12564   ""
12565 {
12566   if (which_alternative != 0)
12567     return "#";
12568   else if (get_attr_length (insn) == 4)
12569     return "<bd> %l0";
12570   else
12571     return "<bd_neg> $+8\;b %l0";
12572 }
12573   [(set_attr "type" "branch")
12574    (set_attr "length" "*,16,20,20")])
12575
12576 ;; Now the splitter if we could not allocate the CTR register
12577 (define_split
12578   [(set (pc)
12579         (if_then_else (match_operator 2 "comparison_operator"
12580                                       [(match_operand:P 1 "gpc_reg_operand")
12581                                        (const_int 1)])
12582                       (match_operand 5)
12583                       (match_operand 6)))
12584    (set (match_operand:P 0 "nonimmediate_operand")
12585         (plus:P (match_dup 1)
12586                 (const_int -1)))
12587    (clobber (match_scratch:CC 3))
12588    (clobber (match_scratch:P 4))]
12589   "reload_completed"
12590   [(set (pc)
12591         (if_then_else (match_dup 7)
12592                       (match_dup 5)
12593                       (match_dup 6)))]
12594 {
12595   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12596                                 const0_rtx);
12597   emit_insn (gen_rtx_SET (operands[3],
12598                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12599   if (gpc_reg_operand (operands[0], <MODE>mode))
12600     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12601   else
12602     {
12603       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12604       emit_move_insn (operands[0], operands[4]);
12605     } 
12606     /* No DONE so branch comes from the pattern.  */
12607 })
12608
12609 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12610 ;; Note that in the case of long branches we have to decompose this into
12611 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12612 ;; and the CR bit, which means there is no way to conveniently invert the
12613 ;; comparison as is done with plain bdnz/bdz.
12614
12615 (define_insn "<bd>tf_<mode>"
12616   [(set (pc)
12617         (if_then_else
12618           (and
12619              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12620                    (const_int 1))
12621              (match_operator 3 "branch_comparison_operator"
12622                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12623                        (const_int 0)]))
12624           (label_ref (match_operand 0))
12625           (pc)))
12626    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12627         (plus:P (match_dup 1)
12628                 (const_int -1)))
12629    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12630    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12631    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12632   ""
12633 {
12634   if (which_alternative != 0)
12635     return "#";
12636   else if (get_attr_length (insn) == 4)
12637     {
12638       if (branch_positive_comparison_operator (operands[3],
12639                                                GET_MODE (operands[3])))
12640         return "<bd>t %j3,%l0";
12641       else
12642         return "<bd>f %j3,%l0";
12643     }
12644   else
12645     {
12646       static char seq[96];
12647       char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12648       sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12649       return seq;
12650     }
12651 }
12652   [(set_attr "type" "branch")
12653    (set_attr "length" "*,16,20,20")])
12654
12655 ;; Now the splitter if we could not allocate the CTR register
12656 (define_split
12657   [(set (pc)
12658         (if_then_else
12659           (and
12660              (match_operator 1 "comparison_operator"
12661                              [(match_operand:P 0 "gpc_reg_operand")
12662                               (const_int 1)])
12663              (match_operator 3 "branch_comparison_operator"
12664                       [(match_operand 2 "cc_reg_operand")
12665                        (const_int 0)]))
12666           (match_operand 4)
12667           (match_operand 5)))
12668    (set (match_operand:P 6 "int_reg_operand")
12669         (plus:P (match_dup 0)
12670                 (const_int -1)))
12671    (clobber (match_scratch:P 7))
12672    (clobber (match_scratch:CC 8))
12673    (clobber (match_scratch:CCEQ 9))]
12674   "reload_completed"
12675 [(pc)]
12676 {
12677   rtx ctr = operands[0];
12678   rtx ctrcmp = operands[1];
12679   rtx ccin = operands[2];
12680   rtx cccmp = operands[3];
12681   rtx dst1 = operands[4];
12682   rtx dst2 = operands[5];
12683   rtx ctrout = operands[6];
12684   rtx ctrtmp = operands[7];
12685   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12686   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12687   if (!ispos)
12688     cmpcode = reverse_condition (cmpcode);
12689   /* Generate crand/crandc here.  */
12690   emit_insn (gen_rtx_SET (operands[8],
12691                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12692   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12693
12694   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12695   if (ispos)
12696      emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12697                                       operands[8], cccmp, ccin));
12698   else
12699      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12700                                                  operands[8], cccmp, ccin));
12701   if (gpc_reg_operand (operands[0], <MODE>mode))
12702      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12703   else
12704     {
12705       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12706       emit_move_insn (ctrout, ctrtmp);
12707     }
12708   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12709   emit_jump_insn (gen_rtx_SET (pc_rtx,
12710                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12711                                                      dst1, dst2)));
12712   DONE;
12713 })
12714
12715 \f
12716 (define_insn "trap"
12717   [(trap_if (const_int 1) (const_int 0))]
12718   ""
12719   "trap"
12720   [(set_attr "type" "trap")])
12721
12722 (define_expand "ctrap<mode>4"
12723   [(trap_if (match_operator 0 "ordered_comparison_operator"
12724                             [(match_operand:GPR 1 "register_operand")
12725                              (match_operand:GPR 2 "reg_or_short_operand")])
12726             (match_operand 3 "zero_constant" ""))]
12727   ""
12728   "")
12729
12730 (define_insn ""
12731   [(trap_if (match_operator 0 "ordered_comparison_operator"
12732                             [(match_operand:GPR 1 "register_operand" "r")
12733                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12734             (const_int 0))]
12735   ""
12736   "t<wd>%V0%I2 %1,%2"
12737   [(set_attr "type" "trap")])
12738 \f
12739 ;; Insns related to generating the function prologue and epilogue.
12740
12741 (define_expand "prologue"
12742   [(use (const_int 0))]
12743   ""
12744 {
12745   rs6000_emit_prologue ();
12746   if (!TARGET_SCHED_PROLOG)
12747     emit_insn (gen_blockage ());
12748   DONE;
12749 })
12750
12751 (define_insn "*movesi_from_cr_one"
12752   [(match_parallel 0 "mfcr_operation"
12753                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12754                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12755                                      (match_operand 3 "immediate_operand" "n")]
12756                           UNSPEC_MOVESI_FROM_CR))])]
12757   "TARGET_MFCRF"
12758 {
12759   int mask = 0;
12760   int i;
12761   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12762   {
12763     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12764     operands[4] = GEN_INT (mask);
12765     output_asm_insn ("mfcr %1,%4", operands);
12766   }
12767   return "";
12768 }
12769   [(set_attr "type" "mfcrf")])
12770
12771 ;; Don't include the volatile CRs since their values are not used wrt CR save
12772 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12773 ;; prologue past an insn (early exit test) that defines a register used in the
12774 ;; prologue.
12775 (define_insn "prologue_movesi_from_cr"
12776   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12777         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12778                     (reg:CC CR4_REGNO)]
12779                    UNSPEC_MOVESI_FROM_CR))]
12780   ""
12781   "mfcr %0"
12782   [(set_attr "type" "mfcr")])
12783
12784 (define_insn "*crsave"
12785   [(match_parallel 0 "crsave_operation"
12786                    [(set (match_operand:SI 1 "memory_operand" "=m")
12787                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12788   ""
12789   "stw %2,%1"
12790   [(set_attr "type" "store")])
12791
12792 (define_insn "*stmw"
12793   [(match_parallel 0 "stmw_operation"
12794                    [(set (match_operand:SI 1 "memory_operand" "=m")
12795                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12796   "TARGET_MULTIPLE"
12797   "stmw %2,%1"
12798   [(set_attr "type" "store")
12799    (set_attr "update" "yes")
12800    (set_attr "indexed" "yes")])
12801
12802 ; The following comment applies to:
12803 ;     save_gpregs_*
12804 ;     save_fpregs_*
12805 ;     restore_gpregs*
12806 ;     return_and_restore_gpregs*
12807 ;     return_and_restore_fpregs*
12808 ;     return_and_restore_fpregs_aix*
12809 ;
12810 ; The out-of-line save / restore functions expects one input argument.
12811 ; Since those are not standard call_insn's, we must avoid using
12812 ; MATCH_OPERAND for that argument. That way the register rename
12813 ; optimization will not try to rename this register.
12814 ; Each pattern is repeated for each possible register number used in 
12815 ; various ABIs (r11, r1, and for some functions r12)
12816
12817 (define_insn "*save_gpregs_<mode>_r11"
12818   [(match_parallel 0 "any_parallel_operand"
12819                    [(clobber (reg:P LR_REGNO))
12820                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12821                     (use (reg:P 11))
12822                     (set (match_operand:P 2 "memory_operand" "=m")
12823                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12824   ""
12825   "bl %1"
12826   [(set_attr "type" "branch")
12827    (set_attr "length" "4")])
12828
12829 (define_insn "*save_gpregs_<mode>_r12"
12830   [(match_parallel 0 "any_parallel_operand"
12831                    [(clobber (reg:P LR_REGNO))
12832                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12833                     (use (reg:P 12))
12834                     (set (match_operand:P 2 "memory_operand" "=m")
12835                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12836   ""
12837   "bl %1"
12838   [(set_attr "type" "branch")
12839    (set_attr "length" "4")])
12840
12841 (define_insn "*save_gpregs_<mode>_r1"
12842   [(match_parallel 0 "any_parallel_operand"
12843                    [(clobber (reg:P LR_REGNO))
12844                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12845                     (use (reg:P 1))
12846                     (set (match_operand:P 2 "memory_operand" "=m")
12847                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12848   ""
12849   "bl %1"
12850   [(set_attr "type" "branch")
12851    (set_attr "length" "4")])
12852
12853 (define_insn "*save_fpregs_<mode>_r11"
12854   [(match_parallel 0 "any_parallel_operand"
12855                    [(clobber (reg:P LR_REGNO))
12856                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12857                     (use (reg:P 11))
12858                     (set (match_operand:DF 2 "memory_operand" "=m")
12859                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12860   ""
12861   "bl %1"
12862   [(set_attr "type" "branch")
12863    (set_attr "length" "4")])
12864
12865 (define_insn "*save_fpregs_<mode>_r12"
12866   [(match_parallel 0 "any_parallel_operand"
12867                    [(clobber (reg:P LR_REGNO))
12868                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12869                     (use (reg:P 12))
12870                     (set (match_operand:DF 2 "memory_operand" "=m")
12871                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12872   ""
12873   "bl %1"
12874   [(set_attr "type" "branch")
12875    (set_attr "length" "4")])
12876
12877 (define_insn "*save_fpregs_<mode>_r1"
12878   [(match_parallel 0 "any_parallel_operand"
12879                    [(clobber (reg:P LR_REGNO))
12880                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12881                     (use (reg:P 1))
12882                     (set (match_operand:DF 2 "memory_operand" "=m")
12883                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12884   ""
12885   "bl %1"
12886   [(set_attr "type" "branch")
12887    (set_attr "length" "4")])
12888
12889 ; This is to explain that changes to the stack pointer should
12890 ; not be moved over loads from or stores to stack memory.
12891 (define_insn "stack_tie"
12892   [(match_parallel 0 "tie_operand"
12893                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12894   ""
12895   ""
12896   [(set_attr "length" "0")])
12897
12898 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12899 ; stay behind all restores from the stack, it cannot be reordered to before
12900 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
12901 (define_insn "stack_restore_tie"
12902   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12903         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12904                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12905    (set (mem:BLK (scratch)) (const_int 0))]
12906   "TARGET_32BIT"
12907   "@
12908    mr %0,%1
12909    add%I2 %0,%1,%2"
12910   [(set_attr "type" "*,add")])
12911
12912 (define_expand "epilogue"
12913   [(use (const_int 0))]
12914   ""
12915 {
12916   if (!TARGET_SCHED_PROLOG)
12917     emit_insn (gen_blockage ());
12918   rs6000_emit_epilogue (FALSE);
12919   DONE;
12920 })
12921
12922 ; On some processors, doing the mtcrf one CC register at a time is
12923 ; faster (like on the 604e).  On others, doing them all at once is
12924 ; faster; for instance, on the 601 and 750.
12925
12926 (define_expand "movsi_to_cr_one"
12927   [(set (match_operand:CC 0 "cc_reg_operand")
12928         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
12929                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12930   ""
12931   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12932
12933 (define_insn "*movsi_to_cr"
12934   [(match_parallel 0 "mtcrf_operation"
12935                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12936                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12937                                      (match_operand 3 "immediate_operand" "n")]
12938                                     UNSPEC_MOVESI_TO_CR))])]
12939  ""
12940 {
12941   int mask = 0;
12942   int i;
12943   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12944     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12945   operands[4] = GEN_INT (mask);
12946   return "mtcrf %4,%2";
12947 }
12948   [(set_attr "type" "mtcr")])
12949
12950 (define_insn "*mtcrfsi"
12951   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12952         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12953                     (match_operand 2 "immediate_operand" "n")]
12954                    UNSPEC_MOVESI_TO_CR))]
12955   "GET_CODE (operands[0]) == REG
12956    && CR_REGNO_P (REGNO (operands[0]))
12957    && GET_CODE (operands[2]) == CONST_INT
12958    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12959   "mtcrf %R0,%1"
12960   [(set_attr "type" "mtcr")])
12961
12962 ; The load-multiple instructions have similar properties.
12963 ; Note that "load_multiple" is a name known to the machine-independent
12964 ; code that actually corresponds to the PowerPC load-string.
12965
12966 (define_insn "*lmw"
12967   [(match_parallel 0 "lmw_operation"
12968                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12969                          (match_operand:SI 2 "memory_operand" "m"))])]
12970   "TARGET_MULTIPLE"
12971   "lmw %1,%2"
12972   [(set_attr "type" "load")
12973    (set_attr "update" "yes")
12974    (set_attr "indexed" "yes")
12975    (set_attr "cell_micro" "always")])
12976
12977 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12978 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
12979
12980 ; The following comment applies to:
12981 ;     save_gpregs_*
12982 ;     save_fpregs_*
12983 ;     restore_gpregs*
12984 ;     return_and_restore_gpregs*
12985 ;     return_and_restore_fpregs*
12986 ;     return_and_restore_fpregs_aix*
12987 ;
12988 ; The out-of-line save / restore functions expects one input argument.
12989 ; Since those are not standard call_insn's, we must avoid using
12990 ; MATCH_OPERAND for that argument. That way the register rename
12991 ; optimization will not try to rename this register.
12992 ; Each pattern is repeated for each possible register number used in 
12993 ; various ABIs (r11, r1, and for some functions r12)
12994
12995 (define_insn "*restore_gpregs_<mode>_r11"
12996  [(match_parallel 0 "any_parallel_operand"
12997                   [(clobber (reg:P LR_REGNO))
12998                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12999                    (use (reg:P 11))
13000                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13001                         (match_operand:P 3 "memory_operand" "m"))])]
13002  ""
13003  "bl %1"
13004  [(set_attr "type" "branch")
13005   (set_attr "length" "4")])
13006
13007 (define_insn "*restore_gpregs_<mode>_r12"
13008  [(match_parallel 0 "any_parallel_operand"
13009                   [(clobber (reg:P LR_REGNO))
13010                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13011                    (use (reg:P 12))
13012                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13013                         (match_operand:P 3 "memory_operand" "m"))])]
13014  ""
13015  "bl %1"
13016  [(set_attr "type" "branch")
13017   (set_attr "length" "4")])
13018
13019 (define_insn "*restore_gpregs_<mode>_r1"
13020  [(match_parallel 0 "any_parallel_operand"
13021                   [(clobber (reg:P LR_REGNO))
13022                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13023                    (use (reg:P 1))
13024                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13025                         (match_operand:P 3 "memory_operand" "m"))])]
13026  ""
13027  "bl %1"
13028  [(set_attr "type" "branch")
13029   (set_attr "length" "4")])
13030
13031 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13032  [(match_parallel 0 "any_parallel_operand"
13033                   [(return)
13034                    (clobber (reg:P LR_REGNO))
13035                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13036                    (use (reg:P 11))
13037                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13038                         (match_operand:P 3 "memory_operand" "m"))])]
13039  ""
13040  "b %1"
13041  [(set_attr "type" "branch")
13042   (set_attr "length" "4")])
13043
13044 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13045  [(match_parallel 0 "any_parallel_operand"
13046                   [(return)
13047                    (clobber (reg:P LR_REGNO))
13048                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13049                    (use (reg:P 12))
13050                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13051                         (match_operand:P 3 "memory_operand" "m"))])]
13052  ""
13053  "b %1"
13054  [(set_attr "type" "branch")
13055   (set_attr "length" "4")])
13056
13057 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13058  [(match_parallel 0 "any_parallel_operand"
13059                   [(return)
13060                    (clobber (reg:P LR_REGNO))
13061                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13062                    (use (reg:P 1))
13063                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13064                         (match_operand:P 3 "memory_operand" "m"))])]
13065  ""
13066  "b %1"
13067  [(set_attr "type" "branch")
13068   (set_attr "length" "4")])
13069
13070 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13071  [(match_parallel 0 "any_parallel_operand"
13072                   [(return)
13073                    (clobber (reg:P LR_REGNO))
13074                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13075                    (use (reg:P 11))
13076                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13077                         (match_operand:DF 3 "memory_operand" "m"))])]
13078  ""
13079  "b %1"
13080  [(set_attr "type" "branch")
13081   (set_attr "length" "4")])
13082
13083 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13084  [(match_parallel 0 "any_parallel_operand"
13085                   [(return)
13086                    (clobber (reg:P LR_REGNO))
13087                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13088                    (use (reg:P 12))
13089                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13090                         (match_operand:DF 3 "memory_operand" "m"))])]
13091  ""
13092  "b %1"
13093  [(set_attr "type" "branch")
13094   (set_attr "length" "4")])
13095
13096 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13097  [(match_parallel 0 "any_parallel_operand"
13098                   [(return)
13099                    (clobber (reg:P LR_REGNO))
13100                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13101                    (use (reg:P 1))
13102                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13103                         (match_operand:DF 3 "memory_operand" "m"))])]
13104  ""
13105  "b %1"
13106  [(set_attr "type" "branch")
13107   (set_attr "length" "4")])
13108
13109 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13110  [(match_parallel 0 "any_parallel_operand"
13111                   [(return)
13112                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13113                    (use (reg:P 11))
13114                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13115                         (match_operand:DF 3 "memory_operand" "m"))])]
13116  ""
13117  "b %1"
13118  [(set_attr "type" "branch")
13119   (set_attr "length" "4")])
13120
13121 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13122  [(match_parallel 0 "any_parallel_operand"
13123                   [(return)
13124                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13125                    (use (reg:P 1))
13126                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13127                         (match_operand:DF 3 "memory_operand" "m"))])]
13128  ""
13129  "b %1"
13130  [(set_attr "type" "branch")
13131   (set_attr "length" "4")])
13132
13133 ; This is used in compiling the unwind routines.
13134 (define_expand "eh_return"
13135   [(use (match_operand 0 "general_operand"))]
13136   ""
13137 {
13138   if (TARGET_32BIT)
13139     emit_insn (gen_eh_set_lr_si (operands[0]));
13140   else
13141     emit_insn (gen_eh_set_lr_di (operands[0]));
13142   DONE;
13143 })
13144
13145 ; We can't expand this before we know where the link register is stored.
13146 (define_insn "eh_set_lr_<mode>"
13147   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13148                     UNSPECV_EH_RR)
13149    (clobber (match_scratch:P 1 "=&b"))]
13150   ""
13151   "#")
13152
13153 (define_split
13154   [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13155    (clobber (match_scratch 1))]
13156   "reload_completed"
13157   [(const_int 0)]
13158 {
13159   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13160   DONE;
13161 })
13162
13163 (define_insn "prefetch"
13164   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13165              (match_operand:SI 1 "const_int_operand" "n")
13166              (match_operand:SI 2 "const_int_operand" "n"))]
13167   ""
13168 {
13169   if (GET_CODE (operands[0]) == REG)
13170     return INTVAL (operands[1]) ? "dcbtst 0,%0" : "dcbt 0,%0";
13171   return INTVAL (operands[1]) ? "dcbtst %a0" : "dcbt %a0";
13172 }
13173   [(set_attr "type" "load")])
13174 \f
13175 ;; Handle -fsplit-stack.
13176
13177 (define_expand "split_stack_prologue"
13178   [(const_int 0)]
13179   ""
13180 {
13181   rs6000_expand_split_stack_prologue ();
13182   DONE;
13183 })
13184
13185 (define_expand "load_split_stack_limit"
13186   [(set (match_operand 0)
13187         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13188   ""
13189 {
13190   emit_insn (gen_rtx_SET (operands[0],
13191                           gen_rtx_UNSPEC (Pmode,
13192                                           gen_rtvec (1, const0_rtx),
13193                                           UNSPEC_STACK_CHECK)));
13194   DONE;
13195 })
13196
13197 (define_insn "load_split_stack_limit_di"
13198   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13199         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13200   "TARGET_64BIT"
13201   "ld %0,-0x7040(13)"
13202   [(set_attr "type" "load")
13203    (set_attr "update" "no")
13204    (set_attr "indexed" "no")])
13205
13206 (define_insn "load_split_stack_limit_si"
13207   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13208         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13209   "!TARGET_64BIT"
13210   "lwz %0,-0x7020(2)"
13211   [(set_attr "type" "load")
13212    (set_attr "update" "no")
13213    (set_attr "indexed" "no")])
13214
13215 ;; A return instruction which the middle-end doesn't see.
13216 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13217 ;; after the call to __morestack.
13218 (define_insn "split_stack_return"
13219   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13220   ""
13221   "blr"
13222   [(set_attr "type" "jmpreg")])
13223
13224 ;; If there are operand 0 bytes available on the stack, jump to
13225 ;; operand 1.
13226 (define_expand "split_stack_space_check"
13227   [(set (match_dup 2)
13228         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13229    (set (match_dup 3)
13230         (minus (reg STACK_POINTER_REGNUM)
13231                (match_operand 0)))
13232    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13233    (set (pc) (if_then_else
13234               (geu (match_dup 4) (const_int 0))
13235               (label_ref (match_operand 1))
13236               (pc)))]
13237   ""
13238 {
13239   rs6000_split_stack_space_check (operands[0], operands[1]);
13240   DONE;
13241 })
13242 \f
13243 (define_insn "bpermd_<mode>"
13244   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13245         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13246                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13247   "TARGET_POPCNTD"
13248   "bpermd %0,%1,%2"
13249   [(set_attr "type" "popcnt")])
13250
13251 \f
13252 ;; Builtin fma support.  Handle 
13253 ;; Note that the conditions for expansion are in the FMA_F iterator.
13254
13255 (define_expand "fma<mode>4"
13256   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13257         (fma:FMA_F
13258           (match_operand:FMA_F 1 "gpc_reg_operand")
13259           (match_operand:FMA_F 2 "gpc_reg_operand")
13260           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13261   ""
13262   "")
13263
13264 (define_insn "*fma<mode>4_fpr"
13265   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13266         (fma:SFDF
13267           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13268           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13269           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13270   "TARGET_HARD_FLOAT"
13271   "@
13272    fmadd<Ftrad> %0,%1,%2,%3
13273    xsmadda<Fvsx> %x0,%x1,%x2
13274    xsmaddm<Fvsx> %x0,%x1,%x3"
13275   [(set_attr "type" "fp")])
13276
13277 ; Altivec only has fma and nfms.
13278 (define_expand "fms<mode>4"
13279   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13280         (fma:FMA_F
13281           (match_operand:FMA_F 1 "gpc_reg_operand")
13282           (match_operand:FMA_F 2 "gpc_reg_operand")
13283           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13284   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13285   "")
13286
13287 (define_insn "*fms<mode>4_fpr"
13288   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13289         (fma:SFDF
13290          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13291          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13292          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13293   "TARGET_HARD_FLOAT"
13294   "@
13295    fmsub<Ftrad> %0,%1,%2,%3
13296    xsmsuba<Fvsx> %x0,%x1,%x2
13297    xsmsubm<Fvsx> %x0,%x1,%x3"
13298   [(set_attr "type" "fp")])
13299
13300 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13301 (define_expand "fnma<mode>4"
13302   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13303         (neg:FMA_F
13304           (fma:FMA_F
13305             (match_operand:FMA_F 1 "gpc_reg_operand")
13306             (match_operand:FMA_F 2 "gpc_reg_operand")
13307             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13308   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13309   "")
13310
13311 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13312 (define_expand "fnms<mode>4"
13313   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13314         (neg:FMA_F
13315           (fma:FMA_F
13316             (match_operand:FMA_F 1 "gpc_reg_operand")
13317             (match_operand:FMA_F 2 "gpc_reg_operand")
13318             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13319   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13320   "")
13321
13322 ; Not an official optab name, but used from builtins.
13323 (define_expand "nfma<mode>4"
13324   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13325         (neg:FMA_F
13326           (fma:FMA_F
13327             (match_operand:FMA_F 1 "gpc_reg_operand")
13328             (match_operand:FMA_F 2 "gpc_reg_operand")
13329             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13330   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13331   "")
13332
13333 (define_insn "*nfma<mode>4_fpr"
13334   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13335         (neg:SFDF
13336          (fma:SFDF
13337           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13338           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13339           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13340   "TARGET_HARD_FLOAT"
13341   "@
13342    fnmadd<Ftrad> %0,%1,%2,%3
13343    xsnmadda<Fvsx> %x0,%x1,%x2
13344    xsnmaddm<Fvsx> %x0,%x1,%x3"
13345   [(set_attr "type" "fp")])
13346
13347 ; Not an official optab name, but used from builtins.
13348 (define_expand "nfms<mode>4"
13349   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13350         (neg:FMA_F
13351           (fma:FMA_F
13352             (match_operand:FMA_F 1 "gpc_reg_operand")
13353             (match_operand:FMA_F 2 "gpc_reg_operand")
13354             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13355   ""
13356   "")
13357
13358 (define_insn "*nfmssf4_fpr"
13359   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13360         (neg:SFDF
13361          (fma:SFDF
13362           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13363           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13364           (neg:SFDF
13365            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13366   "TARGET_HARD_FLOAT"
13367   "@
13368    fnmsub<Ftrad> %0,%1,%2,%3
13369    xsnmsuba<Fvsx> %x0,%x1,%x2
13370    xsnmsubm<Fvsx> %x0,%x1,%x3"
13371   [(set_attr "type" "fp")])
13372
13373 \f
13374 (define_expand "rs6000_get_timebase"
13375   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13376   ""
13377 {
13378   if (TARGET_POWERPC64)
13379     emit_insn (gen_rs6000_mftb_di (operands[0]));
13380   else
13381     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13382   DONE;
13383 })
13384
13385 (define_insn "rs6000_get_timebase_ppc32"
13386   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13387         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13388    (clobber (match_scratch:SI 1 "=r"))
13389    (clobber (match_scratch:CC 2 "=y"))]
13390   "!TARGET_POWERPC64"
13391 {
13392   if (WORDS_BIG_ENDIAN)
13393     if (TARGET_MFCRF)
13394       {
13395         return "mfspr %0,269\;"
13396                "mfspr %L0,268\;"
13397                "mfspr %1,269\;"
13398                "cmpw %2,%0,%1\;"
13399                "bne- %2,$-16";
13400       }
13401     else
13402       {
13403         return "mftbu %0\;"
13404                "mftb %L0\;"
13405                "mftbu %1\;"
13406                "cmpw %2,%0,%1\;"
13407                "bne- %2,$-16";
13408       }
13409   else
13410     if (TARGET_MFCRF)
13411       {
13412         return "mfspr %L0,269\;"
13413                "mfspr %0,268\;"
13414                "mfspr %1,269\;"
13415                "cmpw %2,%L0,%1\;"
13416                "bne- %2,$-16";
13417       }
13418     else
13419       {
13420         return "mftbu %L0\;"
13421                "mftb %0\;"
13422                "mftbu %1\;"
13423                "cmpw %2,%L0,%1\;"
13424                "bne- %2,$-16";
13425       }
13426 }
13427   [(set_attr "length" "20")])
13428
13429 (define_insn "rs6000_mftb_<mode>"
13430   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13431         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13432   ""
13433 {
13434   if (TARGET_MFCRF)
13435     return "mfspr %0,268";
13436   else
13437     return "mftb %0";
13438 })
13439
13440 \f
13441 (define_insn "rs6000_mffs"
13442   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13443         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13444   "TARGET_HARD_FLOAT"
13445   "mffs %0")
13446
13447 (define_insn "rs6000_mtfsf"
13448   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13449                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13450                     UNSPECV_MTFSF)]
13451   "TARGET_HARD_FLOAT"
13452   "mtfsf %0,%1")
13453
13454 \f
13455 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13456 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13457 ;; register that is being loaded.  The fused ops must be physically adjacent.
13458
13459 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13460 ;; before register allocation, and is meant to reduce the lifetime for the
13461 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13462 ;; to use the register that is being load.  The peephole2 then gathers any
13463 ;; other fused possibilities that it can find after register allocation.  If
13464 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13465
13466 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13467 ;; before register allocation, so that we can avoid allocating a temporary base
13468 ;; register that won't be used, and that we try to load into base registers,
13469 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13470 ;; (addis followed by load) even on power8.
13471
13472 (define_split
13473   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand")
13474         (match_operand:INT1 1 "toc_fusion_mem_raw"))]
13475   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13476   [(parallel [(set (match_dup 0) (match_dup 2))
13477               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13478               (use (match_dup 3))
13479               (clobber (scratch:DI))])]
13480 {
13481   operands[2] = fusion_wrap_memory_address (operands[1]);
13482   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13483 })
13484
13485 (define_insn "*toc_fusionload_<mode>"
13486   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13487         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13488    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13489    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13490    (clobber (match_scratch:DI 3 "=X,&b"))]
13491   "TARGET_TOC_FUSION_INT"
13492 {
13493   if (base_reg_operand (operands[0], <MODE>mode))
13494     return emit_fusion_gpr_load (operands[0], operands[1]);
13495
13496   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13497 }
13498   [(set_attr "type" "load")
13499    (set_attr "length" "8")])
13500
13501 (define_insn "*toc_fusionload_di"
13502   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13503         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13504    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13505    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13506    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13507   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13508    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13509 {
13510   if (base_reg_operand (operands[0], DImode))
13511     return emit_fusion_gpr_load (operands[0], operands[1]);
13512
13513   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13514 }
13515   [(set_attr "type" "load")
13516    (set_attr "length" "8")])
13517
13518 \f
13519 ;; Find cases where the addis that feeds into a load instruction is either used
13520 ;; once or is the same as the target register, and replace it with the fusion
13521 ;; insn
13522
13523 (define_peephole2
13524   [(set (match_operand:P 0 "base_reg_operand")
13525         (match_operand:P 1 "fusion_gpr_addis"))
13526    (set (match_operand:INT1 2 "base_reg_operand")
13527         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13528   "TARGET_P8_FUSION
13529    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13530                          operands[3])"
13531   [(const_int 0)]
13532 {
13533   expand_fusion_gpr_load (operands);
13534   DONE;
13535 })
13536
13537 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13538 ;; reload)
13539
13540 (define_insn "fusion_gpr_load_<mode>"
13541   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13542         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13543                      UNSPEC_FUSION_GPR))]
13544   "TARGET_P8_FUSION"
13545 {
13546   return emit_fusion_gpr_load (operands[0], operands[1]);
13547 }
13548   [(set_attr "type" "load")
13549    (set_attr "length" "8")])
13550
13551 \f
13552 ;; ISA 3.0 (power9) fusion support
13553 ;; Merge addis with floating load/store to FPRs (or GPRs).
13554 (define_peephole2
13555   [(set (match_operand:P 0 "base_reg_operand")
13556         (match_operand:P 1 "fusion_gpr_addis"))
13557    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand")
13558         (match_operand:SFDF 3 "fusion_offsettable_mem_operand"))]
13559   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13560    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13561   [(const_int 0)]
13562 {
13563   expand_fusion_p9_load (operands);
13564   DONE;
13565 })
13566
13567 (define_peephole2
13568   [(set (match_operand:P 0 "base_reg_operand")
13569         (match_operand:P 1 "fusion_gpr_addis"))
13570    (set (match_operand:SFDF 2 "offsettable_mem_operand")
13571         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand"))]
13572   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13573    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13574    && !rtx_equal_p (operands[0], operands[3])"
13575   [(const_int 0)]
13576 {
13577   expand_fusion_p9_store (operands);
13578   DONE;
13579 })
13580
13581 (define_peephole2
13582   [(set (match_operand:SDI 0 "int_reg_operand")
13583         (match_operand:SDI 1 "upper16_cint_operand"))
13584    (set (match_dup 0)
13585         (ior:SDI (match_dup 0)
13586                  (match_operand:SDI 2 "u_short_cint_operand")))]
13587   "TARGET_P9_FUSION"
13588   [(set (match_dup 0)
13589         (unspec:SDI [(match_dup 1)
13590                      (match_dup 2)] UNSPEC_FUSION_P9))])
13591
13592 (define_peephole2
13593   [(set (match_operand:SDI 0 "int_reg_operand")
13594         (match_operand:SDI 1 "upper16_cint_operand"))
13595    (set (match_operand:SDI 2 "int_reg_operand")
13596         (ior:SDI (match_dup 0)
13597                  (match_operand:SDI 3 "u_short_cint_operand")))]
13598   "TARGET_P9_FUSION
13599    && !rtx_equal_p (operands[0], operands[2])
13600    && peep2_reg_dead_p (2, operands[0])"
13601   [(set (match_dup 2)
13602         (unspec:SDI [(match_dup 1)
13603                      (match_dup 3)] UNSPEC_FUSION_P9))])
13604
13605 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13606 ;; reload).  Because we want to eventually have secondary_reload generate
13607 ;; these, they have to have a single alternative that gives the register
13608 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13609 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13610   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13611         (unspec:GPR_FUSION
13612          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13613          UNSPEC_FUSION_P9))
13614    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13615   "TARGET_P9_FUSION"
13616 {
13617   /* This insn is a secondary reload insn, which cannot have alternatives.
13618      If we are not loading up register 0, use the power8 fusion instead.  */
13619   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13620     return emit_fusion_gpr_load (operands[0], operands[1]);
13621
13622   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13623 }
13624   [(set_attr "type" "load")
13625    (set_attr "length" "8")])
13626
13627 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13628   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13629         (unspec:GPR_FUSION
13630          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13631          UNSPEC_FUSION_P9))
13632    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13633   "TARGET_P9_FUSION"
13634 {
13635   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13636 }
13637   [(set_attr "type" "store")
13638    (set_attr "length" "8")])
13639
13640 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13641   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13642         (unspec:FPR_FUSION
13643          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13644          UNSPEC_FUSION_P9))
13645    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13646   "TARGET_P9_FUSION"
13647 {
13648   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13649 }
13650   [(set_attr "type" "fpload")
13651    (set_attr "length" "8")])
13652
13653 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13654   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13655         (unspec:FPR_FUSION
13656          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13657          UNSPEC_FUSION_P9))
13658    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13659   "TARGET_P9_FUSION"
13660 {
13661   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13662 }
13663   [(set_attr "type" "fpstore")
13664    (set_attr "length" "8")])
13665
13666 (define_insn "*fusion_p9_<mode>_constant"
13667   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13668         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13669                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13670                     UNSPEC_FUSION_P9))] 
13671   "TARGET_P9_FUSION"
13672 {
13673   emit_fusion_addis (operands[0], operands[1]);
13674   return "ori %0,%0,%2";
13675 }
13676   [(set_attr "type" "two")
13677    (set_attr "length" "8")])
13678
13679 \f
13680 ;; Optimize cases where we want to do a D-form load (register+offset) on
13681 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13682 ;; has generated:
13683 ;;      LFD 0,32(3)
13684 ;;      XXLOR 32,0,0
13685 ;;
13686 ;; and we change this to:
13687 ;;      LI 0,32
13688 ;;      LXSDX 32,3,9
13689
13690 (define_peephole2
13691   [(match_scratch:P 0 "b")
13692    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13693         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13694    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13695         (match_dup 1))]
13696   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13697   [(set (match_dup 0)
13698         (match_dup 4))
13699    (set (match_dup 3)
13700         (match_dup 5))]
13701 {
13702   rtx tmp_reg = operands[0];
13703   rtx mem = operands[2];
13704   rtx addr = XEXP (mem, 0);
13705   rtx add_op0, add_op1, new_addr;
13706
13707   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13708   add_op0 = XEXP (addr, 0);
13709   add_op1 = XEXP (addr, 1);
13710   gcc_assert (REG_P (add_op0));
13711   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13712
13713   operands[4] = add_op1;
13714   operands[5] = change_address (mem, <MODE>mode, new_addr);
13715 })
13716
13717 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13718 ;; Altivec register, and the register allocator has generated:
13719 ;;      XXLOR 0,32,32
13720 ;;      STFD 0,32(3)
13721 ;;
13722 ;; and we change this to:
13723 ;;      LI 0,32
13724 ;;      STXSDX 32,3,9
13725
13726 (define_peephole2
13727   [(match_scratch:P 0 "b")
13728    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13729         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13730    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13731         (match_dup 1))]
13732   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13733   [(set (match_dup 0)
13734         (match_dup 4))
13735    (set (match_dup 5)
13736         (match_dup 2))]
13737 {
13738   rtx tmp_reg = operands[0];
13739   rtx mem = operands[3];
13740   rtx addr = XEXP (mem, 0);
13741   rtx add_op0, add_op1, new_addr;
13742
13743   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13744   add_op0 = XEXP (addr, 0);
13745   add_op1 = XEXP (addr, 1);
13746   gcc_assert (REG_P (add_op0));
13747   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13748
13749   operands[4] = add_op1;
13750   operands[5] = change_address (mem, <MODE>mode, new_addr);
13751 })
13752    
13753 \f
13754 ;; Miscellaneous ISA 2.06 (power7) instructions
13755 (define_insn "addg6s"
13756   [(set (match_operand:SI 0 "register_operand" "=r")
13757         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13758                     (match_operand:SI 2 "register_operand" "r")]
13759                    UNSPEC_ADDG6S))]
13760   "TARGET_POPCNTD"
13761   "addg6s %0,%1,%2"
13762   [(set_attr "type" "integer")
13763    (set_attr "length" "4")])
13764
13765 (define_insn "cdtbcd"
13766   [(set (match_operand:SI 0 "register_operand" "=r")
13767         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13768                    UNSPEC_CDTBCD))]
13769   "TARGET_POPCNTD"
13770   "cdtbcd %0,%1"
13771   [(set_attr "type" "integer")
13772    (set_attr "length" "4")])
13773
13774 (define_insn "cbcdtd"
13775   [(set (match_operand:SI 0 "register_operand" "=r")
13776         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13777                    UNSPEC_CBCDTD))]
13778   "TARGET_POPCNTD"
13779   "cbcdtd %0,%1"
13780   [(set_attr "type" "integer")
13781    (set_attr "length" "4")])
13782
13783 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13784                                         UNSPEC_DIVEU])
13785
13786 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13787                              (UNSPEC_DIVEU      "eu")])
13788
13789 (define_insn "div<div_extend>_<mode>"
13790   [(set (match_operand:GPR 0 "register_operand" "=r")
13791         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13792                      (match_operand:GPR 2 "register_operand" "r")]
13793                     UNSPEC_DIV_EXTEND))]
13794   "TARGET_POPCNTD"
13795   "div<wd><div_extend> %0,%1,%2"
13796   [(set_attr "type" "div")
13797    (set_attr "size" "<bits>")])
13798
13799 \f
13800 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13801
13802 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13803 (define_mode_attr FP128_64 [(TF "DF")
13804                             (IF "DF")
13805                             (TD "DI")
13806                             (KF "DI")])
13807
13808 (define_expand "unpack<mode>"
13809   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13810         (unspec:<FP128_64>
13811          [(match_operand:FMOVE128 1 "register_operand")
13812           (match_operand:QI 2 "const_0_to_1_operand")]
13813          UNSPEC_UNPACK_128BIT))]
13814   "FLOAT128_2REG_P (<MODE>mode)"
13815   "")
13816
13817 (define_insn_and_split "unpack<mode>_dm"
13818   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13819         (unspec:<FP128_64>
13820          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13821           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13822          UNSPEC_UNPACK_128BIT))]
13823   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13824   "#"
13825   "&& reload_completed"
13826   [(set (match_dup 0) (match_dup 3))]
13827 {
13828   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13829
13830   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13831     {
13832       emit_note (NOTE_INSN_DELETED);
13833       DONE;
13834     }
13835
13836   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13837 }
13838   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13839    (set_attr "length" "4")])
13840
13841 (define_insn_and_split "unpack<mode>_nodm"
13842   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13843         (unspec:<FP128_64>
13844          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13845           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13846          UNSPEC_UNPACK_128BIT))]
13847   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13848   "#"
13849   "&& reload_completed"
13850   [(set (match_dup 0) (match_dup 3))]
13851 {
13852   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13853
13854   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13855     {
13856       emit_note (NOTE_INSN_DELETED);
13857       DONE;
13858     }
13859
13860   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13861 }
13862   [(set_attr "type" "fp,fpstore")
13863    (set_attr "length" "4")])
13864
13865 (define_insn_and_split "pack<mode>"
13866   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13867         (unspec:FMOVE128
13868          [(match_operand:<FP128_64> 1 "register_operand" "d")
13869           (match_operand:<FP128_64> 2 "register_operand" "d")]
13870          UNSPEC_PACK_128BIT))]
13871   "FLOAT128_2REG_P (<MODE>mode)"
13872   "#"
13873   "&& reload_completed"
13874   [(set (match_dup 3) (match_dup 1))
13875    (set (match_dup 4) (match_dup 2))]
13876 {
13877   unsigned dest_hi = REGNO (operands[0]);
13878   unsigned dest_lo = dest_hi + 1;
13879
13880   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13881   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13882
13883   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13884   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13885 }
13886   [(set_attr "type" "fp")
13887    (set_attr "length" "8")])
13888
13889 (define_insn "unpack<mode>"
13890   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13891         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13892                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13893          UNSPEC_UNPACK_128BIT))]
13894   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13895 {
13896   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13897     return ASM_COMMENT_START " xxpermdi to same register";
13898
13899   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13900   return "xxpermdi %x0,%x1,%x1,%3";
13901 }
13902   [(set_attr "type" "vecperm")])
13903
13904 (define_insn "pack<mode>"
13905   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13906         (unspec:FMOVE128_VSX
13907          [(match_operand:DI 1 "register_operand" "wa")
13908           (match_operand:DI 2 "register_operand" "wa")]
13909          UNSPEC_PACK_128BIT))]
13910   "TARGET_VSX"
13911   "xxpermdi %x0,%x1,%x2,0"
13912   [(set_attr "type" "vecperm")])
13913
13914
13915 \f
13916 ;; ISA 2.08 IEEE 128-bit floating point support.
13917
13918 (define_insn "add<mode>3"
13919   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13920         (plus:IEEE128
13921          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13922          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13923   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13924   "xsaddqp %0,%1,%2"
13925   [(set_attr "type" "vecfloat")
13926    (set_attr "size" "128")])
13927
13928 (define_insn "sub<mode>3"
13929   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13930         (minus:IEEE128
13931          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13932          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13933   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13934   "xssubqp %0,%1,%2"
13935   [(set_attr "type" "vecfloat")
13936    (set_attr "size" "128")])
13937
13938 (define_insn "mul<mode>3"
13939   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13940         (mult:IEEE128
13941          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13942          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13943   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13944   "xsmulqp %0,%1,%2"
13945   [(set_attr "type" "qmul")
13946    (set_attr "size" "128")])
13947
13948 (define_insn "div<mode>3"
13949   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13950         (div:IEEE128
13951          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13952          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13953   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13954   "xsdivqp %0,%1,%2"
13955   [(set_attr "type" "vecdiv")
13956    (set_attr "size" "128")])
13957
13958 (define_insn "sqrt<mode>2"
13959   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13960         (sqrt:IEEE128
13961          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13962   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13963    "xssqrtqp %0,%1"
13964   [(set_attr "type" "vecdiv")
13965    (set_attr "size" "128")])
13966
13967 (define_expand "copysign<mode>3"
13968   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13969    (use (match_operand:IEEE128 1 "altivec_register_operand"))
13970    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13971   "FLOAT128_IEEE_P (<MODE>mode)"
13972 {
13973   if (TARGET_FLOAT128_HW)
13974     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13975                                          operands[2]));
13976   else
13977     {
13978       rtx tmp = gen_reg_rtx (<MODE>mode);
13979       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13980                                            operands[2], tmp));
13981     }
13982   DONE;
13983 })
13984
13985 (define_insn "copysign<mode>3_hard"
13986   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13987         (unspec:IEEE128
13988          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13989           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13990          UNSPEC_COPYSIGN))]
13991   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13992    "xscpsgnqp %0,%2,%1"
13993   [(set_attr "type" "vecmove")
13994    (set_attr "size" "128")])
13995
13996 (define_insn "copysign<mode>3_soft"
13997   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13998         (unspec:IEEE128
13999          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14000           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14001           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14002          UNSPEC_COPYSIGN))]
14003   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14004    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14005   [(set_attr "type" "veccomplex")
14006    (set_attr "length" "8")])
14007
14008 (define_insn "neg<mode>2_hw"
14009   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14010         (neg:IEEE128
14011          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14012   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14013   "xsnegqp %0,%1"
14014   [(set_attr "type" "vecmove")
14015    (set_attr "size" "128")])
14016
14017
14018 (define_insn "abs<mode>2_hw"
14019   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14020         (abs:IEEE128
14021          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14022   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14023   "xsabsqp %0,%1"
14024   [(set_attr "type" "vecmove")
14025    (set_attr "size" "128")])
14026
14027
14028 (define_insn "*nabs<mode>2_hw"
14029   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14030         (neg:IEEE128
14031          (abs:IEEE128
14032           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14033   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14034   "xsnabsqp %0,%1"
14035   [(set_attr "type" "vecmove")
14036    (set_attr "size" "128")])
14037
14038 ;; Initially don't worry about doing fusion
14039 (define_insn "fma<mode>4_hw"
14040   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14041         (fma:IEEE128
14042          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14043          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14044          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14045   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14046   "xsmaddqp %0,%1,%2"
14047   [(set_attr "type" "qmul")
14048    (set_attr "size" "128")])
14049
14050 (define_insn "*fms<mode>4_hw"
14051   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14052         (fma:IEEE128
14053          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14054          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14055          (neg:IEEE128
14056           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14057   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14058   "xsmsubqp %0,%1,%2"
14059   [(set_attr "type" "qmul")
14060    (set_attr "size" "128")])
14061
14062 (define_insn "*nfma<mode>4_hw"
14063   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14064         (neg:IEEE128
14065          (fma:IEEE128
14066           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14067           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14068           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14069   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14070   "xsnmaddqp %0,%1,%2"
14071   [(set_attr "type" "qmul")
14072    (set_attr "size" "128")])
14073
14074 (define_insn "*nfms<mode>4_hw"
14075   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14076         (neg:IEEE128
14077          (fma:IEEE128
14078           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14079           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14080           (neg:IEEE128
14081            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14082   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14083   "xsnmsubqp %0,%1,%2"
14084   [(set_attr "type" "qmul")
14085    (set_attr "size" "128")])
14086
14087 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14088   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14089         (float_extend:IEEE128
14090          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14091   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14092   "xscvdpqp %0,%1"
14093   [(set_attr "type" "vecfloat")
14094    (set_attr "size" "128")])
14095
14096 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14097 ;; point is a simple copy.
14098 (define_insn_and_split "extendkftf2"
14099   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14100         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14101   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14102   "@
14103    #
14104    xxlor %x0,%x1,%x1"
14105   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14106   [(const_int 0)]
14107 {
14108   emit_note (NOTE_INSN_DELETED);
14109   DONE;
14110 }
14111   [(set_attr "type" "*,veclogical")
14112    (set_attr "length" "0,4")])
14113
14114 (define_insn_and_split "trunctfkf2"
14115   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14116         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14117   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14118   "@
14119    #
14120    xxlor %x0,%x1,%x1"
14121   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14122   [(const_int 0)]
14123 {
14124   emit_note (NOTE_INSN_DELETED);
14125   DONE;
14126 }
14127   [(set_attr "type" "*,veclogical")
14128    (set_attr "length" "0,4")])
14129
14130 (define_insn "trunc<mode>df2_hw"
14131   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14132         (float_truncate:DF
14133          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14134   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14135   "xscvqpdp %0,%1"
14136   [(set_attr "type" "vecfloat")
14137    (set_attr "size" "128")])
14138
14139 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14140 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14141 ;; conversion
14142 (define_insn_and_split "trunc<mode>sf2_hw"
14143   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14144         (float_truncate:SF
14145          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14146    (clobber (match_scratch:DF 2 "=v"))]
14147   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14148   "#"
14149   "&& 1"
14150   [(set (match_dup 2)
14151         (unspec:DF [(match_dup 1)]
14152                    UNSPEC_TRUNC_ROUND_TO_ODD))
14153    (set (match_dup 0)
14154         (float_truncate:SF (match_dup 2)))]
14155 {
14156   if (GET_CODE (operands[2]) == SCRATCH)
14157     operands[2] = gen_reg_rtx (DFmode);
14158 }
14159   [(set_attr "type" "vecfloat")
14160    (set_attr "length" "8")])
14161
14162 ;; Conversion between IEEE 128-bit and integer types
14163
14164 ;; The fix function for DImode and SImode was declared earlier as a
14165 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14166 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14167 ;; unless we have the IEEE 128-bit hardware.
14168 ;;
14169 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14170 ;; to provide a GPR target that used direct move and a conversion in the GPR
14171 ;; which works around QImode/HImode not being allowed in vector registers in
14172 ;; ISA 2.07 (power8).
14173 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14174   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14175         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14176   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14177   "xscvqp<su><wd>z %0,%1"
14178   [(set_attr "type" "vecfloat")
14179    (set_attr "size" "128")])
14180
14181 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14182   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14183         (any_fix:QHI
14184          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14185   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14186   "xscvqp<su>wz %0,%1"
14187   [(set_attr "type" "vecfloat")
14188    (set_attr "size" "128")])
14189
14190 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14191 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14192 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14193   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14194         (any_fix:QHSI
14195          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14196    (clobber (match_scratch:QHSI 2 "=v"))]
14197   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14198   "#"
14199   "&& reload_completed"
14200   [(set (match_dup 2)
14201         (any_fix:QHSI (match_dup 1)))
14202    (set (match_dup 0)
14203         (match_dup 2))])
14204
14205 (define_insn "float_<mode>di2_hw"
14206   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14207         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14208   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14209   "xscvsdqp %0,%1"
14210   [(set_attr "type" "vecfloat")
14211    (set_attr "size" "128")])
14212
14213 (define_insn_and_split "float_<mode>si2_hw"
14214   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14215         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14216    (clobber (match_scratch:DI 2 "=v"))]
14217   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14218   "#"
14219   "&& 1"
14220   [(set (match_dup 2)
14221         (sign_extend:DI (match_dup 1)))
14222    (set (match_dup 0)
14223         (float:IEEE128 (match_dup 2)))]
14224 {
14225   if (GET_CODE (operands[2]) == SCRATCH)
14226     operands[2] = gen_reg_rtx (DImode);
14227
14228   if (MEM_P (operands[1]))
14229     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14230 })
14231
14232 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14233   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14234         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14235    (clobber (match_scratch:DI 2 "=X,r,X"))]
14236   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14237   "#"
14238   "&& reload_completed"
14239   [(const_int 0)]
14240 {
14241   rtx dest = operands[0];
14242   rtx src = operands[1];
14243   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14244
14245   if (altivec_register_operand (src, <QHI:MODE>mode))
14246     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14247   else if (int_reg_operand (src, <QHI:MODE>mode))
14248     {
14249       rtx ext_di = operands[2];
14250       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14251       emit_move_insn (dest_di, ext_di);
14252     }
14253   else if (MEM_P (src))
14254     {
14255       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14256       emit_move_insn (dest_qhi, src);
14257       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14258     }
14259   else
14260     gcc_unreachable ();
14261
14262   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14263   DONE;
14264 }
14265   [(set_attr "length" "8,12,12")
14266    (set_attr "type" "vecfloat")
14267    (set_attr "size" "128")])
14268
14269 (define_insn "floatuns_<mode>di2_hw"
14270   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14271         (unsigned_float:IEEE128
14272          (match_operand:DI 1 "altivec_register_operand" "v")))]
14273   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14274   "xscvudqp %0,%1"
14275   [(set_attr "type" "vecfloat")
14276    (set_attr "size" "128")])
14277
14278 (define_insn_and_split "floatuns_<mode>si2_hw"
14279   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14280         (unsigned_float:IEEE128
14281          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14282    (clobber (match_scratch:DI 2 "=v"))]
14283   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14284   "#"
14285   "&& 1"
14286   [(set (match_dup 2)
14287         (zero_extend:DI (match_dup 1)))
14288    (set (match_dup 0)
14289         (float:IEEE128 (match_dup 2)))]
14290 {
14291   if (GET_CODE (operands[2]) == SCRATCH)
14292     operands[2] = gen_reg_rtx (DImode);
14293
14294   if (MEM_P (operands[1]))
14295     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14296 })
14297
14298 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14299   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14300         (unsigned_float:IEEE128
14301          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14302    (clobber (match_scratch:DI 2 "=X,r,X"))]
14303   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14304   "#"
14305   "&& reload_completed"
14306   [(const_int 0)]
14307 {
14308   rtx dest = operands[0];
14309   rtx src = operands[1];
14310   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14311
14312   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14313     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14314   else if (int_reg_operand (src, <QHI:MODE>mode))
14315     {
14316       rtx ext_di = operands[2];
14317       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14318       emit_move_insn (dest_di, ext_di);
14319     }
14320   else
14321     gcc_unreachable ();
14322
14323   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14324   DONE;
14325 }
14326   [(set_attr "length" "8,12,8")
14327    (set_attr "type" "vecfloat")
14328    (set_attr "size" "128")])
14329
14330 ;; IEEE 128-bit round to integer built-in functions
14331 (define_insn "floor<mode>2"
14332   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14333         (unspec:IEEE128
14334          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14335          UNSPEC_FRIM))]
14336   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14337   "xsrqpi 1,%0,%1,3"
14338   [(set_attr "type" "vecfloat")
14339    (set_attr "size" "128")])
14340
14341 (define_insn "ceil<mode>2"
14342   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14343         (unspec:IEEE128
14344          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14345          UNSPEC_FRIP))]
14346   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14347   "xsrqpi 1,%0,%1,2"
14348   [(set_attr "type" "vecfloat")
14349    (set_attr "size" "128")])
14350
14351 (define_insn "btrunc<mode>2"
14352   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14353         (unspec:IEEE128
14354          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14355          UNSPEC_FRIZ))]
14356   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14357   "xsrqpi 1,%0,%1,1"
14358   [(set_attr "type" "vecfloat")
14359    (set_attr "size" "128")])
14360
14361 (define_insn "round<mode>2"
14362   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14363         (unspec:IEEE128
14364          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14365          UNSPEC_FRIN))]
14366   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14367   "xsrqpi 0,%0,%1,0"
14368   [(set_attr "type" "vecfloat")
14369    (set_attr "size" "128")])
14370
14371 ;; IEEE 128-bit instructions with round to odd semantics
14372 (define_insn "add<mode>3_odd"
14373   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14374         (unspec:IEEE128
14375          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14376           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14377          UNSPEC_ADD_ROUND_TO_ODD))]
14378   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14379   "xsaddqpo %0,%1,%2"
14380   [(set_attr "type" "vecfloat")
14381    (set_attr "size" "128")])
14382
14383 (define_insn "sub<mode>3_odd"
14384   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14385         (unspec:IEEE128
14386          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14387           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14388          UNSPEC_SUB_ROUND_TO_ODD))]
14389   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14390   "xssubqpo %0,%1,%2"
14391   [(set_attr "type" "vecfloat")
14392    (set_attr "size" "128")])
14393
14394 (define_insn "mul<mode>3_odd"
14395   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14396         (unspec:IEEE128
14397          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14398           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14399          UNSPEC_MUL_ROUND_TO_ODD))]
14400   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14401   "xsmulqpo %0,%1,%2"
14402   [(set_attr "type" "qmul")
14403    (set_attr "size" "128")])
14404
14405 (define_insn "div<mode>3_odd"
14406   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14407         (unspec:IEEE128
14408          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14409           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14410          UNSPEC_DIV_ROUND_TO_ODD))]
14411   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14412   "xsdivqpo %0,%1,%2"
14413   [(set_attr "type" "vecdiv")
14414    (set_attr "size" "128")])
14415
14416 (define_insn "sqrt<mode>2_odd"
14417   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14418         (unspec:IEEE128
14419          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14420          UNSPEC_SQRT_ROUND_TO_ODD))]
14421   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14422    "xssqrtqpo %0,%1"
14423   [(set_attr "type" "vecdiv")
14424    (set_attr "size" "128")])
14425
14426 (define_insn "fma<mode>4_odd"
14427   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14428         (unspec:IEEE128
14429          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14430           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14431           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14432          UNSPEC_FMA_ROUND_TO_ODD))]
14433   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14434   "xsmaddqpo %0,%1,%2"
14435   [(set_attr "type" "qmul")
14436    (set_attr "size" "128")])
14437
14438 (define_insn "*fms<mode>4_odd"
14439   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14440         (unspec:IEEE128
14441          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14442           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14443           (neg:IEEE128
14444            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14445          UNSPEC_FMA_ROUND_TO_ODD))]
14446   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14447   "xsmsubqpo %0,%1,%2"
14448   [(set_attr "type" "qmul")
14449    (set_attr "size" "128")])
14450
14451 (define_insn "*nfma<mode>4_odd"
14452   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14453         (neg:IEEE128
14454          (unspec:IEEE128
14455           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14456            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14457            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14458           UNSPEC_FMA_ROUND_TO_ODD)))]
14459   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14460   "xsnmaddqpo %0,%1,%2"
14461   [(set_attr "type" "qmul")
14462    (set_attr "size" "128")])
14463
14464 (define_insn "*nfms<mode>4_odd"
14465   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14466         (neg:IEEE128
14467          (unspec:IEEE128
14468           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14469            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14470            (neg:IEEE128
14471             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14472           UNSPEC_FMA_ROUND_TO_ODD)))]
14473   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14474   "xsnmsubqpo %0,%1,%2"
14475   [(set_attr "type" "qmul")
14476    (set_attr "size" "128")])
14477
14478 (define_insn "trunc<mode>df2_odd"
14479   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14480         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14481                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14482   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14483   "xscvqpdpo %0,%1"
14484   [(set_attr "type" "vecfloat")
14485    (set_attr "size" "128")])
14486
14487 ;; IEEE 128-bit comparisons
14488 (define_insn "*cmp<mode>_hw"
14489   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14490         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14491                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14492   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14493    "xscmpuqp %0,%1,%2"
14494   [(set_attr "type" "veccmp")
14495    (set_attr "size" "128")])
14496
14497 \f
14498
14499 (include "sync.md")
14500 (include "vector.md")
14501 (include "vsx.md")
14502 (include "altivec.md")
14503 (include "dfp.md")
14504 (include "crypto.md")
14505 (include "htm.md")