[gcc]
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob757ec38084d286010c6c20d6336fecbcbc6243c7
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)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; REGNOS
27 (define_constants
28   [(FIRST_GPR_REGNO             0)
29    (STACK_POINTER_REGNUM        1)
30    (TOC_REGNUM                  2)
31    (STATIC_CHAIN_REGNUM         11)
32    (HARD_FRAME_POINTER_REGNUM   31)
33    (LAST_GPR_REGNO              31)
34    (FIRST_FPR_REGNO             32)
35    (LAST_FPR_REGNO              63)
36    (LR_REGNO                    65)
37    (CTR_REGNO                   66)
38    (ARG_POINTER_REGNUM          67)
39    (CR0_REGNO                   68)
40    (CR1_REGNO                   69)
41    (CR2_REGNO                   70)
42    (CR3_REGNO                   71)
43    (CR4_REGNO                   72)
44    (CR5_REGNO                   73)
45    (CR6_REGNO                   74)
46    (CR7_REGNO                   75)
47    (MAX_CR_REGNO                75)
48    (CA_REGNO                    76)
49    (FIRST_ALTIVEC_REGNO         77)
50    (LAST_ALTIVEC_REGNO          108)
51    (VRSAVE_REGNO                109)
52    (VSCR_REGNO                  110)
53    (FRAME_POINTER_REGNUM        111)
54    (TFHAR_REGNO                 112)
55    (TFIAR_REGNO                 113)
56    (TEXASR_REGNO                114)
57   ])
60 ;; UNSPEC usage
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_DIVEO
134    UNSPEC_DIVEU
135    UNSPEC_DIVEUO
136    UNSPEC_UNPACK_128BIT
137    UNSPEC_PACK_128BIT
138    UNSPEC_LSQ
139    UNSPEC_FUSION_GPR
140    UNSPEC_STACK_CHECK
141    UNSPEC_FUSION_P9
142    UNSPEC_FUSION_ADDIS
143    UNSPEC_ADD_ROUND_TO_ODD
144    UNSPEC_SUB_ROUND_TO_ODD
145    UNSPEC_MUL_ROUND_TO_ODD
146    UNSPEC_DIV_ROUND_TO_ODD
147    UNSPEC_FMA_ROUND_TO_ODD
148    UNSPEC_SQRT_ROUND_TO_ODD
149    UNSPEC_TRUNC_ROUND_TO_ODD
150    UNSPEC_SIGNBIT
151    UNSPEC_SF_FROM_SI
152    UNSPEC_SI_FROM_SF
153   ])
156 ;; UNSPEC_VOLATILE usage
159 (define_c_enum "unspecv"
160   [UNSPECV_BLOCK
161    UNSPECV_LL                   ; load-locked
162    UNSPECV_SC                   ; store-conditional
163    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
164    UNSPECV_EH_RR                ; eh_reg_restore
165    UNSPECV_ISYNC                ; isync instruction
166    UNSPECV_MFTB                 ; move from time base
167    UNSPECV_NLGR                 ; non-local goto receiver
168    UNSPECV_MFFS                 ; Move from FPSCR
169    UNSPECV_MTFSF                ; Move to FPSCR Fields
170    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
171    UNSPECV_SPEC_BARRIER         ; Speculation barrier
172   ])
175 ;; Define an insn type attribute.  This is used in function unit delay
176 ;; computations.
177 (define_attr "type"
178   "integer,two,three,
179    add,logical,shift,insert,
180    mul,halfmul,div,
181    exts,cntlz,popcnt,isel,
182    load,store,fpload,fpstore,vecload,vecstore,
183    cmp,
184    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
185    cr_logical,mfcr,mfcrf,mtcr,
186    fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
187    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
188    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
189    veclogical,veccmpfx,vecexts,vecmove,
190    htm,htmsimple,dfp"
191   (const_string "integer"))
193 ;; What data size does this instruction work on?
194 ;; This is used for insert, mul and others as necessary.
195 (define_attr "size" "8,16,32,64,128" (const_string "32"))
197 ;; What is the insn_cost for this insn?  The target hook can still override
198 ;; this.  For optimizing for size the "length" attribute is used instead.
199 (define_attr "cost" "" (const_int 0))
201 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
202 ;; This is used for add, logical, shift, exts, mul.
203 (define_attr "dot" "no,yes" (const_string "no"))
205 ;; Does this instruction sign-extend its result?
206 ;; This is used for load insns.
207 (define_attr "sign_extend" "no,yes" (const_string "no"))
209 ;; Does this cr_logical instruction have three operands?  That is, BT != BB.
210 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
212 ;; Does this instruction use indexed (that is, reg+reg) addressing?
213 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
214 ;; it is automatically set based on that.  If a load or store instruction
215 ;; has fewer than two operands it needs to set this attribute manually
216 ;; or the compiler will crash.
217 (define_attr "indexed" "no,yes"
218   (if_then_else (ior (match_operand 0 "indexed_address_mem")
219                      (match_operand 1 "indexed_address_mem"))
220                 (const_string "yes")
221                 (const_string "no")))
223 ;; Does this instruction use update addressing?
224 ;; This is used for load and store insns.  See the comments for "indexed".
225 (define_attr "update" "no,yes"
226   (if_then_else (ior (match_operand 0 "update_address_mem")
227                      (match_operand 1 "update_address_mem"))
228                 (const_string "yes")
229                 (const_string "no")))
231 ;; Is this instruction using operands[2] as shift amount, and can that be a
232 ;; register?
233 ;; This is used for shift insns.
234 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
236 ;; Is this instruction using a shift amount from a register?
237 ;; This is used for shift insns.
238 (define_attr "var_shift" "no,yes"
239   (if_then_else (and (eq_attr "type" "shift")
240                      (eq_attr "maybe_var_shift" "yes"))
241                 (if_then_else (match_operand 2 "gpc_reg_operand")
242                               (const_string "yes")
243                               (const_string "no"))
244                 (const_string "no")))
246 ;; Is copying of this instruction disallowed?
247 (define_attr "cannot_copy" "no,yes" (const_string "no"))
249 ;; Define floating point instruction sub-types for use with Xfpu.md
250 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
252 ;; Length (in bytes).
253 ; '(pc)' in the following doesn't include the instruction itself; it is
254 ; calculated as if the instruction had zero size.
255 (define_attr "length" ""
256   (if_then_else (eq_attr "type" "branch")
257                 (if_then_else (and (ge (minus (match_dup 0) (pc))
258                                        (const_int -32768))
259                                    (lt (minus (match_dup 0) (pc))
260                                        (const_int 32764)))
261                               (const_int 4)
262                               (const_int 8))
263                 (const_int 4)))
265 ;; Processor type -- this attribute must exactly match the processor_type
266 ;; enumeration in rs6000-opts.h.
267 (define_attr "cpu"
268   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
269    ppc750,ppc7400,ppc7450,
270    ppc403,ppc405,ppc440,ppc476,
271    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
272    power4,power5,power6,power7,power8,power9,
273    rs64a,mpccore,cell,ppca2,titan"
274   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
277 ;; If this instruction is microcoded on the CELL processor
278 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
279 (define_attr "cell_micro" "not,conditional,always"
280   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
281                           (eq_attr "dot" "yes"))
282                      (and (eq_attr "type" "load")
283                           (eq_attr "sign_extend" "yes"))
284                      (and (eq_attr "type" "shift")
285                           (eq_attr "var_shift" "yes")))
286                 (const_string "always")
287                 (const_string "not")))
289 (automata_option "ndfa")
291 (include "rs64.md")
292 (include "mpc.md")
293 (include "40x.md")
294 (include "440.md")
295 (include "476.md")
296 (include "601.md")
297 (include "603.md")
298 (include "6xx.md")
299 (include "7xx.md")
300 (include "7450.md")
301 (include "8540.md")
302 (include "e300c2c3.md")
303 (include "e500mc.md")
304 (include "e500mc64.md")
305 (include "e5500.md")
306 (include "e6500.md")
307 (include "power4.md")
308 (include "power5.md")
309 (include "power6.md")
310 (include "power7.md")
311 (include "power8.md")
312 (include "power9.md")
313 (include "cell.md")
314 (include "xfpu.md")
315 (include "a2.md")
316 (include "titan.md")
318 (include "predicates.md")
319 (include "constraints.md")
321 (include "darwin.md")
324 ;; Mode iterators
326 ; This mode iterator allows :GPR to be used to indicate the allowable size
327 ; of whole values in GPRs.
328 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
330 ; And again, for patterns that need two (potentially) different integer modes.
331 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
333 ; Any supported integer mode.
334 (define_mode_iterator INT [QI HI SI DI TI PTI])
336 ; Any supported integer mode that fits in one register.
337 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
339 ; Integer modes supported in VSX registers with ISA 3.0 instructions
340 (define_mode_iterator INT_ISA3 [QI HI SI DI])
342 ; Everything we can extend QImode to.
343 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
345 ; Everything we can extend HImode to.
346 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
348 ; Everything we can extend SImode to.
349 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
351 ; QImode or HImode for small integer moves and small atomic ops
352 (define_mode_iterator QHI [QI HI])
354 ; QImode, HImode, SImode for fused ops only for GPR loads
355 (define_mode_iterator QHSI [QI HI SI])
357 ; HImode or SImode for sign extended fusion ops
358 (define_mode_iterator HSI [HI SI])
360 ; SImode or DImode, even if DImode doesn't fit in GPRs.
361 (define_mode_iterator SDI [SI DI])
363 ; Types that can be fused with an ADDIS instruction to load or store a GPR
364 ; register that has reg+offset addressing.
365 (define_mode_iterator GPR_FUSION [QI
366                                   HI
367                                   SI
368                                   (DI   "TARGET_POWERPC64")
369                                   SF
370                                   (DF   "TARGET_POWERPC64")])
372 ; Types that can be fused with an ADDIS instruction to load or store a FPR
373 ; register that has reg+offset addressing.
374 (define_mode_iterator FPR_FUSION [DI SF DF])
376 ; The size of a pointer.  Also, the size of the value that a record-condition
377 ; (one with a '.') will compare; and the size used for arithmetic carries.
378 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
380 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
381 ; PTImode is GPR only)
382 (define_mode_iterator TI2 [TI PTI])
384 ; Any hardware-supported floating-point mode
385 (define_mode_iterator FP [
386   (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
387   (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
388   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
389   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
390   (KF "TARGET_FLOAT128_TYPE")
391   (DD "TARGET_DFP")
392   (TD "TARGET_DFP")])
394 ; Any fma capable floating-point mode.
395 (define_mode_iterator FMA_F [
396   (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
397   (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
398        || VECTOR_UNIT_VSX_P (DFmode)")
399   (V2SF "TARGET_PAIRED_FLOAT")
400   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
401   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
402   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
403   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
404   ])
406 ; Floating point move iterators to combine binary and decimal moves
407 (define_mode_iterator FMOVE32 [SF SD])
408 (define_mode_iterator FMOVE64 [DF DD])
409 (define_mode_iterator FMOVE64X [DI DF DD])
410 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
411                                 (IF "FLOAT128_IBM_P (IFmode)")
412                                 (TD "TARGET_HARD_FLOAT")])
414 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
415                                     (IF "FLOAT128_2REG_P (IFmode)")
416                                     (TD "TARGET_HARD_FLOAT")])
418 ; Iterators for 128 bit types for direct move
419 (define_mode_iterator FMOVE128_GPR [TI
420                                     V16QI
421                                     V8HI
422                                     V4SI
423                                     V4SF
424                                     V2DI
425                                     V2DF
426                                     V1TI
427                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
428                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
430 ; Iterator for 128-bit VSX types for pack/unpack
431 (define_mode_iterator FMOVE128_VSX [V1TI KF])
433 ; Whether a floating point move is ok, don't allow SD without hardware FP
434 (define_mode_attr fmove_ok [(SF "")
435                             (DF "")
436                             (SD "TARGET_HARD_FLOAT")
437                             (DD "")])
439 ; Convert REAL_VALUE to the appropriate bits
440 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
441                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
442                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
443                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
445 ; Whether 0.0 has an all-zero bit pattern
446 (define_mode_attr zero_fp [(SF "j")
447                            (DF "j")
448                            (TF "j")
449                            (IF "j")
450                            (KF "j")
451                            (SD "wn")
452                            (DD "wn")
453                            (TD "wn")])
455 ; Definitions for 64-bit VSX
456 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
458 ; Definitions for 64-bit direct move
459 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
461 ; Definitions for 64-bit use of altivec registers
462 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
464 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
465 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
467 ; These modes do not fit in integer registers in 32-bit mode.
468 (define_mode_iterator DIFD [DI DF DD])
470 ; Iterator for reciprocal estimate instructions
471 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
473 ; Iterator for just SF/DF
474 (define_mode_iterator SFDF [SF DF])
476 ; Like SFDF, but a different name to match conditional move where the
477 ; comparison operands may be a different mode than the input operands.
478 (define_mode_iterator SFDF2 [SF DF])
480 ; Iterator for 128-bit floating point that uses the IBM double-double format
481 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
482                               (TF "FLOAT128_IBM_P (TFmode)")])
484 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
485 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
486                                (TF "FLOAT128_IEEE_P (TFmode)")])
488 ; Iterator for 128-bit floating point
489 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
490                                 (IF "TARGET_FLOAT128_TYPE")
491                                 (TF "TARGET_LONG_DOUBLE_128")])
493 ; Iterator for signbit on 64-bit machines with direct move
494 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
495                                (TF "FLOAT128_VECTOR_P (TFmode)")])
497 ; Iterator for ISA 3.0 supported floating point types
498 (define_mode_iterator FP_ISA3 [SF DF])
500 ; SF/DF suffix for traditional floating instructions
501 (define_mode_attr Ftrad         [(SF "s") (DF "")])
503 ; SF/DF suffix for VSX instructions
504 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
506 ; SF/DF constraint for arithmetic on traditional floating point registers
507 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
509 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
510 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
511 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
512 ; format.
513 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
515 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
516 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
517 ; instructions added in ISA 2.07 (power8)
518 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
520 ; SF/DF constraint for arithmetic on altivec registers
521 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
523 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
524 (define_mode_attr Fs            [(SF "s")  (DF "d")])
526 ; FRE/FRES support
527 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
528 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
530 ; Conditional returns.
531 (define_code_iterator any_return [return simple_return])
532 (define_code_attr return_pred [(return "direct_return ()")
533                                (simple_return "1")])
534 (define_code_attr return_str [(return "") (simple_return "simple_")])
536 ; Logical operators.
537 (define_code_iterator iorxor            [ior xor])
538 (define_code_iterator and_ior_xor       [and ior xor])
540 ; Signed/unsigned variants of ops.
541 (define_code_iterator any_extend        [sign_extend zero_extend])
542 (define_code_iterator any_fix           [fix unsigned_fix])
543 (define_code_iterator any_float         [float unsigned_float])
545 (define_code_attr u  [(sign_extend      "")
546                       (zero_extend      "u")
547                       (fix              "")
548                       (unsigned_fix     "u")])
550 (define_code_attr su [(sign_extend      "s")
551                       (zero_extend      "u")
552                       (fix              "s")
553                       (unsigned_fix     "s")
554                       (float            "s")
555                       (unsigned_float   "u")])
557 (define_code_attr az [(sign_extend      "a")
558                       (zero_extend      "z")
559                       (fix              "a")
560                       (unsigned_fix     "z")
561                       (float            "a")
562                       (unsigned_float   "z")])
564 (define_code_attr uns [(fix             "")
565                        (unsigned_fix    "uns")
566                        (float           "")
567                        (unsigned_float  "uns")])
569 ; Various instructions that come in SI and DI forms.
570 ; A generic w/d attribute, for things like cmpw/cmpd.
571 (define_mode_attr wd [(QI    "b")
572                       (HI    "h")
573                       (SI    "w")
574                       (DI    "d")
575                       (V16QI "b")
576                       (V8HI  "h")
577                       (V4SI  "w")
578                       (V2DI  "d")
579                       (V1TI  "q")
580                       (TI    "q")])
582 ;; How many bits in this mode?
583 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
585 ; DImode bits
586 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
588 ;; Bitmask for shift instructions
589 (define_mode_attr hH [(SI "h") (DI "H")])
591 ;; A mode twice the size of the given mode
592 (define_mode_attr dmode [(SI "di") (DI "ti")])
593 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
595 ;; Suffix for reload patterns
596 (define_mode_attr ptrsize [(SI "32bit")
597                            (DI "64bit")])
599 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
600                             (DI "TARGET_64BIT")])
602 (define_mode_attr mptrsize [(SI "si")
603                             (DI "di")])
605 (define_mode_attr ptrload [(SI "lwz")
606                            (DI "ld")])
608 (define_mode_attr ptrm [(SI "m")
609                         (DI "Y")])
611 (define_mode_attr rreg [(SF   "f")
612                         (DF   "ws")
613                         (TF   "f")
614                         (TD   "f")
615                         (V4SF "wf")
616                         (V2DF "wd")])
618 (define_mode_attr rreg2 [(SF   "f")
619                          (DF   "d")])
621 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
622                                  (DF "TARGET_FCFID")])
624 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
625                                 (DF "TARGET_DOUBLE_FLOAT")])
627 ;; Mode iterator for logical operations on 128-bit types
628 (define_mode_iterator BOOL_128          [TI
629                                          PTI
630                                          (V16QI "TARGET_ALTIVEC")
631                                          (V8HI  "TARGET_ALTIVEC")
632                                          (V4SI  "TARGET_ALTIVEC")
633                                          (V4SF  "TARGET_ALTIVEC")
634                                          (V2DI  "TARGET_ALTIVEC")
635                                          (V2DF  "TARGET_ALTIVEC")
636                                          (V1TI  "TARGET_ALTIVEC")])
638 ;; For the GPRs we use 3 constraints for register outputs, two that are the
639 ;; same as the output register, and a third where the output register is an
640 ;; early clobber, so we don't have to deal with register overlaps.  For the
641 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
642 ;; either.
644 ;; Mode attribute for boolean operation register constraints for output
645 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
646                                          (PTI   "&r,r,r")
647                                          (V16QI "wa,v,&?r,?r,?r")
648                                          (V8HI  "wa,v,&?r,?r,?r")
649                                          (V4SI  "wa,v,&?r,?r,?r")
650                                          (V4SF  "wa,v,&?r,?r,?r")
651                                          (V2DI  "wa,v,&?r,?r,?r")
652                                          (V2DF  "wa,v,&?r,?r,?r")
653                                          (V1TI  "wa,v,&?r,?r,?r")])
655 ;; Mode attribute for boolean operation register constraints for operand1
656 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
657                                          (PTI   "r,0,r")
658                                          (V16QI "wa,v,r,0,r")
659                                          (V8HI  "wa,v,r,0,r")
660                                          (V4SI  "wa,v,r,0,r")
661                                          (V4SF  "wa,v,r,0,r")
662                                          (V2DI  "wa,v,r,0,r")
663                                          (V2DF  "wa,v,r,0,r")
664                                          (V1TI  "wa,v,r,0,r")])
666 ;; Mode attribute for boolean operation register constraints for operand2
667 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
668                                          (PTI   "r,r,0")
669                                          (V16QI "wa,v,r,r,0")
670                                          (V8HI  "wa,v,r,r,0")
671                                          (V4SI  "wa,v,r,r,0")
672                                          (V4SF  "wa,v,r,r,0")
673                                          (V2DI  "wa,v,r,r,0")
674                                          (V2DF  "wa,v,r,r,0")
675                                          (V1TI  "wa,v,r,r,0")])
677 ;; Mode attribute for boolean operation register constraints for operand1
678 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
679 ;; is used for operand1 or operand2
680 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
681                                          (PTI   "r,0,0")
682                                          (V16QI "wa,v,r,0,0")
683                                          (V8HI  "wa,v,r,0,0")
684                                          (V4SI  "wa,v,r,0,0")
685                                          (V4SF  "wa,v,r,0,0")
686                                          (V2DI  "wa,v,r,0,0")
687                                          (V2DF  "wa,v,r,0,0")
688                                          (V1TI  "wa,v,r,0,0")])
690 ;; Reload iterator for creating the function to allocate a base register to
691 ;; supplement addressing modes.
692 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
693                               SF SD SI DF DD DI TI PTI KF IF TF])
695 ;; Iterate over smin, smax
696 (define_code_iterator fp_minmax [smin smax])
698 (define_code_attr     minmax    [(smin "min")
699                                  (smax "max")])
701 (define_code_attr     SMINMAX   [(smin "SMIN")
702                                  (smax "SMAX")])
704 ;; Iterator to optimize the following cases:
705 ;;      D-form load to FPR register & move to Altivec register
706 ;;      Move Altivec register to FPR register and store
707 (define_mode_iterator ALTIVEC_DFORM [DF
708                                      (SF "TARGET_P8_VECTOR")
709                                      (DI "TARGET_POWERPC64")])
712 ;; Start with fixed-point load and store insns.  Here we put only the more
713 ;; complex forms.  Basic data transfer is done later.
715 (define_insn "zero_extendqi<mode>2"
716   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
717         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
718   ""
719   "@
720    lbz%U1%X1 %0,%1
721    rlwinm %0,%1,0,0xff
722    lxsibzx %x0,%y1
723    vextractub %0,%1,7"
724   [(set_attr "type" "load,shift,fpload,vecperm")])
726 (define_insn_and_split "*zero_extendqi<mode>2_dot"
727   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
728         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
729                     (const_int 0)))
730    (clobber (match_scratch:EXTQI 0 "=r,r"))]
731   ""
732   "@
733    andi. %0,%1,0xff
734    #"
735   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
736   [(set (match_dup 0)
737         (zero_extend:EXTQI (match_dup 1)))
738    (set (match_dup 2)
739         (compare:CC (match_dup 0)
740                     (const_int 0)))]
741   ""
742   [(set_attr "type" "logical")
743    (set_attr "dot" "yes")
744    (set_attr "length" "4,8")])
746 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
747   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
748         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
749                     (const_int 0)))
750    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
751         (zero_extend:EXTQI (match_dup 1)))]
752   ""
753   "@
754    andi. %0,%1,0xff
755    #"
756   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
757   [(set (match_dup 0)
758         (zero_extend:EXTQI (match_dup 1)))
759    (set (match_dup 2)
760         (compare:CC (match_dup 0)
761                     (const_int 0)))]
762   ""
763   [(set_attr "type" "logical")
764    (set_attr "dot" "yes")
765    (set_attr "length" "4,8")])
768 (define_insn "zero_extendhi<mode>2"
769   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
770         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
771   ""
772   "@
773    lhz%U1%X1 %0,%1
774    rlwinm %0,%1,0,0xffff
775    lxsihzx %x0,%y1
776    vextractuh %0,%1,6"
777   [(set_attr "type" "load,shift,fpload,vecperm")])
779 (define_insn_and_split "*zero_extendhi<mode>2_dot"
780   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
781         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
782                     (const_int 0)))
783    (clobber (match_scratch:EXTHI 0 "=r,r"))]
784   ""
785   "@
786    andi. %0,%1,0xffff
787    #"
788   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
789   [(set (match_dup 0)
790         (zero_extend:EXTHI (match_dup 1)))
791    (set (match_dup 2)
792         (compare:CC (match_dup 0)
793                     (const_int 0)))]
794   ""
795   [(set_attr "type" "logical")
796    (set_attr "dot" "yes")
797    (set_attr "length" "4,8")])
799 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
800   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
801         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
802                     (const_int 0)))
803    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
804         (zero_extend:EXTHI (match_dup 1)))]
805   ""
806   "@
807    andi. %0,%1,0xffff
808    #"
809   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
810   [(set (match_dup 0)
811         (zero_extend:EXTHI (match_dup 1)))
812    (set (match_dup 2)
813         (compare:CC (match_dup 0)
814                     (const_int 0)))]
815   ""
816   [(set_attr "type" "logical")
817    (set_attr "dot" "yes")
818    (set_attr "length" "4,8")])
821 (define_insn "zero_extendsi<mode>2"
822   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
823         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
824   ""
825   "@
826    lwz%U1%X1 %0,%1
827    rldicl %0,%1,0,32
828    lfiwzx %0,%y1
829    lxsiwzx %x0,%y1
830    mtvsrwz %x0,%1
831    mfvsrwz %0,%x1
832    xxextractuw %x0,%x1,4"
833   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
835 (define_insn_and_split "*zero_extendsi<mode>2_dot"
836   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
837         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
838                     (const_int 0)))
839    (clobber (match_scratch:EXTSI 0 "=r,r"))]
840   ""
841   "@
842    rldicl. %0,%1,0,32
843    #"
844   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
845   [(set (match_dup 0)
846         (zero_extend:DI (match_dup 1)))
847    (set (match_dup 2)
848         (compare:CC (match_dup 0)
849                     (const_int 0)))]
850   ""
851   [(set_attr "type" "shift")
852    (set_attr "dot" "yes")
853    (set_attr "length" "4,8")])
855 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
856   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
857         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
858                     (const_int 0)))
859    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
860         (zero_extend:EXTSI (match_dup 1)))]
861   ""
862   "@
863    rldicl. %0,%1,0,32
864    #"
865   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
866   [(set (match_dup 0)
867         (zero_extend:EXTSI (match_dup 1)))
868    (set (match_dup 2)
869         (compare:CC (match_dup 0)
870                     (const_int 0)))]
871   ""
872   [(set_attr "type" "shift")
873    (set_attr "dot" "yes")
874    (set_attr "length" "4,8")])
877 (define_insn "extendqi<mode>2"
878   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
879         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
880   ""
881   "@
882    extsb %0,%1
883    vextsb2d %0,%1"
884   [(set_attr "type" "exts,vecperm")])
886 (define_insn_and_split "*extendqi<mode>2_dot"
887   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
888         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
889                     (const_int 0)))
890    (clobber (match_scratch:EXTQI 0 "=r,r"))]
891   ""
892   "@
893    extsb. %0,%1
894    #"
895   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
896   [(set (match_dup 0)
897         (sign_extend:EXTQI (match_dup 1)))
898    (set (match_dup 2)
899         (compare:CC (match_dup 0)
900                     (const_int 0)))]
901   ""
902   [(set_attr "type" "exts")
903    (set_attr "dot" "yes")
904    (set_attr "length" "4,8")])
906 (define_insn_and_split "*extendqi<mode>2_dot2"
907   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
908         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
909                     (const_int 0)))
910    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
911         (sign_extend:EXTQI (match_dup 1)))]
912   ""
913   "@
914    extsb. %0,%1
915    #"
916   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
917   [(set (match_dup 0)
918         (sign_extend:EXTQI (match_dup 1)))
919    (set (match_dup 2)
920         (compare:CC (match_dup 0)
921                     (const_int 0)))]
922   ""
923   [(set_attr "type" "exts")
924    (set_attr "dot" "yes")
925    (set_attr "length" "4,8")])
928 (define_expand "extendhi<mode>2"
929   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
930         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
931   ""
932   "")
934 (define_insn "*extendhi<mode>2"
935   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
936         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
937   ""
938   "@
939    lha%U1%X1 %0,%1
940    extsh %0,%1
941    #
942    vextsh2d %0,%1"
943   [(set_attr "type" "load,exts,fpload,vecperm")
944    (set_attr "sign_extend" "yes")
945    (set_attr "length" "4,4,8,4")])
947 (define_split
948   [(set (match_operand:EXTHI 0 "altivec_register_operand")
949         (sign_extend:EXTHI
950          (match_operand:HI 1 "indexed_or_indirect_operand")))]
951   "TARGET_P9_VECTOR && reload_completed"
952   [(set (match_dup 2)
953         (match_dup 1))
954    (set (match_dup 0)
955         (sign_extend:EXTHI (match_dup 2)))]
957   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
960 (define_insn_and_split "*extendhi<mode>2_dot"
961   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
962         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
963                     (const_int 0)))
964    (clobber (match_scratch:EXTHI 0 "=r,r"))]
965   ""
966   "@
967    extsh. %0,%1
968    #"
969   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
970   [(set (match_dup 0)
971         (sign_extend:EXTHI (match_dup 1)))
972    (set (match_dup 2)
973         (compare:CC (match_dup 0)
974                     (const_int 0)))]
975   ""
976   [(set_attr "type" "exts")
977    (set_attr "dot" "yes")
978    (set_attr "length" "4,8")])
980 (define_insn_and_split "*extendhi<mode>2_dot2"
981   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
982         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
983                     (const_int 0)))
984    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
985         (sign_extend:EXTHI (match_dup 1)))]
986   ""
987   "@
988    extsh. %0,%1
989    #"
990   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
991   [(set (match_dup 0)
992         (sign_extend:EXTHI (match_dup 1)))
993    (set (match_dup 2)
994         (compare:CC (match_dup 0)
995                     (const_int 0)))]
996   ""
997   [(set_attr "type" "exts")
998    (set_attr "dot" "yes")
999    (set_attr "length" "4,8")])
1002 (define_insn "extendsi<mode>2"
1003   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1004                      "=r, r,   wl,    wu,    wj,    wK,     wH,    wr")
1006         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1007                      "Y,  r,   Z,     Z,     r,     wK,     wH,    ?wIwH")))]
1008   ""
1009   "@
1010    lwa%U1%X1 %0,%1
1011    extsw %0,%1
1012    lfiwax %0,%y1
1013    lxsiwax %x0,%y1
1014    mtvsrwa %x0,%1
1015    vextsw2d %0,%1
1016    #
1017    #"
1018   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1019    (set_attr "sign_extend" "yes")
1020    (set_attr "length" "4,4,4,4,4,4,8,8")])
1022 (define_split
1023   [(set (match_operand:EXTSI 0 "int_reg_operand")
1024         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1025   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1026   [(set (match_dup 2)
1027         (match_dup 1))
1028    (set (match_dup 0)
1029         (sign_extend:DI (match_dup 2)))]
1031   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1034 (define_split
1035   [(set (match_operand:DI 0 "altivec_register_operand")
1036         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1037   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1038   [(const_int 0)]
1040   rtx dest = operands[0];
1041   rtx src = operands[1];
1042   int dest_regno = REGNO (dest);
1043   int src_regno = REGNO (src);
1044   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1045   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1047   if (VECTOR_ELT_ORDER_BIG)
1048     {
1049       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1050       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1051     }
1052   else
1053     {
1054       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1055       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1056     }
1057   DONE;
1060 (define_insn_and_split "*extendsi<mode>2_dot"
1061   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1062         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1063                     (const_int 0)))
1064    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1065   ""
1066   "@
1067    extsw. %0,%1
1068    #"
1069   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1070   [(set (match_dup 0)
1071         (sign_extend:EXTSI (match_dup 1)))
1072    (set (match_dup 2)
1073         (compare:CC (match_dup 0)
1074                     (const_int 0)))]
1075   ""
1076   [(set_attr "type" "exts")
1077    (set_attr "dot" "yes")
1078    (set_attr "length" "4,8")])
1080 (define_insn_and_split "*extendsi<mode>2_dot2"
1081   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1082         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1083                     (const_int 0)))
1084    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1085         (sign_extend:EXTSI (match_dup 1)))]
1086   ""
1087   "@
1088    extsw. %0,%1
1089    #"
1090   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1091   [(set (match_dup 0)
1092         (sign_extend:EXTSI (match_dup 1)))
1093    (set (match_dup 2)
1094         (compare:CC (match_dup 0)
1095                     (const_int 0)))]
1096   ""
1097   [(set_attr "type" "exts")
1098    (set_attr "dot" "yes")
1099    (set_attr "length" "4,8")])
1101 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1103 (define_insn "*macchwc"
1104   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1105         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1106                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1107                                        (const_int 16))
1108                                       (sign_extend:SI
1109                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1110                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1111                     (const_int 0)))
1112    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1113         (plus:SI (mult:SI (ashiftrt:SI
1114                            (match_dup 2)
1115                            (const_int 16))
1116                           (sign_extend:SI
1117                            (match_dup 1)))
1118                  (match_dup 4)))]
1119   "TARGET_MULHW"
1120   "macchw. %0,%1,%2"
1121   [(set_attr "type" "halfmul")])
1123 (define_insn "*macchw"
1124   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1125         (plus:SI (mult:SI (ashiftrt:SI
1126                            (match_operand:SI 2 "gpc_reg_operand" "r")
1127                            (const_int 16))
1128                           (sign_extend:SI
1129                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1130                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1131   "TARGET_MULHW"
1132   "macchw %0,%1,%2"
1133   [(set_attr "type" "halfmul")])
1135 (define_insn "*macchwuc"
1136   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1137         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1138                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1139                                        (const_int 16))
1140                                       (zero_extend:SI
1141                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1142                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1143                     (const_int 0)))
1144    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1145         (plus:SI (mult:SI (lshiftrt:SI
1146                            (match_dup 2)
1147                            (const_int 16))
1148                           (zero_extend:SI
1149                            (match_dup 1)))
1150                  (match_dup 4)))]
1151   "TARGET_MULHW"
1152   "macchwu. %0,%1,%2"
1153   [(set_attr "type" "halfmul")])
1155 (define_insn "*macchwu"
1156   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1157         (plus:SI (mult:SI (lshiftrt:SI
1158                            (match_operand:SI 2 "gpc_reg_operand" "r")
1159                            (const_int 16))
1160                           (zero_extend:SI
1161                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1162                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1163   "TARGET_MULHW"
1164   "macchwu %0,%1,%2"
1165   [(set_attr "type" "halfmul")])
1167 (define_insn "*machhwc"
1168   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1169         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1170                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1171                                        (const_int 16))
1172                                       (ashiftrt:SI
1173                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1174                                        (const_int 16)))
1175                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1176                     (const_int 0)))
1177    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1178         (plus:SI (mult:SI (ashiftrt:SI
1179                            (match_dup 1)
1180                            (const_int 16))
1181                           (ashiftrt:SI
1182                            (match_dup 2)
1183                            (const_int 16)))
1184                  (match_dup 4)))]
1185   "TARGET_MULHW"
1186   "machhw. %0,%1,%2"
1187   [(set_attr "type" "halfmul")])
1189 (define_insn "*machhw"
1190   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1191         (plus:SI (mult:SI (ashiftrt:SI
1192                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1193                            (const_int 16))
1194                           (ashiftrt:SI
1195                            (match_operand:SI 2 "gpc_reg_operand" "r")
1196                            (const_int 16)))
1197                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1198   "TARGET_MULHW"
1199   "machhw %0,%1,%2"
1200   [(set_attr "type" "halfmul")])
1202 (define_insn "*machhwuc"
1203   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1204         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1205                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1206                                        (const_int 16))
1207                                       (lshiftrt:SI
1208                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1209                                        (const_int 16)))
1210                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1211                     (const_int 0)))
1212    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1213         (plus:SI (mult:SI (lshiftrt:SI
1214                            (match_dup 1)
1215                            (const_int 16))
1216                           (lshiftrt:SI
1217                            (match_dup 2)
1218                            (const_int 16)))
1219                  (match_dup 4)))]
1220   "TARGET_MULHW"
1221   "machhwu. %0,%1,%2"
1222   [(set_attr "type" "halfmul")])
1224 (define_insn "*machhwu"
1225   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1226         (plus:SI (mult:SI (lshiftrt:SI
1227                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1228                            (const_int 16))
1229                           (lshiftrt:SI
1230                            (match_operand:SI 2 "gpc_reg_operand" "r")
1231                            (const_int 16)))
1232                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1233   "TARGET_MULHW"
1234   "machhwu %0,%1,%2"
1235   [(set_attr "type" "halfmul")])
1237 (define_insn "*maclhwc"
1238   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1239         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1240                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1241                                       (sign_extend:SI
1242                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1243                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1244                     (const_int 0)))
1245    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1246         (plus:SI (mult:SI (sign_extend:SI
1247                            (match_dup 1))
1248                           (sign_extend:SI
1249                            (match_dup 2)))
1250                  (match_dup 4)))]
1251   "TARGET_MULHW"
1252   "maclhw. %0,%1,%2"
1253   [(set_attr "type" "halfmul")])
1255 (define_insn "*maclhw"
1256   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1257         (plus:SI (mult:SI (sign_extend:SI
1258                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1259                           (sign_extend:SI
1260                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1261                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1262   "TARGET_MULHW"
1263   "maclhw %0,%1,%2"
1264   [(set_attr "type" "halfmul")])
1266 (define_insn "*maclhwuc"
1267   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1268         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1269                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1270                                       (zero_extend:SI
1271                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1272                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1273                     (const_int 0)))
1274    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1275         (plus:SI (mult:SI (zero_extend:SI
1276                            (match_dup 1))
1277                           (zero_extend:SI
1278                            (match_dup 2)))
1279                  (match_dup 4)))]
1280   "TARGET_MULHW"
1281   "maclhwu. %0,%1,%2"
1282   [(set_attr "type" "halfmul")])
1284 (define_insn "*maclhwu"
1285   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1286         (plus:SI (mult:SI (zero_extend:SI
1287                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1288                           (zero_extend:SI
1289                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1290                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1291   "TARGET_MULHW"
1292   "maclhwu %0,%1,%2"
1293   [(set_attr "type" "halfmul")])
1295 (define_insn "*nmacchwc"
1296   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1297         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1298                               (mult:SI (ashiftrt:SI
1299                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1300                                         (const_int 16))
1301                                        (sign_extend:SI
1302                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1303                     (const_int 0)))
1304    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1305         (minus:SI (match_dup 4)
1306                   (mult:SI (ashiftrt:SI
1307                             (match_dup 2)
1308                             (const_int 16))
1309                            (sign_extend:SI
1310                             (match_dup 1)))))]
1311   "TARGET_MULHW"
1312   "nmacchw. %0,%1,%2"
1313   [(set_attr "type" "halfmul")])
1315 (define_insn "*nmacchw"
1316   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1317         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1318                   (mult:SI (ashiftrt:SI
1319                             (match_operand:SI 2 "gpc_reg_operand" "r")
1320                             (const_int 16))
1321                            (sign_extend:SI
1322                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1323   "TARGET_MULHW"
1324   "nmacchw %0,%1,%2"
1325   [(set_attr "type" "halfmul")])
1327 (define_insn "*nmachhwc"
1328   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1329         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1330                               (mult:SI (ashiftrt:SI
1331                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1332                                         (const_int 16))
1333                                        (ashiftrt:SI
1334                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1335                                         (const_int 16))))
1336                     (const_int 0)))
1337    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1338         (minus:SI (match_dup 4)
1339                   (mult:SI (ashiftrt:SI
1340                             (match_dup 1)
1341                             (const_int 16))
1342                            (ashiftrt:SI
1343                             (match_dup 2)
1344                             (const_int 16)))))]
1345   "TARGET_MULHW"
1346   "nmachhw. %0,%1,%2"
1347   [(set_attr "type" "halfmul")])
1349 (define_insn "*nmachhw"
1350   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1351         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1352                   (mult:SI (ashiftrt:SI
1353                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1354                             (const_int 16))
1355                            (ashiftrt:SI
1356                             (match_operand:SI 2 "gpc_reg_operand" "r")
1357                             (const_int 16)))))]
1358   "TARGET_MULHW"
1359   "nmachhw %0,%1,%2"
1360   [(set_attr "type" "halfmul")])
1362 (define_insn "*nmaclhwc"
1363   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1364         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1365                               (mult:SI (sign_extend:SI
1366                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1367                                        (sign_extend:SI
1368                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1369                     (const_int 0)))
1370    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1371         (minus:SI (match_dup 4)
1372                   (mult:SI (sign_extend:SI
1373                             (match_dup 1))
1374                            (sign_extend:SI
1375                             (match_dup 2)))))]
1376   "TARGET_MULHW"
1377   "nmaclhw. %0,%1,%2"
1378   [(set_attr "type" "halfmul")])
1380 (define_insn "*nmaclhw"
1381   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1382         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1383                   (mult:SI (sign_extend:SI
1384                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1385                            (sign_extend:SI
1386                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1387   "TARGET_MULHW"
1388   "nmaclhw %0,%1,%2"
1389   [(set_attr "type" "halfmul")])
1391 (define_insn "*mulchwc"
1392   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1393         (compare:CC (mult:SI (ashiftrt:SI
1394                               (match_operand:SI 2 "gpc_reg_operand" "r")
1395                               (const_int 16))
1396                              (sign_extend:SI
1397                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1398                     (const_int 0)))
1399    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1400         (mult:SI (ashiftrt:SI
1401                   (match_dup 2)
1402                   (const_int 16))
1403                  (sign_extend:SI
1404                   (match_dup 1))))]
1405   "TARGET_MULHW"
1406   "mulchw. %0,%1,%2"
1407   [(set_attr "type" "halfmul")])
1409 (define_insn "*mulchw"
1410   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1411         (mult:SI (ashiftrt:SI
1412                   (match_operand:SI 2 "gpc_reg_operand" "r")
1413                   (const_int 16))
1414                  (sign_extend:SI
1415                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1416   "TARGET_MULHW"
1417   "mulchw %0,%1,%2"
1418   [(set_attr "type" "halfmul")])
1420 (define_insn "*mulchwuc"
1421   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1422         (compare:CC (mult:SI (lshiftrt:SI
1423                               (match_operand:SI 2 "gpc_reg_operand" "r")
1424                               (const_int 16))
1425                              (zero_extend:SI
1426                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1427                     (const_int 0)))
1428    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1429         (mult:SI (lshiftrt:SI
1430                   (match_dup 2)
1431                   (const_int 16))
1432                  (zero_extend:SI
1433                   (match_dup 1))))]
1434   "TARGET_MULHW"
1435   "mulchwu. %0,%1,%2"
1436   [(set_attr "type" "halfmul")])
1438 (define_insn "*mulchwu"
1439   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1440         (mult:SI (lshiftrt:SI
1441                   (match_operand:SI 2 "gpc_reg_operand" "r")
1442                   (const_int 16))
1443                  (zero_extend:SI
1444                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1445   "TARGET_MULHW"
1446   "mulchwu %0,%1,%2"
1447   [(set_attr "type" "halfmul")])
1449 (define_insn "*mulhhwc"
1450   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1451         (compare:CC (mult:SI (ashiftrt:SI
1452                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1453                               (const_int 16))
1454                              (ashiftrt:SI
1455                               (match_operand:SI 2 "gpc_reg_operand" "r")
1456                               (const_int 16)))
1457                     (const_int 0)))
1458    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1459         (mult:SI (ashiftrt:SI
1460                   (match_dup 1)
1461                   (const_int 16))
1462                  (ashiftrt:SI
1463                   (match_dup 2)
1464                   (const_int 16))))]
1465   "TARGET_MULHW"
1466   "mulhhw. %0,%1,%2"
1467   [(set_attr "type" "halfmul")])
1469 (define_insn "*mulhhw"
1470   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1471         (mult:SI (ashiftrt:SI
1472                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1473                   (const_int 16))
1474                  (ashiftrt:SI
1475                   (match_operand:SI 2 "gpc_reg_operand" "r")
1476                   (const_int 16))))]
1477   "TARGET_MULHW"
1478   "mulhhw %0,%1,%2"
1479   [(set_attr "type" "halfmul")])
1481 (define_insn "*mulhhwuc"
1482   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1483         (compare:CC (mult:SI (lshiftrt:SI
1484                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1485                               (const_int 16))
1486                              (lshiftrt:SI
1487                               (match_operand:SI 2 "gpc_reg_operand" "r")
1488                               (const_int 16)))
1489                     (const_int 0)))
1490    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1491         (mult:SI (lshiftrt:SI
1492                   (match_dup 1)
1493                   (const_int 16))
1494                  (lshiftrt:SI
1495                   (match_dup 2)
1496                   (const_int 16))))]
1497   "TARGET_MULHW"
1498   "mulhhwu. %0,%1,%2"
1499   [(set_attr "type" "halfmul")])
1501 (define_insn "*mulhhwu"
1502   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1503         (mult:SI (lshiftrt:SI
1504                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1505                   (const_int 16))
1506                  (lshiftrt:SI
1507                   (match_operand:SI 2 "gpc_reg_operand" "r")
1508                   (const_int 16))))]
1509   "TARGET_MULHW"
1510   "mulhhwu %0,%1,%2"
1511   [(set_attr "type" "halfmul")])
1513 (define_insn "*mullhwc"
1514   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1515         (compare:CC (mult:SI (sign_extend:SI
1516                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1517                              (sign_extend:SI
1518                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1519                     (const_int 0)))
1520    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1521         (mult:SI (sign_extend:SI
1522                   (match_dup 1))
1523                  (sign_extend:SI
1524                   (match_dup 2))))]
1525   "TARGET_MULHW"
1526   "mullhw. %0,%1,%2"
1527   [(set_attr "type" "halfmul")])
1529 (define_insn "*mullhw"
1530   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1531         (mult:SI (sign_extend:SI
1532                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1533                  (sign_extend:SI
1534                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1535   "TARGET_MULHW"
1536   "mullhw %0,%1,%2"
1537   [(set_attr "type" "halfmul")])
1539 (define_insn "*mullhwuc"
1540   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1541         (compare:CC (mult:SI (zero_extend:SI
1542                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1543                              (zero_extend:SI
1544                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1545                     (const_int 0)))
1546    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1547         (mult:SI (zero_extend:SI
1548                   (match_dup 1))
1549                  (zero_extend:SI
1550                   (match_dup 2))))]
1551   "TARGET_MULHW"
1552   "mullhwu. %0,%1,%2"
1553   [(set_attr "type" "halfmul")])
1555 (define_insn "*mullhwu"
1556   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1557         (mult:SI (zero_extend:SI
1558                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1559                  (zero_extend:SI
1560                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1561   "TARGET_MULHW"
1562   "mullhwu %0,%1,%2"
1563   [(set_attr "type" "halfmul")])
1565 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1566 (define_insn "dlmzb"
1567   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1568         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1569                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1570                    UNSPEC_DLMZB_CR))
1571    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1572         (unspec:SI [(match_dup 1)
1573                     (match_dup 2)]
1574                    UNSPEC_DLMZB))]
1575   "TARGET_DLMZB"
1576   "dlmzb. %0,%1,%2")
1578 (define_expand "strlensi"
1579   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1580         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1581                     (match_operand:QI 2 "const_int_operand" "")
1582                     (match_operand 3 "const_int_operand" "")]
1583                    UNSPEC_DLMZB_STRLEN))
1584    (clobber (match_scratch:CC 4 "=x"))]
1585   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1587   rtx result = operands[0];
1588   rtx src = operands[1];
1589   rtx search_char = operands[2];
1590   rtx align = operands[3];
1591   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1592   rtx loop_label, end_label, mem, cr0, cond;
1593   if (search_char != const0_rtx
1594       || GET_CODE (align) != CONST_INT
1595       || INTVAL (align) < 8)
1596         FAIL;
1597   word1 = gen_reg_rtx (SImode);
1598   word2 = gen_reg_rtx (SImode);
1599   scratch_dlmzb = gen_reg_rtx (SImode);
1600   scratch_string = gen_reg_rtx (Pmode);
1601   loop_label = gen_label_rtx ();
1602   end_label = gen_label_rtx ();
1603   addr = force_reg (Pmode, XEXP (src, 0));
1604   emit_move_insn (scratch_string, addr);
1605   emit_label (loop_label);
1606   mem = change_address (src, SImode, scratch_string);
1607   emit_move_insn (word1, mem);
1608   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1609   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1610   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1611   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1612   emit_jump_insn (gen_rtx_SET (pc_rtx,
1613                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1614                                                      cond,
1615                                                      gen_rtx_LABEL_REF
1616                                                        (VOIDmode,
1617                                                         end_label),
1618                                                      pc_rtx)));
1619   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1620   emit_jump_insn (gen_rtx_SET (pc_rtx,
1621                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1622   emit_barrier ();
1623   emit_label (end_label);
1624   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1625   emit_insn (gen_subsi3 (result, scratch_string, addr));
1626   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1627   DONE;
1630 ;; Fixed-point arithmetic insns.
1632 (define_expand "add<mode>3"
1633   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1634         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1635                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1636   ""
1638   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1639     {
1640       rtx lo0 = gen_lowpart (SImode, operands[0]);
1641       rtx lo1 = gen_lowpart (SImode, operands[1]);
1642       rtx lo2 = gen_lowpart (SImode, operands[2]);
1643       rtx hi0 = gen_highpart (SImode, operands[0]);
1644       rtx hi1 = gen_highpart (SImode, operands[1]);
1645       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1647       if (!reg_or_short_operand (lo2, SImode))
1648         lo2 = force_reg (SImode, lo2);
1649       if (!adde_operand (hi2, SImode))
1650         hi2 = force_reg (SImode, hi2);
1652       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1653       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1654       DONE;
1655     }
1657   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1658     {
1659       rtx tmp = ((!can_create_pseudo_p ()
1660                   || rtx_equal_p (operands[0], operands[1]))
1661                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1663       /* Adding a constant to r0 is not a valid insn, so use a different
1664          strategy in that case.  */
1665       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1666         {
1667           if (operands[0] == operands[1])
1668             FAIL;
1669           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1670           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1671           DONE;
1672         }
1674       HOST_WIDE_INT val = INTVAL (operands[2]);
1675       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1676       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1678       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1679         FAIL;
1681       /* The ordering here is important for the prolog expander.
1682          When space is allocated from the stack, adding 'low' first may
1683          produce a temporary deallocation (which would be bad).  */
1684       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1685       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1686       DONE;
1687     }
1690 (define_insn "*add<mode>3"
1691   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1692         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1693                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1694   ""
1695   "@
1696    add %0,%1,%2
1697    addi %0,%1,%2
1698    addis %0,%1,%v2"
1699   [(set_attr "type" "add")])
1701 (define_insn "addsi3_high"
1702   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1703         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1704                  (high:SI (match_operand 2 "" ""))))]
1705   "TARGET_MACHO && !TARGET_64BIT"
1706   "addis %0,%1,ha16(%2)"
1707   [(set_attr "type" "add")])
1709 (define_insn_and_split "*add<mode>3_dot"
1710   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1711         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1712                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1713                     (const_int 0)))
1714    (clobber (match_scratch:GPR 0 "=r,r"))]
1715   "<MODE>mode == Pmode"
1716   "@
1717    add. %0,%1,%2
1718    #"
1719   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1720   [(set (match_dup 0)
1721         (plus:GPR (match_dup 1)
1722                  (match_dup 2)))
1723    (set (match_dup 3)
1724         (compare:CC (match_dup 0)
1725                     (const_int 0)))]
1726   ""
1727   [(set_attr "type" "add")
1728    (set_attr "dot" "yes")
1729    (set_attr "length" "4,8")])
1731 (define_insn_and_split "*add<mode>3_dot2"
1732   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1733         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1734                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1735                     (const_int 0)))
1736    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1737         (plus:GPR (match_dup 1)
1738                   (match_dup 2)))]
1739   "<MODE>mode == Pmode"
1740   "@
1741    add. %0,%1,%2
1742    #"
1743   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1744   [(set (match_dup 0)
1745         (plus:GPR (match_dup 1)
1746                   (match_dup 2)))
1747    (set (match_dup 3)
1748         (compare:CC (match_dup 0)
1749                     (const_int 0)))]
1750   ""
1751   [(set_attr "type" "add")
1752    (set_attr "dot" "yes")
1753    (set_attr "length" "4,8")])
1755 (define_insn_and_split "*add<mode>3_imm_dot"
1756   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1757         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1758                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1759                     (const_int 0)))
1760    (clobber (match_scratch:GPR 0 "=r,r"))
1761    (clobber (reg:GPR CA_REGNO))]
1762   "<MODE>mode == Pmode"
1763   "@
1764    addic. %0,%1,%2
1765    #"
1766   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1767   [(set (match_dup 0)
1768         (plus:GPR (match_dup 1)
1769                   (match_dup 2)))
1770    (set (match_dup 3)
1771         (compare:CC (match_dup 0)
1772                     (const_int 0)))]
1773   ""
1774   [(set_attr "type" "add")
1775    (set_attr "dot" "yes")
1776    (set_attr "length" "4,8")])
1778 (define_insn_and_split "*add<mode>3_imm_dot2"
1779   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1780         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1781                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1782                     (const_int 0)))
1783    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1784         (plus:GPR (match_dup 1)
1785                   (match_dup 2)))
1786    (clobber (reg:GPR CA_REGNO))]
1787   "<MODE>mode == Pmode"
1788   "@
1789    addic. %0,%1,%2
1790    #"
1791   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1792   [(set (match_dup 0)
1793         (plus:GPR (match_dup 1)
1794                   (match_dup 2)))
1795    (set (match_dup 3)
1796         (compare:CC (match_dup 0)
1797                     (const_int 0)))]
1798   ""
1799   [(set_attr "type" "add")
1800    (set_attr "dot" "yes")
1801    (set_attr "length" "4,8")])
1803 ;; Split an add that we can't do in one insn into two insns, each of which
1804 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1805 ;; add should be last in case the result gets used in an address.
1807 (define_split
1808   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1809         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1810                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1811   ""
1812   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1813    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1815   HOST_WIDE_INT val = INTVAL (operands[2]);
1816   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1817   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1819   operands[4] = GEN_INT (low);
1820   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1821     operands[3] = GEN_INT (rest);
1822   else if (can_create_pseudo_p ())
1823     {
1824       operands[3] = gen_reg_rtx (DImode);
1825       emit_move_insn (operands[3], operands[2]);
1826       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1827       DONE;
1828     }
1829   else
1830     FAIL;
1834 (define_insn "add<mode>3_carry"
1835   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1836         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1837                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1838    (set (reg:P CA_REGNO)
1839         (ltu:P (plus:P (match_dup 1)
1840                        (match_dup 2))
1841                (match_dup 1)))]
1842   ""
1843   "add%I2c %0,%1,%2"
1844   [(set_attr "type" "add")])
1846 (define_insn "*add<mode>3_imm_carry_pos"
1847   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1848         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1849                 (match_operand:P 2 "short_cint_operand" "n")))
1850    (set (reg:P CA_REGNO)
1851         (geu:P (match_dup 1)
1852                (match_operand:P 3 "const_int_operand" "n")))]
1853   "INTVAL (operands[2]) > 0
1854    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1855   "addic %0,%1,%2"
1856   [(set_attr "type" "add")])
1858 (define_insn "*add<mode>3_imm_carry_0"
1859   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1860         (match_operand:P 1 "gpc_reg_operand" "r"))
1861    (set (reg:P CA_REGNO)
1862         (const_int 0))]
1863   ""
1864   "addic %0,%1,0"
1865   [(set_attr "type" "add")])
1867 (define_insn "*add<mode>3_imm_carry_m1"
1868   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1869         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1870                 (const_int -1)))
1871    (set (reg:P CA_REGNO)
1872         (ne:P (match_dup 1)
1873               (const_int 0)))]
1874   ""
1875   "addic %0,%1,-1"
1876   [(set_attr "type" "add")])
1878 (define_insn "*add<mode>3_imm_carry_neg"
1879   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1880         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1881                 (match_operand:P 2 "short_cint_operand" "n")))
1882    (set (reg:P CA_REGNO)
1883         (gtu:P (match_dup 1)
1884                (match_operand:P 3 "const_int_operand" "n")))]
1885   "INTVAL (operands[2]) < 0
1886    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1887   "addic %0,%1,%2"
1888   [(set_attr "type" "add")])
1891 (define_expand "add<mode>3_carry_in"
1892   [(parallel [
1893      (set (match_operand:GPR 0 "gpc_reg_operand")
1894           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1895                               (match_operand:GPR 2 "adde_operand"))
1896                     (reg:GPR CA_REGNO)))
1897      (clobber (reg:GPR CA_REGNO))])]
1898   ""
1900   if (operands[2] == const0_rtx)
1901     {
1902       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1903       DONE;
1904     }
1905   if (operands[2] == constm1_rtx)
1906     {
1907       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1908       DONE;
1909     }
1912 (define_insn "*add<mode>3_carry_in_internal"
1913   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1914         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1915                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1916                   (reg:GPR CA_REGNO)))
1917    (clobber (reg:GPR CA_REGNO))]
1918   ""
1919   "adde %0,%1,%2"
1920   [(set_attr "type" "add")])
1922 (define_insn "*add<mode>3_carry_in_internal2"
1923   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1924         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1925                             (reg:GPR CA_REGNO))
1926                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
1927    (clobber (reg:GPR CA_REGNO))]
1928   ""
1929   "adde %0,%1,%2"
1930   [(set_attr "type" "add")])
1932 (define_insn "add<mode>3_carry_in_0"
1933   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1934         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1935                   (reg:GPR CA_REGNO)))
1936    (clobber (reg:GPR CA_REGNO))]
1937   ""
1938   "addze %0,%1"
1939   [(set_attr "type" "add")])
1941 (define_insn "add<mode>3_carry_in_m1"
1942   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1943         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1944                             (reg:GPR CA_REGNO))
1945                   (const_int -1)))
1946    (clobber (reg:GPR CA_REGNO))]
1947   ""
1948   "addme %0,%1"
1949   [(set_attr "type" "add")])
1952 (define_expand "one_cmpl<mode>2"
1953   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1954         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1955   ""
1957   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1958     {
1959       rs6000_split_logical (operands, NOT, false, false, false);
1960       DONE;
1961     }
1964 (define_insn "*one_cmpl<mode>2"
1965   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1966         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1967   ""
1968   "not %0,%1")
1970 (define_insn_and_split "*one_cmpl<mode>2_dot"
1971   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1972         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1973                     (const_int 0)))
1974    (clobber (match_scratch:GPR 0 "=r,r"))]
1975   "<MODE>mode == Pmode"
1976   "@
1977    not. %0,%1
1978    #"
1979   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1980   [(set (match_dup 0)
1981         (not:GPR (match_dup 1)))
1982    (set (match_dup 2)
1983         (compare:CC (match_dup 0)
1984                     (const_int 0)))]
1985   ""
1986   [(set_attr "type" "logical")
1987    (set_attr "dot" "yes")
1988    (set_attr "length" "4,8")])
1990 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1991   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1992         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1993                     (const_int 0)))
1994    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1995         (not:GPR (match_dup 1)))]
1996   "<MODE>mode == Pmode"
1997   "@
1998    not. %0,%1
1999    #"
2000   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2001   [(set (match_dup 0)
2002         (not:GPR (match_dup 1)))
2003    (set (match_dup 2)
2004         (compare:CC (match_dup 0)
2005                     (const_int 0)))]
2006   ""
2007   [(set_attr "type" "logical")
2008    (set_attr "dot" "yes")
2009    (set_attr "length" "4,8")])
2012 (define_expand "sub<mode>3"
2013   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2014         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
2015                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
2016   ""
2018   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2019     {
2020       rtx lo0 = gen_lowpart (SImode, operands[0]);
2021       rtx lo1 = gen_lowpart (SImode, operands[1]);
2022       rtx lo2 = gen_lowpart (SImode, operands[2]);
2023       rtx hi0 = gen_highpart (SImode, operands[0]);
2024       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2025       rtx hi2 = gen_highpart (SImode, operands[2]);
2027       if (!reg_or_short_operand (lo1, SImode))
2028         lo1 = force_reg (SImode, lo1);
2029       if (!adde_operand (hi1, SImode))
2030         hi1 = force_reg (SImode, hi1);
2032       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2033       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2034       DONE;
2035     }
2037   if (short_cint_operand (operands[1], <MODE>mode))
2038     {
2039       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2040       DONE;
2041     }
2044 (define_insn "*subf<mode>3"
2045   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2046         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2047                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2048   ""
2049   "subf %0,%1,%2"
2050   [(set_attr "type" "add")])
2052 (define_insn_and_split "*subf<mode>3_dot"
2053   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2054         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2055                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2056                     (const_int 0)))
2057    (clobber (match_scratch:GPR 0 "=r,r"))]
2058   "<MODE>mode == Pmode"
2059   "@
2060    subf. %0,%1,%2
2061    #"
2062   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2063   [(set (match_dup 0)
2064         (minus:GPR (match_dup 2)
2065                    (match_dup 1)))
2066    (set (match_dup 3)
2067         (compare:CC (match_dup 0)
2068                     (const_int 0)))]
2069   ""
2070   [(set_attr "type" "add")
2071    (set_attr "dot" "yes")
2072    (set_attr "length" "4,8")])
2074 (define_insn_and_split "*subf<mode>3_dot2"
2075   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2076         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2077                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2078                     (const_int 0)))
2079    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2080         (minus:GPR (match_dup 2)
2081                    (match_dup 1)))]
2082   "<MODE>mode == Pmode"
2083   "@
2084    subf. %0,%1,%2
2085    #"
2086   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2087   [(set (match_dup 0)
2088         (minus:GPR (match_dup 2)
2089                    (match_dup 1)))
2090    (set (match_dup 3)
2091         (compare:CC (match_dup 0)
2092                     (const_int 0)))]
2093   ""
2094   [(set_attr "type" "add")
2095    (set_attr "dot" "yes")
2096    (set_attr "length" "4,8")])
2098 (define_insn "subf<mode>3_imm"
2099   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2100         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2101                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2102    (clobber (reg:GPR CA_REGNO))]
2103   ""
2104   "subfic %0,%1,%2"
2105   [(set_attr "type" "add")])
2107 (define_insn_and_split "subf<mode>3_carry_dot2"
2108   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2109         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2110                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2111                     (const_int 0)))
2112    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
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   "<MODE>mode == Pmode"
2119   "@
2120    subfc. %0,%1,%2
2121    #"
2122   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2123   [(parallel [(set (match_dup 0)
2124                    (minus:P (match_dup 2)
2125                             (match_dup 1)))
2126               (set (reg:P CA_REGNO)
2127                    (leu:P (match_dup 1)
2128                           (match_dup 2)))])
2129    (set (match_dup 3)
2130         (compare:CC (match_dup 0)
2131                     (const_int 0)))]
2132   ""
2133   [(set_attr "type" "add")
2134    (set_attr "dot" "yes")
2135    (set_attr "length" "4,8")])
2137 (define_insn "subf<mode>3_carry"
2138   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2139         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2140                  (match_operand:P 1 "gpc_reg_operand" "r")))
2141    (set (reg:P CA_REGNO)
2142         (leu:P (match_dup 1)
2143                (match_dup 2)))]
2144   ""
2145   "subf%I2c %0,%1,%2"
2146   [(set_attr "type" "add")])
2148 (define_insn "*subf<mode>3_imm_carry_0"
2149   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2150         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2151    (set (reg:P CA_REGNO)
2152         (eq:P (match_dup 1)
2153               (const_int 0)))]
2154   ""
2155   "subfic %0,%1,0"
2156   [(set_attr "type" "add")])
2158 (define_insn "*subf<mode>3_imm_carry_m1"
2159   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2160         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2161    (set (reg:P CA_REGNO)
2162         (const_int 1))]
2163   ""
2164   "subfic %0,%1,-1"
2165   [(set_attr "type" "add")])
2168 (define_expand "subf<mode>3_carry_in"
2169   [(parallel [
2170      (set (match_operand:GPR 0 "gpc_reg_operand")
2171           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2172                               (reg:GPR CA_REGNO))
2173                     (match_operand:GPR 2 "adde_operand")))
2174      (clobber (reg:GPR CA_REGNO))])]
2175   ""
2177   if (operands[2] == const0_rtx)
2178     {
2179       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2180       DONE;
2181     }
2182   if (operands[2] == constm1_rtx)
2183     {
2184       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2185       DONE;
2186     }
2189 (define_insn "*subf<mode>3_carry_in_internal"
2190   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2191         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2192                             (reg:GPR CA_REGNO))
2193                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2194    (clobber (reg:GPR CA_REGNO))]
2195   ""
2196   "subfe %0,%1,%2"
2197   [(set_attr "type" "add")])
2199 (define_insn "subf<mode>3_carry_in_0"
2200   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2201         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2202                   (reg:GPR CA_REGNO)))
2203    (clobber (reg:GPR CA_REGNO))]
2204   ""
2205   "subfze %0,%1"
2206   [(set_attr "type" "add")])
2208 (define_insn "subf<mode>3_carry_in_m1"
2209   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2210         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2211                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2212                   (const_int -2)))
2213    (clobber (reg:GPR CA_REGNO))]
2214   ""
2215   "subfme %0,%1"
2216   [(set_attr "type" "add")])
2218 (define_insn "subf<mode>3_carry_in_xx"
2219   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2220         (plus:GPR (reg:GPR CA_REGNO)
2221                   (const_int -1)))
2222    (clobber (reg:GPR CA_REGNO))]
2223   ""
2224   "subfe %0,%0,%0"
2225   [(set_attr "type" "add")])
2228 (define_insn "neg<mode>2"
2229   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2230         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2231   ""
2232   "neg %0,%1"
2233   [(set_attr "type" "add")])
2235 (define_insn_and_split "*neg<mode>2_dot"
2236   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2237         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2238                     (const_int 0)))
2239    (clobber (match_scratch:GPR 0 "=r,r"))]
2240   "<MODE>mode == Pmode"
2241   "@
2242    neg. %0,%1
2243    #"
2244   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2245   [(set (match_dup 0)
2246         (neg:GPR (match_dup 1)))
2247    (set (match_dup 2)
2248         (compare:CC (match_dup 0)
2249                     (const_int 0)))]
2250   ""
2251   [(set_attr "type" "add")
2252    (set_attr "dot" "yes")
2253    (set_attr "length" "4,8")])
2255 (define_insn_and_split "*neg<mode>2_dot2"
2256   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2257         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2258                     (const_int 0)))
2259    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2260         (neg:GPR (match_dup 1)))]
2261   "<MODE>mode == Pmode"
2262   "@
2263    neg. %0,%1
2264    #"
2265   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2266   [(set (match_dup 0)
2267         (neg:GPR (match_dup 1)))
2268    (set (match_dup 2)
2269         (compare:CC (match_dup 0)
2270                     (const_int 0)))]
2271   ""
2272   [(set_attr "type" "add")
2273    (set_attr "dot" "yes")
2274    (set_attr "length" "4,8")])
2277 (define_insn "clz<mode>2"
2278   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2279         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2280   ""
2281   "cntlz<wd> %0,%1"
2282   [(set_attr "type" "cntlz")])
2284 (define_expand "ctz<mode>2"
2285    [(set (match_operand:GPR 0 "gpc_reg_operand")
2286          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2287   ""
2289   if (TARGET_CTZ)
2290     {
2291       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2292       DONE;
2293     }
2295   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2296   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2297   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2299   if (TARGET_POPCNTD)
2300     {
2301       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2302       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2303       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2304       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2305     }
2306   else
2307     {
2308       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2309       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2310       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2311       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2312     }
2314   DONE;
2317 (define_insn "ctz<mode>2_hw"
2318   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2319         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2320   "TARGET_CTZ"
2321   "cnttz<wd> %0,%1"
2322   [(set_attr "type" "cntlz")])
2324 (define_expand "ffs<mode>2"
2325   [(set (match_operand:GPR 0 "gpc_reg_operand")
2326         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2327   ""
2329   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2330   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2331   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2332   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2333   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2334   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2335   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2336   DONE;
2340 (define_expand "popcount<mode>2"
2341   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2342         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2343   "TARGET_POPCNTB || TARGET_POPCNTD"
2345   rs6000_emit_popcount (operands[0], operands[1]);
2346   DONE;
2349 (define_insn "popcntb<mode>2"
2350   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2351         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2352                     UNSPEC_POPCNTB))]
2353   "TARGET_POPCNTB"
2354   "popcntb %0,%1"
2355   [(set_attr "type" "popcnt")])
2357 (define_insn "popcntd<mode>2"
2358   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2359         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2360   "TARGET_POPCNTD"
2361   "popcnt<wd> %0,%1"
2362   [(set_attr "type" "popcnt")])
2365 (define_expand "parity<mode>2"
2366   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2367         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2368   "TARGET_POPCNTB"
2370   rs6000_emit_parity (operands[0], operands[1]);
2371   DONE;
2374 (define_insn "parity<mode>2_cmpb"
2375   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2376         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2377   "TARGET_CMPB && TARGET_POPCNTB"
2378   "prty<wd> %0,%1"
2379   [(set_attr "type" "popcnt")])
2381 (define_insn "cmpb<mode>3"
2382   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2383         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2384                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2385   "TARGET_CMPB"
2386   "cmpb %0,%1,%2"
2387   [(set_attr "type" "cmp")])
2389 ;; Since the hardware zeros the upper part of the register, save generating the
2390 ;; AND immediate if we are converting to unsigned
2391 (define_insn "*bswap<mode>2_extenddi"
2392   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2393         (zero_extend:DI
2394          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2395   "TARGET_POWERPC64"
2396   "l<wd>brx %0,%y1"
2397   [(set_attr "length" "4")
2398    (set_attr "type" "load")])
2400 (define_insn "*bswaphi2_extendsi"
2401   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2402         (zero_extend:SI
2403          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2404   ""
2405   "lhbrx %0,%y1"
2406   [(set_attr "length" "4")
2407    (set_attr "type" "load")])
2409 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2410 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2411 ;; load with byte swap, which can be slower than doing it in the registers.  It
2412 ;; also prevents certain failures with the RELOAD register allocator.
2414 (define_expand "bswap<mode>2"
2415   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2416    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2417   ""
2419   rtx dest = operands[0];
2420   rtx src = operands[1];
2422   if (!REG_P (dest) && !REG_P (src))
2423     src = force_reg (<MODE>mode, src);
2425   if (MEM_P (src))
2426     emit_insn (gen_bswap<mode>2_load (dest, src));
2427   else if (MEM_P (dest))
2428     emit_insn (gen_bswap<mode>2_store (dest, src));
2429   else
2430     emit_insn (gen_bswap<mode>2_reg (dest, src));
2431   DONE;
2434 (define_insn "bswap<mode>2_load"
2435   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2436         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2437   ""
2438   "l<wd>brx %0,%y1"
2439   [(set_attr "type" "load")])
2441 (define_insn "bswap<mode>2_store"
2442   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2443         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2444   ""
2445   "st<wd>brx %1,%y0"
2446   [(set_attr "type" "store")])
2448 (define_insn_and_split "bswaphi2_reg"
2449   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2450         (bswap:HI
2451          (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2452    (clobber (match_scratch:SI 2 "=&r,X"))]
2453   ""
2454   "@
2455    #
2456    xxbrh %x0,%x1"
2457   "reload_completed && int_reg_operand (operands[0], HImode)"
2458   [(set (match_dup 3)
2459         (and:SI (lshiftrt:SI (match_dup 4)
2460                              (const_int 8))
2461                 (const_int 255)))
2462    (set (match_dup 2)
2463         (and:SI (ashift:SI (match_dup 4)
2464                            (const_int 8))
2465                 (const_int 65280)))             ;; 0xff00
2466    (set (match_dup 3)
2467         (ior:SI (match_dup 3)
2468                 (match_dup 2)))]
2470   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2471   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2473   [(set_attr "length" "12,4")
2474    (set_attr "type" "*,vecperm")])
2476 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2477 ;; zero_extract insns do not change for -mlittle.
2478 (define_insn_and_split "bswapsi2_reg"
2479   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2480         (bswap:SI
2481          (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2482   ""
2483   "@
2484    #
2485    xxbrw %x0,%x1"
2486   "reload_completed && int_reg_operand (operands[0], SImode)"
2487   [(set (match_dup 0)                                   ; DABC
2488         (rotate:SI (match_dup 1)
2489                    (const_int 24)))
2490    (set (match_dup 0)                                   ; DCBC
2491         (ior:SI (and:SI (ashift:SI (match_dup 1)
2492                                    (const_int 8))
2493                         (const_int 16711680))
2494                 (and:SI (match_dup 0)
2495                         (const_int -16711681))))
2496    (set (match_dup 0)                                   ; DCBA
2497         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2498                                      (const_int 24))
2499                         (const_int 255))
2500                 (and:SI (match_dup 0)
2501                         (const_int -256))))]
2502   ""
2503   [(set_attr "length" "12,4")
2504    (set_attr "type" "*,vecperm")])
2506 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2507 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2508 ;; complex code.
2510 (define_expand "bswapdi2"
2511   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2512                    (bswap:DI
2513                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2514               (clobber (match_scratch:DI 2 ""))
2515               (clobber (match_scratch:DI 3 ""))])]
2516   ""
2518   rtx dest = operands[0];
2519   rtx src = operands[1];
2521   if (!REG_P (dest) && !REG_P (src))
2522     operands[1] = src = force_reg (DImode, src);
2524   if (TARGET_POWERPC64 && TARGET_LDBRX)
2525     {
2526       if (MEM_P (src))
2527         emit_insn (gen_bswapdi2_load (dest, src));
2528       else if (MEM_P (dest))
2529         emit_insn (gen_bswapdi2_store (dest, src));
2530       else if (TARGET_P9_VECTOR)
2531         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2532       else
2533         emit_insn (gen_bswapdi2_reg (dest, src));
2534       DONE;
2535     }
2537   if (!TARGET_POWERPC64)
2538     {
2539       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2540          that uses 64-bit registers needs the same scratch registers as 64-bit
2541          mode.  */
2542       emit_insn (gen_bswapdi2_32bit (dest, src));
2543       DONE;
2544     }
2547 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2548 (define_insn "bswapdi2_load"
2549   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2550         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2551   "TARGET_POWERPC64 && TARGET_LDBRX"
2552   "ldbrx %0,%y1"
2553   [(set_attr "type" "load")])
2555 (define_insn "bswapdi2_store"
2556   [(set (match_operand:DI 0 "memory_operand" "=Z")
2557         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2558   "TARGET_POWERPC64 && TARGET_LDBRX"
2559   "stdbrx %1,%y0"
2560   [(set_attr "type" "store")])
2562 (define_insn "bswapdi2_xxbrd"
2563   [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2564         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2565   "TARGET_P9_VECTOR"
2566   "xxbrd %x0,%x1"
2567   [(set_attr "type" "vecperm")])
2569 (define_insn "bswapdi2_reg"
2570   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2571         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2572    (clobber (match_scratch:DI 2 "=&r"))
2573    (clobber (match_scratch:DI 3 "=&r"))]
2574   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2575   "#"
2576   [(set_attr "length" "36")])
2578 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2579 (define_insn "*bswapdi2_64bit"
2580   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2581         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2582    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2583    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2584   "TARGET_POWERPC64 && !TARGET_LDBRX
2585    && (REG_P (operands[0]) || REG_P (operands[1]))
2586    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2587    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2588   "#"
2589   [(set_attr "length" "16,12,36")])
2591 (define_split
2592   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2593         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2594    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2595    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2596   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2597   [(const_int 0)]
2598   "
2600   rtx dest   = operands[0];
2601   rtx src    = operands[1];
2602   rtx op2    = operands[2];
2603   rtx op3    = operands[3];
2604   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2605                                     BYTES_BIG_ENDIAN ? 4 : 0);
2606   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2607                                      BYTES_BIG_ENDIAN ? 4 : 0);
2608   rtx addr1;
2609   rtx addr2;
2610   rtx word1;
2611   rtx word2;
2613   addr1 = XEXP (src, 0);
2614   if (GET_CODE (addr1) == PLUS)
2615     {
2616       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2617       if (TARGET_AVOID_XFORM)
2618         {
2619           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2620           addr2 = op2;
2621         }
2622       else
2623         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2624     }
2625   else if (TARGET_AVOID_XFORM)
2626     {
2627       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2628       addr2 = op2;
2629     }
2630   else
2631     {
2632       emit_move_insn (op2, GEN_INT (4));
2633       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2634     }
2636   word1 = change_address (src, SImode, addr1);
2637   word2 = change_address (src, SImode, addr2);
2639   if (BYTES_BIG_ENDIAN)
2640     {
2641       emit_insn (gen_bswapsi2 (op3_32, word2));
2642       emit_insn (gen_bswapsi2 (dest_32, word1));
2643     }
2644   else
2645     {
2646       emit_insn (gen_bswapsi2 (op3_32, word1));
2647       emit_insn (gen_bswapsi2 (dest_32, word2));
2648     }
2650   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2651   emit_insn (gen_iordi3 (dest, dest, op3));
2652   DONE;
2655 (define_split
2656   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2657         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2658    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2659    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2660   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2661   [(const_int 0)]
2662   "
2664   rtx dest   = operands[0];
2665   rtx src    = operands[1];
2666   rtx op2    = operands[2];
2667   rtx op3    = operands[3];
2668   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2669                                     BYTES_BIG_ENDIAN ? 4 : 0);
2670   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2671                                     BYTES_BIG_ENDIAN ? 4 : 0);
2672   rtx addr1;
2673   rtx addr2;
2674   rtx word1;
2675   rtx word2;
2677   addr1 = XEXP (dest, 0);
2678   if (GET_CODE (addr1) == PLUS)
2679     {
2680       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2681       if (TARGET_AVOID_XFORM)
2682         {
2683           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2684           addr2 = op2;
2685         }
2686       else
2687         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2688     }
2689   else if (TARGET_AVOID_XFORM)
2690     {
2691       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2692       addr2 = op2;
2693     }
2694   else
2695     {
2696       emit_move_insn (op2, GEN_INT (4));
2697       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2698     }
2700   word1 = change_address (dest, SImode, addr1);
2701   word2 = change_address (dest, SImode, addr2);
2703   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2705   if (BYTES_BIG_ENDIAN)
2706     {
2707       emit_insn (gen_bswapsi2 (word1, src_si));
2708       emit_insn (gen_bswapsi2 (word2, op3_si));
2709     }
2710   else
2711     {
2712       emit_insn (gen_bswapsi2 (word2, src_si));
2713       emit_insn (gen_bswapsi2 (word1, op3_si));
2714     }
2715   DONE;
2718 (define_split
2719   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2720         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2721    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2722    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2723   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2724   [(const_int 0)]
2725   "
2727   rtx dest    = operands[0];
2728   rtx src     = operands[1];
2729   rtx op2     = operands[2];
2730   rtx op3     = operands[3];
2731   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2732   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2733   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2734   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2735   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2737   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2738   emit_insn (gen_bswapsi2 (dest_si, src_si));
2739   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2740   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2741   emit_insn (gen_iordi3 (dest, dest, op3));
2742   DONE;
2745 (define_insn "bswapdi2_32bit"
2746   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2747         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2748    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2749   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2750   "#"
2751   [(set_attr "length" "16,12,36")])
2753 (define_split
2754   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2755         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2756    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2757   "!TARGET_POWERPC64 && reload_completed"
2758   [(const_int 0)]
2759   "
2761   rtx dest  = operands[0];
2762   rtx src   = operands[1];
2763   rtx op2   = operands[2];
2764   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2765   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2766   rtx addr1;
2767   rtx addr2;
2768   rtx word1;
2769   rtx word2;
2771   addr1 = XEXP (src, 0);
2772   if (GET_CODE (addr1) == PLUS)
2773     {
2774       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2775       if (TARGET_AVOID_XFORM
2776           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2777         {
2778           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2779           addr2 = op2;
2780         }
2781       else
2782         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2783     }
2784   else if (TARGET_AVOID_XFORM
2785            || REGNO (addr1) == REGNO (dest2))
2786     {
2787       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2788       addr2 = op2;
2789     }
2790   else
2791     {
2792       emit_move_insn (op2, GEN_INT (4));
2793       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2794     }
2796   word1 = change_address (src, SImode, addr1);
2797   word2 = change_address (src, SImode, addr2);
2799   emit_insn (gen_bswapsi2 (dest2, word1));
2800   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2801      thus allowing us to omit an early clobber on the output.  */
2802   emit_insn (gen_bswapsi2 (dest1, word2));
2803   DONE;
2806 (define_split
2807   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2808         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2809    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2810   "!TARGET_POWERPC64 && reload_completed"
2811   [(const_int 0)]
2812   "
2814   rtx dest = operands[0];
2815   rtx src  = operands[1];
2816   rtx op2  = operands[2];
2817   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2818   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2819   rtx addr1;
2820   rtx addr2;
2821   rtx word1;
2822   rtx word2;
2824   addr1 = XEXP (dest, 0);
2825   if (GET_CODE (addr1) == PLUS)
2826     {
2827       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2828       if (TARGET_AVOID_XFORM)
2829         {
2830           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2831           addr2 = op2;
2832         }
2833       else
2834         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2835     }
2836   else if (TARGET_AVOID_XFORM)
2837     {
2838       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2839       addr2 = op2;
2840     }
2841   else
2842     {
2843       emit_move_insn (op2, GEN_INT (4));
2844       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2845     }
2847   word1 = change_address (dest, SImode, addr1);
2848   word2 = change_address (dest, SImode, addr2);
2850   emit_insn (gen_bswapsi2 (word2, src1));
2851   emit_insn (gen_bswapsi2 (word1, src2));
2852   DONE;
2855 (define_split
2856   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2857         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2858    (clobber (match_operand:SI 2 "" ""))]
2859   "!TARGET_POWERPC64 && reload_completed"
2860   [(const_int 0)]
2861   "
2863   rtx dest  = operands[0];
2864   rtx src   = operands[1];
2865   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2866   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2867   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2868   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2870   emit_insn (gen_bswapsi2 (dest1, src2));
2871   emit_insn (gen_bswapsi2 (dest2, src1));
2872   DONE;
2876 (define_insn "mul<mode>3"
2877   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2878         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2879                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2880   ""
2881   "@
2882    mull<wd> %0,%1,%2
2883    mulli %0,%1,%2"
2884    [(set_attr "type" "mul")
2885     (set (attr "size")
2886       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2887                 (const_string "8")
2888              (match_operand:GPR 2 "short_cint_operand" "")
2889                 (const_string "16")]
2890         (const_string "<bits>")))])
2892 (define_insn_and_split "*mul<mode>3_dot"
2893   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2894         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2895                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2896                     (const_int 0)))
2897    (clobber (match_scratch:GPR 0 "=r,r"))]
2898   "<MODE>mode == Pmode"
2899   "@
2900    mull<wd>. %0,%1,%2
2901    #"
2902   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2903   [(set (match_dup 0)
2904         (mult:GPR (match_dup 1)
2905                   (match_dup 2)))
2906    (set (match_dup 3)
2907         (compare:CC (match_dup 0)
2908                     (const_int 0)))]
2909   ""
2910   [(set_attr "type" "mul")
2911    (set_attr "size" "<bits>")
2912    (set_attr "dot" "yes")
2913    (set_attr "length" "4,8")])
2915 (define_insn_and_split "*mul<mode>3_dot2"
2916   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2917         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2918                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2919                     (const_int 0)))
2920    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2921         (mult:GPR (match_dup 1)
2922                   (match_dup 2)))]
2923   "<MODE>mode == Pmode"
2924   "@
2925    mull<wd>. %0,%1,%2
2926    #"
2927   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2928   [(set (match_dup 0)
2929         (mult:GPR (match_dup 1)
2930                   (match_dup 2)))
2931    (set (match_dup 3)
2932         (compare:CC (match_dup 0)
2933                     (const_int 0)))]
2934   ""
2935   [(set_attr "type" "mul")
2936    (set_attr "size" "<bits>")
2937    (set_attr "dot" "yes")
2938    (set_attr "length" "4,8")])
2941 (define_expand "<su>mul<mode>3_highpart"
2942   [(set (match_operand:GPR 0 "gpc_reg_operand")
2943         (subreg:GPR
2944           (mult:<DMODE> (any_extend:<DMODE>
2945                           (match_operand:GPR 1 "gpc_reg_operand"))
2946                         (any_extend:<DMODE>
2947                           (match_operand:GPR 2 "gpc_reg_operand")))
2948          0))]
2949   ""
2951   if (<MODE>mode == SImode && TARGET_POWERPC64)
2952     {
2953       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2954                                              operands[2]));
2955       DONE;
2956     }
2958   if (!WORDS_BIG_ENDIAN)
2959     {
2960       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2961                                                  operands[2]));
2962       DONE;
2963     }
2966 (define_insn "*<su>mul<mode>3_highpart"
2967   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2968         (subreg:GPR
2969           (mult:<DMODE> (any_extend:<DMODE>
2970                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2971                         (any_extend:<DMODE>
2972                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2973          0))]
2974   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2975   "mulh<wd><u> %0,%1,%2"
2976   [(set_attr "type" "mul")
2977    (set_attr "size" "<bits>")])
2979 (define_insn "<su>mulsi3_highpart_le"
2980   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2981         (subreg:SI
2982           (mult:DI (any_extend:DI
2983                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2984                    (any_extend:DI
2985                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2986          4))]
2987   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2988   "mulhw<u> %0,%1,%2"
2989   [(set_attr "type" "mul")])
2991 (define_insn "<su>muldi3_highpart_le"
2992   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2993         (subreg:DI
2994           (mult:TI (any_extend:TI
2995                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2996                    (any_extend:TI
2997                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2998          8))]
2999   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3000   "mulhd<u> %0,%1,%2"
3001   [(set_attr "type" "mul")
3002    (set_attr "size" "64")])
3004 (define_insn "<su>mulsi3_highpart_64"
3005   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3006         (truncate:SI
3007           (lshiftrt:DI
3008             (mult:DI (any_extend:DI
3009                        (match_operand:SI 1 "gpc_reg_operand" "r"))
3010                      (any_extend:DI
3011                        (match_operand:SI 2 "gpc_reg_operand" "r")))
3012             (const_int 32))))]
3013   "TARGET_POWERPC64"
3014   "mulhw<u> %0,%1,%2"
3015   [(set_attr "type" "mul")])
3017 (define_expand "<u>mul<mode><dmode>3"
3018   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3019         (mult:<DMODE> (any_extend:<DMODE>
3020                         (match_operand:GPR 1 "gpc_reg_operand"))
3021                       (any_extend:<DMODE>
3022                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3023   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3025   rtx l = gen_reg_rtx (<MODE>mode);
3026   rtx h = gen_reg_rtx (<MODE>mode);
3027   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3028   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3029   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3030   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3031   DONE;
3034 (define_insn "*maddld4"
3035   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3036         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3037                           (match_operand:DI 2 "gpc_reg_operand" "r"))
3038                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
3039   "TARGET_MADDLD"
3040   "maddld %0,%1,%2,%3"
3041   [(set_attr "type" "mul")])
3043 (define_insn "udiv<mode>3"
3044   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3045         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3046                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3047   ""
3048   "div<wd>u %0,%1,%2"
3049   [(set_attr "type" "div")
3050    (set_attr "size" "<bits>")])
3053 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3054 ;; modulus.  If it isn't a power of two, force operands into register and do
3055 ;; a normal divide.
3056 (define_expand "div<mode>3"
3057   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3058         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3059                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3060   ""
3062   if (CONST_INT_P (operands[2])
3063       && INTVAL (operands[2]) > 0
3064       && exact_log2 (INTVAL (operands[2])) >= 0)
3065     {
3066       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3067       DONE;
3068     }
3070   operands[2] = force_reg (<MODE>mode, operands[2]);
3073 (define_insn "*div<mode>3"
3074   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3075         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3076                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3077   ""
3078   "div<wd> %0,%1,%2"
3079   [(set_attr "type" "div")
3080    (set_attr "size" "<bits>")])
3082 (define_insn "div<mode>3_sra"
3083   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3084         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3085                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3086    (clobber (reg:GPR CA_REGNO))]
3087   ""
3088   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3089   [(set_attr "type" "two")
3090    (set_attr "length" "8")])
3092 (define_insn_and_split "*div<mode>3_sra_dot"
3093   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3094         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3095                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3096                     (const_int 0)))
3097    (clobber (match_scratch:GPR 0 "=r,r"))
3098    (clobber (reg:GPR CA_REGNO))]
3099   "<MODE>mode == Pmode"
3100   "@
3101    sra<wd>i %0,%1,%p2\;addze. %0,%0
3102    #"
3103   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3104   [(parallel [(set (match_dup 0)
3105                    (div:GPR (match_dup 1)
3106                             (match_dup 2)))
3107               (clobber (reg:GPR CA_REGNO))])
3108    (set (match_dup 3)
3109         (compare:CC (match_dup 0)
3110                     (const_int 0)))]
3111   ""
3112   [(set_attr "type" "two")
3113    (set_attr "length" "8,12")
3114    (set_attr "cell_micro" "not")])
3116 (define_insn_and_split "*div<mode>3_sra_dot2"
3117   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3118         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3119                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3120                     (const_int 0)))
3121    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3122         (div:GPR (match_dup 1)
3123                  (match_dup 2)))
3124    (clobber (reg:GPR CA_REGNO))]
3125   "<MODE>mode == Pmode"
3126   "@
3127    sra<wd>i %0,%1,%p2\;addze. %0,%0
3128    #"
3129   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3130   [(parallel [(set (match_dup 0)
3131                    (div:GPR (match_dup 1)
3132                             (match_dup 2)))
3133               (clobber (reg:GPR CA_REGNO))])
3134    (set (match_dup 3)
3135         (compare:CC (match_dup 0)
3136                     (const_int 0)))]
3137   ""
3138   [(set_attr "type" "two")
3139    (set_attr "length" "8,12")
3140    (set_attr "cell_micro" "not")])
3142 (define_expand "mod<mode>3"
3143   [(set (match_operand:GPR 0 "gpc_reg_operand")
3144         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3145                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3146   ""
3148   int i;
3149   rtx temp1;
3150   rtx temp2;
3152   if (GET_CODE (operands[2]) != CONST_INT
3153       || INTVAL (operands[2]) <= 0
3154       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3155     {
3156       if (!TARGET_MODULO)
3157         FAIL;
3159       operands[2] = force_reg (<MODE>mode, operands[2]);
3160     }
3161   else
3162     {
3163       temp1 = gen_reg_rtx (<MODE>mode);
3164       temp2 = gen_reg_rtx (<MODE>mode);
3166       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3167       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3168       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3169       DONE;
3170     }
3173 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3174 ;; mod, prefer putting the result of mod into a different register
3175 (define_insn "*mod<mode>3"
3176   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3177         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3178                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3179   "TARGET_MODULO"
3180   "mods<wd> %0,%1,%2"
3181   [(set_attr "type" "div")
3182    (set_attr "size" "<bits>")])
3185 (define_insn "umod<mode>3"
3186   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3187         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3188                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3189   "TARGET_MODULO"
3190   "modu<wd> %0,%1,%2"
3191   [(set_attr "type" "div")
3192    (set_attr "size" "<bits>")])
3194 ;; On machines with modulo support, do a combined div/mod the old fashioned
3195 ;; method, since the multiply/subtract is faster than doing the mod instruction
3196 ;; after a divide.
3198 (define_peephole2
3199   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3200         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3201                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3202    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3203         (mod:GPR (match_dup 1)
3204                  (match_dup 2)))]
3205   "TARGET_MODULO
3206    && ! reg_mentioned_p (operands[0], operands[1])
3207    && ! reg_mentioned_p (operands[0], operands[2])
3208    && ! reg_mentioned_p (operands[3], operands[1])
3209    && ! reg_mentioned_p (operands[3], operands[2])"
3210   [(set (match_dup 0)
3211         (div:GPR (match_dup 1)
3212                  (match_dup 2)))
3213    (set (match_dup 3)
3214         (mult:GPR (match_dup 0)
3215                   (match_dup 2)))
3216    (set (match_dup 3)
3217         (minus:GPR (match_dup 1)
3218                    (match_dup 3)))])
3220 (define_peephole2
3221   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3222         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3223                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3224    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3225         (umod:GPR (match_dup 1)
3226                   (match_dup 2)))]
3227   "TARGET_MODULO
3228    && ! reg_mentioned_p (operands[0], operands[1])
3229    && ! reg_mentioned_p (operands[0], operands[2])
3230    && ! reg_mentioned_p (operands[3], operands[1])
3231    && ! reg_mentioned_p (operands[3], operands[2])"
3232   [(set (match_dup 0)
3233         (udiv:GPR (match_dup 1)
3234                   (match_dup 2)))
3235    (set (match_dup 3)
3236         (mult:GPR (match_dup 0)
3237                   (match_dup 2)))
3238    (set (match_dup 3)
3239         (minus:GPR (match_dup 1)
3240                    (match_dup 3)))])
3243 ;; Logical instructions
3244 ;; The logical instructions are mostly combined by using match_operator,
3245 ;; but the plain AND insns are somewhat different because there is no
3246 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3247 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3249 (define_expand "and<mode>3"
3250   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3251         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3252                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3253   ""
3255   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3256     {
3257       rs6000_split_logical (operands, AND, false, false, false);
3258       DONE;
3259     }
3261   if (CONST_INT_P (operands[2]))
3262     {
3263       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3264         {
3265           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3266           DONE;
3267         }
3269       if (logical_const_operand (operands[2], <MODE>mode))
3270         {
3271           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3272           DONE;
3273         }
3275       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3276         {
3277           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3278           DONE;
3279         }
3281       operands[2] = force_reg (<MODE>mode, operands[2]);
3282     }
3286 (define_insn "and<mode>3_imm"
3287   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3288         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3289                  (match_operand:GPR 2 "logical_const_operand" "n")))
3290    (clobber (match_scratch:CC 3 "=x"))]
3291   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3292   "andi%e2. %0,%1,%u2"
3293   [(set_attr "type" "logical")
3294    (set_attr "dot" "yes")])
3296 (define_insn_and_split "*and<mode>3_imm_dot"
3297   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3298         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3299                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3300                     (const_int 0)))
3301    (clobber (match_scratch:GPR 0 "=r,r"))
3302    (clobber (match_scratch:CC 4 "=X,x"))]
3303   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3304    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3305   "@
3306    andi%e2. %0,%1,%u2
3307    #"
3308   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3309   [(parallel [(set (match_dup 0)
3310                    (and:GPR (match_dup 1)
3311                             (match_dup 2)))
3312               (clobber (match_dup 4))])
3313    (set (match_dup 3)
3314         (compare:CC (match_dup 0)
3315                     (const_int 0)))]
3316   ""
3317   [(set_attr "type" "logical")
3318    (set_attr "dot" "yes")
3319    (set_attr "length" "4,8")])
3321 (define_insn_and_split "*and<mode>3_imm_dot2"
3322   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3323         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3324                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3325                     (const_int 0)))
3326    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3327         (and:GPR (match_dup 1)
3328                  (match_dup 2)))
3329    (clobber (match_scratch:CC 4 "=X,x"))]
3330   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3331    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3332   "@
3333    andi%e2. %0,%1,%u2
3334    #"
3335   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3336   [(parallel [(set (match_dup 0)
3337                    (and:GPR (match_dup 1)
3338                             (match_dup 2)))
3339               (clobber (match_dup 4))])
3340    (set (match_dup 3)
3341         (compare:CC (match_dup 0)
3342                     (const_int 0)))]
3343   ""
3344   [(set_attr "type" "logical")
3345    (set_attr "dot" "yes")
3346    (set_attr "length" "4,8")])
3348 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3349   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3350         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3351                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3352                     (const_int 0)))
3353    (clobber (match_scratch:GPR 0 "=r,r"))]
3354   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3355    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3356   "@
3357    andi%e2. %0,%1,%u2
3358    #"
3359   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3360   [(set (match_dup 0)
3361         (and:GPR (match_dup 1)
3362                  (match_dup 2)))
3363    (set (match_dup 3)
3364         (compare:CC (match_dup 0)
3365                     (const_int 0)))]
3366   ""
3367   [(set_attr "type" "logical")
3368    (set_attr "dot" "yes")
3369    (set_attr "length" "4,8")])
3371 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3372   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3373         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3374                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3375                     (const_int 0)))
3376    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3377         (and:GPR (match_dup 1)
3378                  (match_dup 2)))]
3379   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3380    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3381   "@
3382    andi%e2. %0,%1,%u2
3383    #"
3384   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3385   [(set (match_dup 0)
3386         (and:GPR (match_dup 1)
3387                  (match_dup 2)))
3388    (set (match_dup 3)
3389         (compare:CC (match_dup 0)
3390                     (const_int 0)))]
3391   ""
3392   [(set_attr "type" "logical")
3393    (set_attr "dot" "yes")
3394    (set_attr "length" "4,8")])
3396 (define_insn "*and<mode>3_imm_dot_shifted"
3397   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3398         (compare:CC
3399           (and:GPR
3400             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3401                           (match_operand:SI 4 "const_int_operand" "n"))
3402             (match_operand:GPR 2 "const_int_operand" "n"))
3403           (const_int 0)))
3404    (clobber (match_scratch:GPR 0 "=r"))]
3405   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3406                                    << INTVAL (operands[4])),
3407                           DImode)
3408    && (<MODE>mode == Pmode
3409        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3411   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3412   return "andi%e2. %0,%1,%u2";
3414   [(set_attr "type" "logical")
3415    (set_attr "dot" "yes")])
3418 (define_insn "and<mode>3_mask"
3419   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3420         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3421                  (match_operand:GPR 2 "const_int_operand" "n")))]
3422   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3424   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3426   [(set_attr "type" "shift")])
3428 (define_insn_and_split "*and<mode>3_mask_dot"
3429   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3430         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3431                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3432                     (const_int 0)))
3433    (clobber (match_scratch:GPR 0 "=r,r"))]
3434   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3435    && !logical_const_operand (operands[2], <MODE>mode)
3436    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3438   if (which_alternative == 0)
3439     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3440   else
3441     return "#";
3443   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3444   [(set (match_dup 0)
3445         (and:GPR (match_dup 1)
3446                  (match_dup 2)))
3447    (set (match_dup 3)
3448         (compare:CC (match_dup 0)
3449                     (const_int 0)))]
3450   ""
3451   [(set_attr "type" "shift")
3452    (set_attr "dot" "yes")
3453    (set_attr "length" "4,8")])
3455 (define_insn_and_split "*and<mode>3_mask_dot2"
3456   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3457         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3458                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3459                     (const_int 0)))
3460    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3461         (and:GPR (match_dup 1)
3462                  (match_dup 2)))]
3463   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3464    && !logical_const_operand (operands[2], <MODE>mode)
3465    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3467   if (which_alternative == 0)
3468     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3469   else
3470     return "#";
3472   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3473   [(set (match_dup 0)
3474         (and:GPR (match_dup 1)
3475                  (match_dup 2)))
3476    (set (match_dup 3)
3477         (compare:CC (match_dup 0)
3478                     (const_int 0)))]
3479   ""
3480   [(set_attr "type" "shift")
3481    (set_attr "dot" "yes")
3482    (set_attr "length" "4,8")])
3485 (define_insn_and_split "*and<mode>3_2insn"
3486   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3487         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3488                  (match_operand:GPR 2 "const_int_operand" "n")))]
3489   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3490    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3491         || logical_const_operand (operands[2], <MODE>mode))"
3492   "#"
3493   "&& 1"
3494   [(pc)]
3496   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3497   DONE;
3499   [(set_attr "type" "shift")
3500    (set_attr "length" "8")])
3502 (define_insn_and_split "*and<mode>3_2insn_dot"
3503   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3504         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3505                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3506                     (const_int 0)))
3507    (clobber (match_scratch:GPR 0 "=r,r"))]
3508   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3509    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3510    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3511         || logical_const_operand (operands[2], <MODE>mode))"
3512   "#"
3513   "&& reload_completed"
3514   [(pc)]
3516   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3517   DONE;
3519   [(set_attr "type" "shift")
3520    (set_attr "dot" "yes")
3521    (set_attr "length" "8,12")])
3523 (define_insn_and_split "*and<mode>3_2insn_dot2"
3524   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3525         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3526                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3527                     (const_int 0)))
3528    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3529         (and:GPR (match_dup 1)
3530                  (match_dup 2)))]
3531   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3532    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3533    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3534         || logical_const_operand (operands[2], <MODE>mode))"
3535   "#"
3536   "&& reload_completed"
3537   [(pc)]
3539   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3540   DONE;
3542   [(set_attr "type" "shift")
3543    (set_attr "dot" "yes")
3544    (set_attr "length" "8,12")])
3547 (define_expand "<code><mode>3"
3548   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3549         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3550                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3551   ""
3553   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3554     {
3555       rs6000_split_logical (operands, <CODE>, false, false, false);
3556       DONE;
3557     }
3559   if (non_logical_cint_operand (operands[2], <MODE>mode))
3560     {
3561       rtx tmp = ((!can_create_pseudo_p ()
3562                   || rtx_equal_p (operands[0], operands[1]))
3563                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3565       HOST_WIDE_INT value = INTVAL (operands[2]);
3566       HOST_WIDE_INT lo = value & 0xffff;
3567       HOST_WIDE_INT hi = value - lo;
3569       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3570       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3571       DONE;
3572     }
3574   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3575     operands[2] = force_reg (<MODE>mode, operands[2]);
3578 (define_split
3579   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3580         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3581                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3582   ""
3583   [(set (match_dup 3)
3584         (iorxor:GPR (match_dup 1)
3585                     (match_dup 4)))
3586    (set (match_dup 0)
3587         (iorxor:GPR (match_dup 3)
3588                     (match_dup 5)))]
3590   operands[3] = ((!can_create_pseudo_p ()
3591                   || rtx_equal_p (operands[0], operands[1]))
3592                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3594   HOST_WIDE_INT value = INTVAL (operands[2]);
3595   HOST_WIDE_INT lo = value & 0xffff;
3596   HOST_WIDE_INT hi = value - lo;
3598   operands[4] = GEN_INT (hi);
3599   operands[5] = GEN_INT (lo);
3602 (define_insn "*bool<mode>3_imm"
3603   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3604         (match_operator:GPR 3 "boolean_or_operator"
3605          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3606           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3607   ""
3608   "%q3i%e2 %0,%1,%u2"
3609   [(set_attr "type" "logical")])
3611 (define_insn "*bool<mode>3"
3612   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3613         (match_operator:GPR 3 "boolean_operator"
3614          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3615           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3616   ""
3617   "%q3 %0,%1,%2"
3618   [(set_attr "type" "logical")])
3620 (define_insn_and_split "*bool<mode>3_dot"
3621   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3622         (compare:CC (match_operator:GPR 3 "boolean_operator"
3623          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3624           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3625          (const_int 0)))
3626    (clobber (match_scratch:GPR 0 "=r,r"))]
3627   "<MODE>mode == Pmode"
3628   "@
3629    %q3. %0,%1,%2
3630    #"
3631   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3632   [(set (match_dup 0)
3633         (match_dup 3))
3634    (set (match_dup 4)
3635         (compare:CC (match_dup 0)
3636                     (const_int 0)))]
3637   ""
3638   [(set_attr "type" "logical")
3639    (set_attr "dot" "yes")
3640    (set_attr "length" "4,8")])
3642 (define_insn_and_split "*bool<mode>3_dot2"
3643   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3644         (compare:CC (match_operator:GPR 3 "boolean_operator"
3645          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3646           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3647          (const_int 0)))
3648    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3649         (match_dup 3))]
3650   "<MODE>mode == Pmode"
3651   "@
3652    %q3. %0,%1,%2
3653    #"
3654   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3655   [(set (match_dup 0)
3656         (match_dup 3))
3657    (set (match_dup 4)
3658         (compare:CC (match_dup 0)
3659                     (const_int 0)))]
3660   ""
3661   [(set_attr "type" "logical")
3662    (set_attr "dot" "yes")
3663    (set_attr "length" "4,8")])
3666 (define_insn "*boolc<mode>3"
3667   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3668         (match_operator:GPR 3 "boolean_operator"
3669          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3670           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3671   ""
3672   "%q3 %0,%1,%2"
3673   [(set_attr "type" "logical")])
3675 (define_insn_and_split "*boolc<mode>3_dot"
3676   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3677         (compare:CC (match_operator:GPR 3 "boolean_operator"
3678          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3679           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3680          (const_int 0)))
3681    (clobber (match_scratch:GPR 0 "=r,r"))]
3682   "<MODE>mode == Pmode"
3683   "@
3684    %q3. %0,%1,%2
3685    #"
3686   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3687   [(set (match_dup 0)
3688         (match_dup 3))
3689    (set (match_dup 4)
3690         (compare:CC (match_dup 0)
3691                     (const_int 0)))]
3692   ""
3693   [(set_attr "type" "logical")
3694    (set_attr "dot" "yes")
3695    (set_attr "length" "4,8")])
3697 (define_insn_and_split "*boolc<mode>3_dot2"
3698   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3699         (compare:CC (match_operator:GPR 3 "boolean_operator"
3700          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3701           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3702          (const_int 0)))
3703    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3704         (match_dup 3))]
3705   "<MODE>mode == Pmode"
3706   "@
3707    %q3. %0,%1,%2
3708    #"
3709   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3710   [(set (match_dup 0)
3711         (match_dup 3))
3712    (set (match_dup 4)
3713         (compare:CC (match_dup 0)
3714                     (const_int 0)))]
3715   ""
3716   [(set_attr "type" "logical")
3717    (set_attr "dot" "yes")
3718    (set_attr "length" "4,8")])
3721 (define_insn "*boolcc<mode>3"
3722   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3723         (match_operator:GPR 3 "boolean_operator"
3724          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3725           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3726   ""
3727   "%q3 %0,%1,%2"
3728   [(set_attr "type" "logical")])
3730 (define_insn_and_split "*boolcc<mode>3_dot"
3731   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3732         (compare:CC (match_operator:GPR 3 "boolean_operator"
3733          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3734           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3735          (const_int 0)))
3736    (clobber (match_scratch:GPR 0 "=r,r"))]
3737   "<MODE>mode == Pmode"
3738   "@
3739    %q3. %0,%1,%2
3740    #"
3741   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3742   [(set (match_dup 0)
3743         (match_dup 3))
3744    (set (match_dup 4)
3745         (compare:CC (match_dup 0)
3746                     (const_int 0)))]
3747   ""
3748   [(set_attr "type" "logical")
3749    (set_attr "dot" "yes")
3750    (set_attr "length" "4,8")])
3752 (define_insn_and_split "*boolcc<mode>3_dot2"
3753   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3754         (compare:CC (match_operator:GPR 3 "boolean_operator"
3755          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3756           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3757          (const_int 0)))
3758    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3759         (match_dup 3))]
3760   "<MODE>mode == Pmode"
3761   "@
3762    %q3. %0,%1,%2
3763    #"
3764   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3765   [(set (match_dup 0)
3766         (match_dup 3))
3767    (set (match_dup 4)
3768         (compare:CC (match_dup 0)
3769                     (const_int 0)))]
3770   ""
3771   [(set_attr "type" "logical")
3772    (set_attr "dot" "yes")
3773    (set_attr "length" "4,8")])
3776 ;; TODO: Should have dots of this as well.
3777 (define_insn "*eqv<mode>3"
3778   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3779         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3780                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3781   ""
3782   "eqv %0,%1,%2"
3783   [(set_attr "type" "logical")])
3785 ;; Rotate-and-mask and insert.
3787 (define_insn "*rotl<mode>3_mask"
3788   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3789         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3790                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3791                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3792                  (match_operand:GPR 3 "const_int_operand" "n")))]
3793   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3795   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3797   [(set_attr "type" "shift")
3798    (set_attr "maybe_var_shift" "yes")])
3800 (define_insn_and_split "*rotl<mode>3_mask_dot"
3801   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3802         (compare:CC
3803           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3804                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3805                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3806                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3807           (const_int 0)))
3808    (clobber (match_scratch:GPR 0 "=r,r"))]
3809   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3810    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3812   if (which_alternative == 0)
3813     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3814   else
3815     return "#";
3817   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3818   [(set (match_dup 0)
3819         (and:GPR (match_dup 4)
3820                  (match_dup 3)))
3821    (set (match_dup 5)
3822         (compare:CC (match_dup 0)
3823                     (const_int 0)))]
3824   ""
3825   [(set_attr "type" "shift")
3826    (set_attr "maybe_var_shift" "yes")
3827    (set_attr "dot" "yes")
3828    (set_attr "length" "4,8")])
3830 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3831   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3832         (compare:CC
3833           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3834                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3835                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3836                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3837           (const_int 0)))
3838    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3839         (and:GPR (match_dup 4)
3840                  (match_dup 3)))]
3841   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3842    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3844   if (which_alternative == 0)
3845     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3846   else
3847     return "#";
3849   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3850   [(set (match_dup 0)
3851         (and:GPR (match_dup 4)
3852                  (match_dup 3)))
3853    (set (match_dup 5)
3854         (compare:CC (match_dup 0)
3855                     (const_int 0)))]
3856   ""
3857   [(set_attr "type" "shift")
3858    (set_attr "maybe_var_shift" "yes")
3859    (set_attr "dot" "yes")
3860    (set_attr "length" "4,8")])
3862 ; Special case for less-than-0.  We can do it with just one machine
3863 ; instruction, but the generic optimizers do not realise it is cheap.
3864 (define_insn "*lt0_<mode>di"
3865   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3866         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3867                 (const_int 0)))]
3868   "TARGET_POWERPC64"
3869   "srdi %0,%1,63"
3870   [(set_attr "type" "shift")])
3872 (define_insn "*lt0_<mode>si"
3873   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3874         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3875                 (const_int 0)))]
3876   ""
3877   "rlwinm %0,%1,1,31,31"
3878   [(set_attr "type" "shift")])
3882 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3883 ; both are an AND so are the same precedence).
3884 (define_insn "*rotl<mode>3_insert"
3885   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3886         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3887                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3888                             (match_operand:SI 2 "const_int_operand" "n")])
3889                           (match_operand:GPR 3 "const_int_operand" "n"))
3890                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3891                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3892   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3893    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3895   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3897   [(set_attr "type" "insert")])
3898 ; FIXME: this needs an attr "size", so that the scheduler can see the
3899 ; difference between rlwimi and rldimi.  We also might want dot forms,
3900 ; but not for rlwimi on POWER4 and similar processors.
3902 (define_insn "*rotl<mode>3_insert_2"
3903   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3904         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3905                           (match_operand:GPR 6 "const_int_operand" "n"))
3906                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3907                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3908                             (match_operand:SI 2 "const_int_operand" "n")])
3909                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3910   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3911    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3913   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3915   [(set_attr "type" "insert")])
3917 ; There are also some forms without one of the ANDs.
3918 (define_insn "*rotl<mode>3_insert_3"
3919   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3920         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3921                           (match_operand:GPR 4 "const_int_operand" "n"))
3922                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3923                              (match_operand:SI 2 "const_int_operand" "n"))))]
3924   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3926   if (<MODE>mode == SImode)
3927     return "rlwimi %0,%1,%h2,0,31-%h2";
3928   else
3929     return "rldimi %0,%1,%H2,0";
3931   [(set_attr "type" "insert")])
3933 (define_insn "*rotl<mode>3_insert_4"
3934   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3935         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3936                           (match_operand:GPR 4 "const_int_operand" "n"))
3937                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3938                                (match_operand:SI 2 "const_int_operand" "n"))))]
3939   "<MODE>mode == SImode &&
3940    GET_MODE_PRECISION (<MODE>mode)
3941    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3943   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3944                          - INTVAL (operands[2]));
3945   if (<MODE>mode == SImode)
3946     return "rlwimi %0,%1,%h2,32-%h2,31";
3947   else
3948     return "rldimi %0,%1,%H2,64-%H2";
3950   [(set_attr "type" "insert")])
3952 (define_insn "*rotlsi3_insert_5"
3953   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3954         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3955                         (match_operand:SI 2 "const_int_operand" "n,n"))
3956                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3957                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3958   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3959    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3960    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3961   "@
3962    rlwimi %0,%3,0,%4
3963    rlwimi %0,%1,0,%2"
3964   [(set_attr "type" "insert")])
3966 (define_insn "*rotldi3_insert_6"
3967   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3968         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3969                         (match_operand:DI 2 "const_int_operand" "n"))
3970                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3971                         (match_operand:DI 4 "const_int_operand" "n"))))]
3972   "exact_log2 (-UINTVAL (operands[2])) > 0
3973    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3975   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3976   return "rldimi %0,%3,0,%5";
3978   [(set_attr "type" "insert")
3979    (set_attr "size" "64")])
3981 (define_insn "*rotldi3_insert_7"
3982   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3983         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3984                         (match_operand:DI 4 "const_int_operand" "n"))
3985                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3986                         (match_operand:DI 2 "const_int_operand" "n"))))]
3987   "exact_log2 (-UINTVAL (operands[2])) > 0
3988    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3990   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3991   return "rldimi %0,%3,0,%5";
3993   [(set_attr "type" "insert")
3994    (set_attr "size" "64")])
3997 ; This handles the important case of multiple-precision shifts.  There is
3998 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3999 (define_split
4000   [(set (match_operand:GPR 0 "gpc_reg_operand")
4001         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4002                              (match_operand:SI 3 "const_int_operand"))
4003                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4004                                (match_operand:SI 4 "const_int_operand"))))]
4005   "can_create_pseudo_p ()
4006    && INTVAL (operands[3]) + INTVAL (operands[4])
4007       >= GET_MODE_PRECISION (<MODE>mode)"
4008   [(set (match_dup 5)
4009         (lshiftrt:GPR (match_dup 2)
4010                       (match_dup 4)))
4011    (set (match_dup 0)
4012         (ior:GPR (and:GPR (match_dup 5)
4013                           (match_dup 6))
4014                  (ashift:GPR (match_dup 1)
4015                              (match_dup 3))))]
4017   unsigned HOST_WIDE_INT mask = 1;
4018   mask = (mask << INTVAL (operands[3])) - 1;
4019   operands[5] = gen_reg_rtx (<MODE>mode);
4020   operands[6] = GEN_INT (mask);
4023 (define_split
4024   [(set (match_operand:GPR 0 "gpc_reg_operand")
4025         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4026                                (match_operand:SI 4 "const_int_operand"))
4027                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4028                              (match_operand:SI 3 "const_int_operand"))))]
4029   "can_create_pseudo_p ()
4030    && INTVAL (operands[3]) + INTVAL (operands[4])
4031       >= GET_MODE_PRECISION (<MODE>mode)"
4032   [(set (match_dup 5)
4033         (lshiftrt:GPR (match_dup 2)
4034                       (match_dup 4)))
4035    (set (match_dup 0)
4036         (ior:GPR (and:GPR (match_dup 5)
4037                           (match_dup 6))
4038                  (ashift:GPR (match_dup 1)
4039                              (match_dup 3))))]
4041   unsigned HOST_WIDE_INT mask = 1;
4042   mask = (mask << INTVAL (operands[3])) - 1;
4043   operands[5] = gen_reg_rtx (<MODE>mode);
4044   operands[6] = GEN_INT (mask);
4048 ; Another important case is setting some bits to 1; we can do that with
4049 ; an insert instruction, in many cases.
4050 (define_insn_and_split "*ior<mode>_mask"
4051   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4052         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4053                  (match_operand:GPR 2 "const_int_operand" "n")))
4054    (clobber (match_scratch:GPR 3 "=r"))]
4055   "!logical_const_operand (operands[2], <MODE>mode)
4056    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4057   "#"
4058   "&& 1"
4059   [(set (match_dup 3)
4060         (const_int -1))
4061    (set (match_dup 0)
4062         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4063                                       (match_dup 4))
4064                           (match_dup 2))
4065                  (and:GPR (match_dup 1)
4066                           (match_dup 5))))]
4068   int nb, ne;
4069   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4070   if (GET_CODE (operands[3]) == SCRATCH)
4071     operands[3] = gen_reg_rtx (<MODE>mode);
4072   operands[4] = GEN_INT (ne);
4073   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4075   [(set_attr "type" "two")
4076    (set_attr "length" "8")])
4079 ;; Now the simple shifts.
4081 (define_insn "rotl<mode>3"
4082   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4083         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4084                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4085   ""
4086   "rotl<wd>%I2 %0,%1,%<hH>2"
4087   [(set_attr "type" "shift")
4088    (set_attr "maybe_var_shift" "yes")])
4090 (define_insn "*rotlsi3_64"
4091   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4092         (zero_extend:DI
4093             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4094                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4095   "TARGET_POWERPC64"
4096   "rotlw%I2 %0,%1,%h2"
4097   [(set_attr "type" "shift")
4098    (set_attr "maybe_var_shift" "yes")])
4100 (define_insn_and_split "*rotl<mode>3_dot"
4101   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4102         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4103                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4104                     (const_int 0)))
4105    (clobber (match_scratch:GPR 0 "=r,r"))]
4106   "<MODE>mode == Pmode"
4107   "@
4108    rotl<wd>%I2. %0,%1,%<hH>2
4109    #"
4110   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4111   [(set (match_dup 0)
4112         (rotate:GPR (match_dup 1)
4113                     (match_dup 2)))
4114    (set (match_dup 3)
4115         (compare:CC (match_dup 0)
4116                     (const_int 0)))]
4117   ""
4118   [(set_attr "type" "shift")
4119    (set_attr "maybe_var_shift" "yes")
4120    (set_attr "dot" "yes")
4121    (set_attr "length" "4,8")])
4123 (define_insn_and_split "*rotl<mode>3_dot2"
4124   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4125         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4126                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4127                     (const_int 0)))
4128    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4129         (rotate:GPR (match_dup 1)
4130                     (match_dup 2)))]
4131   "<MODE>mode == Pmode"
4132   "@
4133    rotl<wd>%I2. %0,%1,%<hH>2
4134    #"
4135   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4136   [(set (match_dup 0)
4137         (rotate:GPR (match_dup 1)
4138                     (match_dup 2)))
4139    (set (match_dup 3)
4140         (compare:CC (match_dup 0)
4141                     (const_int 0)))]
4142   ""
4143   [(set_attr "type" "shift")
4144    (set_attr "maybe_var_shift" "yes")
4145    (set_attr "dot" "yes")
4146    (set_attr "length" "4,8")])
4149 (define_insn "ashl<mode>3"
4150   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4151         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4152                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4153   ""
4154   "sl<wd>%I2 %0,%1,%<hH>2"
4155   [(set_attr "type" "shift")
4156    (set_attr "maybe_var_shift" "yes")])
4158 (define_insn "*ashlsi3_64"
4159   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4160         (zero_extend:DI
4161             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4162                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4163   "TARGET_POWERPC64"
4164   "slw%I2 %0,%1,%h2"
4165   [(set_attr "type" "shift")
4166    (set_attr "maybe_var_shift" "yes")])
4168 (define_insn_and_split "*ashl<mode>3_dot"
4169   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4170         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4171                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4172                     (const_int 0)))
4173    (clobber (match_scratch:GPR 0 "=r,r"))]
4174   "<MODE>mode == Pmode"
4175   "@
4176    sl<wd>%I2. %0,%1,%<hH>2
4177    #"
4178   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4179   [(set (match_dup 0)
4180         (ashift:GPR (match_dup 1)
4181                     (match_dup 2)))
4182    (set (match_dup 3)
4183         (compare:CC (match_dup 0)
4184                     (const_int 0)))]
4185   ""
4186   [(set_attr "type" "shift")
4187    (set_attr "maybe_var_shift" "yes")
4188    (set_attr "dot" "yes")
4189    (set_attr "length" "4,8")])
4191 (define_insn_and_split "*ashl<mode>3_dot2"
4192   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4193         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4194                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4195                     (const_int 0)))
4196    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4197         (ashift:GPR (match_dup 1)
4198                     (match_dup 2)))]
4199   "<MODE>mode == Pmode"
4200   "@
4201    sl<wd>%I2. %0,%1,%<hH>2
4202    #"
4203   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4204   [(set (match_dup 0)
4205         (ashift:GPR (match_dup 1)
4206                     (match_dup 2)))
4207    (set (match_dup 3)
4208         (compare:CC (match_dup 0)
4209                     (const_int 0)))]
4210   ""
4211   [(set_attr "type" "shift")
4212    (set_attr "maybe_var_shift" "yes")
4213    (set_attr "dot" "yes")
4214    (set_attr "length" "4,8")])
4216 ;; Pretend we have a memory form of extswsli until register allocation is done
4217 ;; so that we use LWZ to load the value from memory, instead of LWA.
4218 (define_insn_and_split "ashdi3_extswsli"
4219   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4220         (ashift:DI
4221          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4222          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4223   "TARGET_EXTSWSLI"
4224   "@
4225    extswsli %0,%1,%2
4226    #"
4227   "&& reload_completed && MEM_P (operands[1])"
4228   [(set (match_dup 3)
4229         (match_dup 1))
4230    (set (match_dup 0)
4231         (ashift:DI (sign_extend:DI (match_dup 3))
4232                    (match_dup 2)))]
4234   operands[3] = gen_lowpart (SImode, operands[0]);
4236   [(set_attr "type" "shift")
4237    (set_attr "maybe_var_shift" "no")])
4240 (define_insn_and_split "ashdi3_extswsli_dot"
4241   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4242         (compare:CC
4243          (ashift:DI
4244           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4245           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4246          (const_int 0)))
4247    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4248   "TARGET_EXTSWSLI"
4249   "@
4250    extswsli. %0,%1,%2
4251    #
4252    #
4253    #"
4254   "&& reload_completed
4255    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4256        || memory_operand (operands[1], SImode))"
4257   [(pc)]
4259   rtx dest = operands[0];
4260   rtx src = operands[1];
4261   rtx shift = operands[2];
4262   rtx cr = operands[3];
4263   rtx src2;
4265   if (!MEM_P (src))
4266     src2 = src;
4267   else
4268     {
4269       src2 = gen_lowpart (SImode, dest);
4270       emit_move_insn (src2, src);
4271     }
4273   if (REGNO (cr) == CR0_REGNO)
4274     {
4275       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4276       DONE;
4277     }
4279   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4280   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4281   DONE;
4283   [(set_attr "type" "shift")
4284    (set_attr "maybe_var_shift" "no")
4285    (set_attr "dot" "yes")
4286    (set_attr "length" "4,8,8,12")])
4288 (define_insn_and_split "ashdi3_extswsli_dot2"
4289   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4290         (compare:CC
4291          (ashift:DI
4292           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4293           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4294          (const_int 0)))
4295    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4296         (ashift:DI (sign_extend:DI (match_dup 1))
4297                    (match_dup 2)))]
4298   "TARGET_EXTSWSLI"
4299   "@
4300    extswsli. %0,%1,%2
4301    #
4302    #
4303    #"
4304   "&& reload_completed
4305    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4306        || memory_operand (operands[1], SImode))"
4307   [(pc)]
4309   rtx dest = operands[0];
4310   rtx src = operands[1];
4311   rtx shift = operands[2];
4312   rtx cr = operands[3];
4313   rtx src2;
4315   if (!MEM_P (src))
4316     src2 = src;
4317   else
4318     {
4319       src2 = gen_lowpart (SImode, dest);
4320       emit_move_insn (src2, src);
4321     }
4323   if (REGNO (cr) == CR0_REGNO)
4324     {
4325       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4326       DONE;
4327     }
4329   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4330   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4331   DONE;
4333   [(set_attr "type" "shift")
4334    (set_attr "maybe_var_shift" "no")
4335    (set_attr "dot" "yes")
4336    (set_attr "length" "4,8,8,12")])
4338 (define_insn "lshr<mode>3"
4339   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4340         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4341                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4342   ""
4343   "sr<wd>%I2 %0,%1,%<hH>2"
4344   [(set_attr "type" "shift")
4345    (set_attr "maybe_var_shift" "yes")])
4347 (define_insn "*lshrsi3_64"
4348   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4349         (zero_extend:DI
4350             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4351                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4352   "TARGET_POWERPC64"
4353   "srw%I2 %0,%1,%h2"
4354   [(set_attr "type" "shift")
4355    (set_attr "maybe_var_shift" "yes")])
4357 (define_insn_and_split "*lshr<mode>3_dot"
4358   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4359         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4360                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4361                     (const_int 0)))
4362    (clobber (match_scratch:GPR 0 "=r,r"))]
4363   "<MODE>mode == Pmode"
4364   "@
4365    sr<wd>%I2. %0,%1,%<hH>2
4366    #"
4367   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4368   [(set (match_dup 0)
4369         (lshiftrt:GPR (match_dup 1)
4370                       (match_dup 2)))
4371    (set (match_dup 3)
4372         (compare:CC (match_dup 0)
4373                     (const_int 0)))]
4374   ""
4375   [(set_attr "type" "shift")
4376    (set_attr "maybe_var_shift" "yes")
4377    (set_attr "dot" "yes")
4378    (set_attr "length" "4,8")])
4380 (define_insn_and_split "*lshr<mode>3_dot2"
4381   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4382         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4383                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4384                     (const_int 0)))
4385    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4386         (lshiftrt:GPR (match_dup 1)
4387                       (match_dup 2)))]
4388   "<MODE>mode == Pmode"
4389   "@
4390    sr<wd>%I2. %0,%1,%<hH>2
4391    #"
4392   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4393   [(set (match_dup 0)
4394         (lshiftrt:GPR (match_dup 1)
4395                       (match_dup 2)))
4396    (set (match_dup 3)
4397         (compare:CC (match_dup 0)
4398                     (const_int 0)))]
4399   ""
4400   [(set_attr "type" "shift")
4401    (set_attr "maybe_var_shift" "yes")
4402    (set_attr "dot" "yes")
4403    (set_attr "length" "4,8")])
4406 (define_insn "ashr<mode>3"
4407   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4408         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4409                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4410    (clobber (reg:GPR CA_REGNO))]
4411   ""
4412   "sra<wd>%I2 %0,%1,%<hH>2"
4413   [(set_attr "type" "shift")
4414    (set_attr "maybe_var_shift" "yes")])
4416 (define_insn "*ashrsi3_64"
4417   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4418         (sign_extend:DI
4419             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4420                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4421    (clobber (reg:SI CA_REGNO))]
4422   "TARGET_POWERPC64"
4423   "sraw%I2 %0,%1,%h2"
4424   [(set_attr "type" "shift")
4425    (set_attr "maybe_var_shift" "yes")])
4427 (define_insn_and_split "*ashr<mode>3_dot"
4428   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4429         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4430                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4431                     (const_int 0)))
4432    (clobber (match_scratch:GPR 0 "=r,r"))
4433    (clobber (reg:GPR CA_REGNO))]
4434   "<MODE>mode == Pmode"
4435   "@
4436    sra<wd>%I2. %0,%1,%<hH>2
4437    #"
4438   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4439   [(parallel [(set (match_dup 0)
4440                    (ashiftrt:GPR (match_dup 1)
4441                                  (match_dup 2)))
4442               (clobber (reg:GPR CA_REGNO))])
4443    (set (match_dup 3)
4444         (compare:CC (match_dup 0)
4445                     (const_int 0)))]
4446   ""
4447   [(set_attr "type" "shift")
4448    (set_attr "maybe_var_shift" "yes")
4449    (set_attr "dot" "yes")
4450    (set_attr "length" "4,8")])
4452 (define_insn_and_split "*ashr<mode>3_dot2"
4453   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4454         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4455                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4456                     (const_int 0)))
4457    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4458         (ashiftrt:GPR (match_dup 1)
4459                       (match_dup 2)))
4460    (clobber (reg:GPR CA_REGNO))]
4461   "<MODE>mode == Pmode"
4462   "@
4463    sra<wd>%I2. %0,%1,%<hH>2
4464    #"
4465   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4466   [(parallel [(set (match_dup 0)
4467                    (ashiftrt:GPR (match_dup 1)
4468                                  (match_dup 2)))
4469               (clobber (reg:GPR CA_REGNO))])
4470    (set (match_dup 3)
4471         (compare:CC (match_dup 0)
4472                     (const_int 0)))]
4473   ""
4474   [(set_attr "type" "shift")
4475    (set_attr "maybe_var_shift" "yes")
4476    (set_attr "dot" "yes")
4477    (set_attr "length" "4,8")])
4479 ;; Builtins to replace a division to generate FRE reciprocal estimate
4480 ;; instructions and the necessary fixup instructions
4481 (define_expand "recip<mode>3"
4482   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4483    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4484    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4485   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4487    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4488    DONE;
4491 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4492 ;; hardware division.  This is only done before register allocation and with
4493 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4494 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4495 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4496 (define_split
4497   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4498         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4499                     (match_operand 2 "gpc_reg_operand" "")))]
4500   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4501    && can_create_pseudo_p () && flag_finite_math_only
4502    && !flag_trapping_math && flag_reciprocal_math"
4503   [(const_int 0)]
4505   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4506   DONE;
4509 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4510 ;; appropriate fixup.
4511 (define_expand "rsqrt<mode>2"
4512   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4513    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4514   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4516   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4517   DONE;
4520 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4521 ;; modes here, and also add in conditional vsx/power8-vector support to access
4522 ;; values in the traditional Altivec registers if the appropriate
4523 ;; -mupper-regs-{df,sf} option is enabled.
4525 (define_expand "abs<mode>2"
4526   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4527         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4528   "TARGET_<MODE>_INSN"
4529   "")
4531 (define_insn "*abs<mode>2_fpr"
4532   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4533         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4534   "TARGET_<MODE>_FPR"
4535   "@
4536    fabs %0,%1
4537    xsabsdp %x0,%x1"
4538   [(set_attr "type" "fpsimple")
4539    (set_attr "fp_type" "fp_addsub_<Fs>")])
4541 (define_insn "*nabs<mode>2_fpr"
4542   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4543         (neg:SFDF
4544          (abs:SFDF
4545           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4546   "TARGET_<MODE>_FPR"
4547   "@
4548    fnabs %0,%1
4549    xsnabsdp %x0,%x1"
4550   [(set_attr "type" "fpsimple")
4551    (set_attr "fp_type" "fp_addsub_<Fs>")])
4553 (define_expand "neg<mode>2"
4554   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4555         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4556   "TARGET_<MODE>_INSN"
4557   "")
4559 (define_insn "*neg<mode>2_fpr"
4560   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4561         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4562   "TARGET_<MODE>_FPR"
4563   "@
4564    fneg %0,%1
4565    xsnegdp %x0,%x1"
4566   [(set_attr "type" "fpsimple")
4567    (set_attr "fp_type" "fp_addsub_<Fs>")])
4569 (define_expand "add<mode>3"
4570   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4571         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4572                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4573   "TARGET_<MODE>_INSN"
4574   "")
4576 (define_insn "*add<mode>3_fpr"
4577   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4578         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4579                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4580   "TARGET_<MODE>_FPR"
4581   "@
4582    fadd<Ftrad> %0,%1,%2
4583    xsadd<Fvsx> %x0,%x1,%x2"
4584   [(set_attr "type" "fp")
4585    (set_attr "fp_type" "fp_addsub_<Fs>")])
4587 (define_expand "sub<mode>3"
4588   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4589         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4590                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4591   "TARGET_<MODE>_INSN"
4592   "")
4594 (define_insn "*sub<mode>3_fpr"
4595   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4596         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4597                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4598   "TARGET_<MODE>_FPR"
4599   "@
4600    fsub<Ftrad> %0,%1,%2
4601    xssub<Fvsx> %x0,%x1,%x2"
4602   [(set_attr "type" "fp")
4603    (set_attr "fp_type" "fp_addsub_<Fs>")])
4605 (define_expand "mul<mode>3"
4606   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4607         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4608                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4609   "TARGET_<MODE>_INSN"
4610   "")
4612 (define_insn "*mul<mode>3_fpr"
4613   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4614         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4615                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4616   "TARGET_<MODE>_FPR"
4617   "@
4618    fmul<Ftrad> %0,%1,%2
4619    xsmul<Fvsx> %x0,%x1,%x2"
4620   [(set_attr "type" "dmul")
4621    (set_attr "fp_type" "fp_mul_<Fs>")])
4623 (define_expand "div<mode>3"
4624   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4625         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4626                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4627   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4629   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4630       && can_create_pseudo_p () && flag_finite_math_only
4631       && !flag_trapping_math && flag_reciprocal_math)
4632     {
4633       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4634       DONE;
4635     }
4638 (define_insn "*div<mode>3_fpr"
4639   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4640         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4641                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4642   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4643   "@
4644    fdiv<Ftrad> %0,%1,%2
4645    xsdiv<Fvsx> %x0,%x1,%x2"
4646   [(set_attr "type" "<Fs>div")
4647    (set_attr "fp_type" "fp_div_<Fs>")])
4649 (define_insn "*sqrt<mode>2_internal"
4650   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4651         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4652   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4653    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4654   "@
4655    fsqrt<Ftrad> %0,%1
4656    xssqrt<Fvsx> %x0,%x1"
4657   [(set_attr "type" "<Fs>sqrt")
4658    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4660 (define_expand "sqrt<mode>2"
4661   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4662         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4663   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4664    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4666   if (<MODE>mode == SFmode
4667       && TARGET_RECIP_PRECISION
4668       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4669       && !optimize_function_for_size_p (cfun)
4670       && flag_finite_math_only && !flag_trapping_math
4671       && flag_unsafe_math_optimizations)
4672     {
4673       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4674       DONE;
4675     }
4678 ;; Floating point reciprocal approximation
4679 (define_insn "fre<Fs>"
4680   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4681         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4682                      UNSPEC_FRES))]
4683   "TARGET_<FFRE>"
4684   "@
4685    fre<Ftrad> %0,%1
4686    xsre<Fvsx> %x0,%x1"
4687   [(set_attr "type" "fp")])
4689 (define_insn "*rsqrt<mode>2"
4690   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4691         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4692                      UNSPEC_RSQRT))]
4693   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4694   "@
4695    frsqrte<Ftrad> %0,%1
4696    xsrsqrte<Fvsx> %x0,%x1"
4697   [(set_attr "type" "fp")])
4699 ;; Floating point comparisons
4700 (define_insn "*cmp<mode>_fpr"
4701   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4702         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4703                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4704   "TARGET_<MODE>_FPR"
4705   "@
4706    fcmpu %0,%1,%2
4707    xscmpudp %0,%x1,%x2"
4708   [(set_attr "type" "fpcompare")])
4710 ;; Floating point conversions
4711 (define_expand "extendsfdf2"
4712   [(set (match_operand:DF 0 "gpc_reg_operand")
4713         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4714   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4716   if (HONOR_SNANS (SFmode))
4717     operands[1] = force_reg (SFmode, operands[1]);
4720 (define_insn_and_split "*extendsfdf2_fpr"
4721   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4722         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4723   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)"
4724   "@
4725    #
4726    fmr %0,%1
4727    lfs%U1%X1 %0,%1
4728    #
4729    xscpsgndp %x0,%x1,%x1
4730    lxsspx %x0,%y1
4731    lxssp %0,%1"
4732   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4733   [(const_int 0)]
4735   emit_note (NOTE_INSN_DELETED);
4736   DONE;
4738   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4740 (define_insn "*extendsfdf2_snan"
4741   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4742         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4743   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)"
4744   "@
4745    frsp %0,%1
4746    xsrsp %x0,%x1"
4747   [(set_attr "type" "fp")])
4749 (define_expand "truncdfsf2"
4750   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4751         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4752   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4753   "")
4755 (define_insn "*truncdfsf2_fpr"
4756   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4757         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4758   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4759   "@
4760    frsp %0,%1
4761    xsrsp %x0,%x1"
4762   [(set_attr "type" "fp")])
4764 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4765 ;; builtins.c and optabs.c that are not correct for IBM long double
4766 ;; when little-endian.
4767 (define_expand "signbit<mode>2"
4768   [(set (match_dup 2)
4769         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4770    (set (match_dup 3)
4771         (subreg:DI (match_dup 2) 0))
4772    (set (match_dup 4)
4773         (match_dup 5))
4774    (set (match_operand:SI 0 "gpc_reg_operand" "")
4775         (match_dup 6))]
4776   "TARGET_HARD_FLOAT
4777    && (!FLOAT128_IEEE_P (<MODE>mode)
4778        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4780   if (FLOAT128_IEEE_P (<MODE>mode))
4781     {
4782       if (<MODE>mode == KFmode)
4783         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4784       else if (<MODE>mode == TFmode)
4785         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4786       else
4787         gcc_unreachable ();
4788       DONE;
4789     }
4790   operands[2] = gen_reg_rtx (DFmode);
4791   operands[3] = gen_reg_rtx (DImode);
4792   if (TARGET_POWERPC64)
4793     {
4794       operands[4] = gen_reg_rtx (DImode);
4795       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4796       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4797                                     WORDS_BIG_ENDIAN ? 4 : 0);
4798     }
4799   else
4800     {
4801       operands[4] = gen_reg_rtx (SImode);
4802       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4803                                     WORDS_BIG_ENDIAN ? 0 : 4);
4804       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4805     }
4808 (define_expand "copysign<mode>3"
4809   [(set (match_dup 3)
4810         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4811    (set (match_dup 4)
4812         (neg:SFDF (abs:SFDF (match_dup 1))))
4813    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4814         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4815                                (match_dup 5))
4816                          (match_dup 3)
4817                          (match_dup 4)))]
4818   "TARGET_HARD_FLOAT && <TARGET_FLOAT>
4819    && ((TARGET_PPC_GFXOPT
4820         && !HONOR_NANS (<MODE>mode)
4821         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4822        || TARGET_CMPB
4823        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4825   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4826     {
4827       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4828                                              operands[2]));
4829       DONE;
4830     }
4832    operands[3] = gen_reg_rtx (<MODE>mode);
4833    operands[4] = gen_reg_rtx (<MODE>mode);
4834    operands[5] = CONST0_RTX (<MODE>mode);
4835   })
4837 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4838 ;; and load.
4839 (define_insn_and_split "signbit<mode>2_dm"
4840   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4841         (unspec:SI
4842          [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4843          UNSPEC_SIGNBIT))]
4844   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4845   "#"
4846   "&& reload_completed"
4847   [(const_int 0)]
4849   rs6000_split_signbit (operands[0], operands[1]);
4850   DONE;
4852  [(set_attr "length" "8,8,4")
4853   (set_attr "type" "mftgpr,load,integer")])
4855 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4856   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4857         (any_extend:DI
4858          (unspec:SI
4859           [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4860           UNSPEC_SIGNBIT)))]
4861   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4862   "#"
4863   "&& reload_completed"
4864   [(const_int 0)]
4866   rs6000_split_signbit (operands[0], operands[1]);
4867   DONE;
4869  [(set_attr "length" "8,8,4")
4870   (set_attr "type" "mftgpr,load,integer")])
4872 ;; TARGET_MODES_TIEABLE_P doesn't allow DImode to be tied with the various
4873 ;; floating point types, which makes normal SUBREG's problematical.  Instead
4874 ;; use a special pattern to avoid using a normal movdi.
4875 (define_insn "signbit<mode>2_dm2"
4876   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4877         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4878                     (const_int 0)]
4879                    UNSPEC_SIGNBIT))]
4880   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4881   "mfvsrd %0,%x1"
4882  [(set_attr "type" "mftgpr")])
4885 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4886 ;; compiler from optimizing -0.0
4887 (define_insn "copysign<mode>3_fcpsgn"
4888   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4889         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4890                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4891                      UNSPEC_COPYSIGN))]
4892   "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4893   "@
4894    fcpsgn %0,%2,%1
4895    xscpsgndp %x0,%x2,%x1"
4896   [(set_attr "type" "fpsimple")])
4898 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4899 ;; fsel instruction and some auxiliary computations.  Then we just have a
4900 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4901 ;; combine.
4902 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4903 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4904 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4905 ;; define_splits to make them if made by combine.  On VSX machines we have the
4906 ;; min/max instructions.
4908 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4909 ;; to allow either DF/SF to use only traditional registers.
4911 (define_expand "s<minmax><mode>3"
4912   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4913         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4914                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4915   "TARGET_MINMAX_<MODE>"
4917   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4918   DONE;
4921 (define_insn "*s<minmax><mode>3_vsx"
4922   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4923         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4924                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4925   "TARGET_VSX && TARGET_<MODE>_FPR"
4927   return (TARGET_P9_MINMAX
4928           ? "xs<minmax>cdp %x0,%x1,%x2"
4929           : "xs<minmax>dp %x0,%x1,%x2");
4931   [(set_attr "type" "fp")])
4933 ;; The conditional move instructions allow us to perform max and min operations
4934 ;; even when we don't have the appropriate max/min instruction using the FSEL
4935 ;; instruction.
4937 (define_insn_and_split "*s<minmax><mode>3_fpr"
4938   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4939         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4940                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4941   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4942   "#"
4943   "&& 1"
4944   [(const_int 0)]
4946   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4947   DONE;
4950 (define_expand "mov<mode>cc"
4951    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4952          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4953                            (match_operand:GPR 2 "gpc_reg_operand" "")
4954                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4955   "TARGET_ISEL"
4956   "
4958   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4959     DONE;
4960   else
4961     FAIL;
4964 ;; We use the BASE_REGS for the isel input operands because, if rA is
4965 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4966 ;; because we may switch the operands and rB may end up being rA.
4968 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4969 ;; leave out the mode in operand 4 and use one pattern, but reload can
4970 ;; change the mode underneath our feet and then gets confused trying
4971 ;; to reload the value.
4972 (define_insn "isel_signed_<mode>"
4973   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4974         (if_then_else:GPR
4975          (match_operator 1 "scc_comparison_operator"
4976                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4977                           (const_int 0)])
4978          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4979          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4980   "TARGET_ISEL"
4981   "isel %0,%2,%3,%j1"
4982   [(set_attr "type" "isel")])
4984 (define_insn "isel_unsigned_<mode>"
4985   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4986         (if_then_else:GPR
4987          (match_operator 1 "scc_comparison_operator"
4988                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4989                           (const_int 0)])
4990          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4991          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4992   "TARGET_ISEL"
4993   "isel %0,%2,%3,%j1"
4994   [(set_attr "type" "isel")])
4996 ;; These patterns can be useful for combine; they let combine know that
4997 ;; isel can handle reversed comparisons so long as the operands are
4998 ;; registers.
5000 (define_insn "*isel_reversed_signed_<mode>"
5001   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5002         (if_then_else:GPR
5003          (match_operator 1 "scc_rev_comparison_operator"
5004                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
5005                           (const_int 0)])
5006          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5007          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5008   "TARGET_ISEL"
5010   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5011   return "isel %0,%3,%2,%j1";
5013   [(set_attr "type" "isel")])
5015 (define_insn "*isel_reversed_unsigned_<mode>"
5016   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5017         (if_then_else:GPR
5018          (match_operator 1 "scc_rev_comparison_operator"
5019                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5020                           (const_int 0)])
5021          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5022          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5023   "TARGET_ISEL"
5025   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5026   return "isel %0,%3,%2,%j1";
5028   [(set_attr "type" "isel")])
5030 ;; Floating point conditional move
5031 (define_expand "mov<mode>cc"
5032    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5033          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
5034                             (match_operand:SFDF 2 "gpc_reg_operand" "")
5035                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
5036   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5037   "
5039   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5040     DONE;
5041   else
5042     FAIL;
5045 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5046   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5047         (if_then_else:SFDF
5048          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5049              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5050          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5051          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5052   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5053   "fsel %0,%1,%2,%3"
5054   [(set_attr "type" "fp")])
5056 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5057   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5058         (if_then_else:SFDF
5059          (match_operator:CCFP 1 "fpmask_comparison_operator"
5060                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5061                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5062          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5063          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5064    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5065   "TARGET_P9_MINMAX"
5066   "#"
5067   ""
5068   [(set (match_dup 6)
5069         (if_then_else:V2DI (match_dup 1)
5070                            (match_dup 7)
5071                            (match_dup 8)))
5072    (set (match_dup 0)
5073         (if_then_else:SFDF (ne (match_dup 6)
5074                                (match_dup 8))
5075                            (match_dup 4)
5076                            (match_dup 5)))]
5078   if (GET_CODE (operands[6]) == SCRATCH)
5079     operands[6] = gen_reg_rtx (V2DImode);
5081   operands[7] = CONSTM1_RTX (V2DImode);
5082   operands[8] = CONST0_RTX (V2DImode);
5084  [(set_attr "length" "8")
5085   (set_attr "type" "vecperm")])
5087 ;; Handle inverting the fpmask comparisons.
5088 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5089   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5090         (if_then_else:SFDF
5091          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5092                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5093                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5094          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5095          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5096    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5097   "TARGET_P9_MINMAX"
5098   "#"
5099   "&& 1"
5100   [(set (match_dup 6)
5101         (if_then_else:V2DI (match_dup 9)
5102                            (match_dup 7)
5103                            (match_dup 8)))
5104    (set (match_dup 0)
5105         (if_then_else:SFDF (ne (match_dup 6)
5106                                (match_dup 8))
5107                            (match_dup 5)
5108                            (match_dup 4)))]
5110   rtx op1 = operands[1];
5111   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5113   if (GET_CODE (operands[6]) == SCRATCH)
5114     operands[6] = gen_reg_rtx (V2DImode);
5116   operands[7] = CONSTM1_RTX (V2DImode);
5117   operands[8] = CONST0_RTX (V2DImode);
5119   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5121  [(set_attr "length" "8")
5122   (set_attr "type" "vecperm")])
5124 (define_insn "*fpmask<mode>"
5125   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5126         (if_then_else:V2DI
5127          (match_operator:CCFP 1 "fpmask_comparison_operator"
5128                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5129                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5130          (match_operand:V2DI 4 "all_ones_constant" "")
5131          (match_operand:V2DI 5 "zero_constant" "")))]
5132   "TARGET_P9_MINMAX"
5133   "xscmp%V1dp %x0,%x2,%x3"
5134   [(set_attr "type" "fpcompare")])
5136 (define_insn "*xxsel<mode>"
5137   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5138         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5139                                (match_operand:V2DI 2 "zero_constant" ""))
5140                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5141                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5142   "TARGET_P9_MINMAX"
5143   "xxsel %x0,%x4,%x3,%x1"
5144   [(set_attr "type" "vecmove")])
5147 ;; Conversions to and from floating-point.
5149 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5150 ; don't want to support putting SImode in FPR registers.
5151 (define_insn "lfiwax"
5152   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5153         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5154                    UNSPEC_LFIWAX))]
5155   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5156   "@
5157    lfiwax %0,%y1
5158    lxsiwax %x0,%y1
5159    mtvsrwa %x0,%1
5160    vextsw2d %0,%1"
5161   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5163 ; This split must be run before register allocation because it allocates the
5164 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5165 ; it earlier to allow for the combiner to merge insns together where it might
5166 ; not be needed and also in case the insns are deleted as dead code.
5168 (define_insn_and_split "floatsi<mode>2_lfiwax"
5169   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5170         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5171    (clobber (match_scratch:DI 2 "=wi"))]
5172   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5173    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5174   "#"
5175   ""
5176   [(pc)]
5177   "
5179   rtx dest = operands[0];
5180   rtx src = operands[1];
5181   rtx tmp;
5183   if (!MEM_P (src) && TARGET_POWERPC64
5184       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5185     tmp = convert_to_mode (DImode, src, false);
5186   else
5187     {
5188       tmp = operands[2];
5189       if (GET_CODE (tmp) == SCRATCH)
5190         tmp = gen_reg_rtx (DImode);
5191       if (MEM_P (src))
5192         {
5193           src = rs6000_address_for_fpconvert (src);
5194           emit_insn (gen_lfiwax (tmp, src));
5195         }
5196       else
5197         {
5198           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5199           emit_move_insn (stack, src);
5200           emit_insn (gen_lfiwax (tmp, stack));
5201         }
5202     }
5203   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5204   DONE;
5206   [(set_attr "length" "12")
5207    (set_attr "type" "fpload")])
5209 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5210   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5211         (float:SFDF
5212          (sign_extend:DI
5213           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5214    (clobber (match_scratch:DI 2 "=wi"))]
5215   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5216   "#"
5217   ""
5218   [(pc)]
5219   "
5221   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5222   if (GET_CODE (operands[2]) == SCRATCH)
5223     operands[2] = gen_reg_rtx (DImode);
5224   if (TARGET_P8_VECTOR)
5225     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5226   else
5227     emit_insn (gen_lfiwax (operands[2], operands[1]));
5228   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5229   DONE;
5231   [(set_attr "length" "8")
5232    (set_attr "type" "fpload")])
5234 (define_insn "lfiwzx"
5235   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5236         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5237                    UNSPEC_LFIWZX))]
5238   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5239   "@
5240    lfiwzx %0,%y1
5241    lxsiwzx %x0,%y1
5242    mtvsrwz %x0,%1
5243    xxextractuw %x0,%x1,4"
5244   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5246 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5247   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5248         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5249    (clobber (match_scratch:DI 2 "=wi"))]
5250   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5251   "#"
5252   ""
5253   [(pc)]
5254   "
5256   rtx dest = operands[0];
5257   rtx src = operands[1];
5258   rtx tmp;
5260   if (!MEM_P (src) && TARGET_POWERPC64
5261       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5262     tmp = convert_to_mode (DImode, src, true);
5263   else
5264     {
5265       tmp = operands[2];
5266       if (GET_CODE (tmp) == SCRATCH)
5267         tmp = gen_reg_rtx (DImode);
5268       if (MEM_P (src))
5269         {
5270           src = rs6000_address_for_fpconvert (src);
5271           emit_insn (gen_lfiwzx (tmp, src));
5272         }
5273       else
5274         {
5275           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5276           emit_move_insn (stack, src);
5277           emit_insn (gen_lfiwzx (tmp, stack));
5278         }
5279     }
5280   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5281   DONE;
5283   [(set_attr "length" "12")
5284    (set_attr "type" "fpload")])
5286 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5287   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5288         (unsigned_float:SFDF
5289          (zero_extend:DI
5290           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5291    (clobber (match_scratch:DI 2 "=wi"))]
5292   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5293   "#"
5294   ""
5295   [(pc)]
5296   "
5298   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5299   if (GET_CODE (operands[2]) == SCRATCH)
5300     operands[2] = gen_reg_rtx (DImode);
5301   if (TARGET_P8_VECTOR)
5302     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5303   else
5304     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5305   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5306   DONE;
5308   [(set_attr "length" "8")
5309    (set_attr "type" "fpload")])
5311 ; For each of these conversions, there is a define_expand, a define_insn
5312 ; with a '#' template, and a define_split (with C code).  The idea is
5313 ; to allow constant folding with the template of the define_insn,
5314 ; then to have the insns split later (between sched1 and final).
5316 (define_expand "floatsidf2"
5317   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5318                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5319               (use (match_dup 2))
5320               (use (match_dup 3))
5321               (clobber (match_dup 4))
5322               (clobber (match_dup 5))
5323               (clobber (match_dup 6))])]
5324   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5325   "
5327   if (TARGET_LFIWAX && TARGET_FCFID)
5328     {
5329       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5330       DONE;
5331     }
5332   else if (TARGET_FCFID)
5333     {
5334       rtx dreg = operands[1];
5335       if (!REG_P (dreg))
5336         dreg = force_reg (SImode, dreg);
5337       dreg = convert_to_mode (DImode, dreg, false);
5338       emit_insn (gen_floatdidf2 (operands[0], dreg));
5339       DONE;
5340     }
5342   if (!REG_P (operands[1]))
5343     operands[1] = force_reg (SImode, operands[1]);
5344   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5345   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5346   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5347   operands[5] = gen_reg_rtx (DFmode);
5348   operands[6] = gen_reg_rtx (SImode);
5351 (define_insn_and_split "*floatsidf2_internal"
5352   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5353         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5354    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5355    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5356    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5357    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5358    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5359   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5360   "#"
5361   ""
5362   [(pc)]
5363   "
5365   rtx lowword, highword;
5366   gcc_assert (MEM_P (operands[4]));
5367   highword = adjust_address (operands[4], SImode, 0);
5368   lowword = adjust_address (operands[4], SImode, 4);
5369   if (! WORDS_BIG_ENDIAN)
5370     std::swap (lowword, highword);
5372   emit_insn (gen_xorsi3 (operands[6], operands[1],
5373                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5374   emit_move_insn (lowword, operands[6]);
5375   emit_move_insn (highword, operands[2]);
5376   emit_move_insn (operands[5], operands[4]);
5377   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5378   DONE;
5380   [(set_attr "length" "24")
5381    (set_attr "type" "fp")])
5383 ;; If we don't have a direct conversion to single precision, don't enable this
5384 ;; conversion for 32-bit without fast math, because we don't have the insn to
5385 ;; generate the fixup swizzle to avoid double rounding problems.
5386 (define_expand "floatunssisf2"
5387   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5388         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5389   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5390    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5391        || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5392            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5393   "
5395   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5396     {
5397       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5398       DONE;
5399     }
5400   else
5401     {
5402       rtx dreg = operands[1];
5403       if (!REG_P (dreg))
5404         dreg = force_reg (SImode, dreg);
5405       dreg = convert_to_mode (DImode, dreg, true);
5406       emit_insn (gen_floatdisf2 (operands[0], dreg));
5407       DONE;
5408     }
5411 (define_expand "floatunssidf2"
5412   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5413                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5414               (use (match_dup 2))
5415               (use (match_dup 3))
5416               (clobber (match_dup 4))
5417               (clobber (match_dup 5))])]
5418   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5419   "
5421   if (TARGET_LFIWZX && TARGET_FCFID)
5422     {
5423       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5424       DONE;
5425     }
5426   else if (TARGET_FCFID)
5427     {
5428       rtx dreg = operands[1];
5429       if (!REG_P (dreg))
5430         dreg = force_reg (SImode, dreg);
5431       dreg = convert_to_mode (DImode, dreg, true);
5432       emit_insn (gen_floatdidf2 (operands[0], dreg));
5433       DONE;
5434     }
5436   if (!REG_P (operands[1]))
5437     operands[1] = force_reg (SImode, operands[1]);
5438   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5439   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5440   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5441   operands[5] = gen_reg_rtx (DFmode);
5444 (define_insn_and_split "*floatunssidf2_internal"
5445   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5446         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5447    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5448    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5449    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5450    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5451   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5452    && !(TARGET_FCFID && TARGET_POWERPC64)"
5453   "#"
5454   ""
5455   [(pc)]
5456   "
5458   rtx lowword, highword;
5459   gcc_assert (MEM_P (operands[4]));
5460   highword = adjust_address (operands[4], SImode, 0);
5461   lowword = adjust_address (operands[4], SImode, 4);
5462   if (! WORDS_BIG_ENDIAN)
5463     std::swap (lowword, highword);
5465   emit_move_insn (lowword, operands[1]);
5466   emit_move_insn (highword, operands[2]);
5467   emit_move_insn (operands[5], operands[4]);
5468   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5469   DONE;
5471   [(set_attr "length" "20")
5472    (set_attr "type" "fp")])
5474 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5475 ;; vector registers.  These insns favor doing the sign/zero extension in
5476 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5477 ;; extension and then a direct move.
5479 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5480   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5481                    (float:FP_ISA3
5482                     (match_operand:QHI 1 "input_operand")))
5483               (clobber (match_scratch:DI 2))
5484               (clobber (match_scratch:DI 3))
5485               (clobber (match_scratch:<QHI:MODE> 4))])]
5486   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5488   if (MEM_P (operands[1]))
5489     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5492 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5493   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5494         (float:FP_ISA3
5495          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5496    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5497    (clobber (match_scratch:DI 3 "=X,r,X"))
5498    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5499   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5500   "#"
5501   "&& reload_completed"
5502   [(const_int 0)]
5504   rtx result = operands[0];
5505   rtx input = operands[1];
5506   rtx di = operands[2];
5508   if (!MEM_P (input))
5509     {
5510       rtx tmp = operands[3];
5511       if (altivec_register_operand (input, <QHI:MODE>mode))
5512         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5513       else if (GET_CODE (tmp) == SCRATCH)
5514         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5515       else
5516         {
5517           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5518           emit_move_insn (di, tmp);
5519         }
5520     }
5521   else
5522     {
5523       rtx tmp = operands[4];
5524       emit_move_insn (tmp, input);
5525       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5526     }
5528   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5529   DONE;
5532 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5533   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5534                    (unsigned_float:FP_ISA3
5535                     (match_operand:QHI 1 "input_operand" "")))
5536               (clobber (match_scratch:DI 2 ""))
5537               (clobber (match_scratch:DI 3 ""))])]
5538   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5540   if (MEM_P (operands[1]))
5541     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5544 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5545   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5546         (unsigned_float:FP_ISA3
5547          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5548    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5549    (clobber (match_scratch:DI 3 "=X,r,X"))]
5550   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5551   "#"
5552   "&& reload_completed"
5553   [(const_int 0)]
5555   rtx result = operands[0];
5556   rtx input = operands[1];
5557   rtx di = operands[2];
5559   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5560     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5561   else
5562     {
5563       rtx tmp = operands[3];
5564       if (GET_CODE (tmp) == SCRATCH)
5565         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5566       else
5567         {
5568           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5569           emit_move_insn (di, tmp);
5570         }
5571     }
5573   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5574   DONE;
5577 (define_expand "fix_trunc<mode>si2"
5578   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5579         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5580   "TARGET_HARD_FLOAT && <TARGET_FLOAT>"
5581   "
5583   if (!TARGET_P8_VECTOR)
5584     {
5585       rtx src = force_reg (<MODE>mode, operands[1]);
5587       if (TARGET_STFIWX)
5588         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5589       else
5590         {
5591           rtx tmp = gen_reg_rtx (DImode);
5592           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5593           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5594                                                       tmp, stack));
5595         }
5596       DONE;
5597     }
5600 ; Like the convert to float patterns, this insn must be split before
5601 ; register allocation so that it can allocate the memory slot if it
5602 ; needed
5603 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5604   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5605         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5606    (clobber (match_scratch:DI 2 "=d"))]
5607   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5608    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5609    && TARGET_STFIWX && can_create_pseudo_p ()
5610    && !TARGET_P8_VECTOR"
5611   "#"
5612   ""
5613   [(pc)]
5615   rtx dest = operands[0];
5616   rtx src = operands[1];
5617   rtx tmp = operands[2];
5619   if (GET_CODE (tmp) == SCRATCH)
5620     tmp = gen_reg_rtx (DImode);
5622   emit_insn (gen_fctiwz_<mode> (tmp, src));
5623   if (MEM_P (dest))
5624     {
5625       dest = rs6000_address_for_fpconvert (dest);
5626       emit_insn (gen_stfiwx (dest, tmp));
5627       DONE;
5628     }
5629   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5630     {
5631       dest = gen_lowpart (DImode, dest);
5632       emit_move_insn (dest, tmp);
5633       DONE;
5634     }
5635   else
5636     {
5637       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5638       emit_insn (gen_stfiwx (stack, tmp));
5639       emit_move_insn (dest, stack);
5640       DONE;
5641     }
5643   [(set_attr "length" "12")
5644    (set_attr "type" "fp")])
5646 (define_insn_and_split "fix_trunc<mode>si2_internal"
5647   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5648         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5649    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5650    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5651   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_P8_VECTOR"
5652   "#"
5653   ""
5654   [(pc)]
5655   "
5657   rtx lowword;
5658   gcc_assert (MEM_P (operands[3]));
5659   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5661   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5662   emit_move_insn (operands[3], operands[2]);
5663   emit_move_insn (operands[0], lowword);
5664   DONE;
5666   [(set_attr "length" "16")
5667    (set_attr "type" "fp")])
5669 (define_expand "fix_trunc<mode>di2"
5670   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5671         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5672   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5673   "")
5675 (define_insn "*fix_trunc<mode>di2_fctidz"
5676   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5677         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5678   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5679   "@
5680    fctidz %0,%1
5681    xscvdpsxds %x0,%x1"
5682   [(set_attr "type" "fp")])
5684 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5685   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5686                    (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5687               (clobber (match_scratch:DI 2))])]
5688   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5690   if (MEM_P (operands[0]))
5691     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5694 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5695   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5696         (fix:QHI
5697          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5698    (clobber (match_scratch:DI 2 "=X,wi"))]
5699   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5700   "#"
5701   "&& reload_completed"
5702   [(const_int 0)]
5704   rtx dest = operands[0];
5705   rtx src = operands[1];
5707   if (vsx_register_operand (dest, <QHI:MODE>mode))
5708     {
5709       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5710       emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5711     }
5712   else
5713     {
5714       rtx tmp = operands[2];
5715       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5717       emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5718       emit_move_insn (dest, tmp2);
5719     }
5720   DONE;
5723 (define_expand "fixuns_trunc<mode>si2"
5724   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5725         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5726   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX"
5727   "
5729   if (!TARGET_P8_VECTOR)
5730     {
5731       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5732       DONE;
5733     }
5736 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5737   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5738         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5739    (clobber (match_scratch:DI 2 "=d"))]
5740   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ
5741    && TARGET_STFIWX && can_create_pseudo_p ()
5742    && !TARGET_P8_VECTOR"
5743   "#"
5744   ""
5745   [(pc)]
5747   rtx dest = operands[0];
5748   rtx src = operands[1];
5749   rtx tmp = operands[2];
5751   if (GET_CODE (tmp) == SCRATCH)
5752     tmp = gen_reg_rtx (DImode);
5754   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5755   if (MEM_P (dest))
5756     {
5757       dest = rs6000_address_for_fpconvert (dest);
5758       emit_insn (gen_stfiwx (dest, tmp));
5759       DONE;
5760     }
5761   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5762     {
5763       dest = gen_lowpart (DImode, dest);
5764       emit_move_insn (dest, tmp);
5765       DONE;
5766     }
5767   else
5768     {
5769       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5770       emit_insn (gen_stfiwx (stack, tmp));
5771       emit_move_insn (dest, stack);
5772       DONE;
5773     }
5775   [(set_attr "length" "12")
5776    (set_attr "type" "fp")])
5778 (define_insn "fixuns_trunc<mode>di2"
5779   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5780         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5781   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ"
5782   "@
5783    fctiduz %0,%1
5784    xscvdpuxds %x0,%x1"
5785   [(set_attr "type" "fp")])
5787 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5788   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5789                    (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5790               (clobber (match_scratch:DI 2))])]
5791   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5793   if (MEM_P (operands[0]))
5794     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5797 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5798   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5799         (unsigned_fix:QHI
5800          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5801    (clobber (match_scratch:DI 2 "=X,wi"))]
5802   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5803   "#"
5804   "&& reload_completed"
5805   [(const_int 0)]
5807   rtx dest = operands[0];
5808   rtx src = operands[1];
5810   if (vsx_register_operand (dest, <QHI:MODE>mode))
5811     {
5812       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5813       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5814     }
5815   else
5816     {
5817       rtx tmp = operands[2];
5818       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5820       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5821       emit_move_insn (dest, tmp2);
5822     }
5823   DONE;
5826 ;; If -mvsx-small-integer, we can represent the FIX operation directly.  On
5827 ;; older machines, we have to use an UNSPEC to produce a SImode and move it
5828 ;; to another location, since SImode is not allowed in vector registers.
5829 (define_insn "*fctiw<u>z_<mode>_smallint"
5830   [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5831         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5832   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5833   "@
5834    fctiw<u>z %0,%1
5835    xscvdp<su>xws %x0,%x1"
5836   [(set_attr "type" "fp")])
5838 ;; Combiner pattern to prevent moving the result of converting a floating point
5839 ;; value to 32-bit integer to GPR in order to save it.
5840 (define_insn_and_split "*fctiw<u>z_<mode>_mem"
5841   [(set (match_operand:SI 0 "memory_operand" "=Z")
5842         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5843    (clobber (match_scratch:SI 2 "=wa"))]
5844   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5845   "#"
5846   "&& reload_completed"
5847   [(set (match_dup 2)
5848         (any_fix:SI (match_dup 1)))
5849    (set (match_dup 0)
5850         (match_dup 2))])
5852 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5853 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5854 ;; because the first makes it clear that operand 0 is not live
5855 ;; before the instruction.
5856 (define_insn "fctiwz_<mode>"
5857   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5858         (unspec:DI [(fix:SI
5859                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5860                    UNSPEC_FCTIWZ))]
5861   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5862   "@
5863    fctiwz %0,%1
5864    xscvdpsxws %x0,%x1"
5865   [(set_attr "type" "fp")])
5867 (define_insn "fctiwuz_<mode>"
5868   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5869         (unspec:DI [(unsigned_fix:SI
5870                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5871                    UNSPEC_FCTIWUZ))]
5872   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5873   "@
5874    fctiwuz %0,%1
5875    xscvdpuxws %x0,%x1"
5876   [(set_attr "type" "fp")])
5878 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5879 ;; since the friz instruction does not truncate the value if the floating
5880 ;; point value is < LONG_MIN or > LONG_MAX.
5881 (define_insn "*friz"
5882   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5883         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5884   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5885    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5886   "@
5887    friz %0,%1
5888    xsrdpiz %x0,%x1"
5889   [(set_attr "type" "fp")])
5891 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5892 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5893 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5894 ;; extend it, store it back on the stack from the GPR, load it back into the
5895 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5896 ;; disable using store and load to sign/zero extend the value.
5897 (define_insn_and_split "*round32<mode>2_fprs"
5898   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5899         (float:SFDF
5900          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5901    (clobber (match_scratch:DI 2 "=d"))
5902    (clobber (match_scratch:DI 3 "=d"))]
5903   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5904    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5905    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5906   "#"
5907   ""
5908   [(pc)]
5910   rtx dest = operands[0];
5911   rtx src = operands[1];
5912   rtx tmp1 = operands[2];
5913   rtx tmp2 = operands[3];
5914   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5916   if (GET_CODE (tmp1) == SCRATCH)
5917     tmp1 = gen_reg_rtx (DImode);
5918   if (GET_CODE (tmp2) == SCRATCH)
5919     tmp2 = gen_reg_rtx (DImode);
5921   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5922   emit_insn (gen_stfiwx (stack, tmp1));
5923   emit_insn (gen_lfiwax (tmp2, stack));
5924   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5925   DONE;
5927   [(set_attr "type" "fpload")
5928    (set_attr "length" "16")])
5930 (define_insn_and_split "*roundu32<mode>2_fprs"
5931   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5932         (unsigned_float:SFDF
5933          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5934    (clobber (match_scratch:DI 2 "=d"))
5935    (clobber (match_scratch:DI 3 "=d"))]
5936   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5937    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5938    && can_create_pseudo_p ()"
5939   "#"
5940   ""
5941   [(pc)]
5943   rtx dest = operands[0];
5944   rtx src = operands[1];
5945   rtx tmp1 = operands[2];
5946   rtx tmp2 = operands[3];
5947   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5949   if (GET_CODE (tmp1) == SCRATCH)
5950     tmp1 = gen_reg_rtx (DImode);
5951   if (GET_CODE (tmp2) == SCRATCH)
5952     tmp2 = gen_reg_rtx (DImode);
5954   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5955   emit_insn (gen_stfiwx (stack, tmp1));
5956   emit_insn (gen_lfiwzx (tmp2, stack));
5957   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5958   DONE;
5960   [(set_attr "type" "fpload")
5961    (set_attr "length" "16")])
5963 (define_insn "lrintsfsi2"
5964   [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
5965         (unspec:SI [(match_operand:DF 1 "gpc_reg_operand" "d")]
5966                    UNSPEC_FCTIW))]
5967   "TARGET_SF_FPR && TARGET_FPRND"
5968   "fctiw %0,%1"
5969   [(set_attr "type" "fp")])
5971 ;; No VSX equivalent to fctid
5972 (define_insn "lrint<mode>di2"
5973   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5974         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5975                    UNSPEC_FCTID))]
5976   "TARGET_<MODE>_FPR && TARGET_FPRND"
5977   "fctid %0,%1"
5978   [(set_attr "type" "fp")])
5980 (define_insn "btrunc<mode>2"
5981   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5982         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5983                      UNSPEC_FRIZ))]
5984   "TARGET_<MODE>_FPR && TARGET_FPRND"
5985   "@
5986    friz %0,%1
5987    xsrdpiz %x0,%x1"
5988   [(set_attr "type" "fp")
5989    (set_attr "fp_type" "fp_addsub_<Fs>")])
5991 (define_insn "ceil<mode>2"
5992   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5993         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5994                      UNSPEC_FRIP))]
5995   "TARGET_<MODE>_FPR && TARGET_FPRND"
5996   "@
5997    frip %0,%1
5998    xsrdpip %x0,%x1"
5999   [(set_attr "type" "fp")
6000    (set_attr "fp_type" "fp_addsub_<Fs>")])
6002 (define_insn "floor<mode>2"
6003   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6004         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6005                      UNSPEC_FRIM))]
6006   "TARGET_<MODE>_FPR && TARGET_FPRND"
6007   "@
6008    frim %0,%1
6009    xsrdpim %x0,%x1"
6010   [(set_attr "type" "fp")
6011    (set_attr "fp_type" "fp_addsub_<Fs>")])
6013 ;; No VSX equivalent to frin
6014 (define_insn "round<mode>2"
6015   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6016         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6017                      UNSPEC_FRIN))]
6018   "TARGET_<MODE>_FPR && TARGET_FPRND"
6019   "frin %0,%1"
6020   [(set_attr "type" "fp")
6021    (set_attr "fp_type" "fp_addsub_<Fs>")])
6023 (define_insn "*xsrdpi<mode>2"
6024   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6025         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6026                      UNSPEC_XSRDPI))]
6027   "TARGET_<MODE>_FPR && TARGET_VSX"
6028   "xsrdpi %x0,%x1"
6029   [(set_attr "type" "fp")
6030    (set_attr "fp_type" "fp_addsub_<Fs>")])
6032 (define_expand "lround<mode>di2"
6033   [(set (match_dup 2)
6034         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
6035                      UNSPEC_XSRDPI))
6036    (set (match_operand:DI 0 "gpc_reg_operand" "")
6037         (unspec:DI [(match_dup 2)]
6038                    UNSPEC_FCTID))]
6039   "TARGET_<MODE>_FPR && TARGET_VSX"
6041   operands[2] = gen_reg_rtx (<MODE>mode);
6044 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6045 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6046 ; is only generated for Power8 or later.
6047 (define_insn "stfiwx"
6048   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6049         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6050                    UNSPEC_STFIWX))]
6051   "TARGET_PPC_GFXOPT"
6052   "@
6053    stfiwx %1,%y0
6054    stxsiwx %x1,%y0"
6055   [(set_attr "type" "fpstore")])
6057 ;; If we don't have a direct conversion to single precision, don't enable this
6058 ;; conversion for 32-bit without fast math, because we don't have the insn to
6059 ;; generate the fixup swizzle to avoid double rounding problems.
6060 (define_expand "floatsisf2"
6061   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6062         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6063   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6064    && ((TARGET_FCFIDS && TARGET_LFIWAX)
6065        || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6066            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6067   "
6069   if (TARGET_FCFIDS && TARGET_LFIWAX)
6070     {
6071       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6072       DONE;
6073     }
6074   else if (TARGET_FCFID && TARGET_LFIWAX)
6075     {
6076       rtx dfreg = gen_reg_rtx (DFmode);
6077       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6078       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6079       DONE;
6080     }
6081   else
6082     {
6083       rtx dreg = operands[1];
6084       if (!REG_P (dreg))
6085         dreg = force_reg (SImode, dreg);
6086       dreg = convert_to_mode (DImode, dreg, false);
6087       emit_insn (gen_floatdisf2 (operands[0], dreg));
6088       DONE;
6089     }
6092 (define_insn "floatdidf2"
6093   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6094         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6095   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6096   "@
6097    fcfid %0,%1
6098    xscvsxddp %x0,%x1"
6099   [(set_attr "type" "fp")])
6101 ; Allow the combiner to merge source memory operands to the conversion so that
6102 ; the optimizer/register allocator doesn't try to load the value too early in a
6103 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6104 ; hit.  We will split after reload to avoid the trip through the GPRs
6106 (define_insn_and_split "*floatdidf2_mem"
6107   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6108         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6109    (clobber (match_scratch:DI 2 "=d,wi"))]
6110   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
6111   "#"
6112   "&& reload_completed"
6113   [(set (match_dup 2) (match_dup 1))
6114    (set (match_dup 0) (float:DF (match_dup 2)))]
6115   ""
6116   [(set_attr "length" "8")
6117    (set_attr "type" "fpload")])
6119 (define_expand "floatunsdidf2"
6120   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6121         (unsigned_float:DF
6122          (match_operand:DI 1 "gpc_reg_operand" "")))]
6123   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6124   "")
6126 (define_insn "*floatunsdidf2_fcfidu"
6127   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6128         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6129   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6130   "@
6131    fcfidu %0,%1
6132    xscvuxddp %x0,%x1"
6133   [(set_attr "type" "fp")
6134    (set_attr "length" "4")])
6136 (define_insn_and_split "*floatunsdidf2_mem"
6137   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6138         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6139    (clobber (match_scratch:DI 2 "=d,wi"))]
6140   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6141   "#"
6142   "&& reload_completed"
6143   [(set (match_dup 2) (match_dup 1))
6144    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6145   ""
6146   [(set_attr "length" "8")
6147    (set_attr "type" "fpload")])
6149 (define_expand "floatdisf2"
6150   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6151         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6152   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6153    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6154   "
6156   if (!TARGET_FCFIDS)
6157     {
6158       rtx val = operands[1];
6159       if (!flag_unsafe_math_optimizations)
6160         {
6161           rtx label = gen_label_rtx ();
6162           val = gen_reg_rtx (DImode);
6163           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6164           emit_label (label);
6165         }
6166       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6167       DONE;
6168     }
6171 (define_insn "floatdisf2_fcfids"
6172   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6173         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6174   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6175    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6176   "@
6177    fcfids %0,%1
6178    xscvsxdsp %x0,%x1"
6179   [(set_attr "type" "fp")])
6181 (define_insn_and_split "*floatdisf2_mem"
6182   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6183         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6184    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6185   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6186    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6187   "#"
6188   "&& reload_completed"
6189   [(pc)]
6190   "
6192   emit_move_insn (operands[2], operands[1]);
6193   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6194   DONE;
6196   [(set_attr "length" "8")])
6198 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6199 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6200 ;; from double rounding.
6201 ;; Instead of creating a new cpu type for two FP operations, just use fp
6202 (define_insn_and_split "floatdisf2_internal1"
6203   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6204         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6205    (clobber (match_scratch:DF 2 "=d"))]
6206   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS"
6207   "#"
6208   "&& reload_completed"
6209   [(set (match_dup 2)
6210         (float:DF (match_dup 1)))
6211    (set (match_dup 0)
6212         (float_truncate:SF (match_dup 2)))]
6213   ""
6214   [(set_attr "length" "8")
6215    (set_attr "type" "fp")])
6217 ;; Twiddles bits to avoid double rounding.
6218 ;; Bits that might be truncated when converting to DFmode are replaced
6219 ;; by a bit that won't be lost at that stage, but is below the SFmode
6220 ;; rounding position.
6221 (define_expand "floatdisf2_internal2"
6222   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6223                                               (const_int 53)))
6224               (clobber (reg:DI CA_REGNO))])
6225    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6226                                            (const_int 2047)))
6227    (set (match_dup 3) (plus:DI (match_dup 3)
6228                                (const_int 1)))
6229    (set (match_dup 0) (plus:DI (match_dup 0)
6230                                (const_int 2047)))
6231    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6232                                      (const_int 2)))
6233    (set (match_dup 0) (ior:DI (match_dup 0)
6234                               (match_dup 1)))
6235    (set (match_dup 0) (and:DI (match_dup 0)
6236                               (const_int -2048)))
6237    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6238                            (label_ref (match_operand:DI 2 "" ""))
6239                            (pc)))
6240    (set (match_dup 0) (match_dup 1))]
6241   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6242    && !TARGET_FCFIDS"
6243   "
6245   operands[3] = gen_reg_rtx (DImode);
6246   operands[4] = gen_reg_rtx (CCUNSmode);
6249 (define_expand "floatunsdisf2"
6250   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6251         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6252   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6253    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6254   "")
6256 (define_insn "floatunsdisf2_fcfidus"
6257   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6258         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6259   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6260    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6261   "@
6262    fcfidus %0,%1
6263    xscvuxdsp %x0,%x1"
6264   [(set_attr "type" "fp")])
6266 (define_insn_and_split "*floatunsdisf2_mem"
6267   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6268         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6269    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6270   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6271    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6272   "#"
6273   "&& reload_completed"
6274   [(pc)]
6275   "
6277   emit_move_insn (operands[2], operands[1]);
6278   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6279   DONE;
6281   [(set_attr "length" "8")
6282    (set_attr "type" "fpload")])
6284 ;; Define the TImode operations that can be done in a small number
6285 ;; of instructions.  The & constraints are to prevent the register
6286 ;; allocator from allocating registers that overlap with the inputs
6287 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6288 ;; also allow for the output being the same as one of the inputs.
6290 (define_expand "addti3"
6291   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6292         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6293                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6294   "TARGET_64BIT"
6296   rtx lo0 = gen_lowpart (DImode, operands[0]);
6297   rtx lo1 = gen_lowpart (DImode, operands[1]);
6298   rtx lo2 = gen_lowpart (DImode, operands[2]);
6299   rtx hi0 = gen_highpart (DImode, operands[0]);
6300   rtx hi1 = gen_highpart (DImode, operands[1]);
6301   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6303   if (!reg_or_short_operand (lo2, DImode))
6304     lo2 = force_reg (DImode, lo2);
6305   if (!adde_operand (hi2, DImode))
6306     hi2 = force_reg (DImode, hi2);
6308   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6309   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6310   DONE;
6313 (define_expand "subti3"
6314   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6315         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6316                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6317   "TARGET_64BIT"
6319   rtx lo0 = gen_lowpart (DImode, operands[0]);
6320   rtx lo1 = gen_lowpart (DImode, operands[1]);
6321   rtx lo2 = gen_lowpart (DImode, operands[2]);
6322   rtx hi0 = gen_highpart (DImode, operands[0]);
6323   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6324   rtx hi2 = gen_highpart (DImode, operands[2]);
6326   if (!reg_or_short_operand (lo1, DImode))
6327     lo1 = force_reg (DImode, lo1);
6328   if (!adde_operand (hi1, DImode))
6329     hi1 = force_reg (DImode, hi1);
6331   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6332   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6333   DONE;
6336 ;; 128-bit logical operations expanders
6338 (define_expand "and<mode>3"
6339   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6340         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6341                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6342   ""
6343   "")
6345 (define_expand "ior<mode>3"
6346   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6347         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6348                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6349   ""
6350   "")
6352 (define_expand "xor<mode>3"
6353   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6354         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6355                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6356   ""
6357   "")
6359 (define_expand "one_cmpl<mode>2"
6360   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6361         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6362   ""
6363   "")
6365 (define_expand "nor<mode>3"
6366   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6367         (and:BOOL_128
6368          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6369          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6370   ""
6371   "")
6373 (define_expand "andc<mode>3"
6374   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6375         (and:BOOL_128
6376          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6377          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6378   ""
6379   "")
6381 ;; Power8 vector logical instructions.
6382 (define_expand "eqv<mode>3"
6383   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6384         (not:BOOL_128
6385          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6386                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6387   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6388   "")
6390 ;; Rewrite nand into canonical form
6391 (define_expand "nand<mode>3"
6392   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6393         (ior:BOOL_128
6394          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6395          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6396   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6397   "")
6399 ;; The canonical form is to have the negated element first, so we need to
6400 ;; reverse arguments.
6401 (define_expand "orc<mode>3"
6402   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6403         (ior:BOOL_128
6404          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6405          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6406   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6407   "")
6409 ;; 128-bit logical operations insns and split operations
6410 (define_insn_and_split "*and<mode>3_internal"
6411   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6412         (and:BOOL_128
6413          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6414          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6415   ""
6417   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6418     return "xxland %x0,%x1,%x2";
6420   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6421     return "vand %0,%1,%2";
6423   return "#";
6425   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6426   [(const_int 0)]
6428   rs6000_split_logical (operands, AND, false, false, false);
6429   DONE;
6431   [(set (attr "type")
6432       (if_then_else
6433         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6434         (const_string "veclogical")
6435         (const_string "integer")))
6436    (set (attr "length")
6437       (if_then_else
6438         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6439         (const_string "4")
6440         (if_then_else
6441          (match_test "TARGET_POWERPC64")
6442          (const_string "8")
6443          (const_string "16"))))])
6445 ;; 128-bit IOR/XOR
6446 (define_insn_and_split "*bool<mode>3_internal"
6447   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6448         (match_operator:BOOL_128 3 "boolean_or_operator"
6449          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6450           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6451   ""
6453   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6454     return "xxl%q3 %x0,%x1,%x2";
6456   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6457     return "v%q3 %0,%1,%2";
6459   return "#";
6461   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6462   [(const_int 0)]
6464   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6465   DONE;
6467   [(set (attr "type")
6468       (if_then_else
6469         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6470         (const_string "veclogical")
6471         (const_string "integer")))
6472    (set (attr "length")
6473       (if_then_else
6474         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6475         (const_string "4")
6476         (if_then_else
6477          (match_test "TARGET_POWERPC64")
6478          (const_string "8")
6479          (const_string "16"))))])
6481 ;; 128-bit ANDC/ORC
6482 (define_insn_and_split "*boolc<mode>3_internal1"
6483   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6484         (match_operator:BOOL_128 3 "boolean_operator"
6485          [(not:BOOL_128
6486            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6487           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6488   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6490   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6491     return "xxl%q3 %x0,%x1,%x2";
6493   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6494     return "v%q3 %0,%1,%2";
6496   return "#";
6498   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6499    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6500   [(const_int 0)]
6502   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6503   DONE;
6505   [(set (attr "type")
6506       (if_then_else
6507         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6508         (const_string "veclogical")
6509         (const_string "integer")))
6510    (set (attr "length")
6511       (if_then_else
6512         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6513         (const_string "4")
6514         (if_then_else
6515          (match_test "TARGET_POWERPC64")
6516          (const_string "8")
6517          (const_string "16"))))])
6519 (define_insn_and_split "*boolc<mode>3_internal2"
6520   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6521         (match_operator:TI2 3 "boolean_operator"
6522          [(not:TI2
6523            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6524           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6525   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6526   "#"
6527   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6528   [(const_int 0)]
6530   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6531   DONE;
6533   [(set_attr "type" "integer")
6534    (set (attr "length")
6535         (if_then_else
6536          (match_test "TARGET_POWERPC64")
6537          (const_string "8")
6538          (const_string "16")))])
6540 ;; 128-bit NAND/NOR
6541 (define_insn_and_split "*boolcc<mode>3_internal1"
6542   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6543         (match_operator:BOOL_128 3 "boolean_operator"
6544          [(not:BOOL_128
6545            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6546           (not:BOOL_128
6547            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6548   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6550   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6551     return "xxl%q3 %x0,%x1,%x2";
6553   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6554     return "v%q3 %0,%1,%2";
6556   return "#";
6558   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6559    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6560   [(const_int 0)]
6562   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6563   DONE;
6565   [(set (attr "type")
6566       (if_then_else
6567         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6568         (const_string "veclogical")
6569         (const_string "integer")))
6570    (set (attr "length")
6571       (if_then_else
6572         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6573         (const_string "4")
6574         (if_then_else
6575          (match_test "TARGET_POWERPC64")
6576          (const_string "8")
6577          (const_string "16"))))])
6579 (define_insn_and_split "*boolcc<mode>3_internal2"
6580   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6581         (match_operator:TI2 3 "boolean_operator"
6582          [(not:TI2
6583            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6584           (not:TI2
6585            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6586   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6587   "#"
6588   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6589   [(const_int 0)]
6591   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6592   DONE;
6594   [(set_attr "type" "integer")
6595    (set (attr "length")
6596         (if_then_else
6597          (match_test "TARGET_POWERPC64")
6598          (const_string "8")
6599          (const_string "16")))])
6602 ;; 128-bit EQV
6603 (define_insn_and_split "*eqv<mode>3_internal1"
6604   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6605         (not:BOOL_128
6606          (xor:BOOL_128
6607           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6608           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6609   "TARGET_P8_VECTOR"
6611   if (vsx_register_operand (operands[0], <MODE>mode))
6612     return "xxleqv %x0,%x1,%x2";
6614   return "#";
6616   "TARGET_P8_VECTOR && reload_completed
6617    && int_reg_operand (operands[0], <MODE>mode)"
6618   [(const_int 0)]
6620   rs6000_split_logical (operands, XOR, true, false, false);
6621   DONE;
6623   [(set (attr "type")
6624       (if_then_else
6625         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6626         (const_string "veclogical")
6627         (const_string "integer")))
6628    (set (attr "length")
6629       (if_then_else
6630         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6631         (const_string "4")
6632         (if_then_else
6633          (match_test "TARGET_POWERPC64")
6634          (const_string "8")
6635          (const_string "16"))))])
6637 (define_insn_and_split "*eqv<mode>3_internal2"
6638   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6639         (not:TI2
6640          (xor:TI2
6641           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6642           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6643   "!TARGET_P8_VECTOR"
6644   "#"
6645   "reload_completed && !TARGET_P8_VECTOR"
6646   [(const_int 0)]
6648   rs6000_split_logical (operands, XOR, true, false, false);
6649   DONE;
6651   [(set_attr "type" "integer")
6652    (set (attr "length")
6653         (if_then_else
6654          (match_test "TARGET_POWERPC64")
6655          (const_string "8")
6656          (const_string "16")))])
6658 ;; 128-bit one's complement
6659 (define_insn_and_split "*one_cmpl<mode>3_internal"
6660   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6661         (not:BOOL_128
6662           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6663   ""
6665   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6666     return "xxlnor %x0,%x1,%x1";
6668   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6669     return "vnor %0,%1,%1";
6671   return "#";
6673   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6674   [(const_int 0)]
6676   rs6000_split_logical (operands, NOT, false, false, false);
6677   DONE;
6679   [(set (attr "type")
6680       (if_then_else
6681         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6682         (const_string "veclogical")
6683         (const_string "integer")))
6684    (set (attr "length")
6685       (if_then_else
6686         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6687         (const_string "4")
6688         (if_then_else
6689          (match_test "TARGET_POWERPC64")
6690          (const_string "8")
6691          (const_string "16"))))])
6694 ;; Now define ways of moving data around.
6696 ;; Set up a register with a value from the GOT table
6698 (define_expand "movsi_got"
6699   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6700         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6701                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6702   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6703   "
6705   if (GET_CODE (operands[1]) == CONST)
6706     {
6707       rtx offset = const0_rtx;
6708       HOST_WIDE_INT value;
6710       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6711       value = INTVAL (offset);
6712       if (value != 0)
6713         {
6714           rtx tmp = (!can_create_pseudo_p ()
6715                      ? operands[0]
6716                      : gen_reg_rtx (Pmode));
6717           emit_insn (gen_movsi_got (tmp, operands[1]));
6718           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6719           DONE;
6720         }
6721     }
6723   operands[2] = rs6000_got_register (operands[1]);
6726 (define_insn "*movsi_got_internal"
6727   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6728         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6729                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6730                    UNSPEC_MOVSI_GOT))]
6731   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6732   "lwz %0,%a1@got(%2)"
6733   [(set_attr "type" "load")])
6735 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6736 ;; didn't get allocated to a hard register.
6737 (define_split
6738   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6739         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6740                     (match_operand:SI 2 "memory_operand" "")]
6741                    UNSPEC_MOVSI_GOT))]
6742   "DEFAULT_ABI == ABI_V4
6743     && flag_pic == 1
6744     && reload_completed"
6745   [(set (match_dup 0) (match_dup 2))
6746    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6747                                  UNSPEC_MOVSI_GOT))]
6748   "")
6750 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6751 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6752 ;; and this is even supposed to be faster, but it is simpler not to get
6753 ;; integers in the TOC.
6754 (define_insn "movsi_low"
6755   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6756         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6757                            (match_operand 2 "" ""))))]
6758   "TARGET_MACHO && ! TARGET_64BIT"
6759   "lwz %0,lo16(%2)(%1)"
6760   [(set_attr "type" "load")
6761    (set_attr "length" "4")])
6763 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6764 ;;              STW          STFIWX       STXSIWX      LI           LIS
6765 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6766 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6767 ;;              MF%1         MT%0         MT%0         NOP
6768 (define_insn "*movsi_internal1"
6769   [(set (match_operand:SI 0 "nonimmediate_operand"
6770                 "=r,         r,           r,           ?*wI,        ?*wH,
6771                  m,          ?Z,          ?Z,          r,           r,
6772                  r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6773                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6774                  r,          *c*l,        *h,          *h")
6776         (match_operand:SI 1 "input_operand"
6777                 "r,          U,           m,           Z,           Z,
6778                  r,          wI,          wH,          I,           L,
6779                  n,          wIwH,        O,           wM,          wB,
6780                  O,          wM,          wS,          r,           wIwH,
6781                  *h,         r,           r,           0"))]
6783   "!TARGET_SINGLE_FPU &&
6784    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6785   "@
6786    mr %0,%1
6787    la %0,%a1
6788    lwz%U1%X1 %0,%1
6789    lfiwzx %0,%y1
6790    lxsiwzx %x0,%y1
6791    stw%U0%X0 %1,%0
6792    stfiwx %1,%y0
6793    stxsiwx %x1,%y0
6794    li %0,%1
6795    lis %0,%v1
6796    #
6797    xxlor %x0,%x1,%x1
6798    xxspltib %x0,0
6799    xxspltib %x0,255
6800    vspltisw %0,%1
6801    xxlxor %x0,%x0,%x0
6802    xxlorc %x0,%x0,%x0
6803    #
6804    mtvsrwz %x0,%1
6805    mfvsrwz %0,%x1
6806    mf%1 %0
6807    mt%0 %1
6808    mt%0 %1
6809    nop"
6810   [(set_attr "type"
6811                 "*,          *,           load,        fpload,      fpload,
6812                  store,      fpstore,     fpstore,     *,           *,
6813                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6814                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6815                  *,           *,           *,           *")
6817    (set_attr "length"
6818                 "4,          4,           4,           4,           4,
6819                  4,          4,           4,           4,           4,
6820                  8,          4,           4,           4,           4,
6821                  4,          4,           8,           4,           4,
6822                  4,          4,           4,           4")])
6824 (define_insn "*movsi_internal1_single"
6825   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6826         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6827   "TARGET_SINGLE_FPU &&
6828    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6829   "@
6830    mr %0,%1
6831    la %0,%a1
6832    lwz%U1%X1 %0,%1
6833    stw%U0%X0 %1,%0
6834    li %0,%1
6835    lis %0,%v1
6836    #
6837    mf%1 %0
6838    mt%0 %1
6839    mt%0 %1
6840    nop
6841    stfs%U0%X0 %1,%0
6842    lfs%U1%X1 %0,%1"
6843   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6844    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6846 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6847 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6849 ;; Because SF values are actually stored as DF values within the vector
6850 ;; registers, we need to convert the value to the vector SF format when
6851 ;; we need to use the bits in a union or similar cases.  We only need
6852 ;; to do this transformation when the value is a vector register.  Loads,
6853 ;; stores, and transfers within GPRs are assumed to be safe.
6855 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6856 ;; no alternatives, because the call is created as part of secondary_reload,
6857 ;; and operand #2's register class is used to allocate the temporary register.
6858 ;; This function is called before reload, and it creates the temporary as
6859 ;; needed.
6861 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6862 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6863 ;;              MTVSRWZ
6865 (define_insn_and_split "movsi_from_sf"
6866   [(set (match_operand:SI 0 "nonimmediate_operand"
6867                 "=r,         r,           ?*wI,        ?*wH,     m,
6868                  m,          wY,          Z,           r,        ?*wIwH,
6869                  wIwH")
6871         (unspec:SI [(match_operand:SF 1 "input_operand"
6872                 "r,          m,           Z,           Z,        r,
6873                  f,          wb,          wu,          wIwH,     wIwH,
6874                  r")]
6875                     UNSPEC_SI_FROM_SF))
6877    (clobber (match_scratch:V4SF 2
6878                 "=X,         X,           X,           X,        X,
6879                  X,          X,           X,           wIwH,     X,
6880                  X"))]
6882   "TARGET_NO_SF_SUBREG
6883    && (register_operand (operands[0], SImode)
6884        || register_operand (operands[1], SFmode))"
6885   "@
6886    mr %0,%1
6887    lwz%U1%X1 %0,%1
6888    lfiwzx %0,%y1
6889    lxsiwzx %x0,%y1
6890    stw%U0%X0 %1,%0
6891    stfs%U0%X0 %1,%0
6892    stxssp %1,%0
6893    stxsspx %x1,%y0
6894    #
6895    xscvdpspn %x0,%x1
6896    mtvsrwz %x0,%1"
6897   "&& reload_completed
6898    && int_reg_operand (operands[0], SImode)
6899    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6900   [(const_int 0)]
6902   rtx op0 = operands[0];
6903   rtx op1 = operands[1];
6904   rtx op2 = operands[2];
6905   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6906   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6908   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6909   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6910   DONE;
6912   [(set_attr "type"
6913                 "*,          load,        fpload,      fpload,   store,
6914                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
6915                  mffgpr")
6917    (set_attr "length"
6918                 "4,          4,           4,           4,        4,
6919                  4,          4,           4,           8,        4,
6920                  4")])
6922 ;; movsi_from_sf with zero extension
6924 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6925 ;;              VSX->VSX     MTVSRWZ
6927 (define_insn_and_split "*movdi_from_sf_zero_ext"
6928   [(set (match_operand:DI 0 "gpc_reg_operand"
6929                 "=r,         r,           ?*wI,        ?*wH,     r,
6930                  ?wK,        wIwH")
6932         (zero_extend:DI
6933          (unspec:SI [(match_operand:SF 1 "input_operand"
6934                 "r,          m,           Z,           Z,        wIwH,
6935                  wIwH,       r")]
6936                     UNSPEC_SI_FROM_SF)))
6938    (clobber (match_scratch:V4SF 2
6939                 "=X,         X,           X,           X,        wa,
6940                  wIwH,       X"))]
6942   "TARGET_DIRECT_MOVE_64BIT
6943    && (register_operand (operands[0], DImode)
6944        || register_operand (operands[1], SImode))"
6945   "@
6946    rldicl %0,%1,0,32
6947    lwz%U1%X1 %0,%1
6948    lfiwzx %0,%y1
6949    lxsiwzx %x0,%y1
6950    #
6951    #
6952    mtvsrwz %x0,%1"
6953   "&& reload_completed
6954    && register_operand (operands[0], DImode)
6955    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6956   [(const_int 0)]
6958   rtx op0 = operands[0];
6959   rtx op1 = operands[1];
6960   rtx op2 = operands[2];
6961   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6963   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6964   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6965   DONE;
6967   [(set_attr "type"
6968                 "*,          load,        fpload,      fpload,   two,
6969                  two,        mffgpr")
6971    (set_attr "length"
6972                 "4,          4,           4,           4,        8,
6973                  8,          4")])
6975 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6976 ;; moving it to SImode.  We can do a SFmode store without having to do the
6977 ;; conversion explicitly.  If we are doing a register->register conversion, use
6978 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6979 ;; input will not fit in a SFmode, and the later assumes the value has already
6980 ;; been rounded.
6981 (define_insn "*movsi_from_df"
6982   [(set (match_operand:SI 0 "nonimmediate_operand"         "=wa,m,wY,Z")
6983         (unspec:SI [(float_truncate:SF
6984                      (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6985                     UNSPEC_SI_FROM_SF))]
6987   "TARGET_NO_SF_SUBREG"
6988   "@
6989    xscvdpsp %x0,%x1
6990    stfs%U0%X0 %1,%0
6991    stxssp %1,%0
6992    stxsspx %x1,%y0"
6993   [(set_attr "type"   "fp,fpstore,fpstore,fpstore")])
6995 ;; Split a load of a large constant into the appropriate two-insn
6996 ;; sequence.
6998 (define_split
6999   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7000         (match_operand:SI 1 "const_int_operand" ""))]
7001   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7002    && (INTVAL (operands[1]) & 0xffff) != 0"
7003   [(set (match_dup 0)
7004         (match_dup 2))
7005    (set (match_dup 0)
7006         (ior:SI (match_dup 0)
7007                 (match_dup 3)))]
7008   "
7010   if (rs6000_emit_set_const (operands[0], operands[1]))
7011     DONE;
7012   else
7013     FAIL;
7016 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7017 (define_split
7018   [(set (match_operand:DI 0 "altivec_register_operand")
7019         (match_operand:DI 1 "xxspltib_constant_split"))]
7020   "TARGET_P9_VECTOR && reload_completed"
7021   [(const_int 0)]
7023   rtx op0 = operands[0];
7024   rtx op1 = operands[1];
7025   int r = REGNO (op0);
7026   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7028   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7029   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7030   DONE;
7033 (define_insn "*mov<mode>_internal2"
7034   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7035         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7036                     (const_int 0)))
7037    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7038   ""
7039   "@
7040    cmp<wd>i %2,%0,0
7041    mr. %0,%1
7042    #"
7043   [(set_attr "type" "cmp,logical,cmp")
7044    (set_attr "dot" "yes")
7045    (set_attr "length" "4,4,8")])
7047 (define_split
7048   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7049         (compare:CC (match_operand:P 1 "gpc_reg_operand")
7050                     (const_int 0)))
7051    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7052   "reload_completed"
7053   [(set (match_dup 0) (match_dup 1))
7054    (set (match_dup 2)
7055         (compare:CC (match_dup 0)
7056                     (const_int 0)))]
7057   "")
7059 (define_expand "mov<mode>"
7060   [(set (match_operand:INT 0 "general_operand" "")
7061         (match_operand:INT 1 "any_operand" ""))]
7062   ""
7063   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7065 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7066 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7067 ;;              MTVSRWZ     MF%1       MT%1       NOP
7068 (define_insn "*mov<mode>_internal"
7069   [(set (match_operand:QHI 0 "nonimmediate_operand"
7070                 "=r,        r,         ?*wJwK,    m,         Z,         r,
7071                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7072                  ?*wJwK,    r,         *c*l,      *h")
7074         (match_operand:QHI 1 "input_operand"
7075                 "r,         m,         Z,         r,         wJwK,      i,
7076                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7077                  r,         *h,        r,         0"))]
7079   "gpc_reg_operand (operands[0], <MODE>mode)
7080    || gpc_reg_operand (operands[1], <MODE>mode)"
7081   "@
7082    mr %0,%1
7083    l<wd>z%U1%X1 %0,%1
7084    lxsi<wd>zx %x0,%y1
7085    st<wd>%U0%X0 %1,%0
7086    stxsi<wd>x %x1,%y0
7087    li %0,%1
7088    xxlor %x0,%x1,%x1
7089    xxspltib %x0,0
7090    xxspltib %x0,255
7091    vspltis<wd> %0,%1
7092    #
7093    mfvsrwz %0,%x1
7094    mtvsrwz %x0,%1
7095    mf%1 %0
7096    mt%0 %1
7097    nop"
7098   [(set_attr "type"
7099                 "*,         load,      fpload,    store,     fpstore,   *,
7100                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7101                  mffgpr,    mfjmpr,    mtjmpr,    *")
7103    (set_attr "length"
7104                 "4,         4,         4,         4,         4,         4,
7105                  4,         4,         4,         4,         8,         4,
7106                  4,         4,         4,         4")])
7109 ;; Here is how to move condition codes around.  When we store CC data in
7110 ;; an integer register or memory, we store just the high-order 4 bits.
7111 ;; This lets us not shift in the most common case of CR0.
7112 (define_expand "movcc"
7113   [(set (match_operand:CC 0 "nonimmediate_operand" "")
7114         (match_operand:CC 1 "nonimmediate_operand" ""))]
7115   ""
7116   "")
7118 (define_insn "*movcc_internal1"
7119   [(set (match_operand:CC 0 "nonimmediate_operand"
7120                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7121         (match_operand:CC 1 "general_operand"
7122                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7123   "register_operand (operands[0], CCmode)
7124    || register_operand (operands[1], CCmode)"
7125   "@
7126    mcrf %0,%1
7127    mtcrf 128,%1
7128    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7129    crxor %0,%0,%0
7130    mfcr %0%Q1
7131    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7132    mr %0,%1
7133    li %0,%1
7134    mf%1 %0
7135    mt%0 %1
7136    lwz%U1%X1 %0,%1
7137    stw%U0%X0 %1,%0"
7138   [(set (attr "type")
7139      (cond [(eq_attr "alternative" "0,3")
7140                 (const_string "cr_logical")
7141             (eq_attr "alternative" "1,2")
7142                 (const_string "mtcr")
7143             (eq_attr "alternative" "6,7")
7144                 (const_string "integer")
7145             (eq_attr "alternative" "8")
7146                 (const_string "mfjmpr")
7147             (eq_attr "alternative" "9")
7148                 (const_string "mtjmpr")
7149             (eq_attr "alternative" "10")
7150                 (const_string "load")
7151             (eq_attr "alternative" "11")
7152                 (const_string "store")
7153             (match_test "TARGET_MFCRF")
7154                 (const_string "mfcrf")
7155            ]
7156         (const_string "mfcr")))
7157    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7159 ;; For floating-point, we normally deal with the floating-point registers
7160 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7161 ;; can produce floating-point values in fixed-point registers.  Unless the
7162 ;; value is a simple constant or already in memory, we deal with this by
7163 ;; allocating memory and copying the value explicitly via that memory location.
7165 ;; Move 32-bit binary/decimal floating point
7166 (define_expand "mov<mode>"
7167   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7168         (match_operand:FMOVE32 1 "any_operand" ""))]
7169   "<fmove_ok>"
7170   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7172 (define_split
7173   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7174         (match_operand:FMOVE32 1 "const_double_operand" ""))]
7175   "reload_completed
7176    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7177        || (GET_CODE (operands[0]) == SUBREG
7178            && GET_CODE (SUBREG_REG (operands[0])) == REG
7179            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7180   [(set (match_dup 2) (match_dup 3))]
7181   "
7183   long l;
7185   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7187   if (! TARGET_POWERPC64)
7188     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7189   else
7190     operands[2] = gen_lowpart (SImode, operands[0]);
7192   operands[3] = gen_int_mode (l, SImode);
7195 ;; Originally, we tried to keep movsf and movsd common, but the differences
7196 ;; addressing was making it rather difficult to hide with mode attributes.  In
7197 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7198 ;; before the VSX stores meant that the register allocator would tend to do a
7199 ;; direct move to the GPR (which involves conversion from scalar to
7200 ;; vector/memory formats) to save values in the traditional Altivec registers,
7201 ;; while SDmode had problems on power6 if the GPR store was not first due to
7202 ;; the power6 not having an integer store operation.
7204 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7205 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7206 ;;      MR           MT<x>      MF<x>       NOP
7208 (define_insn "movsf_hardfloat"
7209   [(set (match_operand:SF 0 "nonimmediate_operand"
7210          "=!r,       f,         wb,         wu,        m,         wY,
7211           Z,         m,         ww,         !r,        f,         ww,
7212           !r,        *c*l,      !r,         *h")
7213         (match_operand:SF 1 "input_operand"
7214          "m,         m,         wY,         Z,         f,         wb,
7215           wu,        r,         j,          j,         f,         ww,
7216           r,         r,         *h,         0"))]
7217   "(register_operand (operands[0], SFmode)
7218    || register_operand (operands[1], SFmode))
7219    && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7220    && (TARGET_ALLOW_SF_SUBREG
7221        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7222   "@
7223    lwz%U1%X1 %0,%1
7224    lfs%U1%X1 %0,%1
7225    lxssp %0,%1
7226    lxsspx %x0,%y1
7227    stfs%U0%X0 %1,%0
7228    stxssp %1,%0
7229    stxsspx %x1,%y0
7230    stw%U0%X0 %1,%0
7231    xxlxor %x0,%x0,%x0
7232    li %0,0
7233    fmr %0,%1
7234    xscpsgndp %x0,%x1,%x1
7235    mr %0,%1
7236    mt%0 %1
7237    mf%1 %0
7238    nop"
7239   [(set_attr "type"
7240         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7241          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7242          *,          mtjmpr,    mfjmpr,     *")])
7244 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7245 ;;      FMR          MR         MT%0       MF%1       NOP
7246 (define_insn "movsd_hardfloat"
7247   [(set (match_operand:SD 0 "nonimmediate_operand"
7248          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7249           f,         !r,        *c*l,      !r,        *h")
7250         (match_operand:SD 1 "input_operand"
7251          "m,         Z,         r,         wx,        r,         wh,
7252           f,         r,         r,         *h,        0"))]
7253   "(register_operand (operands[0], SDmode)
7254    || register_operand (operands[1], SDmode))
7255    && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
7256   "@
7257    lwz%U1%X1 %0,%1
7258    lfiwzx %0,%y1
7259    stw%U0%X0 %1,%0
7260    stfiwx %1,%y0
7261    mtvsrwz %x0,%1
7262    mfvsrwz %0,%x1
7263    fmr %0,%1
7264    mr %0,%1
7265    mt%0 %1
7266    mf%1 %0
7267    nop"
7268   [(set_attr "type"
7269         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7270          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7272 (define_insn "*mov<mode>_softfloat"
7273   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7274         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7275   "(gpc_reg_operand (operands[0], <MODE>mode)
7276    || gpc_reg_operand (operands[1], <MODE>mode))
7277    && TARGET_SOFT_FLOAT"
7278   "@
7279    mr %0,%1
7280    mt%0 %1
7281    mf%1 %0
7282    lwz%U1%X1 %0,%1
7283    stw%U0%X0 %1,%0
7284    li %0,%1
7285    lis %0,%v1
7286    #
7287    #
7288    nop"
7289   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7290    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7292 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7293 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7295 ;; Because SF values are actually stored as DF values within the vector
7296 ;; registers, we need to convert the value to the vector SF format when
7297 ;; we need to use the bits in a union or similar cases.  We only need
7298 ;; to do this transformation when the value is a vector register.  Loads,
7299 ;; stores, and transfers within GPRs are assumed to be safe.
7301 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7302 ;; no alternatives, because the call is created as part of secondary_reload,
7303 ;; and operand #2's register class is used to allocate the temporary register.
7304 ;; This function is called before reload, and it creates the temporary as
7305 ;; needed.
7307 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7308 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7309 (define_insn_and_split "movsf_from_si"
7310   [(set (match_operand:SF 0 "nonimmediate_operand"
7311             "=!r,       f,         wb,        wu,        m,         Z,
7312              Z,         wy,        ?r,        !r")
7314         (unspec:SF [(match_operand:SI 1 "input_operand" 
7315             "m,         m,         wY,        Z,         r,         f,
7316              wu,        r,         wy,        r")]
7317                    UNSPEC_SF_FROM_SI))
7319    (clobber (match_scratch:DI 2
7320             "=X,        X,         X,         X,         X,         X,
7321              X,         r,         X,         X"))]
7323   "TARGET_NO_SF_SUBREG
7324    && (register_operand (operands[0], SFmode)
7325        || register_operand (operands[1], SImode))"
7326   "@
7327    lwz%U1%X1 %0,%1
7328    lfs%U1%X1 %0,%1
7329    lxssp %0,%1
7330    lxsspx %x0,%y1
7331    stw%U0%X0 %1,%0
7332    stfiwx %1,%y0
7333    stxsiwx %x1,%y0
7334    #
7335    mfvsrwz %0,%x1
7336    mr %0,%1"
7338   "&& reload_completed
7339    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7340    && int_reg_operand_not_pseudo (operands[1], SImode)"
7341   [(const_int 0)]
7343   rtx op0 = operands[0];
7344   rtx op1 = operands[1];
7345   rtx op2 = operands[2];
7346   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7348   /* Move SF value to upper 32-bits for xscvspdpn.  */
7349   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7350   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7351   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7352   DONE;
7354   [(set_attr "length"
7355             "4,          4,         4,         4,         4,         4,
7356              4,          12,        4,         4")
7357    (set_attr "type"
7358             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7359              fpstore,    vecfloat,  mffgpr,    *")])
7362 ;; Move 64-bit binary/decimal floating point
7363 (define_expand "mov<mode>"
7364   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7365         (match_operand:FMOVE64 1 "any_operand" ""))]
7366   ""
7367   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7369 (define_split
7370   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7371         (match_operand:FMOVE64 1 "const_int_operand" ""))]
7372   "! TARGET_POWERPC64 && reload_completed
7373    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7374        || (GET_CODE (operands[0]) == SUBREG
7375            && GET_CODE (SUBREG_REG (operands[0])) == REG
7376            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7377   [(set (match_dup 2) (match_dup 4))
7378    (set (match_dup 3) (match_dup 1))]
7379   "
7381   int endian = (WORDS_BIG_ENDIAN == 0);
7382   HOST_WIDE_INT value = INTVAL (operands[1]);
7384   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7385   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7386   operands[4] = GEN_INT (value >> 32);
7387   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7390 (define_split
7391   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7392         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7393   "! TARGET_POWERPC64 && reload_completed
7394    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7395        || (GET_CODE (operands[0]) == SUBREG
7396            && GET_CODE (SUBREG_REG (operands[0])) == REG
7397            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7398   [(set (match_dup 2) (match_dup 4))
7399    (set (match_dup 3) (match_dup 5))]
7400   "
7402   int endian = (WORDS_BIG_ENDIAN == 0);
7403   long l[2];
7405   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7407   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7408   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7409   operands[4] = gen_int_mode (l[endian], SImode);
7410   operands[5] = gen_int_mode (l[1 - endian], SImode);
7413 (define_split
7414   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7415         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7416   "TARGET_POWERPC64 && reload_completed
7417    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7418        || (GET_CODE (operands[0]) == SUBREG
7419            && GET_CODE (SUBREG_REG (operands[0])) == REG
7420            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7421   [(set (match_dup 2) (match_dup 3))]
7422   "
7424   int endian = (WORDS_BIG_ENDIAN == 0);
7425   long l[2];
7426   HOST_WIDE_INT val;
7428   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7430   operands[2] = gen_lowpart (DImode, operands[0]);
7431   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7432   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7433          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7435   operands[3] = gen_int_mode (val, DImode);
7438 ;; Don't have reload use general registers to load a constant.  It is
7439 ;; less efficient than loading the constant into an FP register, since
7440 ;; it will probably be used there.
7442 ;; The move constraints are ordered to prefer floating point registers before
7443 ;; general purpose registers to avoid doing a store and a load to get the value
7444 ;; into a floating point register when it is needed for a floating point
7445 ;; operation.  Prefer traditional floating point registers over VSX registers,
7446 ;; since the D-form version of the memory instructions does not need a GPR for
7447 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7448 ;; registers.
7450 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7451 ;; except for 0.0 which can be created on VSX with an xor instruction.
7453 (define_insn "*mov<mode>_hardfloat32"
7454   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7455         (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7456   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 
7457    && (gpc_reg_operand (operands[0], <MODE>mode)
7458        || gpc_reg_operand (operands[1], <MODE>mode))"
7459   "@
7460    stfd%U0%X0 %1,%0
7461    lfd%U1%X1 %0,%1
7462    fmr %0,%1
7463    lxsd %0,%1
7464    stxsd %1,%0
7465    lxsd%U1x %x0,%y1
7466    stxsd%U0x %x1,%y0
7467    xxlor %x0,%x1,%x1
7468    xxlxor %x0,%x0,%x0
7469    #
7470    #
7471    #
7472    #"
7473   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7474    (set_attr "size" "64")
7475    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7477 (define_insn "*mov<mode>_softfloat32"
7478   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7479         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7480   "! TARGET_POWERPC64 
7481    && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT)
7482    && (gpc_reg_operand (operands[0], <MODE>mode)
7483        || gpc_reg_operand (operands[1], <MODE>mode))"
7484   "#"
7485   [(set_attr "type" "store,load,two,*,*,*")
7486    (set_attr "length" "8,8,8,8,12,16")])
7488 ; ld/std require word-aligned displacements -> 'Y' constraint.
7489 ; List Y->r and r->Y before r->r for reload.
7490 (define_insn "*mov<mode>_hardfloat64"
7491   [(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>")
7492         (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"))]
7493   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7494    && (gpc_reg_operand (operands[0], <MODE>mode)
7495        || gpc_reg_operand (operands[1], <MODE>mode))"
7496   "@
7497    stfd%U0%X0 %1,%0
7498    lfd%U1%X1 %0,%1
7499    fmr %0,%1
7500    lxsd %0,%1
7501    stxsd %1,%0
7502    lxsd%U1x %x0,%y1
7503    stxsd%U0x %x1,%y0
7504    xxlor %x0,%x1,%x1
7505    xxlxor %x0,%x0,%x0
7506    li %0,0
7507    std%U0%X0 %1,%0
7508    ld%U1%X1 %0,%1
7509    mr %0,%1
7510    mt%0 %1
7511    mf%1 %0
7512    nop
7513    mftgpr %0,%1
7514    mffgpr %0,%1
7515    mfvsrd %0,%x1
7516    mtvsrd %x0,%1"
7517   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7518    (set_attr "size" "64")
7519    (set_attr "length" "4")])
7521 (define_insn "*mov<mode>_softfloat64"
7522   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7523         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7524   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7525    && (gpc_reg_operand (operands[0], <MODE>mode)
7526        || gpc_reg_operand (operands[1], <MODE>mode))"
7527   "@
7528    std%U0%X0 %1,%0
7529    ld%U1%X1 %0,%1
7530    mr %0,%1
7531    mt%0 %1
7532    mf%1 %0
7533    #
7534    #
7535    #
7536    nop"
7537   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7538    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7540 (define_expand "mov<mode>"
7541   [(set (match_operand:FMOVE128 0 "general_operand" "")
7542         (match_operand:FMOVE128 1 "any_operand" ""))]
7543   ""
7544   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7546 ;; It's important to list Y->r and r->Y before r->r because otherwise
7547 ;; reload, given m->r, will try to pick r->r and reload it, which
7548 ;; doesn't make progress.
7550 ;; We can't split little endian direct moves of TDmode, because the words are
7551 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7552 ;; problematical.  Don't allow direct move for this case.
7554 (define_insn_and_split "*mov<mode>_64bit_dm"
7555   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7556         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7557   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7558    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7559    && (gpc_reg_operand (operands[0], <MODE>mode)
7560        || gpc_reg_operand (operands[1], <MODE>mode))"
7561   "#"
7562   "&& reload_completed"
7563   [(pc)]
7564 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7565   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7567 (define_insn_and_split "*movtd_64bit_nodm"
7568   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7569         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7570   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7571    && (gpc_reg_operand (operands[0], TDmode)
7572        || gpc_reg_operand (operands[1], TDmode))"
7573   "#"
7574   "&& reload_completed"
7575   [(pc)]
7576 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7577   [(set_attr "length" "8,8,8,12,12,8")])
7579 (define_insn_and_split "*mov<mode>_32bit"
7580   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7581         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7582   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7583    && (FLOAT128_2REG_P (<MODE>mode)
7584        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7585        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7586    && (gpc_reg_operand (operands[0], <MODE>mode)
7587        || gpc_reg_operand (operands[1], <MODE>mode))"
7588   "#"
7589   "&& reload_completed"
7590   [(pc)]
7591 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7592   [(set_attr "length" "8,8,8,8,20,20,16")])
7594 (define_insn_and_split "*mov<mode>_softfloat"
7595   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7596         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7597   "TARGET_SOFT_FLOAT
7598    && (gpc_reg_operand (operands[0], <MODE>mode)
7599        || gpc_reg_operand (operands[1], <MODE>mode))"
7600   "#"
7601   "&& reload_completed"
7602   [(pc)]
7603 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7604   [(set_attr "length" "20,20,16")])
7606 (define_expand "extenddf<mode>2"
7607   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7608         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7609   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7611   if (FLOAT128_IEEE_P (<MODE>mode))
7612     rs6000_expand_float128_convert (operands[0], operands[1], false);
7613   else if (TARGET_VSX)
7614     {
7615       if (<MODE>mode == TFmode)
7616         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7617       else if (<MODE>mode == IFmode)
7618         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7619       else
7620         gcc_unreachable ();
7621     }
7622    else
7623     {
7624       rtx zero = gen_reg_rtx (DFmode);
7625       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7627       if (<MODE>mode == TFmode)
7628         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7629       else if (<MODE>mode == IFmode)
7630         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7631       else
7632         gcc_unreachable ();
7633     }
7634   DONE;
7637 ;; Allow memory operands for the source to be created by the combiner.
7638 (define_insn_and_split "extenddf<mode>2_fprs"
7639   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7640         (float_extend:IBM128
7641          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7642    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7643   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7644    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7645   "#"
7646   "&& reload_completed"
7647   [(set (match_dup 3) (match_dup 1))
7648    (set (match_dup 4) (match_dup 2))]
7650   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7651   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7653   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7654   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7657 (define_insn_and_split "extenddf<mode>2_vsx"
7658   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7659         (float_extend:IBM128
7660          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7661   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7662   "#"
7663   "&& reload_completed"
7664   [(set (match_dup 2) (match_dup 1))
7665    (set (match_dup 3) (match_dup 4))]
7667   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7668   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7670   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7671   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7672   operands[4] = CONST0_RTX (DFmode);
7675 (define_expand "extendsf<mode>2"
7676   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7677         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7678   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7680   if (FLOAT128_IEEE_P (<MODE>mode))
7681     rs6000_expand_float128_convert (operands[0], operands[1], false);
7682   else
7683     {
7684       rtx tmp = gen_reg_rtx (DFmode);
7685       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7686       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7687     }
7688   DONE;
7691 (define_expand "trunc<mode>df2"
7692   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7693         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7694   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7696   if (FLOAT128_IEEE_P (<MODE>mode))
7697     {
7698       rs6000_expand_float128_convert (operands[0], operands[1], false);
7699       DONE;
7700     }
7703 (define_insn_and_split "trunc<mode>df2_internal1"
7704   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7705         (float_truncate:DF
7706          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7707   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7708    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7709   "@
7710    #
7711    fmr %0,%1"
7712   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7713   [(const_int 0)]
7715   emit_note (NOTE_INSN_DELETED);
7716   DONE;
7718   [(set_attr "type" "fpsimple")])
7720 (define_insn "trunc<mode>df2_internal2"
7721   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7722         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7723   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7724    && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7725   "fadd %0,%1,%L1"
7726   [(set_attr "type" "fp")
7727    (set_attr "fp_type" "fp_addsub_d")])
7729 (define_expand "trunc<mode>sf2"
7730   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7731         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7732   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7734   if (FLOAT128_IEEE_P (<MODE>mode))
7735     rs6000_expand_float128_convert (operands[0], operands[1], false);
7736   else if (<MODE>mode == TFmode)
7737     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7738   else if (<MODE>mode == IFmode)
7739     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7740   else
7741     gcc_unreachable ();
7742   DONE;
7745 (define_insn_and_split "trunc<mode>sf2_fprs"
7746   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7747         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7748    (clobber (match_scratch:DF 2 "=d"))]
7749   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 
7750    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7751   "#"
7752   "&& reload_completed"
7753   [(set (match_dup 2)
7754         (float_truncate:DF (match_dup 1)))
7755    (set (match_dup 0)
7756         (float_truncate:SF (match_dup 2)))]
7757   "")
7759 (define_expand "floatsi<mode>2"
7760   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7761                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7762               (clobber (match_scratch:DI 2))])]
7763   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7765   rtx op0 = operands[0];
7766   rtx op1 = operands[1];
7768   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7769     ;
7770   else if (FLOAT128_IEEE_P (<MODE>mode))
7771     {
7772       rs6000_expand_float128_convert (op0, op1, false);
7773       DONE;
7774     }
7775   else
7776     {
7777       rtx tmp = gen_reg_rtx (DFmode);
7778       expand_float (tmp, op1, false);
7779       if (<MODE>mode == TFmode)
7780         emit_insn (gen_extenddftf2 (op0, tmp));
7781       else if (<MODE>mode == IFmode)
7782         emit_insn (gen_extenddfif2 (op0, tmp));
7783       else
7784         gcc_unreachable ();
7785       DONE;
7786     }
7789 ; fadd, but rounding towards zero.
7790 ; This is probably not the optimal code sequence.
7791 (define_insn "fix_trunc_helper<mode>"
7792   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7793         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7794                    UNSPEC_FIX_TRUNC_TF))
7795    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7796   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7797   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7798   [(set_attr "type" "fp")
7799    (set_attr "length" "20")])
7801 (define_expand "fix_trunc<mode>si2"
7802   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7803         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7804   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7806   rtx op0 = operands[0];
7807   rtx op1 = operands[1];
7809   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7810     ;
7811   else
7812     {
7813       if (FLOAT128_IEEE_P (<MODE>mode))
7814         rs6000_expand_float128_convert (op0, op1, false);
7815       else if (<MODE>mode == TFmode)
7816         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7817       else if (<MODE>mode == IFmode)
7818         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7819       else
7820         gcc_unreachable ();
7821       DONE;
7822     }
7825 (define_expand "fix_trunc<mode>si2_fprs"
7826   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7827                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7828               (clobber (match_dup 2))
7829               (clobber (match_dup 3))
7830               (clobber (match_dup 4))
7831               (clobber (match_dup 5))])]
7832   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7834   operands[2] = gen_reg_rtx (DFmode);
7835   operands[3] = gen_reg_rtx (DFmode);
7836   operands[4] = gen_reg_rtx (DImode);
7837   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7840 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7841   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7842         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7843    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7844    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7845    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7846    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7847   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7848   "#"
7849   ""
7850   [(pc)]
7852   rtx lowword;
7853   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7854                                          operands[3]));
7856   gcc_assert (MEM_P (operands[5]));
7857   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7859   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7860   emit_move_insn (operands[5], operands[4]);
7861   emit_move_insn (operands[0], lowword);
7862   DONE;
7865 (define_expand "fix_trunc<mode>di2"
7866   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7867         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7868   "TARGET_FLOAT128_TYPE"
7870   if (!TARGET_FLOAT128_HW)
7871     {
7872       rs6000_expand_float128_convert (operands[0], operands[1], false);
7873       DONE;
7874     }
7877 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7878   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7879         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7880   "TARGET_FLOAT128_TYPE"
7882   rs6000_expand_float128_convert (operands[0], operands[1], true);
7883   DONE;
7886 (define_expand "floatdi<mode>2"
7887   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7888         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7889   "TARGET_FLOAT128_TYPE"
7891   if (!TARGET_FLOAT128_HW)
7892     {
7893       rs6000_expand_float128_convert (operands[0], operands[1], false);
7894       DONE;
7895     }
7898 (define_expand "floatunsdi<IEEE128:mode>2"
7899   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7900         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7901   "TARGET_FLOAT128_TYPE"
7903   if (!TARGET_FLOAT128_HW)
7904     {
7905       rs6000_expand_float128_convert (operands[0], operands[1], true);
7906       DONE;
7907     }
7910 (define_expand "floatuns<IEEE128:mode>2"
7911   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7912         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7913   "TARGET_FLOAT128_TYPE"
7915   rtx op0 = operands[0];
7916   rtx op1 = operands[1];
7918   if (TARGET_FLOAT128_HW)
7919     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7920   else
7921     rs6000_expand_float128_convert (op0, op1, true);
7922   DONE;
7925 (define_expand "neg<mode>2"
7926   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7927         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7928   "FLOAT128_IEEE_P (<MODE>mode)
7929    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7930   "
7932   if (FLOAT128_IEEE_P (<MODE>mode))
7933     {
7934       if (TARGET_FLOAT128_HW)
7935         {
7936           if (<MODE>mode == TFmode)
7937             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7938           else if (<MODE>mode == KFmode)
7939             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7940           else
7941             gcc_unreachable ();
7942         }
7943       else if (TARGET_FLOAT128_TYPE)
7944         {
7945           if (<MODE>mode == TFmode)
7946             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7947           else if (<MODE>mode == KFmode)
7948             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7949           else
7950             gcc_unreachable ();
7951         }
7952       else
7953         {
7954           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7955           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7956                                                 <MODE>mode,
7957                                                 operands[1], <MODE>mode);
7959           if (target && !rtx_equal_p (target, operands[0]))
7960             emit_move_insn (operands[0], target);
7961         }
7962       DONE;
7963     }
7966 (define_insn "neg<mode>2_internal"
7967   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7968         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7969   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7970   "*
7972   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7973     return \"fneg %L0,%L1\;fneg %0,%1\";
7974   else
7975     return \"fneg %0,%1\;fneg %L0,%L1\";
7977   [(set_attr "type" "fpsimple")
7978    (set_attr "length" "8")])
7980 (define_expand "abs<mode>2"
7981   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7982         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7983   "FLOAT128_IEEE_P (<MODE>mode)
7984    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7985   "
7987   rtx label;
7989   if (FLOAT128_IEEE_P (<MODE>mode))
7990     {
7991       if (TARGET_FLOAT128_HW)
7992         {
7993           if (<MODE>mode == TFmode)
7994             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7995           else if (<MODE>mode == KFmode)
7996             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7997           else
7998             FAIL;
7999           DONE;
8000         }
8001       else if (TARGET_FLOAT128_TYPE)
8002         {
8003           if (<MODE>mode == TFmode)
8004             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8005           else if (<MODE>mode == KFmode)
8006             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8007           else
8008             FAIL;
8009           DONE;
8010         }
8011       else
8012         FAIL;
8013     }
8015   label = gen_label_rtx ();
8016   if (<MODE>mode == TFmode)
8017     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8018   else if (<MODE>mode == TFmode)
8019     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8020   else
8021     FAIL;
8022   emit_label (label);
8023   DONE;
8026 (define_expand "abs<mode>2_internal"
8027   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
8028         (match_operand:IBM128 1 "gpc_reg_operand" ""))
8029    (set (match_dup 3) (match_dup 5))
8030    (set (match_dup 5) (abs:DF (match_dup 5)))
8031    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8032    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8033                            (label_ref (match_operand 2 "" ""))
8034                            (pc)))
8035    (set (match_dup 6) (neg:DF (match_dup 6)))]
8036   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
8037   "
8039   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8040   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8041   operands[3] = gen_reg_rtx (DFmode);
8042   operands[4] = gen_reg_rtx (CCFPmode);
8043   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8044   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8048 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8049 ;; register
8051 (define_expand "ieee_128bit_negative_zero"
8052   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
8053   "TARGET_FLOAT128_TYPE"
8055   rtvec v = rtvec_alloc (16);
8056   int i, high;
8058   for (i = 0; i < 16; i++)
8059     RTVEC_ELT (v, i) = const0_rtx;
8061   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8062   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8064   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8065   DONE;
8068 ;; IEEE 128-bit negate
8070 ;; We have 2 insns here for negate and absolute value.  The first uses
8071 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8072 ;; insns, and second insn after the first split pass loads up the bit to
8073 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8074 ;; neg/abs to create the constant just once.
8076 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8077   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8078         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8079    (clobber (match_scratch:V16QI 2 "=v"))]
8080   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8081   "#"
8082   "&& 1"
8083   [(parallel [(set (match_dup 0)
8084                    (neg:IEEE128 (match_dup 1)))
8085               (use (match_dup 2))])]
8087   if (GET_CODE (operands[2]) == SCRATCH)
8088     operands[2] = gen_reg_rtx (V16QImode);
8090   operands[3] = gen_reg_rtx (V16QImode);
8091   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8093   [(set_attr "length" "8")
8094    (set_attr "type" "vecsimple")])
8096 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8097   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8098         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8099    (use (match_operand:V16QI 2 "register_operand" "v"))]
8100   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8101   "xxlxor %x0,%x1,%x2"
8102   [(set_attr "type" "veclogical")])
8104 ;; IEEE 128-bit absolute value
8105 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8106   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8107         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8108    (clobber (match_scratch:V16QI 2 "=v"))]
8109   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8110   "#"
8111   "&& 1"
8112   [(parallel [(set (match_dup 0)
8113                    (abs:IEEE128 (match_dup 1)))
8114               (use (match_dup 2))])]
8116   if (GET_CODE (operands[2]) == SCRATCH)
8117     operands[2] = gen_reg_rtx (V16QImode);
8119   operands[3] = gen_reg_rtx (V16QImode);
8120   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8122   [(set_attr "length" "8")
8123    (set_attr "type" "vecsimple")])
8125 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8126   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8127         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8128    (use (match_operand:V16QI 2 "register_operand" "v"))]
8129   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8130   "xxlandc %x0,%x1,%x2"
8131   [(set_attr "type" "veclogical")])
8133 ;; IEEE 128-bit negative absolute value
8134 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8135   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8136         (neg:IEEE128
8137          (abs:IEEE128
8138           (match_operand:IEEE128 1 "register_operand" "wa"))))
8139    (clobber (match_scratch:V16QI 2 "=v"))]
8140   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8141    && FLOAT128_IEEE_P (<MODE>mode)"
8142   "#"
8143   "&& 1"
8144   [(parallel [(set (match_dup 0)
8145                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8146               (use (match_dup 2))])]
8148   if (GET_CODE (operands[2]) == SCRATCH)
8149     operands[2] = gen_reg_rtx (V16QImode);
8151   operands[3] = gen_reg_rtx (V16QImode);
8152   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8154   [(set_attr "length" "8")
8155    (set_attr "type" "vecsimple")])
8157 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8158   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8159         (neg:IEEE128
8160          (abs:IEEE128
8161           (match_operand:IEEE128 1 "register_operand" "wa"))))
8162    (use (match_operand:V16QI 2 "register_operand" "v"))]
8163   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8164   "xxlor %x0,%x1,%x2"
8165   [(set_attr "type" "veclogical")])
8167 ;; Float128 conversion functions.  These expand to library function calls.
8168 ;; We use expand to convert from IBM double double to IEEE 128-bit
8169 ;; and trunc for the opposite.
8170 (define_expand "extendiftf2"
8171   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8172         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8173   "TARGET_FLOAT128_TYPE"
8175   rs6000_expand_float128_convert (operands[0], operands[1], false);
8176   DONE;
8179 (define_expand "extendifkf2"
8180   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8181         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8182   "TARGET_FLOAT128_TYPE"
8184   rs6000_expand_float128_convert (operands[0], operands[1], false);
8185   DONE;
8188 (define_expand "extendtfkf2"
8189   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8190         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8191   "TARGET_FLOAT128_TYPE"
8193   rs6000_expand_float128_convert (operands[0], operands[1], false);
8194   DONE;
8197 (define_expand "trunciftf2"
8198   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8199         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8200   "TARGET_FLOAT128_TYPE"
8202   rs6000_expand_float128_convert (operands[0], operands[1], false);
8203   DONE;
8206 (define_expand "truncifkf2"
8207   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8208         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8209   "TARGET_FLOAT128_TYPE"
8211   rs6000_expand_float128_convert (operands[0], operands[1], false);
8212   DONE;
8215 (define_expand "trunckftf2"
8216   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8217         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8218   "TARGET_FLOAT128_TYPE"
8220   rs6000_expand_float128_convert (operands[0], operands[1], false);
8221   DONE;
8224 (define_expand "trunctfif2"
8225   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8226         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8227   "TARGET_FLOAT128_TYPE"
8229   rs6000_expand_float128_convert (operands[0], operands[1], false);
8230   DONE;
8234 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8235 ;; must have 3 arguments, and scratch register constraint must be a single
8236 ;; constraint.
8238 ;; Reload patterns to support gpr load/store with misaligned mem.
8239 ;; and multiple gpr load/store at offset >= 0xfffc
8240 (define_expand "reload_<mode>_store"
8241   [(parallel [(match_operand 0 "memory_operand" "=m")
8242               (match_operand 1 "gpc_reg_operand" "r")
8243               (match_operand:GPR 2 "register_operand" "=&b")])]
8244   ""
8246   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8247   DONE;
8250 (define_expand "reload_<mode>_load"
8251   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8252               (match_operand 1 "memory_operand" "m")
8253               (match_operand:GPR 2 "register_operand" "=b")])]
8254   ""
8256   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8257   DONE;
8261 ;; Reload patterns for various types using the vector registers.  We may need
8262 ;; an additional base register to convert the reg+offset addressing to reg+reg
8263 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8264 ;; index register for gpr registers.
8265 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8266   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8267               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8268               (match_operand:P 2 "register_operand" "=b")])]
8269   "<P:tptrsize>"
8271   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8272   DONE;
8275 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8276   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8277               (match_operand:RELOAD 1 "memory_operand" "m")
8278               (match_operand:P 2 "register_operand" "=b")])]
8279   "<P:tptrsize>"
8281   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8282   DONE;
8286 ;; Reload sometimes tries to move the address to a GPR, and can generate
8287 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8288 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8290 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8291   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8292         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8293                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8294                (const_int -16)))]
8295   "TARGET_ALTIVEC && reload_completed"
8296   "#"
8297   "&& reload_completed"
8298   [(set (match_dup 0)
8299         (plus:P (match_dup 1)
8300                 (match_dup 2)))
8301    (set (match_dup 0)
8302         (and:P (match_dup 0)
8303                (const_int -16)))])
8305 ;; Power8 merge instructions to allow direct move to/from floating point
8306 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8307 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8308 ;; value, since it is allocated in reload and not all of the flow information
8309 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8310 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8311 ;; schedule other instructions between the two instructions.
8313 (define_insn "p8_fmrgow_<mode>"
8314   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8315         (unspec:FMOVE64X [
8316                 (match_operand:DF 1 "register_operand" "d")
8317                 (match_operand:DF 2 "register_operand" "d")]
8318                          UNSPEC_P8V_FMRGOW))]
8319   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8320   "fmrgow %0,%1,%2"
8321   [(set_attr "type" "fpsimple")])
8323 (define_insn "p8_mtvsrwz"
8324   [(set (match_operand:DF 0 "register_operand" "=d")
8325         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8326                    UNSPEC_P8V_MTVSRWZ))]
8327   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8328   "mtvsrwz %x0,%1"
8329   [(set_attr "type" "mftgpr")])
8331 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8332   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8333         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8334                          UNSPEC_P8V_RELOAD_FROM_GPR))
8335    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8336   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8337   "#"
8338   "&& reload_completed"
8339   [(const_int 0)]
8341   rtx dest = operands[0];
8342   rtx src = operands[1];
8343   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8344   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8345   rtx gpr_hi_reg = gen_highpart (SImode, src);
8346   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8348   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8349   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8350   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8351   DONE;
8353   [(set_attr "length" "12")
8354    (set_attr "type" "three")])
8356 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8357 (define_insn "p8_mtvsrd_df"
8358   [(set (match_operand:DF 0 "register_operand" "=wa")
8359         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8360                    UNSPEC_P8V_MTVSRD))]
8361   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8362   "mtvsrd %x0,%1"
8363   [(set_attr "type" "mftgpr")])
8365 (define_insn "p8_xxpermdi_<mode>"
8366   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8367         (unspec:FMOVE128_GPR [
8368                 (match_operand:DF 1 "register_operand" "wa")
8369                 (match_operand:DF 2 "register_operand" "wa")]
8370                 UNSPEC_P8V_XXPERMDI))]
8371   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8372   "xxpermdi %x0,%x1,%x2,0"
8373   [(set_attr "type" "vecperm")])
8375 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8376   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8377         (unspec:FMOVE128_GPR
8378          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8379          UNSPEC_P8V_RELOAD_FROM_GPR))
8380    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8381   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8382   "#"
8383   "&& reload_completed"
8384   [(const_int 0)]
8386   rtx dest = operands[0];
8387   rtx src = operands[1];
8388   /* You might think that we could use op0 as one temp and a DF clobber
8389      as op2, but you'd be wrong.  Secondary reload move patterns don't
8390      check for overlap of the clobber and the destination.  */
8391   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8392   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8393   rtx gpr_hi_reg = gen_highpart (DImode, src);
8394   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8396   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8397   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8398   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8399   DONE;
8401   [(set_attr "length" "12")
8402    (set_attr "type" "three")])
8404 (define_split
8405   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8406         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8407   "reload_completed
8408    && (int_reg_operand (operands[0], <MODE>mode)
8409        || int_reg_operand (operands[1], <MODE>mode))
8410    && (!TARGET_DIRECT_MOVE_128
8411        || (!vsx_register_operand (operands[0], <MODE>mode)
8412            && !vsx_register_operand (operands[1], <MODE>mode)))"
8413   [(pc)]
8414 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8416 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8417 ;; type is stored internally as double precision in the VSX registers, we have
8418 ;; to convert it from the vector format.
8419 (define_insn "p8_mtvsrd_sf"
8420   [(set (match_operand:SF 0 "register_operand" "=wa")
8421         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8422                    UNSPEC_P8V_MTVSRD))]
8423   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8424   "mtvsrd %x0,%1"
8425   [(set_attr "type" "mftgpr")])
8427 (define_insn_and_split "reload_vsx_from_gprsf"
8428   [(set (match_operand:SF 0 "register_operand" "=wa")
8429         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8430                    UNSPEC_P8V_RELOAD_FROM_GPR))
8431    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8432   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8433   "#"
8434   "&& reload_completed"
8435   [(const_int 0)]
8437   rtx op0 = operands[0];
8438   rtx op1 = operands[1];
8439   rtx op2 = operands[2];
8440   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8442   /* Move SF value to upper 32-bits for xscvspdpn.  */
8443   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8444   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8445   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8446   DONE;
8448   [(set_attr "length" "8")
8449    (set_attr "type" "two")])
8451 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8452 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8453 ;; and then doing a move of that.
8454 (define_insn "p8_mfvsrd_3_<mode>"
8455   [(set (match_operand:DF 0 "register_operand" "=r")
8456         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8457                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8458   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8459   "mfvsrd %0,%x1"
8460   [(set_attr "type" "mftgpr")])
8462 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8463   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8464         (unspec:FMOVE128_GPR
8465          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8466          UNSPEC_P8V_RELOAD_FROM_VSX))
8467    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8468   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8469   "#"
8470   "&& reload_completed"
8471   [(const_int 0)]
8473   rtx dest = operands[0];
8474   rtx src = operands[1];
8475   rtx tmp = operands[2];
8476   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8477   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8479   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8480   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8481   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8482   DONE;
8484   [(set_attr "length" "12")
8485    (set_attr "type" "three")])
8487 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8488 ;; type is stored internally as double precision, we have to convert it to the
8489 ;; vector format.
8491 (define_insn_and_split "reload_gpr_from_vsxsf"
8492   [(set (match_operand:SF 0 "register_operand" "=r")
8493         (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8494                    UNSPEC_P8V_RELOAD_FROM_VSX))
8495    (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8496   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8497   "#"
8498   "&& reload_completed"
8499   [(const_int 0)]
8501   rtx op0 = operands[0];
8502   rtx op1 = operands[1];
8503   rtx op2 = operands[2];
8504   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8505   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8507   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8508   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8509   DONE;
8511   [(set_attr "length" "8")
8512    (set_attr "type" "two")])
8515 ;; Next come the multi-word integer load and store and the load and store
8516 ;; multiple insns.
8518 ;; List r->r after r->Y, otherwise reload will try to reload a
8519 ;; non-offsettable address by using r->r which won't make progress.
8520 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8521 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8523 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8524 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8525 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8526 ;;        AVX const  
8528 (define_insn "*movdi_internal32"
8529   [(set (match_operand:DI 0 "nonimmediate_operand"
8530          "=Y,        r,         r,         ^m,        ^d,         ^d,
8531           r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8532           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8533           *wv")
8535         (match_operand:DI 1 "input_operand"
8536           "r,        Y,         r,         d,         m,          d,
8537            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8538            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8539            wB"))]
8541   "! TARGET_POWERPC64
8542    && (gpc_reg_operand (operands[0], DImode)
8543        || gpc_reg_operand (operands[1], DImode))"
8544   "@
8545    #
8546    #
8547    #
8548    stfd%U0%X0 %1,%0
8549    lfd%U1%X1 %0,%1
8550    fmr %0,%1
8551    #
8552    stxsd %1,%0
8553    stxsdx %x1,%y0
8554    lxsd %0,%1
8555    lxsdx %x0,%y1
8556    xxlor %x0,%x1,%x1
8557    xxspltib %x0,0
8558    xxspltib %x0,255
8559    vspltisw %0,%1
8560    xxlxor %x0,%x0,%x0
8561    xxlorc %x0,%x0,%x0
8562    #
8563    #"
8564   [(set_attr "type"
8565                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8566                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8567                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8568                 vecsimple")
8569    (set_attr "size" "64")])
8571 (define_split
8572   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8573         (match_operand:DI 1 "const_int_operand" ""))]
8574   "! TARGET_POWERPC64 && reload_completed
8575    && gpr_or_gpr_p (operands[0], operands[1])
8576    && !direct_move_p (operands[0], operands[1])"
8577   [(set (match_dup 2) (match_dup 4))
8578    (set (match_dup 3) (match_dup 1))]
8579   "
8581   HOST_WIDE_INT value = INTVAL (operands[1]);
8582   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8583                                        DImode);
8584   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8585                                        DImode);
8586   operands[4] = GEN_INT (value >> 32);
8587   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8590 (define_split
8591   [(set (match_operand:DIFD 0 "nonimmediate_operand" "")
8592         (match_operand:DIFD 1 "input_operand" ""))]
8593   "reload_completed && !TARGET_POWERPC64
8594    && gpr_or_gpr_p (operands[0], operands[1])
8595    && !direct_move_p (operands[0], operands[1])"
8596   [(pc)]
8597 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8599 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8600 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8601 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8602 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8603 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8604 (define_insn "*movdi_internal64"
8605   [(set (match_operand:DI 0 "nonimmediate_operand"
8606                "=Y,        r,         r,         r,         r,          r,
8607                 ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
8608                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8609                 *wi,       *wv,       *wv,       r,         *h,         *h,
8610                 ?*r,       ?*wg,      ?*r,       ?*wj")
8612         (match_operand:DI 1 "input_operand"
8613                 "r,        Y,         r,         I,         L,          nF,
8614                  d,        m,         d,         wb,        wv,         wY,
8615                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8616                  wM,       wS,        wB,        *h,        r,          0,
8617                  wg,       r,         wj,        r"))]
8619   "TARGET_POWERPC64
8620    && (gpc_reg_operand (operands[0], DImode)
8621        || gpc_reg_operand (operands[1], DImode))"
8622   "@
8623    std%U0%X0 %1,%0
8624    ld%U1%X1 %0,%1
8625    mr %0,%1
8626    li %0,%1
8627    lis %0,%v1
8628    #
8629    stfd%U0%X0 %1,%0
8630    lfd%U1%X1 %0,%1
8631    fmr %0,%1
8632    stxsd %1,%0
8633    stxsdx %x1,%y0
8634    lxsd %0,%1
8635    lxsdx %x0,%y1
8636    xxlor %x0,%x1,%x1
8637    xxspltib %x0,0
8638    xxspltib %x0,255
8639    #
8640    xxlxor %x0,%x0,%x0
8641    xxlorc %x0,%x0,%x0
8642    #
8643    #
8644    mf%1 %0
8645    mt%0 %1
8646    nop
8647    mftgpr %0,%1
8648    mffgpr %0,%1
8649    mfvsrd %0,%x1
8650    mtvsrd %x0,%1"
8651   [(set_attr "type"
8652                "store,      load,       *,         *,         *,         *,
8653                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8654                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8655                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8656                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8658    (set_attr "size" "64")
8659    (set_attr "length"
8660                "4,         4,         4,         4,         4,          20,
8661                 4,         4,         4,         4,         4,          4,
8662                 4,         4,         4,         4,         4,          8,
8663                 8,         4,         4,         4,         4,          4,
8664                 4,         4,         4,         4")])
8666 ; Some DImode loads are best done as a load of -1 followed by a mask
8667 ; instruction.
8668 (define_split
8669   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8670         (match_operand:DI 1 "const_int_operand"))]
8671   "TARGET_POWERPC64
8672    && num_insns_constant (operands[1], DImode) > 1
8673    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8674    && rs6000_is_valid_and_mask (operands[1], DImode)"
8675   [(set (match_dup 0)
8676         (const_int -1))
8677    (set (match_dup 0)
8678         (and:DI (match_dup 0)
8679                 (match_dup 1)))]
8680   "")
8682 ;; Split a load of a large constant into the appropriate five-instruction
8683 ;; sequence.  Handle anything in a constant number of insns.
8684 ;; When non-easy constants can go in the TOC, this should use
8685 ;; easy_fp_constant predicate.
8686 (define_split
8687   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8688         (match_operand:DI 1 "const_int_operand" ""))]
8689   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8690   [(set (match_dup 0) (match_dup 2))
8691    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8692   "
8694   if (rs6000_emit_set_const (operands[0], operands[1]))
8695     DONE;
8696   else
8697     FAIL;
8700 (define_split
8701   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8702         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8703   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8704   [(set (match_dup 0) (match_dup 2))
8705    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8706   "
8708   if (rs6000_emit_set_const (operands[0], operands[1]))
8709     DONE;
8710   else
8711     FAIL;
8714 (define_split
8715   [(set (match_operand:DI 0 "altivec_register_operand" "")
8716         (match_operand:DI 1 "s5bit_cint_operand" ""))]
8717   "TARGET_VSX && reload_completed"
8718   [(const_int 0)]
8720   rtx op0 = operands[0];
8721   rtx op1 = operands[1];
8722   int r = REGNO (op0);
8723   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8725   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8726   if (op1 != const0_rtx && op1 != constm1_rtx)
8727     {
8728       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8729       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8730     }
8731   DONE;
8734 ;; Split integer constants that can be loaded with XXSPLTIB and a
8735 ;; sign extend operation.
8736 (define_split
8737   [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8738         (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8739   "TARGET_P9_VECTOR && reload_completed"
8740   [(const_int 0)]
8742   rtx op0 = operands[0];
8743   rtx op1 = operands[1];
8744   int r = REGNO (op0);
8745   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8747   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8748   if (<MODE>mode == DImode)
8749     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8750   else if (<MODE>mode == SImode)
8751     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8752   else if (<MODE>mode == HImode)
8753     {
8754       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8755       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8756     }
8757   DONE;
8761 ;; TImode/PTImode is similar, except that we usually want to compute the
8762 ;; address into a register and use lsi/stsi (the exception is during reload).
8764 (define_insn "*mov<mode>_string"
8765   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8766         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8767   "! TARGET_POWERPC64
8768    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8769    && (gpc_reg_operand (operands[0], <MODE>mode)
8770        || gpc_reg_operand (operands[1], <MODE>mode))"
8771   "#"
8772   [(set_attr "type" "store,store,load,load,*,*")
8773    (set_attr "update" "yes")
8774    (set_attr "indexed" "yes")
8775    (set_attr "cell_micro" "conditional")])
8777 (define_insn "*mov<mode>_ppc64"
8778   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8779         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8780   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8781    && (gpc_reg_operand (operands[0], <MODE>mode)
8782        || gpc_reg_operand (operands[1], <MODE>mode)))"
8784   return rs6000_output_move_128bit (operands);
8786   [(set_attr "type" "store,store,load,load,*,*")
8787    (set_attr "length" "8")])
8789 (define_split
8790   [(set (match_operand:TI2 0 "int_reg_operand" "")
8791         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8792   "TARGET_POWERPC64
8793    && (VECTOR_MEM_NONE_P (<MODE>mode)
8794        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8795   [(set (match_dup 2) (match_dup 4))
8796    (set (match_dup 3) (match_dup 5))]
8797   "
8799   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8800                                        <MODE>mode);
8801   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8802                                        <MODE>mode);
8803   if (CONST_WIDE_INT_P (operands[1]))
8804     {
8805       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8806       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8807     }
8808   else if (CONST_INT_P (operands[1]))
8809     {
8810       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8811       operands[5] = operands[1];
8812     }
8813   else
8814     FAIL;
8817 (define_split
8818   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8819         (match_operand:TI2 1 "input_operand" ""))]
8820   "reload_completed
8821    && gpr_or_gpr_p (operands[0], operands[1])
8822    && !direct_move_p (operands[0], operands[1])
8823    && !quad_load_store_p (operands[0], operands[1])"
8824   [(pc)]
8825 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8827 (define_expand "setmemsi"
8828   [(parallel [(set (match_operand:BLK 0 "" "")
8829                    (match_operand 2 "const_int_operand" ""))
8830               (use (match_operand:SI 1 "" ""))
8831               (use (match_operand:SI 3 "" ""))])]
8832   ""
8833   "
8835   /* If value to set is not zero, use the library routine.  */
8836   if (operands[2] != const0_rtx)
8837     FAIL;
8839   if (expand_block_clear (operands))
8840     DONE;
8841   else
8842     FAIL;
8845 ;; String compare N insn.
8846 ;; Argument 0 is the target (result)
8847 ;; Argument 1 is the destination
8848 ;; Argument 2 is the source
8849 ;; Argument 3 is the length
8850 ;; Argument 4 is the alignment
8852 (define_expand "cmpstrnsi"
8853   [(parallel [(set (match_operand:SI 0)
8854                (compare:SI (match_operand:BLK 1)
8855                            (match_operand:BLK 2)))
8856               (use (match_operand:SI 3))
8857               (use (match_operand:SI 4))])]
8858   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8860   if (optimize_insn_for_size_p ())
8861     FAIL;
8863   if (expand_strn_compare (operands, 0))
8864     DONE;
8865   else  
8866     FAIL;
8869 ;; String compare insn.
8870 ;; Argument 0 is the target (result)
8871 ;; Argument 1 is the destination
8872 ;; Argument 2 is the source
8873 ;; Argument 3 is the alignment
8875 (define_expand "cmpstrsi"
8876   [(parallel [(set (match_operand:SI 0)
8877                (compare:SI (match_operand:BLK 1)
8878                            (match_operand:BLK 2)))
8879               (use (match_operand:SI 3))])]
8880   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8882   if (optimize_insn_for_size_p ())
8883     FAIL;
8885   if (expand_strn_compare (operands, 1))
8886     DONE;
8887   else  
8888     FAIL;
8891 ;; Block compare insn.
8892 ;; Argument 0 is the target (result)
8893 ;; Argument 1 is the destination
8894 ;; Argument 2 is the source
8895 ;; Argument 3 is the length
8896 ;; Argument 4 is the alignment
8898 (define_expand "cmpmemsi"
8899   [(parallel [(set (match_operand:SI 0)
8900                (compare:SI (match_operand:BLK 1)
8901                            (match_operand:BLK 2)))
8902               (use (match_operand:SI 3))
8903               (use (match_operand:SI 4))])]
8904   "TARGET_POPCNTD"
8906   if (expand_block_compare (operands))
8907     DONE;
8908   else
8909     FAIL;
8912 ;; String/block move insn.
8913 ;; Argument 0 is the destination
8914 ;; Argument 1 is the source
8915 ;; Argument 2 is the length
8916 ;; Argument 3 is the alignment
8918 (define_expand "movmemsi"
8919   [(parallel [(set (match_operand:BLK 0 "" "")
8920                    (match_operand:BLK 1 "" ""))
8921               (use (match_operand:SI 2 "" ""))
8922               (use (match_operand:SI 3 "" ""))])]
8923   ""
8924   "
8926   if (expand_block_move (operands))
8927     DONE;
8928   else
8929     FAIL;
8932 ;; Define insns that do load or store with update.  Some of these we can
8933 ;; get by using pre-decrement or pre-increment, but the hardware can also
8934 ;; do cases where the increment is not the size of the object.
8936 ;; In all these cases, we use operands 0 and 1 for the register being
8937 ;; incremented because those are the operands that local-alloc will
8938 ;; tie and these are the pair most likely to be tieable (and the ones
8939 ;; that will benefit the most).
8941 (define_insn "*movdi_update1"
8942   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8943         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8944                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8945    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8946         (plus:DI (match_dup 1) (match_dup 2)))]
8947   "TARGET_POWERPC64 && TARGET_UPDATE
8948    && (!avoiding_indexed_address_p (DImode)
8949        || !gpc_reg_operand (operands[2], DImode))"
8950   "@
8951    ldux %3,%0,%2
8952    ldu %3,%2(%0)"
8953   [(set_attr "type" "load")
8954    (set_attr "update" "yes")
8955    (set_attr "indexed" "yes,no")])
8957 (define_insn "movdi_<mode>_update"
8958   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8959                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8960         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8961    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8962         (plus:P (match_dup 1) (match_dup 2)))]
8963   "TARGET_POWERPC64 && TARGET_UPDATE
8964    && (!avoiding_indexed_address_p (Pmode)
8965        || !gpc_reg_operand (operands[2], Pmode)
8966        || (REG_P (operands[0])
8967            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8968   "@
8969    stdux %3,%0,%2
8970    stdu %3,%2(%0)"
8971   [(set_attr "type" "store")
8972    (set_attr "update" "yes")
8973    (set_attr "indexed" "yes,no")])
8975 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8976 ;; needed for stack allocation, even if the user passes -mno-update.
8977 (define_insn "movdi_<mode>_update_stack"
8978   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8979                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8980         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8981    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8982         (plus:P (match_dup 1) (match_dup 2)))]
8983   "TARGET_POWERPC64"
8984   "@
8985    stdux %3,%0,%2
8986    stdu %3,%2(%0)"
8987   [(set_attr "type" "store")
8988    (set_attr "update" "yes")
8989    (set_attr "indexed" "yes,no")])
8991 (define_insn "*movsi_update1"
8992   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8993         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8994                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8995    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8996         (plus:SI (match_dup 1) (match_dup 2)))]
8997   "TARGET_UPDATE
8998    && (!avoiding_indexed_address_p (SImode)
8999        || !gpc_reg_operand (operands[2], SImode))"
9000   "@
9001    lwzux %3,%0,%2
9002    lwzu %3,%2(%0)"
9003   [(set_attr "type" "load")
9004    (set_attr "update" "yes")
9005    (set_attr "indexed" "yes,no")])
9007 (define_insn "*movsi_update2"
9008   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9009         (sign_extend:DI
9010          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9011                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9012    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9013         (plus:DI (match_dup 1) (match_dup 2)))]
9014   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9015   "lwaux %3,%0,%2"
9016   [(set_attr "type" "load")
9017    (set_attr "sign_extend" "yes")
9018    (set_attr "update" "yes")
9019    (set_attr "indexed" "yes")])
9021 (define_insn "movsi_update"
9022   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9023                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9024         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9025    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9026         (plus:SI (match_dup 1) (match_dup 2)))]
9027   "TARGET_UPDATE
9028    && (!avoiding_indexed_address_p (SImode)
9029        || !gpc_reg_operand (operands[2], SImode)
9030        || (REG_P (operands[0])
9031            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9032   "@
9033    stwux %3,%0,%2
9034    stwu %3,%2(%0)"
9035   [(set_attr "type" "store")
9036    (set_attr "update" "yes")
9037    (set_attr "indexed" "yes,no")])
9039 ;; This is an unconditional pattern; needed for stack allocation, even
9040 ;; if the user passes -mno-update.
9041 (define_insn "movsi_update_stack"
9042   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9043                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9044         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9045    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9046         (plus:SI (match_dup 1) (match_dup 2)))]
9047   ""
9048   "@
9049    stwux %3,%0,%2
9050    stwu %3,%2(%0)"
9051   [(set_attr "type" "store")
9052    (set_attr "update" "yes")
9053    (set_attr "indexed" "yes,no")])
9055 (define_insn "*movhi_update1"
9056   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9057         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9058                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9059    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9060         (plus:SI (match_dup 1) (match_dup 2)))]
9061   "TARGET_UPDATE
9062    && (!avoiding_indexed_address_p (SImode)
9063        || !gpc_reg_operand (operands[2], SImode))"
9064   "@
9065    lhzux %3,%0,%2
9066    lhzu %3,%2(%0)"
9067   [(set_attr "type" "load")
9068    (set_attr "update" "yes")
9069    (set_attr "indexed" "yes,no")])
9071 (define_insn "*movhi_update2"
9072   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9073         (zero_extend:SI
9074          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9075                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9076    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9077         (plus:SI (match_dup 1) (match_dup 2)))]
9078   "TARGET_UPDATE
9079    && (!avoiding_indexed_address_p (SImode)
9080        || !gpc_reg_operand (operands[2], SImode))"
9081   "@
9082    lhzux %3,%0,%2
9083    lhzu %3,%2(%0)"
9084   [(set_attr "type" "load")
9085    (set_attr "update" "yes")
9086    (set_attr "indexed" "yes,no")])
9088 (define_insn "*movhi_update3"
9089   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9090         (sign_extend:SI
9091          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9092                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9093    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9094         (plus:SI (match_dup 1) (match_dup 2)))]
9095   "TARGET_UPDATE
9096    && !(avoiding_indexed_address_p (SImode)
9097         && gpc_reg_operand (operands[2], SImode))"
9098   "@
9099    lhaux %3,%0,%2
9100    lhau %3,%2(%0)"
9101   [(set_attr "type" "load")
9102    (set_attr "sign_extend" "yes")
9103    (set_attr "update" "yes")
9104    (set_attr "indexed" "yes,no")])
9106 (define_insn "*movhi_update4"
9107   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9108                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9109         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9110    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9111         (plus:SI (match_dup 1) (match_dup 2)))]
9112   "TARGET_UPDATE
9113    && (!avoiding_indexed_address_p (SImode)
9114        || !gpc_reg_operand (operands[2], SImode))"
9115   "@
9116    sthux %3,%0,%2
9117    sthu %3,%2(%0)"
9118   [(set_attr "type" "store")
9119    (set_attr "update" "yes")
9120    (set_attr "indexed" "yes,no")])
9122 (define_insn "*movqi_update1"
9123   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9124         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9125                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9126    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9127         (plus:SI (match_dup 1) (match_dup 2)))]
9128   "TARGET_UPDATE
9129    && (!avoiding_indexed_address_p (SImode)
9130        || !gpc_reg_operand (operands[2], SImode))"
9131   "@
9132    lbzux %3,%0,%2
9133    lbzu %3,%2(%0)"
9134   [(set_attr "type" "load")
9135    (set_attr "update" "yes")
9136    (set_attr "indexed" "yes,no")])
9138 (define_insn "*movqi_update2"
9139   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9140         (zero_extend:SI
9141          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9142                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9143    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9144         (plus:SI (match_dup 1) (match_dup 2)))]
9145   "TARGET_UPDATE
9146    && (!avoiding_indexed_address_p (SImode)
9147        || !gpc_reg_operand (operands[2], SImode))"
9148   "@
9149    lbzux %3,%0,%2
9150    lbzu %3,%2(%0)"
9151   [(set_attr "type" "load")
9152    (set_attr "update" "yes")
9153    (set_attr "indexed" "yes,no")])
9155 (define_insn "*movqi_update3"
9156   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9157                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9158         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9159    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9160         (plus:SI (match_dup 1) (match_dup 2)))]
9161   "TARGET_UPDATE
9162    && (!avoiding_indexed_address_p (SImode)
9163        || !gpc_reg_operand (operands[2], SImode))"
9164   "@
9165    stbux %3,%0,%2
9166    stbu %3,%2(%0)"
9167   [(set_attr "type" "store")
9168    (set_attr "update" "yes")
9169    (set_attr "indexed" "yes,no")])
9171 (define_insn "*movsf_update1"
9172   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9173         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9174                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9175    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9176         (plus:SI (match_dup 1) (match_dup 2)))]
9177   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9178    && (!avoiding_indexed_address_p (SImode)
9179        || !gpc_reg_operand (operands[2], SImode))"
9180   "@
9181    lfsux %3,%0,%2
9182    lfsu %3,%2(%0)"
9183   [(set_attr "type" "fpload")
9184    (set_attr "update" "yes")
9185    (set_attr "indexed" "yes,no")])
9187 (define_insn "*movsf_update2"
9188   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9189                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9190         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9191    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9192         (plus:SI (match_dup 1) (match_dup 2)))]
9193   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9194    && (!avoiding_indexed_address_p (SImode)
9195        || !gpc_reg_operand (operands[2], SImode))"
9196   "@
9197    stfsux %3,%0,%2
9198    stfsu %3,%2(%0)"
9199   [(set_attr "type" "fpstore")
9200    (set_attr "update" "yes")
9201    (set_attr "indexed" "yes,no")])
9203 (define_insn "*movsf_update3"
9204   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9205         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9206                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9207    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9208         (plus:SI (match_dup 1) (match_dup 2)))]
9209   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9210    && (!avoiding_indexed_address_p (SImode)
9211        || !gpc_reg_operand (operands[2], SImode))"
9212   "@
9213    lwzux %3,%0,%2
9214    lwzu %3,%2(%0)"
9215   [(set_attr "type" "load")
9216    (set_attr "update" "yes")
9217    (set_attr "indexed" "yes,no")])
9219 (define_insn "*movsf_update4"
9220   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9221                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9222         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9223    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9224         (plus:SI (match_dup 1) (match_dup 2)))]
9225   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9226    && (!avoiding_indexed_address_p (SImode)
9227        || !gpc_reg_operand (operands[2], SImode))"
9228   "@
9229    stwux %3,%0,%2
9230    stwu %3,%2(%0)"
9231   [(set_attr "type" "store")
9232    (set_attr "update" "yes")
9233    (set_attr "indexed" "yes,no")])
9235 (define_insn "*movdf_update1"
9236   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9237         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9238                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9239    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9240         (plus:SI (match_dup 1) (match_dup 2)))]
9241   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9242    && (!avoiding_indexed_address_p (SImode)
9243        || !gpc_reg_operand (operands[2], SImode))"
9244   "@
9245    lfdux %3,%0,%2
9246    lfdu %3,%2(%0)"
9247   [(set_attr "type" "fpload")
9248    (set_attr "update" "yes")
9249    (set_attr "indexed" "yes,no")
9250    (set_attr "size" "64")])
9252 (define_insn "*movdf_update2"
9253   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9254                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9255         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9256    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9257         (plus:SI (match_dup 1) (match_dup 2)))]
9258   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9259    && (!avoiding_indexed_address_p (SImode)
9260        || !gpc_reg_operand (operands[2], SImode))"
9261   "@
9262    stfdux %3,%0,%2
9263    stfdu %3,%2(%0)"
9264   [(set_attr "type" "fpstore")
9265    (set_attr "update" "yes")
9266    (set_attr "indexed" "yes,no")])
9269 ;; After inserting conditional returns we can sometimes have
9270 ;; unnecessary register moves.  Unfortunately we cannot have a
9271 ;; modeless peephole here, because some single SImode sets have early
9272 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9273 ;; sequences, using get_attr_length here will smash the operands
9274 ;; array.  Neither is there an early_cobbler_p predicate.
9275 ;; Also this optimization interferes with scalars going into
9276 ;; altivec registers (the code does reloading through the FPRs).
9277 (define_peephole2
9278   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9279         (match_operand:DF 1 "any_operand" ""))
9280    (set (match_operand:DF 2 "gpc_reg_operand" "")
9281         (match_dup 0))]
9282   "!TARGET_VSX
9283    && peep2_reg_dead_p (2, operands[0])"
9284   [(set (match_dup 2) (match_dup 1))])
9286 (define_peephole2
9287   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9288         (match_operand:SF 1 "any_operand" ""))
9289    (set (match_operand:SF 2 "gpc_reg_operand" "")
9290         (match_dup 0))]
9291   "!TARGET_P8_VECTOR
9292    && peep2_reg_dead_p (2, operands[0])"
9293   [(set (match_dup 2) (match_dup 1))])
9296 ;; TLS support.
9298 ;; Mode attributes for different ABIs.
9299 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9300 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9301 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9302 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9304 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9305   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9306         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9307               (match_operand 4 "" "g")))
9308    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9309                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9310                    UNSPEC_TLSGD)
9311    (clobber (reg:SI LR_REGNO))]
9312   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9314   if (TARGET_CMODEL != CMODEL_SMALL)
9315     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9316            "bl %z3\;nop";
9317   else
9318     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9320   "&& TARGET_TLS_MARKERS"
9321   [(set (match_dup 0)
9322         (unspec:TLSmode [(match_dup 1)
9323                          (match_dup 2)]
9324                         UNSPEC_TLSGD))
9325    (parallel [(set (match_dup 0)
9326                    (call (mem:TLSmode (match_dup 3))
9327                          (match_dup 4)))
9328               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9329               (clobber (reg:SI LR_REGNO))])]
9330   ""
9331   [(set_attr "type" "two")
9332    (set (attr "length")
9333      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9334                    (const_int 16)
9335                    (const_int 12)))])
9337 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9338   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9339         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9340               (match_operand 4 "" "g")))
9341    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9342                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9343                    UNSPEC_TLSGD)
9344    (clobber (reg:SI LR_REGNO))]
9345   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9347   if (flag_pic)
9348     {
9349       if (TARGET_SECURE_PLT && flag_pic == 2)
9350         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9351       else
9352         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9353     }
9354   else
9355     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9357   "&& TARGET_TLS_MARKERS"
9358   [(set (match_dup 0)
9359         (unspec:TLSmode [(match_dup 1)
9360                          (match_dup 2)]
9361                         UNSPEC_TLSGD))
9362    (parallel [(set (match_dup 0)
9363                    (call (mem:TLSmode (match_dup 3))
9364                          (match_dup 4)))
9365               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9366               (clobber (reg:SI LR_REGNO))])]
9367   ""
9368   [(set_attr "type" "two")
9369    (set_attr "length" "8")])
9371 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9372   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9373         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9374                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9375                         UNSPEC_TLSGD))]
9376   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9377   "addi %0,%1,%2@got@tlsgd"
9378   "&& TARGET_CMODEL != CMODEL_SMALL"
9379   [(set (match_dup 3)
9380         (high:TLSmode
9381             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9382    (set (match_dup 0)
9383         (lo_sum:TLSmode (match_dup 3)
9384             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9385   "
9387   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9389   [(set (attr "length")
9390      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9391                    (const_int 8)
9392                    (const_int 4)))])
9394 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9395   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9396      (high:TLSmode
9397        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9398                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9399                        UNSPEC_TLSGD)))]
9400   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9401   "addis %0,%1,%2@got@tlsgd@ha"
9402   [(set_attr "length" "4")])
9404 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9405   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9406      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9407        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9408                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9409                        UNSPEC_TLSGD)))]
9410   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9411   "addi %0,%1,%2@got@tlsgd@l"
9412   [(set_attr "length" "4")])
9414 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9415   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9416         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9417               (match_operand 2 "" "g")))
9418    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9419                    UNSPEC_TLSGD)
9420    (clobber (reg:SI LR_REGNO))]
9421   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9422    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9423   "bl %z1(%3@tlsgd)\;nop"
9424   [(set_attr "type" "branch")
9425    (set_attr "length" "8")])
9427 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9428   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9429         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9430               (match_operand 2 "" "g")))
9431    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9432                    UNSPEC_TLSGD)
9433    (clobber (reg:SI LR_REGNO))]
9434   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9436   if (flag_pic)
9437     {
9438       if (TARGET_SECURE_PLT && flag_pic == 2)
9439         return "bl %z1+32768(%3@tlsgd)@plt";
9440       return "bl %z1(%3@tlsgd)@plt";
9441     }
9442   return "bl %z1(%3@tlsgd)";
9444   [(set_attr "type" "branch")
9445    (set_attr "length" "4")])
9447 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9448   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9449         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9450               (match_operand 3 "" "g")))
9451    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9452                    UNSPEC_TLSLD)
9453    (clobber (reg:SI LR_REGNO))]
9454   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9456   if (TARGET_CMODEL != CMODEL_SMALL)
9457     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9458            "bl %z2\;nop";
9459   else
9460     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9462   "&& TARGET_TLS_MARKERS"
9463   [(set (match_dup 0)
9464         (unspec:TLSmode [(match_dup 1)]
9465                         UNSPEC_TLSLD))
9466    (parallel [(set (match_dup 0)
9467                    (call (mem:TLSmode (match_dup 2))
9468                          (match_dup 3)))
9469               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9470               (clobber (reg:SI LR_REGNO))])]
9471   ""
9472   [(set_attr "type" "two")
9473    (set (attr "length")
9474      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9475                    (const_int 16)
9476                    (const_int 12)))])
9478 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9479   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9480         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9481               (match_operand 3 "" "g")))
9482    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9483                    UNSPEC_TLSLD)
9484    (clobber (reg:SI LR_REGNO))]
9485   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9487   if (flag_pic)
9488     {
9489       if (TARGET_SECURE_PLT && flag_pic == 2)
9490         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9491       else
9492         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9493     }
9494   else
9495     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9497   "&& TARGET_TLS_MARKERS"
9498   [(set (match_dup 0)
9499         (unspec:TLSmode [(match_dup 1)]
9500                         UNSPEC_TLSLD))
9501    (parallel [(set (match_dup 0)
9502                    (call (mem:TLSmode (match_dup 2))
9503                          (match_dup 3)))
9504               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9505               (clobber (reg:SI LR_REGNO))])]
9506   ""
9507   [(set_attr "length" "8")])
9509 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9510   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9511         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9512                         UNSPEC_TLSLD))]
9513   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9514   "addi %0,%1,%&@got@tlsld"
9515   "&& TARGET_CMODEL != CMODEL_SMALL"
9516   [(set (match_dup 2)
9517         (high:TLSmode
9518             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9519    (set (match_dup 0)
9520         (lo_sum:TLSmode (match_dup 2)
9521             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9522   "
9524   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9526   [(set (attr "length")
9527      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9528                    (const_int 8)
9529                    (const_int 4)))])
9531 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9532   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9533      (high:TLSmode
9534        (unspec:TLSmode [(const_int 0)
9535                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9536                        UNSPEC_TLSLD)))]
9537   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9538   "addis %0,%1,%&@got@tlsld@ha"
9539   [(set_attr "length" "4")])
9541 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9542   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9543      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9544        (unspec:TLSmode [(const_int 0)
9545                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9546                        UNSPEC_TLSLD)))]
9547   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9548   "addi %0,%1,%&@got@tlsld@l"
9549   [(set_attr "length" "4")])
9551 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9552   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9553         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9554               (match_operand 2 "" "g")))
9555    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9556    (clobber (reg:SI LR_REGNO))]
9557   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9558    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9559   "bl %z1(%&@tlsld)\;nop"
9560   [(set_attr "type" "branch")
9561    (set_attr "length" "8")])
9563 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9564   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9565         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9566               (match_operand 2 "" "g")))
9567    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9568    (clobber (reg:SI LR_REGNO))]
9569   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9571   if (flag_pic)
9572     {
9573       if (TARGET_SECURE_PLT && flag_pic == 2)
9574         return "bl %z1+32768(%&@tlsld)@plt";
9575       return "bl %z1(%&@tlsld)@plt";
9576     }
9577   return "bl %z1(%&@tlsld)";
9579   [(set_attr "type" "branch")
9580    (set_attr "length" "4")])
9582 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9583   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9584         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9585                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9586                         UNSPEC_TLSDTPREL))]
9587   "HAVE_AS_TLS"
9588   "addi %0,%1,%2@dtprel")
9590 (define_insn "tls_dtprel_ha_<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_TLSDTPRELHA))]
9595   "HAVE_AS_TLS"
9596   "addis %0,%1,%2@dtprel@ha")
9598 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9599   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9600         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9601                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9602                         UNSPEC_TLSDTPRELLO))]
9603   "HAVE_AS_TLS"
9604   "addi %0,%1,%2@dtprel@l")
9606 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9607   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9608         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9609                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9610                         UNSPEC_TLSGOTDTPREL))]
9611   "HAVE_AS_TLS"
9612   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9613   "&& TARGET_CMODEL != CMODEL_SMALL"
9614   [(set (match_dup 3)
9615         (high:TLSmode
9616             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9617    (set (match_dup 0)
9618         (lo_sum:TLSmode (match_dup 3)
9619             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9620   "
9622   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9624   [(set (attr "length")
9625      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9626                    (const_int 8)
9627                    (const_int 4)))])
9629 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9630   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9631      (high:TLSmode
9632        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9633                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9634                        UNSPEC_TLSGOTDTPREL)))]
9635   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9636   "addis %0,%1,%2@got@dtprel@ha"
9637   [(set_attr "length" "4")])
9639 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9640   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9641      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9642          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9643                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9644                          UNSPEC_TLSGOTDTPREL)))]
9645   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9646   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9647   [(set_attr "length" "4")])
9649 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9650   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9651         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9652                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9653                         UNSPEC_TLSTPREL))]
9654   "HAVE_AS_TLS"
9655   "addi %0,%1,%2@tprel")
9657 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9658   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9659         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9660                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9661                         UNSPEC_TLSTPRELHA))]
9662   "HAVE_AS_TLS"
9663   "addis %0,%1,%2@tprel@ha")
9665 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9666   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9667         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9668                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9669                         UNSPEC_TLSTPRELLO))]
9670   "HAVE_AS_TLS"
9671   "addi %0,%1,%2@tprel@l")
9673 ;; "b" output constraint here and on tls_tls input to support linker tls
9674 ;; optimization.  The linker may edit the instructions emitted by a
9675 ;; tls_got_tprel/tls_tls pair to addis,addi.
9676 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9677   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9678         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9679                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9680                         UNSPEC_TLSGOTTPREL))]
9681   "HAVE_AS_TLS"
9682   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9683   "&& TARGET_CMODEL != CMODEL_SMALL"
9684   [(set (match_dup 3)
9685         (high:TLSmode
9686             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9687    (set (match_dup 0)
9688         (lo_sum:TLSmode (match_dup 3)
9689             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9690   "
9692   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9694   [(set (attr "length")
9695      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9696                    (const_int 8)
9697                    (const_int 4)))])
9699 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9700   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9701      (high:TLSmode
9702        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9703                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9704                        UNSPEC_TLSGOTTPREL)))]
9705   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9706   "addis %0,%1,%2@got@tprel@ha"
9707   [(set_attr "length" "4")])
9709 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9710   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9711      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9712          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9713                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9714                          UNSPEC_TLSGOTTPREL)))]
9715   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9716   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9717   [(set_attr "length" "4")])
9719 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9720   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9721         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9722                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9723                         UNSPEC_TLSTLS))]
9724   "TARGET_ELF && HAVE_AS_TLS"
9725   "add %0,%1,%2@tls")
9727 (define_expand "tls_get_tpointer"
9728   [(set (match_operand:SI 0 "gpc_reg_operand" "")
9729         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9730   "TARGET_XCOFF && HAVE_AS_TLS"
9731   "
9733   emit_insn (gen_tls_get_tpointer_internal ());
9734   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9735   DONE;
9738 (define_insn "tls_get_tpointer_internal"
9739   [(set (reg:SI 3)
9740         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9741    (clobber (reg:SI LR_REGNO))]
9742   "TARGET_XCOFF && HAVE_AS_TLS"
9743   "bla __get_tpointer")
9745 (define_expand "tls_get_addr<mode>"
9746   [(set (match_operand:P 0 "gpc_reg_operand" "")
9747         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9748                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9749   "TARGET_XCOFF && HAVE_AS_TLS"
9750   "
9752   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9753   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9754   emit_insn (gen_tls_get_addr_internal<mode> ());
9755   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9756   DONE;
9759 (define_insn "tls_get_addr_internal<mode>"
9760   [(set (reg:P 3)
9761         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9762    (clobber (reg:P 0))
9763    (clobber (reg:P 4))
9764    (clobber (reg:P 5))
9765    (clobber (reg:P 11))
9766    (clobber (reg:CC CR0_REGNO))
9767    (clobber (reg:P LR_REGNO))]
9768   "TARGET_XCOFF && HAVE_AS_TLS"
9769   "bla __tls_get_addr")
9771 ;; Next come insns related to the calling sequence.
9773 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9774 ;; We move the back-chain and decrement the stack pointer.
9776 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9777 ;; constant alloca, using that predicate will force the generic code to put
9778 ;; the constant size into a register before calling the expander.
9780 ;; As a result the expander would not have the constant size information
9781 ;; in those cases and would have to generate less efficient code.
9783 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9784 ;; the constant size.  The value is forced into a register if necessary.
9786 (define_expand "allocate_stack"
9787   [(set (match_operand 0 "gpc_reg_operand" "")
9788         (minus (reg 1) (match_operand 1 "reg_or_cint_operand" "")))
9789    (set (reg 1)
9790         (minus (reg 1) (match_dup 1)))]
9791   ""
9792   "
9793 { rtx chain = gen_reg_rtx (Pmode);
9794   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9795   rtx neg_op0;
9796   rtx insn, par, set, mem;
9798   /* By allowing reg_or_cint_operand as the predicate we can get
9799      better code for stack-clash-protection because we do not lose
9800      size information.  But the rest of the code expects the operand
9801      to be reg_or_short_operand.  If it isn't, then force it into
9802      a register.  */
9803   rtx orig_op1 = operands[1];
9804   if (!reg_or_short_operand (operands[1], Pmode))
9805     operands[1] = force_reg (Pmode, operands[1]);
9807   emit_move_insn (chain, stack_bot);
9809   /* Check stack bounds if necessary.  */
9810   if (crtl->limit_stack)
9811     {
9812       rtx available;
9813       available = expand_binop (Pmode, sub_optab,
9814                                 stack_pointer_rtx, stack_limit_rtx,
9815                                 NULL_RTX, 1, OPTAB_WIDEN);
9816       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9817     }
9819   /* Allocate and probe if requested.
9820      This may look similar to the loop we use for prologue allocations,
9821      but it is critically different.  For the former we know the loop
9822      will iterate, but do not know that generally here.  The former
9823      uses that knowledge to rotate the loop.  Combining them would be
9824      possible with some performance cost.  */
9825   if (flag_stack_clash_protection)
9826     {
9827       rtx rounded_size, last_addr, residual;
9828       HOST_WIDE_INT probe_interval;
9829       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9830                                                 &residual, &probe_interval,
9831                                                 orig_op1);
9832       
9833       /* We do occasionally get in here with constant sizes, we might
9834          as well do a reasonable job when we obviously can.  */
9835       if (rounded_size != const0_rtx)
9836         {
9837           rtx loop_lab, end_loop;
9838           bool rotated = CONST_INT_P (rounded_size);
9839           rtx update = GEN_INT (-probe_interval);
9840           if (probe_interval > 32768)
9841             update = force_reg (Pmode, update);
9843           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9844                                                         last_addr, rotated);
9846           if (Pmode == SImode)
9847             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9848                                                stack_pointer_rtx,
9849                                                update, chain));
9850           else
9851             emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9852                                                   stack_pointer_rtx,
9853                                                   update, chain));
9854           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9855                                                       last_addr, rotated);
9856         }
9858       /* Now handle residuals.  We just have to set operands[1] correctly
9859          and let the rest of the expander run.  */
9860       operands[1] = residual;
9861       if (!CONST_INT_P (residual))
9862         operands[1] = force_reg (Pmode, operands[1]);
9863     }
9865   if (GET_CODE (operands[1]) != CONST_INT
9866       || INTVAL (operands[1]) < -32767
9867       || INTVAL (operands[1]) > 32768)
9868     {
9869       neg_op0 = gen_reg_rtx (Pmode);
9870       if (TARGET_32BIT)
9871         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9872       else
9873         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9874     }
9875   else
9876     neg_op0 = GEN_INT (- INTVAL (operands[1]));
9878   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9879                                        : gen_movdi_di_update_stack))
9880                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9881                          chain));
9882   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9883      it now and set the alias set/attributes. The above gen_*_update
9884      calls will generate a PARALLEL with the MEM set being the first
9885      operation. */
9886   par = PATTERN (insn);
9887   gcc_assert (GET_CODE (par) == PARALLEL);
9888   set = XVECEXP (par, 0, 0);
9889   gcc_assert (GET_CODE (set) == SET);
9890   mem = SET_DEST (set);
9891   gcc_assert (MEM_P (mem));
9892   MEM_NOTRAP_P (mem) = 1;
9893   set_mem_alias_set (mem, get_frame_alias_set ());
9895   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9896   DONE;
9899 ;; These patterns say how to save and restore the stack pointer.  We need not
9900 ;; save the stack pointer at function level since we are careful to
9901 ;; preserve the backchain.  At block level, we have to restore the backchain
9902 ;; when we restore the stack pointer.
9904 ;; For nonlocal gotos, we must save both the stack pointer and its
9905 ;; backchain and restore both.  Note that in the nonlocal case, the
9906 ;; save area is a memory location.
9908 (define_expand "save_stack_function"
9909   [(match_operand 0 "any_operand" "")
9910    (match_operand 1 "any_operand" "")]
9911   ""
9912   "DONE;")
9914 (define_expand "restore_stack_function"
9915   [(match_operand 0 "any_operand" "")
9916    (match_operand 1 "any_operand" "")]
9917   ""
9918   "DONE;")
9920 ;; Adjust stack pointer (op0) to a new value (op1).
9921 ;; First copy old stack backchain to new location, and ensure that the
9922 ;; scheduler won't reorder the sp assignment before the backchain write.
9923 (define_expand "restore_stack_block"
9924   [(set (match_dup 2) (match_dup 3))
9925    (set (match_dup 4) (match_dup 2))
9926    (match_dup 5)
9927    (set (match_operand 0 "register_operand" "")
9928         (match_operand 1 "register_operand" ""))]
9929   ""
9930   "
9932   rtvec p;
9934   operands[1] = force_reg (Pmode, operands[1]);
9935   operands[2] = gen_reg_rtx (Pmode);
9936   operands[3] = gen_frame_mem (Pmode, operands[0]);
9937   operands[4] = gen_frame_mem (Pmode, operands[1]);
9938   p = rtvec_alloc (1);
9939   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9940                                   const0_rtx);
9941   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9944 (define_expand "save_stack_nonlocal"
9945   [(set (match_dup 3) (match_dup 4))
9946    (set (match_operand 0 "memory_operand" "") (match_dup 3))
9947    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9948   ""
9949   "
9951   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9953   /* Copy the backchain to the first word, sp to the second.  */
9954   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9955   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9956   operands[3] = gen_reg_rtx (Pmode);
9957   operands[4] = gen_frame_mem (Pmode, operands[1]);
9960 (define_expand "restore_stack_nonlocal"
9961   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9962    (set (match_dup 3) (match_dup 4))
9963    (set (match_dup 5) (match_dup 2))
9964    (match_dup 6)
9965    (set (match_operand 0 "register_operand" "") (match_dup 3))]
9966   ""
9967   "
9969   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9970   rtvec p;
9972   /* Restore the backchain from the first word, sp from the second.  */
9973   operands[2] = gen_reg_rtx (Pmode);
9974   operands[3] = gen_reg_rtx (Pmode);
9975   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9976   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9977   operands[5] = gen_frame_mem (Pmode, operands[3]);
9978   p = rtvec_alloc (1);
9979   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9980                                   const0_rtx);
9981   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9984 ;; TOC register handling.
9986 ;; Code to initialize the TOC register...
9988 (define_insn "load_toc_aix_si"
9989   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9990                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9991               (use (reg:SI 2))])]
9992   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9993   "*
9995   char buf[30];
9996   extern int need_toc_init;
9997   need_toc_init = 1;
9998   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9999   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10000   operands[2] = gen_rtx_REG (Pmode, 2);
10001   return \"lwz %0,%1(%2)\";
10003   [(set_attr "type" "load")
10004    (set_attr "update" "no")
10005    (set_attr "indexed" "no")])
10007 (define_insn "load_toc_aix_di"
10008   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10009                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10010               (use (reg:DI 2))])]
10011   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10012   "*
10014   char buf[30];
10015   extern int need_toc_init;
10016   need_toc_init = 1;
10017   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10018                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10019   if (TARGET_ELF)
10020     strcat (buf, \"@toc\");
10021   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10022   operands[2] = gen_rtx_REG (Pmode, 2);
10023   return \"ld %0,%1(%2)\";
10025   [(set_attr "type" "load")
10026    (set_attr "update" "no")
10027    (set_attr "indexed" "no")])
10029 (define_insn "load_toc_v4_pic_si"
10030   [(set (reg:SI LR_REGNO)
10031         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10032   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10033   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10034   [(set_attr "type" "branch")
10035    (set_attr "length" "4")])
10037 (define_expand "load_toc_v4_PIC_1"
10038   [(parallel [(set (reg:SI LR_REGNO)
10039                    (match_operand:SI 0 "immediate_operand" "s"))
10040               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10041   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10042    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10043   "")
10045 (define_insn "load_toc_v4_PIC_1_normal"
10046   [(set (reg:SI LR_REGNO)
10047         (match_operand:SI 0 "immediate_operand" "s"))
10048    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10049   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10050    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10051   "bcl 20,31,%0\\n%0:"
10052   [(set_attr "type" "branch")
10053    (set_attr "length" "4")
10054    (set_attr "cannot_copy" "yes")])
10056 (define_insn "load_toc_v4_PIC_1_476"
10057   [(set (reg:SI LR_REGNO)
10058         (match_operand:SI 0 "immediate_operand" "s"))
10059    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10060   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10061    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10062   "*
10064   char name[32];
10065   static char templ[32];
10067   get_ppc476_thunk_name (name);
10068   sprintf (templ, \"bl %s\\n%%0:\", name);
10069   return templ;
10071   [(set_attr "type" "branch")
10072    (set_attr "length" "4")
10073    (set_attr "cannot_copy" "yes")])
10075 (define_expand "load_toc_v4_PIC_1b"
10076   [(parallel [(set (reg:SI LR_REGNO)
10077                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10078                                (label_ref (match_operand 1 "" ""))]
10079                            UNSPEC_TOCPTR))
10080               (match_dup 1)])]
10081   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10082   "")
10084 (define_insn "load_toc_v4_PIC_1b_normal"
10085   [(set (reg:SI LR_REGNO)
10086         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10087                     (label_ref (match_operand 1 "" ""))]
10088                 UNSPEC_TOCPTR))
10089    (match_dup 1)]
10090   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10091   "bcl 20,31,$+8\;.long %0-$"
10092   [(set_attr "type" "branch")
10093    (set_attr "length" "8")])
10095 (define_insn "load_toc_v4_PIC_1b_476"
10096   [(set (reg:SI LR_REGNO)
10097         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10098                     (label_ref (match_operand 1 "" ""))]
10099                 UNSPEC_TOCPTR))
10100    (match_dup 1)]
10101   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10102   "*
10104   char name[32];
10105   static char templ[32];
10107   get_ppc476_thunk_name (name);
10108   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10109   return templ;
10111   [(set_attr "type" "branch")
10112    (set_attr "length" "16")])
10114 (define_insn "load_toc_v4_PIC_2"
10115   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10116         (mem:SI (plus:SI
10117                   (match_operand:SI 1 "gpc_reg_operand" "b")
10118                   (const
10119                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10120                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10121   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10122   "lwz %0,%2-%3(%1)"
10123   [(set_attr "type" "load")])
10125 (define_insn "load_toc_v4_PIC_3b"
10126   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10127         (plus:SI
10128           (match_operand:SI 1 "gpc_reg_operand" "b")
10129           (high:SI
10130             (const
10131               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10132                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10133   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10134   "addis %0,%1,%2-%3@ha")
10136 (define_insn "load_toc_v4_PIC_3c"
10137   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10138         (lo_sum:SI
10139           (match_operand:SI 1 "gpc_reg_operand" "b")
10140           (const
10141             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10142                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10143   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10144   "addi %0,%1,%2-%3@l")
10146 ;; If the TOC is shared over a translation unit, as happens with all
10147 ;; the kinds of PIC that we support, we need to restore the TOC
10148 ;; pointer only when jumping over units of translation.
10149 ;; On Darwin, we need to reload the picbase.
10151 (define_expand "builtin_setjmp_receiver"
10152   [(use (label_ref (match_operand 0 "" "")))]
10153   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10154    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10155    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10156   "
10158 #if TARGET_MACHO
10159   if (DEFAULT_ABI == ABI_DARWIN)
10160     {
10161       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10162       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10163       rtx tmplabrtx;
10164       char tmplab[20];
10166       crtl->uses_pic_offset_table = 1;
10167       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10168                                   CODE_LABEL_NUMBER (operands[0]));
10169       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10171       emit_insn (gen_load_macho_picbase (tmplabrtx));
10172       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10173       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10174     }
10175   else
10176 #endif
10177     rs6000_emit_load_toc_table (FALSE);
10178   DONE;
10181 ;; Largetoc support
10182 (define_insn "*largetoc_high"
10183   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10184         (high:DI
10185           (unspec [(match_operand:DI 1 "" "")
10186                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10187                   UNSPEC_TOCREL)))]
10188    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10189    "addis %0,%2,%1@toc@ha")
10191 (define_insn "*largetoc_high_aix<mode>"
10192   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10193         (high:P
10194           (unspec [(match_operand:P 1 "" "")
10195                    (match_operand:P 2 "gpc_reg_operand" "b")]
10196                   UNSPEC_TOCREL)))]
10197    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10198    "addis %0,%1@u(%2)")
10200 (define_insn "*largetoc_high_plus"
10201   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10202         (high:DI
10203           (plus:DI
10204             (unspec [(match_operand:DI 1 "" "")
10205                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10206                     UNSPEC_TOCREL)
10207             (match_operand:DI 3 "add_cint_operand" "n"))))]
10208    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10209    "addis %0,%2,%1+%3@toc@ha")
10211 (define_insn "*largetoc_high_plus_aix<mode>"
10212   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10213         (high:P
10214           (plus:P
10215             (unspec [(match_operand:P 1 "" "")
10216                      (match_operand:P 2 "gpc_reg_operand" "b")]
10217                     UNSPEC_TOCREL)
10218             (match_operand:P 3 "add_cint_operand" "n"))))]
10219    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10220    "addis %0,%1+%3@u(%2)")
10222 (define_insn "*largetoc_low"
10223   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10224         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10225                    (match_operand:DI 2 "" "")))]
10226    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10227    "addi %0,%1,%2@l")
10229 (define_insn "*largetoc_low_aix<mode>"
10230   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10231         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10232                    (match_operand:P 2 "" "")))]
10233    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10234    "la %0,%2@l(%1)")
10236 (define_insn_and_split "*tocref<mode>"
10237   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10238         (match_operand:P 1 "small_toc_ref" "R"))]
10239    "TARGET_TOC"
10240    "la %0,%a1"
10241    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10242   [(set (match_dup 0) (high:P (match_dup 1)))
10243    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10245 ;; Elf specific ways of loading addresses for non-PIC code.
10246 ;; The output of this could be r0, but we make a very strong
10247 ;; preference for a base register because it will usually
10248 ;; be needed there.
10249 (define_insn "elf_high"
10250   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10251         (high:SI (match_operand 1 "" "")))]
10252   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10253   "lis %0,%1@ha")
10255 (define_insn "elf_low"
10256   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10257         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10258                    (match_operand 2 "" "")))]
10259    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10260    "la %0,%2@l(%1)")
10262 ;; Call and call_value insns
10263 (define_expand "call"
10264   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10265                     (match_operand 1 "" ""))
10266               (use (match_operand 2 "" ""))
10267               (clobber (reg:SI LR_REGNO))])]
10268   ""
10269   "
10271 #if TARGET_MACHO
10272   if (MACHOPIC_INDIRECT)
10273     operands[0] = machopic_indirect_call_target (operands[0]);
10274 #endif
10276   gcc_assert (GET_CODE (operands[0]) == MEM);
10277   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10279   operands[0] = XEXP (operands[0], 0);
10281   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10282     {
10283       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10284       DONE;
10285     }
10287   if (GET_CODE (operands[0]) != SYMBOL_REF
10288       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10289     {
10290       if (INTVAL (operands[2]) & CALL_LONG)
10291         operands[0] = rs6000_longcall_ref (operands[0]);
10293       switch (DEFAULT_ABI)
10294         {
10295         case ABI_V4:
10296         case ABI_DARWIN:
10297           operands[0] = force_reg (Pmode, operands[0]);
10298           break;
10300         default:
10301           gcc_unreachable ();
10302         }
10303     }
10306 (define_expand "call_value"
10307   [(parallel [(set (match_operand 0 "" "")
10308                    (call (mem:SI (match_operand 1 "address_operand" ""))
10309                          (match_operand 2 "" "")))
10310               (use (match_operand 3 "" ""))
10311               (clobber (reg:SI LR_REGNO))])]
10312   ""
10313   "
10315 #if TARGET_MACHO
10316   if (MACHOPIC_INDIRECT)
10317     operands[1] = machopic_indirect_call_target (operands[1]);
10318 #endif
10320   gcc_assert (GET_CODE (operands[1]) == MEM);
10321   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10323   operands[1] = XEXP (operands[1], 0);
10325   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10326     {
10327       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10328       DONE;
10329     }
10331   if (GET_CODE (operands[1]) != SYMBOL_REF
10332       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10333     {
10334       if (INTVAL (operands[3]) & CALL_LONG)
10335         operands[1] = rs6000_longcall_ref (operands[1]);
10337       switch (DEFAULT_ABI)
10338         {
10339         case ABI_V4:
10340         case ABI_DARWIN:
10341           operands[1] = force_reg (Pmode, operands[1]);
10342           break;
10344         default:
10345           gcc_unreachable ();
10346         }
10347     }
10350 ;; Call to function in current module.  No TOC pointer reload needed.
10351 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10352 ;; either the function was not prototyped, or it was prototyped as a
10353 ;; variable argument function.  It is > 0 if FP registers were passed
10354 ;; and < 0 if they were not.
10356 (define_insn "*call_local32"
10357   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10358          (match_operand 1 "" "g,g"))
10359    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10360    (clobber (reg:SI LR_REGNO))]
10361   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10362   "*
10364   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10365     output_asm_insn (\"crxor 6,6,6\", operands);
10367   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10368     output_asm_insn (\"creqv 6,6,6\", operands);
10370   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10372   [(set_attr "type" "branch")
10373    (set_attr "length" "4,8")])
10375 (define_insn "*call_local64"
10376   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10377          (match_operand 1 "" "g,g"))
10378    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10379    (clobber (reg:SI LR_REGNO))]
10380   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10381   "*
10383   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10384     output_asm_insn (\"crxor 6,6,6\", operands);
10386   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10387     output_asm_insn (\"creqv 6,6,6\", operands);
10389   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10391   [(set_attr "type" "branch")
10392    (set_attr "length" "4,8")])
10394 (define_insn "*call_value_local32"
10395   [(set (match_operand 0 "" "")
10396         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10397               (match_operand 2 "" "g,g")))
10398    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10399    (clobber (reg:SI LR_REGNO))]
10400   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10401   "*
10403   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10404     output_asm_insn (\"crxor 6,6,6\", operands);
10406   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10407     output_asm_insn (\"creqv 6,6,6\", operands);
10409   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10411   [(set_attr "type" "branch")
10412    (set_attr "length" "4,8")])
10415 (define_insn "*call_value_local64"
10416   [(set (match_operand 0 "" "")
10417         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10418               (match_operand 2 "" "g,g")))
10419    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10420    (clobber (reg:SI LR_REGNO))]
10421   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10422   "*
10424   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10425     output_asm_insn (\"crxor 6,6,6\", operands);
10427   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10428     output_asm_insn (\"creqv 6,6,6\", operands);
10430   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10432   [(set_attr "type" "branch")
10433    (set_attr "length" "4,8")])
10436 ;; A function pointer under System V is just a normal pointer
10437 ;; operands[0] is the function pointer
10438 ;; operands[1] is the stack size to clean up
10439 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10440 ;; which indicates how to set cr1
10442 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10443   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10444          (match_operand 1 "" "g,g,g,g"))
10445    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10446    (clobber (reg:SI LR_REGNO))]
10447   "DEFAULT_ABI == ABI_V4
10448    || DEFAULT_ABI == ABI_DARWIN"
10450   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10451     output_asm_insn ("crxor 6,6,6", operands);
10453   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10454     output_asm_insn ("creqv 6,6,6", operands);
10456   if (rs6000_speculate_indirect_jumps
10457       || which_alternative == 1 || which_alternative == 3)
10458     return "b%T0l";
10459   else
10460     return "crset 2\;beq%T0l-";
10462   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10463    (set (attr "length")
10464         (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10465                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10466                         (const_int 1)))
10467                   (const_string "4")
10468                (and (eq (symbol_ref "which_alternative") (const_int 0))
10469                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10470                         (const_int 0)))
10471                   (const_string "8")
10472                (eq (symbol_ref "which_alternative") (const_int 1))
10473                   (const_string "4")
10474                (and (eq (symbol_ref "which_alternative") (const_int 2))
10475                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10476                         (const_int 1)))
10477                   (const_string "8")
10478                (and (eq (symbol_ref "which_alternative") (const_int 2))
10479                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10480                         (const_int 0)))
10481                   (const_string "12")
10482                (eq (symbol_ref "which_alternative") (const_int 3))
10483                   (const_string "8")]
10484               (const_string "4")))])
10486 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10487   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10488          (match_operand 1 "" "g,g"))
10489    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10490    (clobber (reg:SI LR_REGNO))]
10491   "(DEFAULT_ABI == ABI_DARWIN
10492    || (DEFAULT_ABI == ABI_V4
10493        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10495   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10496     output_asm_insn ("crxor 6,6,6", operands);
10498   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10499     output_asm_insn ("creqv 6,6,6", operands);
10501 #if TARGET_MACHO
10502   return output_call(insn, operands, 0, 2);
10503 #else
10504   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10505     {
10506       gcc_assert (!TARGET_SECURE_PLT);
10507       return "bl %z0@plt";
10508     }
10509   else
10510     return "bl %z0";
10511 #endif
10513   "DEFAULT_ABI == ABI_V4
10514    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10515    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10516   [(parallel [(call (mem:SI (match_dup 0))
10517                     (match_dup 1))
10518               (use (match_dup 2))
10519               (use (match_dup 3))
10520               (clobber (reg:SI LR_REGNO))])]
10522   operands[3] = pic_offset_table_rtx;
10524   [(set_attr "type" "branch,branch")
10525    (set_attr "length" "4,8")])
10527 (define_insn "*call_nonlocal_sysv_secure<mode>"
10528   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10529          (match_operand 1 "" "g,g"))
10530    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10531    (use (match_operand:SI 3 "register_operand" "r,r"))
10532    (clobber (reg:SI LR_REGNO))]
10533   "(DEFAULT_ABI == ABI_V4
10534     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10535     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10537   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10538     output_asm_insn ("crxor 6,6,6", operands);
10540   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10541     output_asm_insn ("creqv 6,6,6", operands);
10543   if (flag_pic == 2)
10544     /* The magic 32768 offset here and in the other sysv call insns
10545        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10546        See sysv4.h:toc_section.  */
10547     return "bl %z0+32768@plt";
10548   else
10549     return "bl %z0@plt";
10551   [(set_attr "type" "branch,branch")
10552    (set_attr "length" "4,8")])
10554 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10555   [(set (match_operand 0 "" "")
10556         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10557               (match_operand 2 "" "g,g,g,g")))
10558    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10559    (clobber (reg:SI LR_REGNO))]
10560   "DEFAULT_ABI == ABI_V4
10561    || DEFAULT_ABI == ABI_DARWIN"
10563   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10564     output_asm_insn ("crxor 6,6,6", operands);
10566   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10567     output_asm_insn ("creqv 6,6,6", operands);
10569   if (rs6000_speculate_indirect_jumps
10570       || which_alternative == 1 || which_alternative == 3)
10571     return "b%T1l";
10572   else
10573     return "crset 2\;beq%T1l-";
10575   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10576    (set (attr "length")
10577         (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10578                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10579                         (const_int 1)))
10580                   (const_string "4")
10581                (and (eq (symbol_ref "which_alternative") (const_int 0))
10582                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10583                         (const_int 0)))
10584                   (const_string "8")
10585                (eq (symbol_ref "which_alternative") (const_int 1))
10586                   (const_string "4")
10587                (and (eq (symbol_ref "which_alternative") (const_int 2))
10588                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10589                         (const_int 1)))
10590                   (const_string "8")
10591                (and (eq (symbol_ref "which_alternative") (const_int 2))
10592                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10593                         (const_int 0)))
10594                   (const_string "12")
10595                (eq (symbol_ref "which_alternative") (const_int 3))
10596                   (const_string "8")]
10597               (const_string "4")))])
10599 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10600   [(set (match_operand 0 "" "")
10601         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10602               (match_operand 2 "" "g,g")))
10603    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10604    (clobber (reg:SI LR_REGNO))]
10605   "(DEFAULT_ABI == ABI_DARWIN
10606    || (DEFAULT_ABI == ABI_V4
10607        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10609   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10610     output_asm_insn ("crxor 6,6,6", operands);
10612   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10613     output_asm_insn ("creqv 6,6,6", operands);
10615 #if TARGET_MACHO
10616   return output_call(insn, operands, 1, 3);
10617 #else
10618   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10619     {
10620       gcc_assert (!TARGET_SECURE_PLT);
10621       return "bl %z1@plt";
10622     }
10623   else
10624     return "bl %z1";
10625 #endif
10627   "DEFAULT_ABI == ABI_V4
10628    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10629    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10630   [(parallel [(set (match_dup 0)
10631                    (call (mem:SI (match_dup 1))
10632                          (match_dup 2)))
10633               (use (match_dup 3))
10634               (use (match_dup 4))
10635               (clobber (reg:SI LR_REGNO))])]
10637   operands[4] = pic_offset_table_rtx;
10639   [(set_attr "type" "branch,branch")
10640    (set_attr "length" "4,8")])
10642 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10643   [(set (match_operand 0 "" "")
10644         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10645               (match_operand 2 "" "g,g")))
10646    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10647    (use (match_operand:SI 4 "register_operand" "r,r"))
10648    (clobber (reg:SI LR_REGNO))]
10649   "(DEFAULT_ABI == ABI_V4
10650     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10651     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10653   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10654     output_asm_insn ("crxor 6,6,6", operands);
10656   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10657     output_asm_insn ("creqv 6,6,6", operands);
10659   if (flag_pic == 2)
10660     return "bl %z1+32768@plt";
10661   else
10662     return "bl %z1@plt";
10664   [(set_attr "type" "branch,branch")
10665    (set_attr "length" "4,8")])
10668 ;; Call to AIX abi function in the same module.
10670 (define_insn "*call_local_aix<mode>"
10671   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10672          (match_operand 1 "" "g"))
10673    (clobber (reg:P LR_REGNO))]
10674   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10675   "bl %z0"
10676   [(set_attr "type" "branch")
10677    (set_attr "length" "4")])
10679 (define_insn "*call_value_local_aix<mode>"
10680   [(set (match_operand 0 "" "")
10681         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10682               (match_operand 2 "" "g")))
10683    (clobber (reg:P LR_REGNO))]
10684   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10685   "bl %z1"
10686   [(set_attr "type" "branch")
10687    (set_attr "length" "4")])
10689 ;; Call to AIX abi function which may be in another module.
10690 ;; Restore the TOC pointer (r2) after the call.
10692 (define_insn "*call_nonlocal_aix<mode>"
10693   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10694          (match_operand 1 "" "g"))
10695    (clobber (reg:P LR_REGNO))]
10696   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10697   "bl %z0\;nop"
10698   [(set_attr "type" "branch")
10699    (set_attr "length" "8")])
10701 (define_insn "*call_value_nonlocal_aix<mode>"
10702   [(set (match_operand 0 "" "")
10703         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10704               (match_operand 2 "" "g")))
10705    (clobber (reg:P LR_REGNO))]
10706   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10707   "bl %z1\;nop"
10708   [(set_attr "type" "branch")
10709    (set_attr "length" "8")])
10711 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10712 ;; Operand0 is the addresss of the function to call
10713 ;; Operand2 is the location in the function descriptor to load r2 from
10714 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10716 (define_insn "*call_indirect_aix<mode>"
10717   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10718          (match_operand 1 "" "g,g"))
10719    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10720    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10721    (clobber (reg:P LR_REGNO))]
10722   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10723   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10724   [(set_attr "type" "jmpreg")
10725    (set_attr "length" "12")])
10727 (define_insn "*call_indirect_aix<mode>_nospec"
10728   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10729          (match_operand 1 "" "g,g"))
10730    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10731    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10732    (clobber (reg:P LR_REGNO))]
10733   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10734   "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10735   [(set_attr "type" "jmpreg")
10736    (set_attr "length" "16")])
10738 (define_insn "*call_value_indirect_aix<mode>"
10739   [(set (match_operand 0 "" "")
10740         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10741               (match_operand 2 "" "g,g")))
10742    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10743    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10744    (clobber (reg:P LR_REGNO))]
10745   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10746   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10747   [(set_attr "type" "jmpreg")
10748    (set_attr "length" "12")])
10750 (define_insn "*call_value_indirect_aix<mode>_nospec"
10751   [(set (match_operand 0 "" "")
10752         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10753               (match_operand 2 "" "g,g")))
10754    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10755    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10756    (clobber (reg:P LR_REGNO))]
10757   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10758   "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10759   [(set_attr "type" "jmpreg")
10760    (set_attr "length" "16")])
10762 ;; Call to indirect functions with the ELFv2 ABI.
10763 ;; Operand0 is the addresss of the function to call
10764 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10766 (define_insn "*call_indirect_elfv2<mode>"
10767   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10768          (match_operand 1 "" "g,g"))
10769    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10770    (clobber (reg:P LR_REGNO))]
10771   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10772   "b%T0l\;<ptrload> 2,%2(1)"
10773   [(set_attr "type" "jmpreg")
10774    (set_attr "length" "8")])
10776 ;; Variant with deliberate misprediction.
10777 (define_insn "*call_indirect_elfv2<mode>_nospec"
10778   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10779          (match_operand 1 "" "g,g"))
10780    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10781    (clobber (reg:P LR_REGNO))]
10782   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10783   "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10784   [(set_attr "type" "jmpreg")
10785    (set_attr "length" "12")])
10787 (define_insn "*call_value_indirect_elfv2<mode>"
10788   [(set (match_operand 0 "" "")
10789         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10790               (match_operand 2 "" "g,g")))
10791    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10792    (clobber (reg:P LR_REGNO))]
10793   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10794   "b%T1l\;<ptrload> 2,%3(1)"
10795   [(set_attr "type" "jmpreg")
10796    (set_attr "length" "8")])
10798 ; Variant with deliberate misprediction.
10799 (define_insn "*call_value_indirect_elfv2<mode>_nospec"
10800   [(set (match_operand 0 "" "")
10801         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10802               (match_operand 2 "" "g,g")))
10803    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10804    (clobber (reg:P LR_REGNO))]
10805   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10806   "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10807   [(set_attr "type" "jmpreg")
10808    (set_attr "length" "12")])
10810 ;; Call subroutine returning any type.
10811 (define_expand "untyped_call"
10812   [(parallel [(call (match_operand 0 "" "")
10813                     (const_int 0))
10814               (match_operand 1 "" "")
10815               (match_operand 2 "" "")])]
10816   ""
10817   "
10819   int i;
10821   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10823   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10824     {
10825       rtx set = XVECEXP (operands[2], 0, i);
10826       emit_move_insn (SET_DEST (set), SET_SRC (set));
10827     }
10829   /* The optimizer does not know that the call sets the function value
10830      registers we stored in the result block.  We avoid problems by
10831      claiming that all hard registers are used and clobbered at this
10832      point.  */
10833   emit_insn (gen_blockage ());
10835   DONE;
10838 ;; sibling call patterns
10839 (define_expand "sibcall"
10840   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10841                     (match_operand 1 "" ""))
10842               (use (match_operand 2 "" ""))
10843               (simple_return)])]
10844   ""
10845   "
10847 #if TARGET_MACHO
10848   if (MACHOPIC_INDIRECT)
10849     operands[0] = machopic_indirect_call_target (operands[0]);
10850 #endif
10852   gcc_assert (GET_CODE (operands[0]) == MEM);
10853   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10855   operands[0] = XEXP (operands[0], 0);
10857   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10858     {
10859       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10860       DONE;
10861     }
10864 (define_expand "sibcall_value"
10865   [(parallel [(set (match_operand 0 "register_operand" "")
10866                 (call (mem:SI (match_operand 1 "address_operand" ""))
10867                       (match_operand 2 "" "")))
10868               (use (match_operand 3 "" ""))
10869               (simple_return)])]
10870   ""
10871   "
10873 #if TARGET_MACHO
10874   if (MACHOPIC_INDIRECT)
10875     operands[1] = machopic_indirect_call_target (operands[1]);
10876 #endif
10878   gcc_assert (GET_CODE (operands[1]) == MEM);
10879   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10881   operands[1] = XEXP (operands[1], 0);
10883   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10884     {
10885       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10886       DONE;
10887     }
10890 (define_insn "*sibcall_local32"
10891   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10892          (match_operand 1 "" "g,g"))
10893    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10894    (simple_return)]
10895   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10896   "*
10898   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10899     output_asm_insn (\"crxor 6,6,6\", operands);
10901   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10902     output_asm_insn (\"creqv 6,6,6\", operands);
10904   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10906   [(set_attr "type" "branch")
10907    (set_attr "length" "4,8")])
10909 (define_insn "*sibcall_local64"
10910   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10911          (match_operand 1 "" "g,g"))
10912    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10913    (simple_return)]
10914   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10915   "*
10917   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10918     output_asm_insn (\"crxor 6,6,6\", operands);
10920   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10921     output_asm_insn (\"creqv 6,6,6\", operands);
10923   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10925   [(set_attr "type" "branch")
10926    (set_attr "length" "4,8")])
10928 (define_insn "*sibcall_value_local32"
10929   [(set (match_operand 0 "" "")
10930         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10931               (match_operand 2 "" "g,g")))
10932    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10933    (simple_return)]
10934   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10935   "*
10937   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10938     output_asm_insn (\"crxor 6,6,6\", operands);
10940   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10941     output_asm_insn (\"creqv 6,6,6\", operands);
10943   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10945   [(set_attr "type" "branch")
10946    (set_attr "length" "4,8")])
10948 (define_insn "*sibcall_value_local64"
10949   [(set (match_operand 0 "" "")
10950         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10951               (match_operand 2 "" "g,g")))
10952    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10953    (simple_return)]
10954   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10955   "*
10957   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10958     output_asm_insn (\"crxor 6,6,6\", operands);
10960   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10961     output_asm_insn (\"creqv 6,6,6\", operands);
10963   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10965   [(set_attr "type" "branch")
10966    (set_attr "length" "4,8")])
10968 (define_insn "*sibcall_nonlocal_sysv<mode>"
10969   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10970          (match_operand 1 "" ""))
10971    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10972    (simple_return)]
10973   "(DEFAULT_ABI == ABI_DARWIN
10974     || DEFAULT_ABI == ABI_V4)
10975    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10976   "*
10978   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10979     output_asm_insn (\"crxor 6,6,6\", operands);
10981   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10982     output_asm_insn (\"creqv 6,6,6\", operands);
10984   if (which_alternative >= 2)
10985     {
10986       if (rs6000_speculate_indirect_jumps)
10987         return \"b%T0\";
10988       else
10989         /* Can use CR0 since it is volatile across sibcalls.  */
10990         return \"crset 2\;beq%T0-\;b $\";
10991     }
10992   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10993     {
10994       gcc_assert (!TARGET_SECURE_PLT);
10995       return \"b %z0@plt\";
10996     }
10997   else
10998     return \"b %z0\";
11000   [(set_attr "type" "branch")
11001    (set (attr "length")
11002         (cond [(eq (symbol_ref "which_alternative") (const_int 0))
11003                   (const_string "4")
11004                (eq (symbol_ref "which_alternative") (const_int 1))
11005                   (const_string "8")
11006                (and (eq (symbol_ref "which_alternative") (const_int 2))
11007                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11008                         (const_int 1)))
11009                   (const_string "4")
11010                (and (eq (symbol_ref "which_alternative") (const_int 2))
11011                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11012                         (const_int 0)))
11013                   (const_string "12")
11014                (and (eq (symbol_ref "which_alternative") (const_int 3))
11015                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11016                         (const_int 1)))
11017                   (const_string "8")
11018                (and (eq (symbol_ref "which_alternative") (const_int 3))
11019                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11020                         (const_int 0)))
11021                   (const_string "16")]
11022               (const_string "4")))])
11024 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11025   [(set (match_operand 0 "" "")
11026         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11027               (match_operand 2 "" "")))
11028    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11029    (simple_return)]
11030   "(DEFAULT_ABI == ABI_DARWIN
11031     || DEFAULT_ABI == ABI_V4)
11032    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11033   "*
11035   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11036     output_asm_insn (\"crxor 6,6,6\", operands);
11038   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11039     output_asm_insn (\"creqv 6,6,6\", operands);
11041   if (which_alternative >= 2)
11042     {
11043       if (rs6000_speculate_indirect_jumps)
11044         return \"b%T1\";
11045       else
11046         /* Can use CR0 since it is volatile across sibcalls.  */
11047         return \"crset 2\;beq%T1-\;b $\";
11048     }
11049   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11050     {
11051       gcc_assert (!TARGET_SECURE_PLT);
11052       return \"b %z1@plt\";
11053     }
11054   else
11055     return \"b %z1\";
11057   [(set_attr "type" "branch")
11058    (set (attr "length")
11059         (cond [(eq (symbol_ref "which_alternative") (const_int 0))
11060                   (const_string "4")
11061                (eq (symbol_ref "which_alternative") (const_int 1))
11062                   (const_string "8")
11063                (and (eq (symbol_ref "which_alternative") (const_int 2))
11064                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11065                         (const_int 1)))
11066                   (const_string "4")
11067                (and (eq (symbol_ref "which_alternative") (const_int 2))
11068                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11069                         (const_int 0)))
11070                   (const_string "12")
11071                (and (eq (symbol_ref "which_alternative") (const_int 3))
11072                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11073                         (const_int 1)))
11074                   (const_string "8")
11075                (and (eq (symbol_ref "which_alternative") (const_int 3))
11076                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11077                         (const_int 0)))
11078                   (const_string "16")]
11079               (const_string "4")))])
11081 ;; AIX ABI sibling call patterns.
11083 (define_insn "*sibcall_aix<mode>"
11084   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11085          (match_operand 1 "" "g,g"))
11086    (simple_return)]
11087   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11088   "@
11089    b %z0
11090    b%T0"
11091   [(set_attr "type" "branch")
11092    (set_attr "length" "4")])
11094 (define_insn "*sibcall_value_aix<mode>"
11095   [(set (match_operand 0 "" "")
11096         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11097               (match_operand 2 "" "g,g")))
11098    (simple_return)]
11099   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11100   "@
11101    b %z1
11102    b%T1"
11103   [(set_attr "type" "branch")
11104    (set_attr "length" "4")])
11106 (define_expand "sibcall_epilogue"
11107   [(use (const_int 0))]
11108   ""
11110   if (!TARGET_SCHED_PROLOG)
11111     emit_insn (gen_blockage ());
11112   rs6000_emit_epilogue (TRUE);
11113   DONE;
11116 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11117 ;; all of memory.  This blocks insns from being moved across this point.
11119 (define_insn "blockage"
11120   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11121   ""
11122   "")
11124 (define_expand "probe_stack_address"
11125   [(use (match_operand 0 "address_operand"))]
11126   ""
11128   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11129   MEM_VOLATILE_P (operands[0]) = 1;
11131   if (TARGET_64BIT)
11132     emit_insn (gen_probe_stack_di (operands[0]));
11133   else
11134     emit_insn (gen_probe_stack_si (operands[0]));
11135   DONE;
11138 (define_insn "probe_stack_<mode>"
11139   [(set (match_operand:P 0 "memory_operand" "=m")
11140         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11141   ""
11143   operands[1] = gen_rtx_REG (Pmode, 0);
11144   return "st<wd>%U0%X0 %1,%0";
11146   [(set_attr "type" "store")
11147    (set (attr "update")
11148         (if_then_else (match_operand 0 "update_address_mem")
11149                       (const_string "yes")
11150                       (const_string "no")))
11151    (set (attr "indexed")
11152         (if_then_else (match_operand 0 "indexed_address_mem")
11153                       (const_string "yes")
11154                       (const_string "no")))
11155    (set_attr "length" "4")])
11157 (define_insn "probe_stack_range<P:mode>"
11158   [(set (match_operand:P 0 "register_operand" "=&r")
11159         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11160                             (match_operand:P 2 "register_operand" "r")
11161                             (match_operand:P 3 "register_operand" "r")]
11162                            UNSPECV_PROBE_STACK_RANGE))]
11163   ""
11164   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11165   [(set_attr "type" "three")])
11167 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11168 ;; signed & unsigned, and one type of branch.
11170 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11171 ;; insns, and branches.
11173 (define_expand "cbranch<mode>4"
11174   [(use (match_operator 0 "comparison_operator"
11175          [(match_operand:GPR 1 "gpc_reg_operand" "")
11176           (match_operand:GPR 2 "reg_or_short_operand" "")]))
11177    (use (match_operand 3 ""))]
11178   ""
11179   "
11181   /* Take care of the possibility that operands[2] might be negative but
11182      this might be a logical operation.  That insn doesn't exist.  */
11183   if (GET_CODE (operands[2]) == CONST_INT
11184       && INTVAL (operands[2]) < 0)
11185     {
11186       operands[2] = force_reg (<MODE>mode, operands[2]);
11187       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11188                                     GET_MODE (operands[0]),
11189                                     operands[1], operands[2]);
11190    }
11192   rs6000_emit_cbranch (<MODE>mode, operands);
11193   DONE;
11196 (define_expand "cbranch<mode>4"
11197   [(use (match_operator 0 "comparison_operator"
11198          [(match_operand:FP 1 "gpc_reg_operand" "")
11199           (match_operand:FP 2 "gpc_reg_operand" "")]))
11200    (use (match_operand 3 ""))]
11201   ""
11202   "
11204   rs6000_emit_cbranch (<MODE>mode, operands);
11205   DONE;
11208 (define_expand "cstore<mode>4_signed"
11209   [(use (match_operator 1 "signed_comparison_operator"
11210          [(match_operand:P 2 "gpc_reg_operand")
11211           (match_operand:P 3 "gpc_reg_operand")]))
11212    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11213   ""
11215   enum rtx_code cond_code = GET_CODE (operands[1]);
11217   rtx op0 = operands[0];
11218   rtx op1 = operands[2];
11219   rtx op2 = operands[3];
11221   if (cond_code == GE || cond_code == LT)
11222     {
11223       cond_code = swap_condition (cond_code);
11224       std::swap (op1, op2);
11225     }
11227   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11228   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11229   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11231   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11232   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11233   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11235   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11237   if (cond_code == LE)
11238     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11239   else
11240     {
11241       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11242       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11243       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11244     }
11246   DONE;
11249 (define_expand "cstore<mode>4_unsigned"
11250   [(use (match_operator 1 "unsigned_comparison_operator"
11251          [(match_operand:P 2 "gpc_reg_operand")
11252           (match_operand:P 3 "reg_or_short_operand")]))
11253    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11254   ""
11256   enum rtx_code cond_code = GET_CODE (operands[1]);
11258   rtx op0 = operands[0];
11259   rtx op1 = operands[2];
11260   rtx op2 = operands[3];
11262   if (cond_code == GEU || cond_code == LTU)
11263     {
11264       cond_code = swap_condition (cond_code);
11265       std::swap (op1, op2);
11266     }
11268   if (!gpc_reg_operand (op1, <MODE>mode))
11269     op1 = force_reg (<MODE>mode, op1);
11270   if (!reg_or_short_operand (op2, <MODE>mode))
11271     op2 = force_reg (<MODE>mode, op2);
11273   rtx tmp = gen_reg_rtx (<MODE>mode);
11274   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11276   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11277   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11279   if (cond_code == LEU)
11280     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11281   else
11282     emit_insn (gen_neg<mode>2 (op0, tmp2));
11284   DONE;
11287 (define_expand "cstore_si_as_di"
11288   [(use (match_operator 1 "unsigned_comparison_operator"
11289          [(match_operand:SI 2 "gpc_reg_operand")
11290           (match_operand:SI 3 "reg_or_short_operand")]))
11291    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11292   ""
11294   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11295   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11297   operands[2] = force_reg (SImode, operands[2]);
11298   operands[3] = force_reg (SImode, operands[3]);
11299   rtx op1 = gen_reg_rtx (DImode);
11300   rtx op2 = gen_reg_rtx (DImode);
11301   convert_move (op1, operands[2], uns_flag);
11302   convert_move (op2, operands[3], uns_flag);
11304   if (cond_code == GT || cond_code == LE)
11305     {
11306       cond_code = swap_condition (cond_code);
11307       std::swap (op1, op2);
11308     }
11310   rtx tmp = gen_reg_rtx (DImode);
11311   rtx tmp2 = gen_reg_rtx (DImode);
11312   emit_insn (gen_subdi3 (tmp, op1, op2));
11313   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11315   rtx tmp3;
11316   switch (cond_code)
11317     {
11318     default:
11319       gcc_unreachable ();
11320     case LT:
11321       tmp3 = tmp2;
11322       break;
11323     case GE:
11324       tmp3 = gen_reg_rtx (DImode);
11325       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11326       break;
11327     }
11329   convert_move (operands[0], tmp3, 1);
11331   DONE;
11334 (define_expand "cstore<mode>4_signed_imm"
11335   [(use (match_operator 1 "signed_comparison_operator"
11336          [(match_operand:GPR 2 "gpc_reg_operand")
11337           (match_operand:GPR 3 "immediate_operand")]))
11338    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11339   ""
11341   bool invert = false;
11343   enum rtx_code cond_code = GET_CODE (operands[1]);
11345   rtx op0 = operands[0];
11346   rtx op1 = operands[2];
11347   HOST_WIDE_INT val = INTVAL (operands[3]);
11349   if (cond_code == GE || cond_code == GT)
11350     {
11351       cond_code = reverse_condition (cond_code);
11352       invert = true;
11353     }
11355   if (cond_code == LE)
11356     val++;
11358   rtx tmp = gen_reg_rtx (<MODE>mode);
11359   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11360   rtx x = gen_reg_rtx (<MODE>mode);
11361   if (val < 0)
11362     emit_insn (gen_and<mode>3 (x, op1, tmp));
11363   else
11364     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11366   if (invert)
11367     {
11368       rtx tmp = gen_reg_rtx (<MODE>mode);
11369       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11370       x = tmp;
11371     }
11373   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11374   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11376   DONE;
11379 (define_expand "cstore<mode>4_unsigned_imm"
11380   [(use (match_operator 1 "unsigned_comparison_operator"
11381          [(match_operand:GPR 2 "gpc_reg_operand")
11382           (match_operand:GPR 3 "immediate_operand")]))
11383    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11384   ""
11386   bool invert = false;
11388   enum rtx_code cond_code = GET_CODE (operands[1]);
11390   rtx op0 = operands[0];
11391   rtx op1 = operands[2];
11392   HOST_WIDE_INT val = INTVAL (operands[3]);
11394   if (cond_code == GEU || cond_code == GTU)
11395     {
11396       cond_code = reverse_condition (cond_code);
11397       invert = true;
11398     }
11400   if (cond_code == LEU)
11401     val++;
11403   rtx tmp = gen_reg_rtx (<MODE>mode);
11404   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11405   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11406   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11407   rtx x = gen_reg_rtx (<MODE>mode);
11408   if (val < 0)
11409     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11410   else
11411     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11413   if (invert)
11414     {
11415       rtx tmp = gen_reg_rtx (<MODE>mode);
11416       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11417       x = tmp;
11418     }
11420   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11421   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11423   DONE;
11426 (define_expand "cstore<mode>4"
11427   [(use (match_operator 1 "comparison_operator"
11428          [(match_operand:GPR 2 "gpc_reg_operand")
11429           (match_operand:GPR 3 "reg_or_short_operand")]))
11430    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11431   ""
11433   /* Expanding EQ and NE directly to some machine instructions does not help
11434      but does hurt combine.  So don't.  */
11435   if (GET_CODE (operands[1]) == EQ)
11436     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11437   else if (<MODE>mode == Pmode
11438            && GET_CODE (operands[1]) == NE)
11439     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11440   else if (GET_CODE (operands[1]) == NE)
11441     {
11442       rtx tmp = gen_reg_rtx (<MODE>mode);
11443       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11444       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11445     }
11447   /* If ISEL is fast, expand to it.  */
11448   else if (TARGET_ISEL)
11449     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11451   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11452      etc. combinations magically work out just right.  */
11453   else if (<MODE>mode == Pmode
11454            && unsigned_comparison_operator (operands[1], VOIDmode))
11455     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11456                                            operands[2], operands[3]));
11458   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11459   else if (<MODE>mode == SImode && Pmode == DImode)
11460     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11461                                     operands[2], operands[3]));
11463   /* For signed comparisons against a constant, we can do some simple
11464      bit-twiddling.  */
11465   else if (signed_comparison_operator (operands[1], VOIDmode)
11466            && CONST_INT_P (operands[3]))
11467     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11468                                              operands[2], operands[3]));
11470   /* And similarly for unsigned comparisons.  */
11471   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11472            && CONST_INT_P (operands[3]))
11473     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11474                                                operands[2], operands[3]));
11476   /* We also do not want to use mfcr for signed comparisons.  */
11477   else if (<MODE>mode == Pmode
11478            && signed_comparison_operator (operands[1], VOIDmode))
11479     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11480                                          operands[2], operands[3]));
11482   /* Everything else, use the mfcr brute force.  */
11483   else
11484     rs6000_emit_sCOND (<MODE>mode, operands);
11486   DONE;
11489 (define_expand "cstore<mode>4"
11490   [(use (match_operator 1 "comparison_operator"
11491          [(match_operand:FP 2 "gpc_reg_operand")
11492           (match_operand:FP 3 "gpc_reg_operand")]))
11493    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11494   ""
11496   rs6000_emit_sCOND (<MODE>mode, operands);
11497   DONE;
11501 (define_expand "stack_protect_set"
11502   [(match_operand 0 "memory_operand")
11503    (match_operand 1 "memory_operand")]
11504   ""
11506   if (rs6000_stack_protector_guard == SSP_TLS)
11507     {
11508       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11509       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11510       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11511       operands[1] = gen_rtx_MEM (Pmode, addr);
11512     }
11514   if (TARGET_64BIT)
11515     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11516   else
11517     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11519   DONE;
11522 (define_insn "stack_protect_setsi"
11523   [(set (match_operand:SI 0 "memory_operand" "=m")
11524         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11525    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11526   "TARGET_32BIT"
11527   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11528   [(set_attr "type" "three")
11529    (set_attr "length" "12")])
11531 (define_insn "stack_protect_setdi"
11532   [(set (match_operand:DI 0 "memory_operand" "=Y")
11533         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11534    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11535   "TARGET_64BIT"
11536   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11537   [(set_attr "type" "three")
11538    (set_attr "length" "12")])
11540 (define_expand "stack_protect_test"
11541   [(match_operand 0 "memory_operand")
11542    (match_operand 1 "memory_operand")
11543    (match_operand 2 "")]
11544   ""
11546   rtx guard = operands[1];
11548   if (rs6000_stack_protector_guard == SSP_TLS)
11549     {
11550       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11551       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11552       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11553       guard = gen_rtx_MEM (Pmode, addr);
11554     }
11556   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11557   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11558   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11559   emit_jump_insn (jump);
11561   DONE;
11564 (define_insn "stack_protect_testsi"
11565   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11566         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11567                       (match_operand:SI 2 "memory_operand" "m,m")]
11568                      UNSPEC_SP_TEST))
11569    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11570    (clobber (match_scratch:SI 3 "=&r,&r"))]
11571   "TARGET_32BIT"
11572   "@
11573    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11574    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11575   [(set_attr "length" "16,20")])
11577 (define_insn "stack_protect_testdi"
11578   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11579         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11580                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11581                      UNSPEC_SP_TEST))
11582    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11583    (clobber (match_scratch:DI 3 "=&r,&r"))]
11584   "TARGET_64BIT"
11585   "@
11586    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11587    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11588   [(set_attr "length" "16,20")])
11591 ;; Here are the actual compare insns.
11592 (define_insn "*cmp<mode>_signed"
11593   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11594         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11595                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11596   ""
11597   "cmp<wd>%I2 %0,%1,%2"
11598   [(set_attr "type" "cmp")])
11600 (define_insn "*cmp<mode>_unsigned"
11601   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11602         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11603                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11604   ""
11605   "cmpl<wd>%I2 %0,%1,%2"
11606   [(set_attr "type" "cmp")])
11608 ;; If we are comparing a register for equality with a large constant,
11609 ;; we can do this with an XOR followed by a compare.  But this is profitable
11610 ;; only if the large constant is only used for the comparison (and in this
11611 ;; case we already have a register to reuse as scratch).
11613 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11614 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11616 (define_peephole2
11617   [(set (match_operand:SI 0 "register_operand")
11618         (match_operand:SI 1 "logical_const_operand" ""))
11619    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11620                        [(match_dup 0)
11621                         (match_operand:SI 2 "logical_const_operand" "")]))
11622    (set (match_operand:CC 4 "cc_reg_operand" "")
11623         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11624                     (match_dup 0)))
11625    (set (pc)
11626         (if_then_else (match_operator 6 "equality_operator"
11627                        [(match_dup 4) (const_int 0)])
11628                       (match_operand 7 "" "")
11629                       (match_operand 8 "" "")))]
11630   "peep2_reg_dead_p (3, operands[0])
11631    && peep2_reg_dead_p (4, operands[4])
11632    && REGNO (operands[0]) != REGNO (operands[5])"
11633  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11634   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11635   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11638   /* Get the constant we are comparing against, and see what it looks like
11639      when sign-extended from 16 to 32 bits.  Then see what constant we could
11640      XOR with SEXTC to get the sign-extended value.  */
11641   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11642                                               SImode,
11643                                               operands[1], operands[2]);
11644   HOST_WIDE_INT c = INTVAL (cnst);
11645   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11646   HOST_WIDE_INT xorv = c ^ sextc;
11648   operands[9] = GEN_INT (xorv);
11649   operands[10] = GEN_INT (sextc);
11652 ;; The following two insns don't exist as single insns, but if we provide
11653 ;; them, we can swap an add and compare, which will enable us to overlap more
11654 ;; of the required delay between a compare and branch.  We generate code for
11655 ;; them by splitting.
11657 (define_insn ""
11658   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11659         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11660                     (match_operand:SI 2 "short_cint_operand" "i")))
11661    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11662         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11663   ""
11664   "#"
11665   [(set_attr "length" "8")])
11667 (define_insn ""
11668   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11669         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11670                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11671    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11672         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11673   ""
11674   "#"
11675   [(set_attr "length" "8")])
11677 (define_split
11678   [(set (match_operand:CC 3 "cc_reg_operand" "")
11679         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11680                     (match_operand:SI 2 "short_cint_operand" "")))
11681    (set (match_operand:SI 0 "gpc_reg_operand" "")
11682         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11683   ""
11684   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11685    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11687 (define_split
11688   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11689         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11690                        (match_operand:SI 2 "u_short_cint_operand" "")))
11691    (set (match_operand:SI 0 "gpc_reg_operand" "")
11692         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11693   ""
11694   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11695    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11697 ;; Only need to compare second words if first words equal
11698 (define_insn "*cmp<mode>_internal1"
11699   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11700         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11701                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11702   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11703    && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11704   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11705   [(set_attr "type" "fpcompare")
11706    (set_attr "length" "12")])
11708 (define_insn_and_split "*cmp<mode>_internal2"
11709   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11710         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11711                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11712     (clobber (match_scratch:DF 3 "=d"))
11713     (clobber (match_scratch:DF 4 "=d"))
11714     (clobber (match_scratch:DF 5 "=d"))
11715     (clobber (match_scratch:DF 6 "=d"))
11716     (clobber (match_scratch:DF 7 "=d"))
11717     (clobber (match_scratch:DF 8 "=d"))
11718     (clobber (match_scratch:DF 9 "=d"))
11719     (clobber (match_scratch:DF 10 "=d"))
11720     (clobber (match_scratch:GPR 11 "=b"))]
11721   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11722    && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11723   "#"
11724   "&& reload_completed"
11725   [(set (match_dup 3) (match_dup 14))
11726    (set (match_dup 4) (match_dup 15))
11727    (set (match_dup 9) (abs:DF (match_dup 5)))
11728    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11729    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11730                            (label_ref (match_dup 12))
11731                            (pc)))
11732    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11733    (set (pc) (label_ref (match_dup 13)))
11734    (match_dup 12)
11735    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11736    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11737    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11738    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11739    (match_dup 13)]
11741   REAL_VALUE_TYPE rv;
11742   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11743   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11745   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11746   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11747   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11748   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11749   operands[12] = gen_label_rtx ();
11750   operands[13] = gen_label_rtx ();
11751   real_inf (&rv);
11752   operands[14] = force_const_mem (DFmode,
11753                                   const_double_from_real_value (rv, DFmode));
11754   operands[15] = force_const_mem (DFmode,
11755                                   const_double_from_real_value (dconst0,
11756                                                                 DFmode));
11757   if (TARGET_TOC)
11758     {
11759       rtx tocref;
11760       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11761       operands[14] = gen_const_mem (DFmode, tocref);
11762       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11763       operands[15] = gen_const_mem (DFmode, tocref);
11764       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11765       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11766     }
11769 ;; Now we have the scc insns.  We can do some combinations because of the
11770 ;; way the machine works.
11772 ;; Note that this is probably faster if we can put an insn between the
11773 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11774 ;; cases the insns below which don't use an intermediate CR field will
11775 ;; be used instead.
11776 (define_insn ""
11777   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11778         (match_operator:SI 1 "scc_comparison_operator"
11779                            [(match_operand 2 "cc_reg_operand" "y")
11780                             (const_int 0)]))]
11781   ""
11782   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11783   [(set (attr "type")
11784      (cond [(match_test "TARGET_MFCRF")
11785                 (const_string "mfcrf")
11786            ]
11787         (const_string "mfcr")))
11788    (set_attr "length" "8")])
11790 ;; Same as above, but get the OV/ORDERED bit.
11791 (define_insn "move_from_CR_ov_bit"
11792   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11793         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11794                    UNSPEC_MV_CR_OV))]
11795   "TARGET_PAIRED_FLOAT"
11796   "mfcr %0\;rlwinm %0,%0,%t1,1"
11797   [(set_attr "type" "mfcr")
11798    (set_attr "length" "8")])
11800 (define_insn ""
11801   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11802         (match_operator:DI 1 "scc_comparison_operator"
11803                            [(match_operand 2 "cc_reg_operand" "y")
11804                             (const_int 0)]))]
11805   "TARGET_POWERPC64"
11806   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11807   [(set (attr "type")
11808      (cond [(match_test "TARGET_MFCRF")
11809                 (const_string "mfcrf")
11810            ]
11811         (const_string "mfcr")))
11812    (set_attr "length" "8")])
11814 (define_insn ""
11815   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11816         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11817                                        [(match_operand 2 "cc_reg_operand" "y,y")
11818                                         (const_int 0)])
11819                     (const_int 0)))
11820    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11821         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11822   "TARGET_32BIT"
11823   "@
11824    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11825    #"
11826   [(set_attr "type" "shift")
11827    (set_attr "dot" "yes")
11828    (set_attr "length" "8,16")])
11830 (define_split
11831   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11832         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11833                                        [(match_operand 2 "cc_reg_operand" "")
11834                                         (const_int 0)])
11835                     (const_int 0)))
11836    (set (match_operand:SI 3 "gpc_reg_operand" "")
11837         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11838   "TARGET_32BIT && reload_completed"
11839   [(set (match_dup 3)
11840         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11841    (set (match_dup 0)
11842         (compare:CC (match_dup 3)
11843                     (const_int 0)))]
11844   "")
11846 (define_insn ""
11847   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11848         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11849                                       [(match_operand 2 "cc_reg_operand" "y")
11850                                        (const_int 0)])
11851                    (match_operand:SI 3 "const_int_operand" "n")))]
11852   ""
11853   "*
11855   int is_bit = ccr_bit (operands[1], 1);
11856   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11857   int count;
11859   if (is_bit >= put_bit)
11860     count = is_bit - put_bit;
11861   else
11862     count = 32 - (put_bit - is_bit);
11864   operands[4] = GEN_INT (count);
11865   operands[5] = GEN_INT (put_bit);
11867   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11869   [(set (attr "type")
11870      (cond [(match_test "TARGET_MFCRF")
11871                 (const_string "mfcrf")
11872            ]
11873         (const_string "mfcr")))
11874    (set_attr "length" "8")])
11876 (define_insn ""
11877   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11878         (compare:CC
11879          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11880                                        [(match_operand 2 "cc_reg_operand" "y,y")
11881                                         (const_int 0)])
11882                     (match_operand:SI 3 "const_int_operand" "n,n"))
11883          (const_int 0)))
11884    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11885         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11886                    (match_dup 3)))]
11887   ""
11888   "*
11890   int is_bit = ccr_bit (operands[1], 1);
11891   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11892   int count;
11894   /* Force split for non-cc0 compare.  */
11895   if (which_alternative == 1)
11896      return \"#\";
11898   if (is_bit >= put_bit)
11899     count = is_bit - put_bit;
11900   else
11901     count = 32 - (put_bit - is_bit);
11903   operands[5] = GEN_INT (count);
11904   operands[6] = GEN_INT (put_bit);
11906   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11908   [(set_attr "type" "shift")
11909    (set_attr "dot" "yes")
11910    (set_attr "length" "8,16")])
11912 (define_split
11913   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11914         (compare:CC
11915          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11916                                        [(match_operand 2 "cc_reg_operand")
11917                                         (const_int 0)])
11918                     (match_operand:SI 3 "const_int_operand"))
11919          (const_int 0)))
11920    (set (match_operand:SI 4 "gpc_reg_operand")
11921         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11922                    (match_dup 3)))]
11923   "reload_completed"
11924   [(set (match_dup 4)
11925         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11926                    (match_dup 3)))
11927    (set (match_dup 0)
11928         (compare:CC (match_dup 4)
11929                     (const_int 0)))]
11930   "")
11933 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11934 (define_code_attr UNS [(eq "CC")
11935                        (ne "CC")
11936                        (lt "CC") (ltu "CCUNS")
11937                        (gt "CC") (gtu "CCUNS")
11938                        (le "CC") (leu "CCUNS")
11939                        (ge "CC") (geu "CCUNS")])
11940 (define_code_attr UNSu_ [(eq "")
11941                          (ne "")
11942                          (lt "") (ltu "u_")
11943                          (gt "") (gtu "u_")
11944                          (le "") (leu "u_")
11945                          (ge "") (geu "u_")])
11946 (define_code_attr UNSIK [(eq "I")
11947                          (ne "I")
11948                          (lt "I") (ltu "K")
11949                          (gt "I") (gtu "K")
11950                          (le "I") (leu "K")
11951                          (ge "I") (geu "K")])
11953 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11954   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11955         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11956                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11957    (clobber (match_scratch:GPR 3 "=r"))
11958    (clobber (match_scratch:GPR 4 "=r"))
11959    (clobber (match_scratch:<UNS> 5 "=y"))]
11960   "TARGET_ISEL
11961    && !(<CODE> == EQ && operands[2] == const0_rtx)
11962    && !(<CODE> == NE && operands[2] == const0_rtx
11963         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11964   "#"
11965   "&& 1"
11966   [(pc)]
11968   rtx_code code = <CODE>;
11969   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11970     {
11971       HOST_WIDE_INT val = INTVAL (operands[2]);
11972       if (code == LT && val != -0x8000)
11973         {
11974           code = LE;
11975           val--;
11976         }
11977       if (code == GT && val != 0x7fff)
11978         {
11979           code = GE;
11980           val++;
11981         }
11982       if (code == LTU && val != 0)
11983         {
11984           code = LEU;
11985           val--;
11986         }
11987       if (code == GTU && val != 0xffff)
11988         {
11989           code = GEU;
11990           val++;
11991         }
11992       operands[2] = GEN_INT (val);
11993     }
11995   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11996     operands[3] = const0_rtx;
11997   else
11998     {
11999       if (GET_CODE (operands[3]) == SCRATCH)
12000         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
12001       emit_move_insn (operands[3], const0_rtx);
12002     }
12004   if (GET_CODE (operands[4]) == SCRATCH)
12005     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
12006   emit_move_insn (operands[4], const1_rtx);
12008   if (GET_CODE (operands[5]) == SCRATCH)
12009     operands[5] = gen_reg_rtx (<UNS>mode);
12011   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
12012   emit_insn (gen_rtx_SET (operands[5], c1));
12014   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
12015   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
12016   emit_move_insn (operands[0], x);
12018   DONE;
12020   [(set (attr "cost")
12021         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12022                                    || <CODE> == NE
12023                                    || <CODE> == LE || <CODE> == GE
12024                                    || <CODE> == LEU || <CODE> == GEU")
12025                       (const_string "9")
12026                       (const_string "10")))])
12028 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12029                               (DI "rKJI")])
12031 (define_expand "eq<mode>3"
12032   [(parallel [
12033      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12034           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12035                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12036      (clobber (match_scratch:GPR 3 "=r"))
12037      (clobber (match_scratch:GPR 4 "=r"))])]
12038   ""
12040   if (TARGET_ISEL && operands[2] != const0_rtx)
12041     {
12042       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12043                                            operands[2]));
12044       DONE;
12045     }
12048 (define_insn_and_split "*eq<mode>3"
12049   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12050         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12051                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12052    (clobber (match_scratch:GPR 3 "=r"))
12053    (clobber (match_scratch:GPR 4 "=r"))]
12054   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12055   "#"
12056   "&& 1"
12057   [(set (match_dup 4)
12058         (clz:GPR (match_dup 3)))
12059    (set (match_dup 0)
12060         (lshiftrt:GPR (match_dup 4)
12061                       (match_dup 5)))]
12063   operands[3] = rs6000_emit_eqne (<MODE>mode,
12064                                   operands[1], operands[2], operands[3]);
12066   if (GET_CODE (operands[4]) == SCRATCH)
12067     operands[4] = gen_reg_rtx (<MODE>mode);
12069   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12071   [(set (attr "length")
12072         (if_then_else (match_test "operands[2] == const0_rtx")
12073                       (const_string "8")
12074                       (const_string "12")))])
12076 (define_expand "ne<mode>3"
12077   [(parallel [
12078      (set (match_operand:P 0 "gpc_reg_operand" "=r")
12079           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12080                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12081      (clobber (match_scratch:P 3 "=r"))
12082      (clobber (match_scratch:P 4 "=r"))
12083      (clobber (reg:P CA_REGNO))])]
12084   ""
12086   if (TARGET_ISEL && operands[2] != const0_rtx)
12087     {
12088       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12089                                            operands[2]));
12090       DONE;
12091     }
12094 (define_insn_and_split "*ne<mode>3"
12095   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12096         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12097               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12098    (clobber (match_scratch:P 3 "=r"))
12099    (clobber (match_scratch:P 4 "=r"))
12100    (clobber (reg:P CA_REGNO))]
12101   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12102   "#"
12103   "&& 1"
12104   [(parallel [(set (match_dup 4)
12105                    (plus:P (match_dup 3)
12106                            (const_int -1)))
12107               (set (reg:P CA_REGNO)
12108                    (ne:P (match_dup 3)
12109                          (const_int 0)))])
12110    (parallel [(set (match_dup 0)
12111                    (plus:P (plus:P (not:P (match_dup 4))
12112                                    (reg:P CA_REGNO))
12113                            (match_dup 3)))
12114               (clobber (reg:P CA_REGNO))])]
12116   operands[3] = rs6000_emit_eqne (<MODE>mode,
12117                                   operands[1], operands[2], operands[3]);
12119   if (GET_CODE (operands[4]) == SCRATCH)
12120     operands[4] = gen_reg_rtx (<MODE>mode);
12122   [(set (attr "length")
12123         (if_then_else (match_test "operands[2] == const0_rtx")
12124                       (const_string "8")
12125                       (const_string "12")))])
12127 (define_insn_and_split "*neg_eq_<mode>"
12128   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12129         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12130                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12131    (clobber (match_scratch:P 3 "=r"))
12132    (clobber (match_scratch:P 4 "=r"))
12133    (clobber (reg:P CA_REGNO))]
12134   ""
12135   "#"
12136   ""
12137   [(parallel [(set (match_dup 4)
12138                    (plus:P (match_dup 3)
12139                            (const_int -1)))
12140               (set (reg:P CA_REGNO)
12141                    (ne:P (match_dup 3)
12142                          (const_int 0)))])
12143    (parallel [(set (match_dup 0)
12144                    (plus:P (reg:P CA_REGNO)
12145                            (const_int -1)))
12146               (clobber (reg:P CA_REGNO))])]
12148   operands[3] = rs6000_emit_eqne (<MODE>mode,
12149                                   operands[1], operands[2], operands[3]);
12151   if (GET_CODE (operands[4]) == SCRATCH)
12152     operands[4] = gen_reg_rtx (<MODE>mode);
12154   [(set (attr "length")
12155         (if_then_else (match_test "operands[2] == const0_rtx")
12156                       (const_string "8")
12157                       (const_string "12")))])
12159 (define_insn_and_split "*neg_ne_<mode>"
12160   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12161         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12162                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12163    (clobber (match_scratch:P 3 "=r"))
12164    (clobber (match_scratch:P 4 "=r"))
12165    (clobber (reg:P CA_REGNO))]
12166   ""
12167   "#"
12168   ""
12169   [(parallel [(set (match_dup 4)
12170                    (neg:P (match_dup 3)))
12171               (set (reg:P CA_REGNO)
12172                    (eq:P (match_dup 3)
12173                          (const_int 0)))])
12174    (parallel [(set (match_dup 0)
12175                    (plus:P (reg:P CA_REGNO)
12176                            (const_int -1)))
12177               (clobber (reg:P CA_REGNO))])]
12179   operands[3] = rs6000_emit_eqne (<MODE>mode,
12180                                   operands[1], operands[2], operands[3]);
12182   if (GET_CODE (operands[4]) == SCRATCH)
12183     operands[4] = gen_reg_rtx (<MODE>mode);
12185   [(set (attr "length")
12186         (if_then_else (match_test "operands[2] == const0_rtx")
12187                       (const_string "8")
12188                       (const_string "12")))])
12190 (define_insn_and_split "*plus_eq_<mode>"
12191   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12192         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12193                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12194                 (match_operand:P 3 "gpc_reg_operand" "r")))
12195    (clobber (match_scratch:P 4 "=r"))
12196    (clobber (match_scratch:P 5 "=r"))
12197    (clobber (reg:P CA_REGNO))]
12198   ""
12199   "#"
12200   ""
12201   [(parallel [(set (match_dup 5)
12202                    (neg:P (match_dup 4)))
12203               (set (reg:P CA_REGNO)
12204                    (eq:P (match_dup 4)
12205                          (const_int 0)))])
12206    (parallel [(set (match_dup 0)
12207                    (plus:P (match_dup 3)
12208                            (reg:P CA_REGNO)))
12209               (clobber (reg:P CA_REGNO))])]
12211   operands[4] = rs6000_emit_eqne (<MODE>mode,
12212                                   operands[1], operands[2], operands[4]);
12214   if (GET_CODE (operands[5]) == SCRATCH)
12215     operands[5] = gen_reg_rtx (<MODE>mode);
12217   [(set (attr "length")
12218         (if_then_else (match_test "operands[2] == const0_rtx")
12219                       (const_string "8")
12220                       (const_string "12")))])
12222 (define_insn_and_split "*plus_ne_<mode>"
12223   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12224         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12225                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12226                 (match_operand:P 3 "gpc_reg_operand" "r")))
12227    (clobber (match_scratch:P 4 "=r"))
12228    (clobber (match_scratch:P 5 "=r"))
12229    (clobber (reg:P CA_REGNO))]
12230   ""
12231   "#"
12232   ""
12233   [(parallel [(set (match_dup 5)
12234                    (plus:P (match_dup 4)
12235                            (const_int -1)))
12236               (set (reg:P CA_REGNO)
12237                    (ne:P (match_dup 4)
12238                          (const_int 0)))])
12239    (parallel [(set (match_dup 0)
12240                    (plus:P (match_dup 3)
12241                            (reg:P CA_REGNO)))
12242               (clobber (reg:P CA_REGNO))])]
12244   operands[4] = rs6000_emit_eqne (<MODE>mode,
12245                                   operands[1], operands[2], operands[4]);
12247   if (GET_CODE (operands[5]) == SCRATCH)
12248     operands[5] = gen_reg_rtx (<MODE>mode);
12250   [(set (attr "length")
12251         (if_then_else (match_test "operands[2] == const0_rtx")
12252                       (const_string "8")
12253                       (const_string "12")))])
12255 (define_insn_and_split "*minus_eq_<mode>"
12256   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12257         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12258                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12259                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12260    (clobber (match_scratch:P 4 "=r"))
12261    (clobber (match_scratch:P 5 "=r"))
12262    (clobber (reg:P CA_REGNO))]
12263   ""
12264   "#"
12265   ""
12266   [(parallel [(set (match_dup 5)
12267                    (plus:P (match_dup 4)
12268                            (const_int -1)))
12269               (set (reg:P CA_REGNO)
12270                    (ne:P (match_dup 4)
12271                          (const_int 0)))])
12272    (parallel [(set (match_dup 0)
12273                    (plus:P (plus:P (match_dup 3)
12274                                    (reg:P CA_REGNO))
12275                            (const_int -1)))
12276               (clobber (reg:P CA_REGNO))])]
12278   operands[4] = rs6000_emit_eqne (<MODE>mode,
12279                                   operands[1], operands[2], operands[4]);
12281   if (GET_CODE (operands[5]) == SCRATCH)
12282     operands[5] = gen_reg_rtx (<MODE>mode);
12284   [(set (attr "length")
12285         (if_then_else (match_test "operands[2] == const0_rtx")
12286                       (const_string "8")
12287                       (const_string "12")))])
12289 (define_insn_and_split "*minus_ne_<mode>"
12290   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12291         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12292                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12293                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12294    (clobber (match_scratch:P 4 "=r"))
12295    (clobber (match_scratch:P 5 "=r"))
12296    (clobber (reg:P CA_REGNO))]
12297   ""
12298   "#"
12299   ""
12300   [(parallel [(set (match_dup 5)
12301                    (neg:P (match_dup 4)))
12302               (set (reg:P CA_REGNO)
12303                    (eq:P (match_dup 4)
12304                          (const_int 0)))])
12305    (parallel [(set (match_dup 0)
12306                    (plus:P (plus:P (match_dup 3)
12307                                    (reg:P CA_REGNO))
12308                            (const_int -1)))
12309               (clobber (reg:P CA_REGNO))])]
12311   operands[4] = rs6000_emit_eqne (<MODE>mode,
12312                                   operands[1], operands[2], operands[4]);
12314   if (GET_CODE (operands[5]) == SCRATCH)
12315     operands[5] = gen_reg_rtx (<MODE>mode);
12317   [(set (attr "length")
12318         (if_then_else (match_test "operands[2] == const0_rtx")
12319                       (const_string "8")
12320                       (const_string "12")))])
12322 (define_insn_and_split "*eqsi3_ext<mode>"
12323   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12324         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12325                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12326    (clobber (match_scratch:SI 3 "=r"))
12327    (clobber (match_scratch:SI 4 "=r"))]
12328   ""
12329   "#"
12330   ""
12331   [(set (match_dup 4)
12332         (clz:SI (match_dup 3)))
12333    (set (match_dup 0)
12334         (zero_extend:EXTSI
12335           (lshiftrt:SI (match_dup 4)
12336                        (const_int 5))))]
12338   operands[3] = rs6000_emit_eqne (SImode,
12339                                   operands[1], operands[2], operands[3]);
12341   if (GET_CODE (operands[4]) == SCRATCH)
12342     operands[4] = gen_reg_rtx (SImode);
12344   [(set (attr "length")
12345         (if_then_else (match_test "operands[2] == const0_rtx")
12346                       (const_string "8")
12347                       (const_string "12")))])
12349 (define_insn_and_split "*nesi3_ext<mode>"
12350   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12351         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12352                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12353    (clobber (match_scratch:SI 3 "=r"))
12354    (clobber (match_scratch:SI 4 "=r"))
12355    (clobber (match_scratch:EXTSI 5 "=r"))]
12356   "!TARGET_ISEL"
12357   "#"
12358   "&& 1"
12359   [(set (match_dup 4)
12360         (clz:SI (match_dup 3)))
12361    (set (match_dup 5)
12362         (zero_extend:EXTSI
12363           (lshiftrt:SI (match_dup 4)
12364                        (const_int 5))))
12365    (set (match_dup 0)
12366         (xor:EXTSI (match_dup 5)
12367                    (const_int 1)))]
12369   operands[3] = rs6000_emit_eqne (SImode,
12370                                   operands[1], operands[2], operands[3]);
12372   if (GET_CODE (operands[4]) == SCRATCH)
12373     operands[4] = gen_reg_rtx (SImode);
12374   if (GET_CODE (operands[5]) == SCRATCH)
12375     operands[5] = gen_reg_rtx (<MODE>mode);
12377   [(set (attr "length")
12378         (if_then_else (match_test "operands[2] == const0_rtx")
12379                       (const_string "12")
12380                       (const_string "16")))])
12382 ;; Define both directions of branch and return.  If we need a reload
12383 ;; register, we'd rather use CR0 since it is much easier to copy a
12384 ;; register CC value to there.
12386 (define_insn ""
12387   [(set (pc)
12388         (if_then_else (match_operator 1 "branch_comparison_operator"
12389                                       [(match_operand 2 "cc_reg_operand" "y")
12390                                        (const_int 0)])
12391                       (label_ref (match_operand 0))
12392                       (pc)))]
12393   ""
12395   return output_cbranch (operands[1], "%l0", 0, insn);
12397   [(set_attr "type" "branch")])
12399 (define_insn ""
12400   [(set (pc)
12401         (if_then_else (match_operator 0 "branch_comparison_operator"
12402                                       [(match_operand 1 "cc_reg_operand" "y")
12403                                        (const_int 0)])
12404                       (any_return)
12405                       (pc)))]
12406   "<return_pred>"
12408   return output_cbranch (operands[0], NULL, 0, insn);
12410   [(set_attr "type" "jmpreg")
12411    (set_attr "length" "4")])
12413 ;; Logic on condition register values.
12415 ; This pattern matches things like
12416 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12417 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12418 ;                                  (const_int 1)))
12419 ; which are generated by the branch logic.
12420 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12422 (define_insn "cceq_ior_compare"
12423   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12424         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12425                         [(match_operator:SI 2
12426                                       "branch_positive_comparison_operator"
12427                                       [(match_operand 3
12428                                                       "cc_reg_operand" "y,y")
12429                                        (const_int 0)])
12430                          (match_operator:SI 4
12431                                       "branch_positive_comparison_operator"
12432                                       [(match_operand 5
12433                                                       "cc_reg_operand" "0,y")
12434                                        (const_int 0)])])
12435                       (const_int 1)))]
12436   ""
12437   "cr%q1 %E0,%j2,%j4"
12438   [(set_attr "type" "cr_logical")
12439    (set_attr "cr_logical_3op" "no,yes")])
12441 ; Why is the constant -1 here, but 1 in the previous pattern?
12442 ; Because ~1 has all but the low bit set.
12443 (define_insn "cceq_ior_compare_complement"
12444   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12445         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12446                         [(not:SI (match_operator:SI 2
12447                                       "branch_positive_comparison_operator"
12448                                       [(match_operand 3
12449                                                       "cc_reg_operand" "y,y")
12450                                        (const_int 0)]))
12451                          (match_operator:SI 4
12452                                 "branch_positive_comparison_operator"
12453                                 [(match_operand 5
12454                                                 "cc_reg_operand" "0,y")
12455                                  (const_int 0)])])
12456                       (const_int -1)))]
12457   ""
12458   "cr%q1 %E0,%j2,%j4"
12459   [(set_attr "type" "cr_logical")
12460    (set_attr "cr_logical_3op" "no,yes")])
12462 (define_insn "*cceq_rev_compare"
12463   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12464         (compare:CCEQ (match_operator:SI 1
12465                                       "branch_positive_comparison_operator"
12466                                       [(match_operand 2
12467                                                       "cc_reg_operand" "0,y")
12468                                        (const_int 0)])
12469                       (const_int 0)))]
12470   ""
12471   "crnot %E0,%j1"
12472   [(set_attr "type" "cr_logical")
12473    (set_attr "cr_logical_3op" "no,yes")])
12475 ;; If we are comparing the result of two comparisons, this can be done
12476 ;; using creqv or crxor.
12478 (define_insn_and_split ""
12479   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12480         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12481                               [(match_operand 2 "cc_reg_operand" "y")
12482                                (const_int 0)])
12483                       (match_operator 3 "branch_comparison_operator"
12484                               [(match_operand 4 "cc_reg_operand" "y")
12485                                (const_int 0)])))]
12486   ""
12487   "#"
12488   ""
12489   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12490                                     (match_dup 5)))]
12491   "
12493   int positive_1, positive_2;
12495   positive_1 = branch_positive_comparison_operator (operands[1],
12496                                                     GET_MODE (operands[1]));
12497   positive_2 = branch_positive_comparison_operator (operands[3],
12498                                                     GET_MODE (operands[3]));
12500   if (! positive_1)
12501     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12502                                                             GET_CODE (operands[1])),
12503                                   SImode,
12504                                   operands[2], const0_rtx);
12505   else if (GET_MODE (operands[1]) != SImode)
12506     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12507                                   operands[2], const0_rtx);
12509   if (! positive_2)
12510     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12511                                                             GET_CODE (operands[3])),
12512                                   SImode,
12513                                   operands[4], const0_rtx);
12514   else if (GET_MODE (operands[3]) != SImode)
12515     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12516                                   operands[4], const0_rtx);
12518   if (positive_1 == positive_2)
12519     {
12520       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12521       operands[5] = constm1_rtx;
12522     }
12523   else
12524     {
12525       operands[5] = const1_rtx;
12526     }
12529 ;; Unconditional branch and return.
12531 (define_insn "jump"
12532   [(set (pc)
12533         (label_ref (match_operand 0)))]
12534   ""
12535   "b %l0"
12536   [(set_attr "type" "branch")])
12538 (define_insn "<return_str>return"
12539   [(any_return)]
12540   "<return_pred>"
12541   "blr"
12542   [(set_attr "type" "jmpreg")])
12544 (define_expand "indirect_jump"
12545   [(set (pc) (match_operand 0 "register_operand"))]
12546  ""
12548   if (!rs6000_speculate_indirect_jumps) {
12549     rtx ccreg = gen_reg_rtx (CCmode);
12550     if (Pmode == DImode)
12551       emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12552     else
12553       emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12554     DONE;
12555   }
12558 (define_insn "*indirect_jump<mode>"
12559   [(set (pc)
12560         (match_operand:P 0 "register_operand" "c,*l"))]
12561   "rs6000_speculate_indirect_jumps"
12562   "b%T0"
12563   [(set_attr "type" "jmpreg")])
12565 (define_insn "indirect_jump<mode>_nospec"
12566   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12567    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12568   "!rs6000_speculate_indirect_jumps"
12569   "crset %E1\;beq%T0- %1\;b $"
12570   [(set_attr "type" "jmpreg")
12571    (set_attr "length" "12")])
12573 ;; Table jump for switch statements:
12574 (define_expand "tablejump"
12575   [(use (match_operand 0))
12576    (use (label_ref (match_operand 1)))]
12577   ""
12579   if (rs6000_speculate_indirect_jumps)
12580     {
12581       if (TARGET_32BIT)
12582         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12583       else
12584         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12585     }
12586   else
12587     {
12588       rtx ccreg = gen_reg_rtx (CCmode);
12589       rtx jump;
12590       if (TARGET_32BIT)
12591         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12592       else
12593         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12594       emit_jump_insn (jump);
12595     }
12596   DONE;
12599 (define_expand "tablejumpsi"
12600   [(set (match_dup 3)
12601         (plus:SI (match_operand:SI 0)
12602                  (match_dup 2)))
12603    (parallel [(set (pc)
12604                    (match_dup 3))
12605               (use (label_ref (match_operand 1)))])]
12606   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12608   operands[0] = force_reg (SImode, operands[0]);
12609   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12610   operands[3] = gen_reg_rtx (SImode);
12613 (define_expand "tablejumpsi_nospec"
12614   [(set (match_dup 4)
12615         (plus:SI (match_operand:SI 0)
12616                  (match_dup 3)))
12617    (parallel [(set (pc)
12618                    (match_dup 4))
12619               (use (label_ref (match_operand 1)))
12620               (clobber (match_operand 2))])]
12621   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12623   operands[0] = force_reg (SImode, operands[0]);
12624   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12625   operands[4] = gen_reg_rtx (SImode);
12628 (define_expand "tablejumpdi"
12629   [(set (match_dup 4)
12630         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12631    (set (match_dup 3)
12632         (plus:DI (match_dup 4)
12633                  (match_dup 2)))
12634    (parallel [(set (pc)
12635                    (match_dup 3))
12636               (use (label_ref (match_operand 1)))])]
12637   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12639   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12640   operands[3] = gen_reg_rtx (DImode);
12641   operands[4] = gen_reg_rtx (DImode);
12644 (define_expand "tablejumpdi_nospec"
12645   [(set (match_dup 5)
12646         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12647    (set (match_dup 4)
12648         (plus:DI (match_dup 5)
12649                  (match_dup 3)))
12650    (parallel [(set (pc)
12651                    (match_dup 4))
12652               (use (label_ref (match_operand 1)))
12653               (clobber (match_operand 2))])]
12654   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12656   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12657   operands[4] = gen_reg_rtx (DImode);
12658   operands[5] = gen_reg_rtx (DImode);
12661 (define_insn "*tablejump<mode>_internal1"
12662   [(set (pc)
12663         (match_operand:P 0 "register_operand" "c,*l"))
12664    (use (label_ref (match_operand 1)))]
12665   "rs6000_speculate_indirect_jumps"
12666   "b%T0"
12667   [(set_attr "type" "jmpreg")])
12669 (define_insn "*tablejump<mode>_internal1_nospec"
12670   [(set (pc)
12671         (match_operand:P 0 "register_operand" "c,*l"))
12672    (use (label_ref (match_operand 1)))
12673    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12674   "!rs6000_speculate_indirect_jumps"
12675   "crset %E2\;beq%T0- %2\;b $"
12676   [(set_attr "type" "jmpreg")
12677    (set_attr "length" "12")])
12679 (define_insn "nop"
12680   [(unspec [(const_int 0)] UNSPEC_NOP)]
12681   ""
12682   "nop")
12684 (define_insn "group_ending_nop"
12685   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12686   ""
12688   if (rs6000_tune == PROCESSOR_POWER6)
12689     return "ori 1,1,0";
12690   return "ori 2,2,0";
12693 (define_insn "rs6000_speculation_barrier"
12694   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12695   ""
12696   "ori 31,31,0")
12698 ;; Define the subtract-one-and-jump insns, starting with the template
12699 ;; so loop.c knows what to generate.
12701 (define_expand "doloop_end"
12702   [(use (match_operand 0))      ; loop pseudo
12703    (use (match_operand 1))]     ; label
12704   ""
12706   if (TARGET_64BIT)
12707     {
12708       if (GET_MODE (operands[0]) != DImode)
12709         FAIL;
12710       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12711     }
12712   else
12713     {
12714       if (GET_MODE (operands[0]) != SImode)
12715         FAIL;
12716       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12717     }
12718   DONE;
12721 (define_expand "ctr<mode>"
12722   [(parallel [(set (pc)
12723                    (if_then_else (ne (match_operand:P 0 "register_operand")
12724                                      (const_int 1))
12725                                  (label_ref (match_operand 1))
12726                                  (pc)))
12727               (set (match_dup 0)
12728                    (plus:P (match_dup 0)
12729                             (const_int -1)))
12730               (clobber (match_scratch:CC 2))
12731               (clobber (match_scratch:P 3))])]
12732   ""
12733   "")
12735 ;; We need to be able to do this for any operand, including MEM, or we
12736 ;; will cause reload to blow up since we don't allow output reloads on
12737 ;; JUMP_INSNs.
12738 ;; For the length attribute to be calculated correctly, the
12739 ;; label MUST be operand 0.
12740 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12741 ;; the ctr<mode> insns.
12743 (define_code_iterator eqne [eq ne])
12744 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12745 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12747 (define_insn "<bd>_<mode>"
12748   [(set (pc)
12749         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12750                           (const_int 1))
12751                       (label_ref (match_operand 0))
12752                       (pc)))
12753    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12754         (plus:P (match_dup 1)
12755                 (const_int -1)))
12756    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12757    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12758   ""
12760   if (which_alternative != 0)
12761     return "#";
12762   else if (get_attr_length (insn) == 4)
12763     return "<bd> %l0";
12764   else
12765     return "<bd_neg> $+8\;b %l0";
12767   [(set_attr "type" "branch")
12768    (set_attr "length" "*,16,20,20")])
12770 ;; Now the splitter if we could not allocate the CTR register
12771 (define_split
12772   [(set (pc)
12773         (if_then_else (match_operator 2 "comparison_operator"
12774                                       [(match_operand:P 1 "gpc_reg_operand")
12775                                        (const_int 1)])
12776                       (match_operand 5)
12777                       (match_operand 6)))
12778    (set (match_operand:P 0 "nonimmediate_operand")
12779         (plus:P (match_dup 1)
12780                 (const_int -1)))
12781    (clobber (match_scratch:CC 3))
12782    (clobber (match_scratch:P 4))]
12783   "reload_completed"
12784   [(set (pc)
12785         (if_then_else (match_dup 7)
12786                       (match_dup 5)
12787                       (match_dup 6)))]
12789   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12790                                 const0_rtx);
12791   emit_insn (gen_rtx_SET (operands[3],
12792                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12793   if (gpc_reg_operand (operands[0], <MODE>mode))
12794     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12795   else
12796     {
12797       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12798       emit_move_insn (operands[0], operands[4]);
12799     } 
12800     /* No DONE so branch comes from the pattern.  */
12803 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12804 ;; Note that in the case of long branches we have to decompose this into
12805 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12806 ;; and the CR bit, which means there is no way to conveniently invert the
12807 ;; comparison as is done with plain bdnz/bdz.
12809 (define_insn "<bd>tf_<mode>"
12810   [(set (pc)
12811         (if_then_else
12812           (and
12813              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12814                    (const_int 1))
12815              (match_operator 3 "branch_comparison_operator"
12816                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12817                        (const_int 0)]))
12818           (label_ref (match_operand 0))
12819           (pc)))
12820    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12821         (plus:P (match_dup 1)
12822                 (const_int -1)))
12823    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12824    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12825    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12826   ""
12828   if (which_alternative != 0)
12829     return "#";
12830   else if (get_attr_length (insn) == 4)
12831     {
12832       if (branch_positive_comparison_operator (operands[3],
12833                                                GET_MODE (operands[3])))
12834         return "<bd>t %j3,%l0";
12835       else
12836         return "<bd>f %j3,%l0";
12837     }
12838   else
12839     {
12840       static char seq[96];
12841       char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12842       sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12843       return seq;
12844     }
12846   [(set_attr "type" "branch")
12847    (set_attr "length" "*,16,20,20")])
12849 ;; Now the splitter if we could not allocate the CTR register
12850 (define_split
12851   [(set (pc)
12852         (if_then_else
12853           (and
12854              (match_operator 1 "comparison_operator"
12855                              [(match_operand:P 0 "gpc_reg_operand")
12856                               (const_int 1)])
12857              (match_operator 3 "branch_comparison_operator"
12858                       [(match_operand 2 "cc_reg_operand")
12859                        (const_int 0)]))
12860           (match_operand 4)
12861           (match_operand 5)))
12862    (set (match_operand:P 6 "int_reg_operand")
12863         (plus:P (match_dup 0)
12864                 (const_int -1)))
12865    (clobber (match_scratch:P 7))
12866    (clobber (match_scratch:CC 8))
12867    (clobber (match_scratch:CCEQ 9))]
12868   "reload_completed"
12869 [(pc)]
12871   rtx ctr = operands[0];
12872   rtx ctrcmp = operands[1];
12873   rtx ccin = operands[2];
12874   rtx cccmp = operands[3];
12875   rtx dst1 = operands[4];
12876   rtx dst2 = operands[5];
12877   rtx ctrout = operands[6];
12878   rtx ctrtmp = operands[7];
12879   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12880   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12881   if (!ispos)
12882     cmpcode = reverse_condition (cmpcode);
12883   /* Generate crand/crandc here.  */
12884   emit_insn (gen_rtx_SET (operands[8],
12885                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12886   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12888   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12889   if (ispos)
12890      emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12891                                       operands[8], cccmp, ccin));
12892   else
12893      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12894                                                  operands[8], cccmp, ccin));
12895   if (gpc_reg_operand (operands[0], <MODE>mode))
12896      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12897   else
12898     {
12899       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12900       emit_move_insn (ctrout, ctrtmp);
12901     }
12902   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12903   emit_jump_insn (gen_rtx_SET (pc_rtx,
12904                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12905                                                      dst1, dst2)));
12906   DONE;
12910 (define_insn "trap"
12911   [(trap_if (const_int 1) (const_int 0))]
12912   ""
12913   "trap"
12914   [(set_attr "type" "trap")])
12916 (define_expand "ctrap<mode>4"
12917   [(trap_if (match_operator 0 "ordered_comparison_operator"
12918                             [(match_operand:GPR 1 "register_operand")
12919                              (match_operand:GPR 2 "reg_or_short_operand")])
12920             (match_operand 3 "zero_constant" ""))]
12921   ""
12922   "")
12924 (define_insn ""
12925   [(trap_if (match_operator 0 "ordered_comparison_operator"
12926                             [(match_operand:GPR 1 "register_operand" "r")
12927                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12928             (const_int 0))]
12929   ""
12930   "t<wd>%V0%I2 %1,%2"
12931   [(set_attr "type" "trap")])
12933 ;; Insns related to generating the function prologue and epilogue.
12935 (define_expand "prologue"
12936   [(use (const_int 0))]
12937   ""
12939   rs6000_emit_prologue ();
12940   if (!TARGET_SCHED_PROLOG)
12941     emit_insn (gen_blockage ());
12942   DONE;
12945 (define_insn "*movesi_from_cr_one"
12946   [(match_parallel 0 "mfcr_operation"
12947                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12948                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12949                                      (match_operand 3 "immediate_operand" "n")]
12950                           UNSPEC_MOVESI_FROM_CR))])]
12951   "TARGET_MFCRF"
12952   "*
12954   int mask = 0;
12955   int i;
12956   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12957   {
12958     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12959     operands[4] = GEN_INT (mask);
12960     output_asm_insn (\"mfcr %1,%4\", operands);
12961   }
12962   return \"\";
12964   [(set_attr "type" "mfcrf")])
12966 ;; Don't include the volatile CRs since their values are not used wrt CR save
12967 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12968 ;; prologue past an insn (early exit test) that defines a register used in the
12969 ;; prologue.
12970 (define_insn "prologue_movesi_from_cr"
12971   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12972         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12973                     (reg:CC CR4_REGNO)]
12974                    UNSPEC_MOVESI_FROM_CR))]
12975   ""
12976   "mfcr %0"
12977   [(set_attr "type" "mfcr")])
12979 (define_insn "*crsave"
12980   [(match_parallel 0 "crsave_operation"
12981                    [(set (match_operand:SI 1 "memory_operand" "=m")
12982                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12983   ""
12984   "stw %2,%1"
12985   [(set_attr "type" "store")])
12987 (define_insn "*stmw"
12988   [(match_parallel 0 "stmw_operation"
12989                    [(set (match_operand:SI 1 "memory_operand" "=m")
12990                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12991   "TARGET_MULTIPLE"
12992   "stmw %2,%1"
12993   [(set_attr "type" "store")
12994    (set_attr "update" "yes")
12995    (set_attr "indexed" "yes")])
12997 ; The following comment applies to:
12998 ;     save_gpregs_*
12999 ;     save_fpregs_*
13000 ;     restore_gpregs*
13001 ;     return_and_restore_gpregs*
13002 ;     return_and_restore_fpregs*
13003 ;     return_and_restore_fpregs_aix*
13005 ; The out-of-line save / restore functions expects one input argument.
13006 ; Since those are not standard call_insn's, we must avoid using
13007 ; MATCH_OPERAND for that argument. That way the register rename
13008 ; optimization will not try to rename this register.
13009 ; Each pattern is repeated for each possible register number used in 
13010 ; various ABIs (r11, r1, and for some functions r12)
13012 (define_insn "*save_gpregs_<mode>_r11"
13013   [(match_parallel 0 "any_parallel_operand"
13014                    [(clobber (reg:P LR_REGNO))
13015                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13016                     (use (reg:P 11))
13017                     (set (match_operand:P 2 "memory_operand" "=m")
13018                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13019   ""
13020   "bl %1"
13021   [(set_attr "type" "branch")
13022    (set_attr "length" "4")])
13024 (define_insn "*save_gpregs_<mode>_r12"
13025   [(match_parallel 0 "any_parallel_operand"
13026                    [(clobber (reg:P LR_REGNO))
13027                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13028                     (use (reg:P 12))
13029                     (set (match_operand:P 2 "memory_operand" "=m")
13030                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13031   ""
13032   "bl %1"
13033   [(set_attr "type" "branch")
13034    (set_attr "length" "4")])
13036 (define_insn "*save_gpregs_<mode>_r1"
13037   [(match_parallel 0 "any_parallel_operand"
13038                    [(clobber (reg:P LR_REGNO))
13039                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13040                     (use (reg:P 1))
13041                     (set (match_operand:P 2 "memory_operand" "=m")
13042                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13043   ""
13044   "bl %1"
13045   [(set_attr "type" "branch")
13046    (set_attr "length" "4")])
13048 (define_insn "*save_fpregs_<mode>_r11"
13049   [(match_parallel 0 "any_parallel_operand"
13050                    [(clobber (reg:P LR_REGNO))
13051                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13052                     (use (reg:P 11))
13053                     (set (match_operand:DF 2 "memory_operand" "=m")
13054                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13055   ""
13056   "bl %1"
13057   [(set_attr "type" "branch")
13058    (set_attr "length" "4")])
13060 (define_insn "*save_fpregs_<mode>_r12"
13061   [(match_parallel 0 "any_parallel_operand"
13062                    [(clobber (reg:P LR_REGNO))
13063                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13064                     (use (reg:P 12))
13065                     (set (match_operand:DF 2 "memory_operand" "=m")
13066                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13067   ""
13068   "bl %1"
13069   [(set_attr "type" "branch")
13070    (set_attr "length" "4")])
13072 (define_insn "*save_fpregs_<mode>_r1"
13073   [(match_parallel 0 "any_parallel_operand"
13074                    [(clobber (reg:P LR_REGNO))
13075                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13076                     (use (reg:P 1))
13077                     (set (match_operand:DF 2 "memory_operand" "=m")
13078                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13079   ""
13080   "bl %1"
13081   [(set_attr "type" "branch")
13082    (set_attr "length" "4")])
13084 ; This is to explain that changes to the stack pointer should
13085 ; not be moved over loads from or stores to stack memory.
13086 (define_insn "stack_tie"
13087   [(match_parallel 0 "tie_operand"
13088                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13089   ""
13090   ""
13091   [(set_attr "length" "0")])
13093 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13094 ; stay behind all restores from the stack, it cannot be reordered to before
13095 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13096 (define_insn "stack_restore_tie"
13097   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13098         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13099                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13100    (set (mem:BLK (scratch)) (const_int 0))]
13101   "TARGET_32BIT"
13102   "@
13103    mr %0,%1
13104    add%I2 %0,%1,%2"
13105   [(set_attr "type" "*,add")])
13107 (define_expand "epilogue"
13108   [(use (const_int 0))]
13109   ""
13111   if (!TARGET_SCHED_PROLOG)
13112     emit_insn (gen_blockage ());
13113   rs6000_emit_epilogue (FALSE);
13114   DONE;
13117 ; On some processors, doing the mtcrf one CC register at a time is
13118 ; faster (like on the 604e).  On others, doing them all at once is
13119 ; faster; for instance, on the 601 and 750.
13121 (define_expand "movsi_to_cr_one"
13122   [(set (match_operand:CC 0 "cc_reg_operand" "")
13123         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13124                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13125   ""
13126   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13128 (define_insn "*movsi_to_cr"
13129   [(match_parallel 0 "mtcrf_operation"
13130                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13131                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13132                                      (match_operand 3 "immediate_operand" "n")]
13133                                     UNSPEC_MOVESI_TO_CR))])]
13134  ""
13135  "*
13137   int mask = 0;
13138   int i;
13139   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13140     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13141   operands[4] = GEN_INT (mask);
13142   return \"mtcrf %4,%2\";
13144   [(set_attr "type" "mtcr")])
13146 (define_insn "*mtcrfsi"
13147   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13148         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13149                     (match_operand 2 "immediate_operand" "n")]
13150                    UNSPEC_MOVESI_TO_CR))]
13151   "GET_CODE (operands[0]) == REG
13152    && CR_REGNO_P (REGNO (operands[0]))
13153    && GET_CODE (operands[2]) == CONST_INT
13154    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13155   "mtcrf %R0,%1"
13156   [(set_attr "type" "mtcr")])
13158 ; The load-multiple instructions have similar properties.
13159 ; Note that "load_multiple" is a name known to the machine-independent
13160 ; code that actually corresponds to the PowerPC load-string.
13162 (define_insn "*lmw"
13163   [(match_parallel 0 "lmw_operation"
13164                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13165                          (match_operand:SI 2 "memory_operand" "m"))])]
13166   "TARGET_MULTIPLE"
13167   "lmw %1,%2"
13168   [(set_attr "type" "load")
13169    (set_attr "update" "yes")
13170    (set_attr "indexed" "yes")
13171    (set_attr "cell_micro" "always")])
13173 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13174 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13176 ; The following comment applies to:
13177 ;     save_gpregs_*
13178 ;     save_fpregs_*
13179 ;     restore_gpregs*
13180 ;     return_and_restore_gpregs*
13181 ;     return_and_restore_fpregs*
13182 ;     return_and_restore_fpregs_aix*
13184 ; The out-of-line save / restore functions expects one input argument.
13185 ; Since those are not standard call_insn's, we must avoid using
13186 ; MATCH_OPERAND for that argument. That way the register rename
13187 ; optimization will not try to rename this register.
13188 ; Each pattern is repeated for each possible register number used in 
13189 ; various ABIs (r11, r1, and for some functions r12)
13191 (define_insn "*restore_gpregs_<mode>_r11"
13192  [(match_parallel 0 "any_parallel_operand"
13193                   [(clobber (reg:P LR_REGNO))
13194                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13195                    (use (reg:P 11))
13196                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13197                         (match_operand:P 3 "memory_operand" "m"))])]
13198  ""
13199  "bl %1"
13200  [(set_attr "type" "branch")
13201   (set_attr "length" "4")])
13203 (define_insn "*restore_gpregs_<mode>_r12"
13204  [(match_parallel 0 "any_parallel_operand"
13205                   [(clobber (reg:P LR_REGNO))
13206                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13207                    (use (reg:P 12))
13208                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13209                         (match_operand:P 3 "memory_operand" "m"))])]
13210  ""
13211  "bl %1"
13212  [(set_attr "type" "branch")
13213   (set_attr "length" "4")])
13215 (define_insn "*restore_gpregs_<mode>_r1"
13216  [(match_parallel 0 "any_parallel_operand"
13217                   [(clobber (reg:P LR_REGNO))
13218                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13219                    (use (reg:P 1))
13220                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13221                         (match_operand:P 3 "memory_operand" "m"))])]
13222  ""
13223  "bl %1"
13224  [(set_attr "type" "branch")
13225   (set_attr "length" "4")])
13227 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13228  [(match_parallel 0 "any_parallel_operand"
13229                   [(return)
13230                    (clobber (reg:P LR_REGNO))
13231                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13232                    (use (reg:P 11))
13233                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13234                         (match_operand:P 3 "memory_operand" "m"))])]
13235  ""
13236  "b %1"
13237  [(set_attr "type" "branch")
13238   (set_attr "length" "4")])
13240 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13241  [(match_parallel 0 "any_parallel_operand"
13242                   [(return)
13243                    (clobber (reg:P LR_REGNO))
13244                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13245                    (use (reg:P 12))
13246                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13247                         (match_operand:P 3 "memory_operand" "m"))])]
13248  ""
13249  "b %1"
13250  [(set_attr "type" "branch")
13251   (set_attr "length" "4")])
13253 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13254  [(match_parallel 0 "any_parallel_operand"
13255                   [(return)
13256                    (clobber (reg:P LR_REGNO))
13257                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13258                    (use (reg:P 1))
13259                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13260                         (match_operand:P 3 "memory_operand" "m"))])]
13261  ""
13262  "b %1"
13263  [(set_attr "type" "branch")
13264   (set_attr "length" "4")])
13266 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13267  [(match_parallel 0 "any_parallel_operand"
13268                   [(return)
13269                    (clobber (reg:P LR_REGNO))
13270                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13271                    (use (reg:P 11))
13272                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13273                         (match_operand:DF 3 "memory_operand" "m"))])]
13274  ""
13275  "b %1"
13276  [(set_attr "type" "branch")
13277   (set_attr "length" "4")])
13279 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13280  [(match_parallel 0 "any_parallel_operand"
13281                   [(return)
13282                    (clobber (reg:P LR_REGNO))
13283                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13284                    (use (reg:P 12))
13285                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13286                         (match_operand:DF 3 "memory_operand" "m"))])]
13287  ""
13288  "b %1"
13289  [(set_attr "type" "branch")
13290   (set_attr "length" "4")])
13292 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13293  [(match_parallel 0 "any_parallel_operand"
13294                   [(return)
13295                    (clobber (reg:P LR_REGNO))
13296                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13297                    (use (reg:P 1))
13298                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13299                         (match_operand:DF 3 "memory_operand" "m"))])]
13300  ""
13301  "b %1"
13302  [(set_attr "type" "branch")
13303   (set_attr "length" "4")])
13305 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13306  [(match_parallel 0 "any_parallel_operand"
13307                   [(return)
13308                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13309                    (use (reg:P 11))
13310                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13311                         (match_operand:DF 3 "memory_operand" "m"))])]
13312  ""
13313  "b %1"
13314  [(set_attr "type" "branch")
13315   (set_attr "length" "4")])
13317 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13318  [(match_parallel 0 "any_parallel_operand"
13319                   [(return)
13320                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13321                    (use (reg:P 1))
13322                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13323                         (match_operand:DF 3 "memory_operand" "m"))])]
13324  ""
13325  "b %1"
13326  [(set_attr "type" "branch")
13327   (set_attr "length" "4")])
13329 ; This is used in compiling the unwind routines.
13330 (define_expand "eh_return"
13331   [(use (match_operand 0 "general_operand" ""))]
13332   ""
13333   "
13335   if (TARGET_32BIT)
13336     emit_insn (gen_eh_set_lr_si (operands[0]));
13337   else
13338     emit_insn (gen_eh_set_lr_di (operands[0]));
13339   DONE;
13342 ; We can't expand this before we know where the link register is stored.
13343 (define_insn "eh_set_lr_<mode>"
13344   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13345                     UNSPECV_EH_RR)
13346    (clobber (match_scratch:P 1 "=&b"))]
13347   ""
13348   "#")
13350 (define_split
13351   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13352    (clobber (match_scratch 1 ""))]
13353   "reload_completed"
13354   [(const_int 0)]
13355   "
13357   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13358   DONE;
13361 (define_insn "prefetch"
13362   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13363              (match_operand:SI 1 "const_int_operand" "n")
13364              (match_operand:SI 2 "const_int_operand" "n"))]
13365   ""
13366   "*
13368   if (GET_CODE (operands[0]) == REG)
13369     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13370   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13372   [(set_attr "type" "load")])
13374 ;; Handle -fsplit-stack.
13376 (define_expand "split_stack_prologue"
13377   [(const_int 0)]
13378   ""
13380   rs6000_expand_split_stack_prologue ();
13381   DONE;
13384 (define_expand "load_split_stack_limit"
13385   [(set (match_operand 0)
13386         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13387   ""
13389   emit_insn (gen_rtx_SET (operands[0],
13390                           gen_rtx_UNSPEC (Pmode,
13391                                           gen_rtvec (1, const0_rtx),
13392                                           UNSPEC_STACK_CHECK)));
13393   DONE;
13396 (define_insn "load_split_stack_limit_di"
13397   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13398         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13399   "TARGET_64BIT"
13400   "ld %0,-0x7040(13)"
13401   [(set_attr "type" "load")
13402    (set_attr "update" "no")
13403    (set_attr "indexed" "no")])
13405 (define_insn "load_split_stack_limit_si"
13406   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13407         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13408   "!TARGET_64BIT"
13409   "lwz %0,-0x7020(2)"
13410   [(set_attr "type" "load")
13411    (set_attr "update" "no")
13412    (set_attr "indexed" "no")])
13414 ;; A return instruction which the middle-end doesn't see.
13415 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13416 ;; after the call to __morestack.
13417 (define_insn "split_stack_return"
13418   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13419   ""
13420   "blr"
13421   [(set_attr "type" "jmpreg")])
13423 ;; If there are operand 0 bytes available on the stack, jump to
13424 ;; operand 1.
13425 (define_expand "split_stack_space_check"
13426   [(set (match_dup 2)
13427         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13428    (set (match_dup 3)
13429         (minus (reg STACK_POINTER_REGNUM)
13430                (match_operand 0)))
13431    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13432    (set (pc) (if_then_else
13433               (geu (match_dup 4) (const_int 0))
13434               (label_ref (match_operand 1))
13435               (pc)))]
13436   ""
13438   rs6000_split_stack_space_check (operands[0], operands[1]);
13439   DONE;
13442 (define_insn "bpermd_<mode>"
13443   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13444         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13445                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13446   "TARGET_POPCNTD"
13447   "bpermd %0,%1,%2"
13448   [(set_attr "type" "popcnt")])
13451 ;; Builtin fma support.  Handle 
13452 ;; Note that the conditions for expansion are in the FMA_F iterator.
13454 (define_expand "fma<mode>4"
13455   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13456         (fma:FMA_F
13457           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13458           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13459           (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13460   ""
13461   "")
13463 (define_insn "*fma<mode>4_fpr"
13464   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13465         (fma:SFDF
13466           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13467           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13468           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13469   "TARGET_<MODE>_FPR"
13470   "@
13471    fmadd<Ftrad> %0,%1,%2,%3
13472    xsmadda<Fvsx> %x0,%x1,%x2
13473    xsmaddm<Fvsx> %x0,%x1,%x3"
13474   [(set_attr "type" "fp")
13475    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13477 ; Altivec only has fma and nfms.
13478 (define_expand "fms<mode>4"
13479   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13480         (fma:FMA_F
13481           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13482           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13483           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13484   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13485   "")
13487 (define_insn "*fms<mode>4_fpr"
13488   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13489         (fma:SFDF
13490          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13491          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13492          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13493   "TARGET_<MODE>_FPR"
13494   "@
13495    fmsub<Ftrad> %0,%1,%2,%3
13496    xsmsuba<Fvsx> %x0,%x1,%x2
13497    xsmsubm<Fvsx> %x0,%x1,%x3"
13498   [(set_attr "type" "fp")
13499    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13501 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13502 (define_expand "fnma<mode>4"
13503   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13504         (neg:FMA_F
13505           (fma:FMA_F
13506             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13507             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13508             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13509   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13510   "")
13512 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13513 (define_expand "fnms<mode>4"
13514   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13515         (neg:FMA_F
13516           (fma:FMA_F
13517             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13518             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13519             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13520   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13521   "")
13523 ; Not an official optab name, but used from builtins.
13524 (define_expand "nfma<mode>4"
13525   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13526         (neg:FMA_F
13527           (fma:FMA_F
13528             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13529             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13530             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13531   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13532   "")
13534 (define_insn "*nfma<mode>4_fpr"
13535   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13536         (neg:SFDF
13537          (fma:SFDF
13538           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13539           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13540           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13541   "TARGET_<MODE>_FPR"
13542   "@
13543    fnmadd<Ftrad> %0,%1,%2,%3
13544    xsnmadda<Fvsx> %x0,%x1,%x2
13545    xsnmaddm<Fvsx> %x0,%x1,%x3"
13546   [(set_attr "type" "fp")
13547    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13549 ; Not an official optab name, but used from builtins.
13550 (define_expand "nfms<mode>4"
13551   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13552         (neg:FMA_F
13553           (fma:FMA_F
13554             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13555             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13556             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13557   ""
13558   "")
13560 (define_insn "*nfmssf4_fpr"
13561   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13562         (neg:SFDF
13563          (fma:SFDF
13564           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13565           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13566           (neg:SFDF
13567            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13568   "TARGET_<MODE>_FPR"
13569   "@
13570    fnmsub<Ftrad> %0,%1,%2,%3
13571    xsnmsuba<Fvsx> %x0,%x1,%x2
13572    xsnmsubm<Fvsx> %x0,%x1,%x3"
13573   [(set_attr "type" "fp")
13574    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13577 (define_expand "rs6000_get_timebase"
13578   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13579   ""
13581   if (TARGET_POWERPC64)
13582     emit_insn (gen_rs6000_mftb_di (operands[0]));
13583   else
13584     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13585   DONE;
13588 (define_insn "rs6000_get_timebase_ppc32"
13589   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13590         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13591    (clobber (match_scratch:SI 1 "=r"))
13592    (clobber (match_scratch:CC 2 "=y"))]
13593   "!TARGET_POWERPC64"
13595   if (WORDS_BIG_ENDIAN)
13596     if (TARGET_MFCRF)
13597       {
13598         return "mfspr %0,269\;"
13599                "mfspr %L0,268\;"
13600                "mfspr %1,269\;"
13601                "cmpw %2,%0,%1\;"
13602                "bne- %2,$-16";
13603       }
13604     else
13605       {
13606         return "mftbu %0\;"
13607                "mftb %L0\;"
13608                "mftbu %1\;"
13609                "cmpw %2,%0,%1\;"
13610                "bne- %2,$-16";
13611       }
13612   else
13613     if (TARGET_MFCRF)
13614       {
13615         return "mfspr %L0,269\;"
13616                "mfspr %0,268\;"
13617                "mfspr %1,269\;"
13618                "cmpw %2,%L0,%1\;"
13619                "bne- %2,$-16";
13620       }
13621     else
13622       {
13623         return "mftbu %L0\;"
13624                "mftb %0\;"
13625                "mftbu %1\;"
13626                "cmpw %2,%L0,%1\;"
13627                "bne- %2,$-16";
13628       }
13630   [(set_attr "length" "20")])
13632 (define_insn "rs6000_mftb_<mode>"
13633   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13634         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13635   ""
13637   if (TARGET_MFCRF)
13638     return "mfspr %0,268";
13639   else
13640     return "mftb %0";
13644 (define_insn "rs6000_mffs"
13645   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13646         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13647   "TARGET_HARD_FLOAT"
13648   "mffs %0")
13650 (define_insn "rs6000_mtfsf"
13651   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13652                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13653                     UNSPECV_MTFSF)]
13654   "TARGET_HARD_FLOAT"
13655   "mtfsf %0,%1")
13658 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13659 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13660 ;; register that is being loaded.  The fused ops must be physically adjacent.
13662 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13663 ;; before register allocation, and is meant to reduce the lifetime for the
13664 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13665 ;; to use the register that is being load.  The peephole2 then gathers any
13666 ;; other fused possibilities that it can find after register allocation.  If
13667 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13669 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13670 ;; before register allocation, so that we can avoid allocating a temporary base
13671 ;; register that won't be used, and that we try to load into base registers,
13672 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13673 ;; (addis followed by load) even on power8.
13675 (define_split
13676   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13677         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13678   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13679   [(parallel [(set (match_dup 0) (match_dup 2))
13680               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13681               (use (match_dup 3))
13682               (clobber (scratch:DI))])]
13684   operands[2] = fusion_wrap_memory_address (operands[1]);
13685   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13688 (define_insn "*toc_fusionload_<mode>"
13689   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13690         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13691    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13692    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13693    (clobber (match_scratch:DI 3 "=X,&b"))]
13694   "TARGET_TOC_FUSION_INT"
13696   if (base_reg_operand (operands[0], <MODE>mode))
13697     return emit_fusion_gpr_load (operands[0], operands[1]);
13699   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13701   [(set_attr "type" "load")
13702    (set_attr "length" "8")])
13704 (define_insn "*toc_fusionload_di"
13705   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13706         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13707    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13708    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13709    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13710   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13711    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13713   if (base_reg_operand (operands[0], DImode))
13714     return emit_fusion_gpr_load (operands[0], operands[1]);
13716   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13718   [(set_attr "type" "load")
13719    (set_attr "length" "8")])
13722 ;; Find cases where the addis that feeds into a load instruction is either used
13723 ;; once or is the same as the target register, and replace it with the fusion
13724 ;; insn
13726 (define_peephole2
13727   [(set (match_operand:P 0 "base_reg_operand" "")
13728         (match_operand:P 1 "fusion_gpr_addis" ""))
13729    (set (match_operand:INT1 2 "base_reg_operand" "")
13730         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13731   "TARGET_P8_FUSION
13732    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13733                          operands[3])"
13734   [(const_int 0)]
13736   expand_fusion_gpr_load (operands);
13737   DONE;
13740 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13741 ;; reload)
13743 (define_insn "fusion_gpr_load_<mode>"
13744   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13745         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13746                      UNSPEC_FUSION_GPR))]
13747   "TARGET_P8_FUSION"
13749   return emit_fusion_gpr_load (operands[0], operands[1]);
13751   [(set_attr "type" "load")
13752    (set_attr "length" "8")])
13755 ;; ISA 3.0 (power9) fusion support
13756 ;; Merge addis with floating load/store to FPRs (or GPRs).
13757 (define_peephole2
13758   [(set (match_operand:P 0 "base_reg_operand" "")
13759         (match_operand:P 1 "fusion_gpr_addis" ""))
13760    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13761         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13762   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13763    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13764   [(const_int 0)]
13766   expand_fusion_p9_load (operands);
13767   DONE;
13770 (define_peephole2
13771   [(set (match_operand:P 0 "base_reg_operand" "")
13772         (match_operand:P 1 "fusion_gpr_addis" ""))
13773    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13774         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13775   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13776    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13777    && !rtx_equal_p (operands[0], operands[3])"
13778   [(const_int 0)]
13780   expand_fusion_p9_store (operands);
13781   DONE;
13784 (define_peephole2
13785   [(set (match_operand:SDI 0 "int_reg_operand" "")
13786         (match_operand:SDI 1 "upper16_cint_operand" ""))
13787    (set (match_dup 0)
13788         (ior:SDI (match_dup 0)
13789                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
13790   "TARGET_P9_FUSION"
13791   [(set (match_dup 0)
13792         (unspec:SDI [(match_dup 1)
13793                      (match_dup 2)] UNSPEC_FUSION_P9))])
13795 (define_peephole2
13796   [(set (match_operand:SDI 0 "int_reg_operand" "")
13797         (match_operand:SDI 1 "upper16_cint_operand" ""))
13798    (set (match_operand:SDI 2 "int_reg_operand" "")
13799         (ior:SDI (match_dup 0)
13800                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
13801   "TARGET_P9_FUSION
13802    && !rtx_equal_p (operands[0], operands[2])
13803    && peep2_reg_dead_p (2, operands[0])"
13804   [(set (match_dup 2)
13805         (unspec:SDI [(match_dup 1)
13806                      (match_dup 3)] UNSPEC_FUSION_P9))])
13808 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13809 ;; reload).  Because we want to eventually have secondary_reload generate
13810 ;; these, they have to have a single alternative that gives the register
13811 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13812 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13813   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13814         (unspec:GPR_FUSION
13815          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13816          UNSPEC_FUSION_P9))
13817    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13818   "TARGET_P9_FUSION"
13820   /* This insn is a secondary reload insn, which cannot have alternatives.
13821      If we are not loading up register 0, use the power8 fusion instead.  */
13822   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13823     return emit_fusion_gpr_load (operands[0], operands[1]);
13825   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13827   [(set_attr "type" "load")
13828    (set_attr "length" "8")])
13830 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13831   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13832         (unspec:GPR_FUSION
13833          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13834          UNSPEC_FUSION_P9))
13835    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13836   "TARGET_P9_FUSION"
13838   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13840   [(set_attr "type" "store")
13841    (set_attr "length" "8")])
13843 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13844   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13845         (unspec:FPR_FUSION
13846          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13847          UNSPEC_FUSION_P9))
13848    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13849   "TARGET_P9_FUSION"
13851   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13853   [(set_attr "type" "fpload")
13854    (set_attr "length" "8")])
13856 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13857   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13858         (unspec:FPR_FUSION
13859          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13860          UNSPEC_FUSION_P9))
13861    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13862   "TARGET_P9_FUSION"
13864   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13866   [(set_attr "type" "fpstore")
13867    (set_attr "length" "8")])
13869 (define_insn "*fusion_p9_<mode>_constant"
13870   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13871         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13872                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13873                     UNSPEC_FUSION_P9))] 
13874   "TARGET_P9_FUSION"
13876   emit_fusion_addis (operands[0], operands[1]);
13877   return "ori %0,%0,%2";
13879   [(set_attr "type" "two")
13880    (set_attr "length" "8")])
13883 ;; Optimize cases where we want to do a D-form load (register+offset) on
13884 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13885 ;; has generated:
13886 ;;      LFD 0,32(3)
13887 ;;      XXLOR 32,0,0
13889 ;; and we change this to:
13890 ;;      LI 0,32
13891 ;;      LXSDX 32,3,9
13893 (define_peephole2
13894   [(match_scratch:P 0 "b")
13895    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13896         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13897    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13898         (match_dup 1))]
13899   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13900   [(set (match_dup 0)
13901         (match_dup 4))
13902    (set (match_dup 3)
13903         (match_dup 5))]
13905   rtx tmp_reg = operands[0];
13906   rtx mem = operands[2];
13907   rtx addr = XEXP (mem, 0);
13908   rtx add_op0, add_op1, new_addr;
13910   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13911   add_op0 = XEXP (addr, 0);
13912   add_op1 = XEXP (addr, 1);
13913   gcc_assert (REG_P (add_op0));
13914   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13916   operands[4] = add_op1;
13917   operands[5] = change_address (mem, <MODE>mode, new_addr);
13920 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13921 ;; Altivec register, and the register allocator has generated:
13922 ;;      XXLOR 0,32,32
13923 ;;      STFD 0,32(3)
13925 ;; and we change this to:
13926 ;;      LI 0,32
13927 ;;      STXSDX 32,3,9
13929 (define_peephole2
13930   [(match_scratch:P 0 "b")
13931    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13932         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13933    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13934         (match_dup 1))]
13935   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13936   [(set (match_dup 0)
13937         (match_dup 4))
13938    (set (match_dup 5)
13939         (match_dup 2))]
13941   rtx tmp_reg = operands[0];
13942   rtx mem = operands[3];
13943   rtx addr = XEXP (mem, 0);
13944   rtx add_op0, add_op1, new_addr;
13946   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13947   add_op0 = XEXP (addr, 0);
13948   add_op1 = XEXP (addr, 1);
13949   gcc_assert (REG_P (add_op0));
13950   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13952   operands[4] = add_op1;
13953   operands[5] = change_address (mem, <MODE>mode, new_addr);
13955    
13957 ;; Miscellaneous ISA 2.06 (power7) instructions
13958 (define_insn "addg6s"
13959   [(set (match_operand:SI 0 "register_operand" "=r")
13960         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13961                     (match_operand:SI 2 "register_operand" "r")]
13962                    UNSPEC_ADDG6S))]
13963   "TARGET_POPCNTD"
13964   "addg6s %0,%1,%2"
13965   [(set_attr "type" "integer")
13966    (set_attr "length" "4")])
13968 (define_insn "cdtbcd"
13969   [(set (match_operand:SI 0 "register_operand" "=r")
13970         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13971                    UNSPEC_CDTBCD))]
13972   "TARGET_POPCNTD"
13973   "cdtbcd %0,%1"
13974   [(set_attr "type" "integer")
13975    (set_attr "length" "4")])
13977 (define_insn "cbcdtd"
13978   [(set (match_operand:SI 0 "register_operand" "=r")
13979         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13980                    UNSPEC_CBCDTD))]
13981   "TARGET_POPCNTD"
13982   "cbcdtd %0,%1"
13983   [(set_attr "type" "integer")
13984    (set_attr "length" "4")])
13986 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13987                                         UNSPEC_DIVEO
13988                                         UNSPEC_DIVEU
13989                                         UNSPEC_DIVEUO])
13991 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13992                              (UNSPEC_DIVEO      "eo")
13993                              (UNSPEC_DIVEU      "eu")
13994                              (UNSPEC_DIVEUO     "euo")])
13996 (define_insn "div<div_extend>_<mode>"
13997   [(set (match_operand:GPR 0 "register_operand" "=r")
13998         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13999                      (match_operand:GPR 2 "register_operand" "r")]
14000                     UNSPEC_DIV_EXTEND))]
14001   "TARGET_POPCNTD"
14002   "div<wd><div_extend> %0,%1,%2"
14003   [(set_attr "type" "div")
14004    (set_attr "size" "<bits>")])
14007 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14009 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14010 (define_mode_attr FP128_64 [(TF "DF")
14011                             (IF "DF")
14012                             (TD "DI")
14013                             (KF "DI")])
14015 (define_expand "unpack<mode>"
14016   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14017         (unspec:<FP128_64>
14018          [(match_operand:FMOVE128 1 "register_operand" "")
14019           (match_operand:QI 2 "const_0_to_1_operand" "")]
14020          UNSPEC_UNPACK_128BIT))]
14021   "FLOAT128_2REG_P (<MODE>mode)"
14022   "")
14024 (define_insn_and_split "unpack<mode>_dm"
14025   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14026         (unspec:<FP128_64>
14027          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14028           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14029          UNSPEC_UNPACK_128BIT))]
14030   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14031   "#"
14032   "&& reload_completed"
14033   [(set (match_dup 0) (match_dup 3))]
14035   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14037   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14038     {
14039       emit_note (NOTE_INSN_DELETED);
14040       DONE;
14041     }
14043   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14045   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14046    (set_attr "length" "4")])
14048 (define_insn_and_split "unpack<mode>_nodm"
14049   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14050         (unspec:<FP128_64>
14051          [(match_operand:FMOVE128 1 "register_operand" "d,d")
14052           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14053          UNSPEC_UNPACK_128BIT))]
14054   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14055   "#"
14056   "&& reload_completed"
14057   [(set (match_dup 0) (match_dup 3))]
14059   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14061   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14062     {
14063       emit_note (NOTE_INSN_DELETED);
14064       DONE;
14065     }
14067   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14069   [(set_attr "type" "fp,fpstore")
14070    (set_attr "length" "4")])
14072 (define_insn_and_split "pack<mode>"
14073   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14074         (unspec:FMOVE128
14075          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14076           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14077          UNSPEC_PACK_128BIT))]
14078   "FLOAT128_2REG_P (<MODE>mode)"
14079   "@
14080    fmr %L0,%2
14081    #"
14082   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14083   [(set (match_dup 3) (match_dup 1))
14084    (set (match_dup 4) (match_dup 2))]
14086   unsigned dest_hi = REGNO (operands[0]);
14087   unsigned dest_lo = dest_hi + 1;
14089   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14090   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14092   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14093   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14095   [(set_attr "type" "fpsimple,fp")
14096    (set_attr "length" "4,8")])
14098 (define_insn "unpack<mode>"
14099   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14100         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14101                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14102          UNSPEC_UNPACK_128BIT))]
14103   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14105   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14106     return ASM_COMMENT_START " xxpermdi to same register";
14108   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14109   return "xxpermdi %x0,%x1,%x1,%3";
14111   [(set_attr "type" "vecperm")])
14113 (define_insn "pack<mode>"
14114   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14115         (unspec:FMOVE128_VSX
14116          [(match_operand:DI 1 "register_operand" "wa")
14117           (match_operand:DI 2 "register_operand" "wa")]
14118          UNSPEC_PACK_128BIT))]
14119   "TARGET_VSX"
14120   "xxpermdi %x0,%x1,%x2,0"
14121   [(set_attr "type" "vecperm")])
14125 ;; ISA 2.08 IEEE 128-bit floating point support.
14127 (define_insn "add<mode>3"
14128   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14129         (plus:IEEE128
14130          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14131          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14132   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14133   "xsaddqp %0,%1,%2"
14134   [(set_attr "type" "vecfloat")
14135    (set_attr "size" "128")])
14137 (define_insn "sub<mode>3"
14138   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14139         (minus:IEEE128
14140          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14141          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14142   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14143   "xssubqp %0,%1,%2"
14144   [(set_attr "type" "vecfloat")
14145    (set_attr "size" "128")])
14147 (define_insn "mul<mode>3"
14148   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14149         (mult:IEEE128
14150          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14151          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14152   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14153   "xsmulqp %0,%1,%2"
14154   [(set_attr "type" "qmul")
14155    (set_attr "size" "128")])
14157 (define_insn "div<mode>3"
14158   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14159         (div:IEEE128
14160          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14161          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14162   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14163   "xsdivqp %0,%1,%2"
14164   [(set_attr "type" "vecdiv")
14165    (set_attr "size" "128")])
14167 (define_insn "sqrt<mode>2"
14168   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14169         (sqrt:IEEE128
14170          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14171   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14172    "xssqrtqp %0,%1"
14173   [(set_attr "type" "vecdiv")
14174    (set_attr "size" "128")])
14176 (define_expand "copysign<mode>3"
14177   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14178    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14179    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14180   "FLOAT128_IEEE_P (<MODE>mode)"
14182   if (TARGET_FLOAT128_HW)
14183     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14184                                          operands[2]));
14185   else
14186     {
14187       rtx tmp = gen_reg_rtx (<MODE>mode);
14188       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14189                                            operands[2], tmp));
14190     }
14191   DONE;
14194 (define_insn "copysign<mode>3_hard"
14195   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14196         (unspec:IEEE128
14197          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14198           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14199          UNSPEC_COPYSIGN))]
14200   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14201    "xscpsgnqp %0,%2,%1"
14202   [(set_attr "type" "vecmove")
14203    (set_attr "size" "128")])
14205 (define_insn "copysign<mode>3_soft"
14206   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14207         (unspec:IEEE128
14208          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14209           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14210           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14211          UNSPEC_COPYSIGN))]
14212   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14213    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14214   [(set_attr "type" "veccomplex")
14215    (set_attr "length" "8")])
14217 (define_insn "neg<mode>2_hw"
14218   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14219         (neg:IEEE128
14220          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14221   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14222   "xsnegqp %0,%1"
14223   [(set_attr "type" "vecmove")
14224    (set_attr "size" "128")])
14227 (define_insn "abs<mode>2_hw"
14228   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14229         (abs:IEEE128
14230          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14231   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14232   "xsabsqp %0,%1"
14233   [(set_attr "type" "vecmove")
14234    (set_attr "size" "128")])
14237 (define_insn "*nabs<mode>2_hw"
14238   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14239         (neg:IEEE128
14240          (abs:IEEE128
14241           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14242   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14243   "xsnabsqp %0,%1"
14244   [(set_attr "type" "vecmove")
14245    (set_attr "size" "128")])
14247 ;; Initially don't worry about doing fusion
14248 (define_insn "fma<mode>4_hw"
14249   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14250         (fma:IEEE128
14251          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14252          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14253          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14254   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14255   "xsmaddqp %0,%1,%2"
14256   [(set_attr "type" "qmul")
14257    (set_attr "size" "128")])
14259 (define_insn "*fms<mode>4_hw"
14260   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14261         (fma:IEEE128
14262          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14263          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14264          (neg:IEEE128
14265           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14266   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14267   "xsmsubqp %0,%1,%2"
14268   [(set_attr "type" "qmul")
14269    (set_attr "size" "128")])
14271 (define_insn "*nfma<mode>4_hw"
14272   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14273         (neg:IEEE128
14274          (fma:IEEE128
14275           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14276           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14277           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14278   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14279   "xsnmaddqp %0,%1,%2"
14280   [(set_attr "type" "qmul")
14281    (set_attr "size" "128")])
14283 (define_insn "*nfms<mode>4_hw"
14284   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14285         (neg:IEEE128
14286          (fma:IEEE128
14287           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14288           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14289           (neg:IEEE128
14290            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14291   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14292   "xsnmsubqp %0,%1,%2"
14293   [(set_attr "type" "qmul")
14294    (set_attr "size" "128")])
14296 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14297   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14298         (float_extend:IEEE128
14299          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14300   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14301   "xscvdpqp %0,%1"
14302   [(set_attr "type" "vecfloat")
14303    (set_attr "size" "128")])
14305 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14306 ;; point is a simple copy.
14307 (define_insn_and_split "extendkftf2"
14308   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14309         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14310   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14311   "@
14312    #
14313    xxlor %x0,%x1,%x1"
14314   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14315   [(const_int 0)]
14317   emit_note (NOTE_INSN_DELETED);
14318   DONE;
14320   [(set_attr "type" "*,veclogical")
14321    (set_attr "length" "0,4")])
14323 (define_insn_and_split "trunctfkf2"
14324   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14325         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14326   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14327   "@
14328    #
14329    xxlor %x0,%x1,%x1"
14330   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14331   [(const_int 0)]
14333   emit_note (NOTE_INSN_DELETED);
14334   DONE;
14336   [(set_attr "type" "*,veclogical")
14337    (set_attr "length" "0,4")])
14339 (define_insn "trunc<mode>df2_hw"
14340   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14341         (float_truncate:DF
14342          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14343   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14344   "xscvqpdp %0,%1"
14345   [(set_attr "type" "vecfloat")
14346    (set_attr "size" "128")])
14348 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14349 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14350 ;; conversion
14351 (define_insn_and_split "trunc<mode>sf2_hw"
14352   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14353         (float_truncate:SF
14354          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14355    (clobber (match_scratch:DF 2 "=v"))]
14356   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14357   "#"
14358   "&& 1"
14359   [(set (match_dup 2)
14360         (unspec:DF [(match_dup 1)]
14361                    UNSPEC_TRUNC_ROUND_TO_ODD))
14362    (set (match_dup 0)
14363         (float_truncate:SF (match_dup 2)))]
14365   if (GET_CODE (operands[2]) == SCRATCH)
14366     operands[2] = gen_reg_rtx (DFmode);
14368   [(set_attr "type" "vecfloat")
14369    (set_attr "length" "8")])
14371 ;; Conversion between IEEE 128-bit and integer types
14372 (define_insn "fix_<mode>di2_hw"
14373   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14374         (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14375   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14376   "xscvqpsdz %0,%1"
14377   [(set_attr "type" "vecfloat")
14378    (set_attr "size" "128")])
14380 (define_insn "fixuns_<mode>di2_hw"
14381   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14382         (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14383   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14384   "xscvqpudz %0,%1"
14385   [(set_attr "type" "vecfloat")
14386    (set_attr "size" "128")])
14388 (define_insn "fix_<mode>si2_hw"
14389   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14390         (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14391   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14392   "xscvqpswz %0,%1"
14393   [(set_attr "type" "vecfloat")
14394    (set_attr "size" "128")])
14396 (define_insn "fixuns_<mode>si2_hw"
14397   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14398         (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14399   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14400   "xscvqpuwz %0,%1"
14401   [(set_attr "type" "vecfloat")
14402    (set_attr "size" "128")])
14404 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14405 ;; floating point value to 32-bit integer to GPR in order to save it.
14406 (define_insn_and_split "*fix<uns>_<mode>_mem"
14407   [(set (match_operand:SI 0 "memory_operand" "=Z")
14408         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14409    (clobber (match_scratch:SI 2 "=v"))]
14410   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14411   "#"
14412   "&& reload_completed"
14413   [(set (match_dup 2)
14414         (any_fix:SI (match_dup 1)))
14415    (set (match_dup 0)
14416         (match_dup 2))])
14418 (define_insn "float_<mode>di2_hw"
14419   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14420         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14421   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14422   "xscvsdqp %0,%1"
14423   [(set_attr "type" "vecfloat")
14424    (set_attr "size" "128")])
14426 (define_insn_and_split "float_<mode>si2_hw"
14427   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14428         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14429    (clobber (match_scratch:DI 2 "=v"))]
14430   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14431   "#"
14432   "&& 1"
14433   [(set (match_dup 2)
14434         (sign_extend:DI (match_dup 1)))
14435    (set (match_dup 0)
14436         (float:IEEE128 (match_dup 2)))]
14438   if (GET_CODE (operands[2]) == SCRATCH)
14439     operands[2] = gen_reg_rtx (DImode);
14441   if (MEM_P (operands[1]))
14442     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14445 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14446   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14447         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14448    (clobber (match_scratch:DI 2 "=X,r,X"))]
14449   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14450   "#"
14451   "&& reload_completed"
14452   [(const_int 0)]
14454   rtx dest = operands[0];
14455   rtx src = operands[1];
14456   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14458   if (altivec_register_operand (src, <QHI:MODE>mode))
14459     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14460   else if (int_reg_operand (src, <QHI:MODE>mode))
14461     {
14462       rtx ext_di = operands[2];
14463       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14464       emit_move_insn (dest_di, ext_di);
14465     }
14466   else if (MEM_P (src))
14467     {
14468       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14469       emit_move_insn (dest_qhi, src);
14470       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14471     }
14472   else
14473     gcc_unreachable ();
14475   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14476   DONE;
14478   [(set_attr "length" "8,12,12")
14479    (set_attr "type" "vecfloat")
14480    (set_attr "size" "128")])
14482 (define_insn "floatuns_<mode>di2_hw"
14483   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14484         (unsigned_float:IEEE128
14485          (match_operand:DI 1 "altivec_register_operand" "v")))]
14486   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14487   "xscvudqp %0,%1"
14488   [(set_attr "type" "vecfloat")
14489    (set_attr "size" "128")])
14491 (define_insn_and_split "floatuns_<mode>si2_hw"
14492   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14493         (unsigned_float:IEEE128
14494          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14495    (clobber (match_scratch:DI 2 "=v"))]
14496   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14497   "#"
14498   "&& 1"
14499   [(set (match_dup 2)
14500         (zero_extend:DI (match_dup 1)))
14501    (set (match_dup 0)
14502         (float:IEEE128 (match_dup 2)))]
14504   if (GET_CODE (operands[2]) == SCRATCH)
14505     operands[2] = gen_reg_rtx (DImode);
14507   if (MEM_P (operands[1]))
14508     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14511 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14512   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14513         (unsigned_float:IEEE128
14514          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14515    (clobber (match_scratch:DI 2 "=X,r,X"))]
14516   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14517   "#"
14518   "&& reload_completed"
14519   [(const_int 0)]
14521   rtx dest = operands[0];
14522   rtx src = operands[1];
14523   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14525   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14526     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14527   else if (int_reg_operand (src, <QHI:MODE>mode))
14528     {
14529       rtx ext_di = operands[2];
14530       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14531       emit_move_insn (dest_di, ext_di);
14532     }
14533   else
14534     gcc_unreachable ();
14536   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14537   DONE;
14539   [(set_attr "length" "8,12,8")
14540    (set_attr "type" "vecfloat")
14541    (set_attr "size" "128")])
14543 ;; IEEE 128-bit round to integer built-in functions
14544 (define_insn "floor<mode>2"
14545   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14546         (unspec:IEEE128
14547          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14548          UNSPEC_FRIM))]
14549   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14550   "xsrqpi 1,%0,%1,3"
14551   [(set_attr "type" "vecfloat")
14552    (set_attr "size" "128")])
14554 (define_insn "ceil<mode>2"
14555   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14556         (unspec:IEEE128
14557          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14558          UNSPEC_FRIP))]
14559   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14560   "xsrqpi 1,%0,%1,2"
14561   [(set_attr "type" "vecfloat")
14562    (set_attr "size" "128")])
14564 (define_insn "btrunc<mode>2"
14565   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14566         (unspec:IEEE128
14567          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14568          UNSPEC_FRIZ))]
14569   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14570   "xsrqpi 1,%0,%1,1"
14571   [(set_attr "type" "vecfloat")
14572    (set_attr "size" "128")])
14574 (define_insn "round<mode>2"
14575   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14576         (unspec:IEEE128
14577          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14578          UNSPEC_FRIN))]
14579   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14580   "xsrqpi 0,%0,%1,0"
14581   [(set_attr "type" "vecfloat")
14582    (set_attr "size" "128")])
14584 ;; IEEE 128-bit instructions with round to odd semantics
14585 (define_insn "add<mode>3_odd"
14586   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14587         (unspec:IEEE128
14588          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14589           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14590          UNSPEC_ADD_ROUND_TO_ODD))]
14591   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14592   "xsaddqpo %0,%1,%2"
14593   [(set_attr "type" "vecfloat")
14594    (set_attr "size" "128")])
14596 (define_insn "sub<mode>3_odd"
14597   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14598         (unspec:IEEE128
14599          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14600           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14601          UNSPEC_SUB_ROUND_TO_ODD))]
14602   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14603   "xssubqpo %0,%1,%2"
14604   [(set_attr "type" "vecfloat")
14605    (set_attr "size" "128")])
14607 (define_insn "mul<mode>3_odd"
14608   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14609         (unspec:IEEE128
14610          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14611           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14612          UNSPEC_MUL_ROUND_TO_ODD))]
14613   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14614   "xsmulqpo %0,%1,%2"
14615   [(set_attr "type" "qmul")
14616    (set_attr "size" "128")])
14618 (define_insn "div<mode>3_odd"
14619   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14620         (unspec:IEEE128
14621          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14622           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14623          UNSPEC_DIV_ROUND_TO_ODD))]
14624   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14625   "xsdivqpo %0,%1,%2"
14626   [(set_attr "type" "vecdiv")
14627    (set_attr "size" "128")])
14629 (define_insn "sqrt<mode>2_odd"
14630   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14631         (unspec:IEEE128
14632          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14633          UNSPEC_SQRT_ROUND_TO_ODD))]
14634   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14635    "xssqrtqpo %0,%1"
14636   [(set_attr "type" "vecdiv")
14637    (set_attr "size" "128")])
14639 (define_insn "fma<mode>4_odd"
14640   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14641         (unspec:IEEE128
14642          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14643           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14644           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14645          UNSPEC_FMA_ROUND_TO_ODD))]
14646   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14647   "xsmaddqpo %0,%1,%2"
14648   [(set_attr "type" "qmul")
14649    (set_attr "size" "128")])
14651 (define_insn "*fms<mode>4_odd"
14652   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14653         (unspec:IEEE128
14654          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14655           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14656           (neg:IEEE128
14657            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14658          UNSPEC_FMA_ROUND_TO_ODD))]
14659   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14660   "xsmsubqpo %0,%1,%2"
14661   [(set_attr "type" "qmul")
14662    (set_attr "size" "128")])
14664 (define_insn "*nfma<mode>4_odd"
14665   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14666         (neg:IEEE128
14667          (unspec:IEEE128
14668           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14669            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14670            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14671           UNSPEC_FMA_ROUND_TO_ODD)))]
14672   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14673   "xsnmaddqpo %0,%1,%2"
14674   [(set_attr "type" "qmul")
14675    (set_attr "size" "128")])
14677 (define_insn "*nfms<mode>4_odd"
14678   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14679         (neg:IEEE128
14680          (unspec:IEEE128
14681           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14682            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14683            (neg:IEEE128
14684             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14685           UNSPEC_FMA_ROUND_TO_ODD)))]
14686   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14687   "xsnmsubqpo %0,%1,%2"
14688   [(set_attr "type" "qmul")
14689    (set_attr "size" "128")])
14691 (define_insn "trunc<mode>df2_odd"
14692   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14693         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14694                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14695   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14696   "xscvqpdpo %0,%1"
14697   [(set_attr "type" "vecfloat")
14698    (set_attr "size" "128")])
14700 ;; IEEE 128-bit comparisons
14701 (define_insn "*cmp<mode>_hw"
14702   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14703         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14704                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14705   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14706    "xscmpuqp %0,%1,%2"
14707   [(set_attr "type" "veccmp")
14708    (set_attr "size" "128")])
14712 (include "sync.md")
14713 (include "vector.md")
14714 (include "vsx.md")
14715 (include "altivec.md")
14716 (include "dfp.md")
14717 (include "paired.md")
14718 (include "crypto.md")
14719 (include "htm.md")