[gcc]
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob3eb415cb209b9c5413f0368ef46bb005254cce97
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2017 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; REGNOS
27 (define_constants
28   [(FIRST_GPR_REGNO             0)
29    (STACK_POINTER_REGNUM        1)
30    (TOC_REGNUM                  2)
31    (STATIC_CHAIN_REGNUM         11)
32    (HARD_FRAME_POINTER_REGNUM   31)
33    (LAST_GPR_REGNO              31)
34    (FIRST_FPR_REGNO             32)
35    (LAST_FPR_REGNO              63)
36    (LR_REGNO                    65)
37    (CTR_REGNO                   66)
38    (ARG_POINTER_REGNUM          67)
39    (CR0_REGNO                   68)
40    (CR1_REGNO                   69)
41    (CR2_REGNO                   70)
42    (CR3_REGNO                   71)
43    (CR4_REGNO                   72)
44    (CR5_REGNO                   73)
45    (CR6_REGNO                   74)
46    (CR7_REGNO                   75)
47    (MAX_CR_REGNO                75)
48    (CA_REGNO                    76)
49    (FIRST_ALTIVEC_REGNO         77)
50    (LAST_ALTIVEC_REGNO          108)
51    (VRSAVE_REGNO                109)
52    (VSCR_REGNO                  110)
53    (SPE_ACC_REGNO               111)
54    (SPEFSCR_REGNO               112)
55    (FRAME_POINTER_REGNUM        113)
56    (TFHAR_REGNO                 114)
57    (TFIAR_REGNO                 115)
58    (TEXASR_REGNO                116)
59    (FIRST_SPE_HIGH_REGNO        117)
60    (LAST_SPE_HIGH_REGNO         148)
61   ])
64 ;; UNSPEC usage
67 (define_c_enum "unspec"
68   [UNSPEC_FRSP                  ; frsp for POWER machines
69    UNSPEC_PROBE_STACK           ; probe stack memory reference
70    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
71    UNSPEC_TOC                   ; address of the TOC (more-or-less)
72    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
73    UNSPEC_MOVSI_GOT
74    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
75    UNSPEC_FCTIWZ
76    UNSPEC_FRIM
77    UNSPEC_FRIN
78    UNSPEC_FRIP
79    UNSPEC_FRIZ
80    UNSPEC_XSRDPI
81    UNSPEC_LD_MPIC               ; load_macho_picbase
82    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
83    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
84    UNSPEC_TLSGD
85    UNSPEC_TLSLD
86    UNSPEC_MOVESI_FROM_CR
87    UNSPEC_MOVESI_TO_CR
88    UNSPEC_TLSDTPREL
89    UNSPEC_TLSDTPRELHA
90    UNSPEC_TLSDTPRELLO
91    UNSPEC_TLSGOTDTPREL
92    UNSPEC_TLSTPREL
93    UNSPEC_TLSTPRELHA
94    UNSPEC_TLSTPRELLO
95    UNSPEC_TLSGOTTPREL
96    UNSPEC_TLSTLS
97    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
98    UNSPEC_MV_CR_GT              ; move_from_CR_gt_bit
99    UNSPEC_STFIWX
100    UNSPEC_POPCNTB
101    UNSPEC_FRES
102    UNSPEC_SP_SET
103    UNSPEC_SP_TEST
104    UNSPEC_SYNC
105    UNSPEC_LWSYNC
106    UNSPEC_SYNC_OP
107    UNSPEC_ATOMIC
108    UNSPEC_CMPXCHG
109    UNSPEC_XCHG
110    UNSPEC_AND
111    UNSPEC_DLMZB
112    UNSPEC_DLMZB_CR
113    UNSPEC_DLMZB_STRLEN
114    UNSPEC_RSQRT
115    UNSPEC_TOCREL
116    UNSPEC_MACHOPIC_OFFSET
117    UNSPEC_BPERM
118    UNSPEC_COPYSIGN
119    UNSPEC_PARITY
120    UNSPEC_CMPB
121    UNSPEC_FCTIW
122    UNSPEC_FCTID
123    UNSPEC_LFIWAX
124    UNSPEC_LFIWZX
125    UNSPEC_FCTIWUZ
126    UNSPEC_NOP
127    UNSPEC_GRP_END_NOP
128    UNSPEC_P8V_FMRGOW
129    UNSPEC_P8V_MTVSRWZ
130    UNSPEC_P8V_RELOAD_FROM_GPR
131    UNSPEC_P8V_MTVSRD
132    UNSPEC_P8V_XXPERMDI
133    UNSPEC_P8V_RELOAD_FROM_VSX
134    UNSPEC_ADDG6S
135    UNSPEC_CDTBCD
136    UNSPEC_CBCDTD
137    UNSPEC_DIVE
138    UNSPEC_DIVEO
139    UNSPEC_DIVEU
140    UNSPEC_DIVEUO
141    UNSPEC_UNPACK_128BIT
142    UNSPEC_PACK_128BIT
143    UNSPEC_LSQ
144    UNSPEC_FUSION_GPR
145    UNSPEC_STACK_CHECK
146    UNSPEC_FUSION_P9
147    UNSPEC_FUSION_ADDIS
148    UNSPEC_ROUND_TO_ODD
149    UNSPEC_SIGNBIT
150    UNSPEC_SF_FROM_SI
151    UNSPEC_SI_FROM_SF
152   ])
155 ;; UNSPEC_VOLATILE usage
158 (define_c_enum "unspecv"
159   [UNSPECV_BLOCK
160    UNSPECV_LL                   ; load-locked
161    UNSPECV_SC                   ; store-conditional
162    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
163    UNSPECV_EH_RR                ; eh_reg_restore
164    UNSPECV_ISYNC                ; isync instruction
165    UNSPECV_MFTB                 ; move from time base
166    UNSPECV_NLGR                 ; non-local goto receiver
167    UNSPECV_MFFS                 ; Move from FPSCR
168    UNSPECV_MTFSF                ; Move to FPSCR Fields
169    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
170   ])
173 ;; Define an insn type attribute.  This is used in function unit delay
174 ;; computations.
175 (define_attr "type"
176   "integer,two,three,
177    add,logical,shift,insert,
178    mul,halfmul,div,
179    exts,cntlz,popcnt,isel,
180    load,store,fpload,fpstore,vecload,vecstore,
181    cmp,
182    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183    cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
184    fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
185    brinc,
186    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
187    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
188    veclogical,veccmpfx,vecexts,vecmove,
189    htm,htmsimple,dfp"
190   (const_string "integer"))
192 ;; What data size does this instruction work on?
193 ;; This is used for insert, mul and others as necessary.
194 (define_attr "size" "8,16,32,64,128" (const_string "32"))
196 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
197 ;; This is used for add, logical, shift, exts, mul.
198 (define_attr "dot" "no,yes" (const_string "no"))
200 ;; Does this instruction sign-extend its result?
201 ;; This is used for load insns.
202 (define_attr "sign_extend" "no,yes" (const_string "no"))
204 ;; Does this instruction use indexed (that is, reg+reg) addressing?
205 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
206 ;; it is automatically set based on that.  If a load or store instruction
207 ;; has fewer than two operands it needs to set this attribute manually
208 ;; or the compiler will crash.
209 (define_attr "indexed" "no,yes"
210   (if_then_else (ior (match_operand 0 "indexed_address_mem")
211                      (match_operand 1 "indexed_address_mem"))
212                 (const_string "yes")
213                 (const_string "no")))
215 ;; Does this instruction use update addressing?
216 ;; This is used for load and store insns.  See the comments for "indexed".
217 (define_attr "update" "no,yes"
218   (if_then_else (ior (match_operand 0 "update_address_mem")
219                      (match_operand 1 "update_address_mem"))
220                 (const_string "yes")
221                 (const_string "no")))
223 ;; Is this instruction using operands[2] as shift amount, and can that be a
224 ;; register?
225 ;; This is used for shift insns.
226 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
228 ;; Is this instruction using a shift amount from a register?
229 ;; This is used for shift insns.
230 (define_attr "var_shift" "no,yes"
231   (if_then_else (and (eq_attr "type" "shift")
232                      (eq_attr "maybe_var_shift" "yes"))
233                 (if_then_else (match_operand 2 "gpc_reg_operand")
234                               (const_string "yes")
235                               (const_string "no"))
236                 (const_string "no")))
238 ;; Is copying of this instruction disallowed?
239 (define_attr "cannot_copy" "no,yes" (const_string "no"))
241 ;; Define floating point instruction sub-types for use with Xfpu.md
242 (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"))
244 ;; Length (in bytes).
245 ; '(pc)' in the following doesn't include the instruction itself; it is
246 ; calculated as if the instruction had zero size.
247 (define_attr "length" ""
248   (if_then_else (eq_attr "type" "branch")
249                 (if_then_else (and (ge (minus (match_dup 0) (pc))
250                                        (const_int -32768))
251                                    (lt (minus (match_dup 0) (pc))
252                                        (const_int 32764)))
253                               (const_int 4)
254                               (const_int 8))
255                 (const_int 4)))
257 ;; Processor type -- this attribute must exactly match the processor_type
258 ;; enumeration in rs6000-opts.h.
259 (define_attr "cpu"
260   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
261    ppc750,ppc7400,ppc7450,
262    ppc403,ppc405,ppc440,ppc476,
263    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
264    power4,power5,power6,power7,power8,power9,
265    rs64a,mpccore,cell,ppca2,titan"
266   (const (symbol_ref "rs6000_cpu_attr")))
269 ;; If this instruction is microcoded on the CELL processor
270 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
271 (define_attr "cell_micro" "not,conditional,always"
272   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
273                           (eq_attr "dot" "yes"))
274                      (and (eq_attr "type" "load")
275                           (eq_attr "sign_extend" "yes"))
276                      (and (eq_attr "type" "shift")
277                           (eq_attr "var_shift" "yes")))
278                 (const_string "always")
279                 (const_string "not")))
281 (automata_option "ndfa")
283 (include "rs64.md")
284 (include "mpc.md")
285 (include "40x.md")
286 (include "440.md")
287 (include "476.md")
288 (include "601.md")
289 (include "603.md")
290 (include "6xx.md")
291 (include "7xx.md")
292 (include "7450.md")
293 (include "8540.md")
294 (include "e300c2c3.md")
295 (include "e500mc.md")
296 (include "e500mc64.md")
297 (include "e5500.md")
298 (include "e6500.md")
299 (include "power4.md")
300 (include "power5.md")
301 (include "power6.md")
302 (include "power7.md")
303 (include "power8.md")
304 (include "power9.md")
305 (include "cell.md")
306 (include "xfpu.md")
307 (include "a2.md")
308 (include "titan.md")
310 (include "predicates.md")
311 (include "constraints.md")
313 (include "darwin.md")
316 ;; Mode iterators
318 ; This mode iterator allows :GPR to be used to indicate the allowable size
319 ; of whole values in GPRs.
320 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
322 ; Any supported integer mode.
323 (define_mode_iterator INT [QI HI SI DI TI PTI])
325 ; Any supported integer mode that fits in one register.
326 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
328 ; Integer modes supported in VSX registers with ISA 3.0 instructions
329 (define_mode_iterator INT_ISA3 [QI HI SI DI])
331 ; Everything we can extend QImode to.
332 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
334 ; Everything we can extend HImode to.
335 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
337 ; Everything we can extend SImode to.
338 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
340 ; QImode or HImode for small integer moves and small atomic ops
341 (define_mode_iterator QHI [QI HI])
343 ; QImode, HImode, SImode for fused ops only for GPR loads
344 (define_mode_iterator QHSI [QI HI SI])
346 ; HImode or SImode for sign extended fusion ops
347 (define_mode_iterator HSI [HI SI])
349 ; SImode or DImode, even if DImode doesn't fit in GPRs.
350 (define_mode_iterator SDI [SI DI])
352 ; Types that can be fused with an ADDIS instruction to load or store a GPR
353 ; register that has reg+offset addressing.
354 (define_mode_iterator GPR_FUSION [QI
355                                   HI
356                                   SI
357                                   (DI   "TARGET_POWERPC64")
358                                   SF
359                                   (DF   "TARGET_POWERPC64")])
361 ; Types that can be fused with an ADDIS instruction to load or store a FPR
362 ; register that has reg+offset addressing.
363 (define_mode_iterator FPR_FUSION [DI SF DF])
365 ; The size of a pointer.  Also, the size of the value that a record-condition
366 ; (one with a '.') will compare; and the size used for arithmetic carries.
367 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
369 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
370 ; PTImode is GPR only)
371 (define_mode_iterator TI2 [TI PTI])
373 ; Any hardware-supported floating-point mode
374 (define_mode_iterator FP [
375   (SF "TARGET_HARD_FLOAT 
376    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
377   (DF "TARGET_HARD_FLOAT 
378    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
379   (TF "TARGET_HARD_FLOAT
380    && (TARGET_FPRS || TARGET_E500_DOUBLE)
381    && TARGET_LONG_DOUBLE_128")
382   (IF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")
383   (KF "TARGET_FLOAT128_TYPE")
384   (DD "TARGET_DFP")
385   (TD "TARGET_DFP")])
387 ; Any fma capable floating-point mode.
388 (define_mode_iterator FMA_F [
389   (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
390   (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
391        || VECTOR_UNIT_VSX_P (DFmode)")
392   (V2SF "TARGET_PAIRED_FLOAT")
393   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
394   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
395   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
396   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
397   ])
399 ; Floating point move iterators to combine binary and decimal moves
400 (define_mode_iterator FMOVE32 [SF SD])
401 (define_mode_iterator FMOVE64 [DF DD])
402 (define_mode_iterator FMOVE64X [DI DF DD])
403 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
404                                 (IF "FLOAT128_IBM_P (IFmode)")
405                                 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
407 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
408                                     (IF "FLOAT128_2REG_P (IFmode)")
409                                     (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
411 ; Iterators for 128 bit types for direct move
412 (define_mode_iterator FMOVE128_GPR [(TI    "TARGET_VSX_TIMODE")
413                                     (V16QI "")
414                                     (V8HI  "")
415                                     (V4SI  "")
416                                     (V4SF  "")
417                                     (V2DI  "")
418                                     (V2DF  "")
419                                     (V1TI  "")
420                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
421                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
423 ; Iterator for 128-bit VSX types for pack/unpack
424 (define_mode_iterator FMOVE128_VSX [V1TI KF])
426 ; Whether a floating point move is ok, don't allow SD without hardware FP
427 (define_mode_attr fmove_ok [(SF "")
428                             (DF "")
429                             (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
430                             (DD "")])
432 ; Convert REAL_VALUE to the appropriate bits
433 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
434                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
435                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
436                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
438 ; Whether 0.0 has an all-zero bit pattern
439 (define_mode_attr zero_fp [(SF "j")
440                            (DF "j")
441                            (TF "j")
442                            (IF "j")
443                            (KF "j")
444                            (SD "wn")
445                            (DD "wn")
446                            (TD "wn")])
448 ; Definitions for 64-bit VSX
449 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
451 ; Definitions for 64-bit direct move
452 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
454 ; Definitions for 64-bit use of altivec registers
455 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
457 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
458 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
460 ; These modes do not fit in integer registers in 32-bit mode.
461 ; but on e500v2, the gpr are 64 bit registers
462 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
464 ; Iterator for reciprocal estimate instructions
465 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
467 ; Iterator for just SF/DF
468 (define_mode_iterator SFDF [SF DF])
470 ; Like SFDF, but a different name to match conditional move where the
471 ; comparison operands may be a different mode than the input operands.
472 (define_mode_iterator SFDF2 [SF DF])
474 ; Iterator for 128-bit floating point that uses the IBM double-double format
475 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
476                               (TF "FLOAT128_IBM_P (TFmode)")])
478 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
479 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
480                                (TF "FLOAT128_IEEE_P (TFmode)")])
482 ; Iterator for 128-bit floating point
483 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
484                                 (IF "TARGET_FLOAT128_TYPE")
485                                 (TF "TARGET_LONG_DOUBLE_128")])
487 ; Iterator for signbit on 64-bit machines with direct move
488 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
489                                (TF "FLOAT128_VECTOR_P (TFmode)")])
491 ; Iterator for ISA 3.0 supported floating point types
492 (define_mode_iterator FP_ISA3 [SF DF])
494 ; SF/DF suffix for traditional floating instructions
495 (define_mode_attr Ftrad         [(SF "s") (DF "")])
497 ; SF/DF suffix for VSX instructions
498 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
500 ; SF/DF constraint for arithmetic on traditional floating point registers
501 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
503 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
504 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
505 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
506 ; format.
507 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
509 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
510 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
511 ; instructions added in ISA 2.07 (power8)
512 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
514 ; SF/DF constraint for arithmetic on altivec registers
515 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
517 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
518 (define_mode_attr Fs            [(SF "s")  (DF "d")])
520 ; FRE/FRES support
521 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
522 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
524 ; Conditional returns.
525 (define_code_iterator any_return [return simple_return])
526 (define_code_attr return_pred [(return "direct_return ()")
527                                (simple_return "1")])
528 (define_code_attr return_str [(return "") (simple_return "simple_")])
530 ; Logical operators.
531 (define_code_iterator iorxor            [ior xor])
532 (define_code_iterator and_ior_xor       [and ior xor])
534 ; Signed/unsigned variants of ops.
535 (define_code_iterator any_extend        [sign_extend zero_extend])
536 (define_code_iterator any_fix           [fix unsigned_fix])
537 (define_code_iterator any_float         [float unsigned_float])
539 (define_code_attr u  [(sign_extend      "")
540                       (zero_extend      "u")
541                       (fix              "")
542                       (unsigned_fix     "u")])
544 (define_code_attr su [(sign_extend      "s")
545                       (zero_extend      "u")
546                       (fix              "s")
547                       (unsigned_fix     "s")
548                       (float            "s")
549                       (unsigned_float   "u")])
551 (define_code_attr az [(sign_extend      "a")
552                       (zero_extend      "z")
553                       (fix              "a")
554                       (unsigned_fix     "z")
555                       (float            "a")
556                       (unsigned_float   "z")])
558 (define_code_attr uns [(fix             "")
559                        (unsigned_fix    "uns")
560                        (float           "")
561                        (unsigned_float  "uns")])
563 ; Various instructions that come in SI and DI forms.
564 ; A generic w/d attribute, for things like cmpw/cmpd.
565 (define_mode_attr wd [(QI    "b")
566                       (HI    "h")
567                       (SI    "w")
568                       (DI    "d")
569                       (V16QI "b")
570                       (V8HI  "h")
571                       (V4SI  "w")
572                       (V2DI  "d")
573                       (V1TI  "q")
574                       (TI    "q")])
576 ;; How many bits in this mode?
577 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
579 ; DImode bits
580 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
582 ;; ISEL/ISEL64 target selection
583 (define_mode_attr sel [(SI "") (DI "64")])
585 ;; Bitmask for shift instructions
586 (define_mode_attr hH [(SI "h") (DI "H")])
588 ;; A mode twice the size of the given mode
589 (define_mode_attr dmode [(SI "di") (DI "ti")])
590 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
592 ;; Suffix for reload patterns
593 (define_mode_attr ptrsize [(SI "32bit")
594                            (DI "64bit")])
596 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
597                             (DI "TARGET_64BIT")])
599 (define_mode_attr mptrsize [(SI "si")
600                             (DI "di")])
602 (define_mode_attr ptrload [(SI "lwz")
603                            (DI "ld")])
605 (define_mode_attr ptrm [(SI "m")
606                         (DI "Y")])
608 (define_mode_attr rreg [(SF   "f")
609                         (DF   "ws")
610                         (TF   "f")
611                         (TD   "f")
612                         (V4SF "wf")
613                         (V2DF "wd")])
615 (define_mode_attr rreg2 [(SF   "f")
616                          (DF   "d")])
618 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
619                                  (DF "TARGET_FCFID")])
621 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
622                                 (DF "TARGET_E500_DOUBLE")])
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")])
705 ;; Start with fixed-point load and store insns.  Here we put only the more
706 ;; complex forms.  Basic data transfer is done later.
708 (define_insn "zero_extendqi<mode>2"
709   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
710         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
711   ""
712   "@
713    lbz%U1%X1 %0,%1
714    rlwinm %0,%1,0,0xff
715    lxsibzx %x0,%y1
716    vextractub %0,%1,7"
717   [(set_attr "type" "load,shift,fpload,vecperm")])
719 (define_insn_and_split "*zero_extendqi<mode>2_dot"
720   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
721         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
722                     (const_int 0)))
723    (clobber (match_scratch:EXTQI 0 "=r,r"))]
724   "rs6000_gen_cell_microcode"
725   "@
726    andi. %0,%1,0xff
727    #"
728   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
729   [(set (match_dup 0)
730         (zero_extend:EXTQI (match_dup 1)))
731    (set (match_dup 2)
732         (compare:CC (match_dup 0)
733                     (const_int 0)))]
734   ""
735   [(set_attr "type" "logical")
736    (set_attr "dot" "yes")
737    (set_attr "length" "4,8")])
739 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
740   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
741         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
742                     (const_int 0)))
743    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
744         (zero_extend:EXTQI (match_dup 1)))]
745   "rs6000_gen_cell_microcode"
746   "@
747    andi. %0,%1,0xff
748    #"
749   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
750   [(set (match_dup 0)
751         (zero_extend:EXTQI (match_dup 1)))
752    (set (match_dup 2)
753         (compare:CC (match_dup 0)
754                     (const_int 0)))]
755   ""
756   [(set_attr "type" "logical")
757    (set_attr "dot" "yes")
758    (set_attr "length" "4,8")])
761 (define_insn "zero_extendhi<mode>2"
762   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
763         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
764   ""
765   "@
766    lhz%U1%X1 %0,%1
767    rlwinm %0,%1,0,0xffff
768    lxsihzx %x0,%y1
769    vextractuh %0,%1,6"
770   [(set_attr "type" "load,shift,fpload,vecperm")])
772 (define_insn_and_split "*zero_extendhi<mode>2_dot"
773   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
774         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
775                     (const_int 0)))
776    (clobber (match_scratch:EXTHI 0 "=r,r"))]
777   "rs6000_gen_cell_microcode"
778   "@
779    andi. %0,%1,0xffff
780    #"
781   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
782   [(set (match_dup 0)
783         (zero_extend:EXTHI (match_dup 1)))
784    (set (match_dup 2)
785         (compare:CC (match_dup 0)
786                     (const_int 0)))]
787   ""
788   [(set_attr "type" "logical")
789    (set_attr "dot" "yes")
790    (set_attr "length" "4,8")])
792 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
793   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
794         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
795                     (const_int 0)))
796    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
797         (zero_extend:EXTHI (match_dup 1)))]
798   "rs6000_gen_cell_microcode"
799   "@
800    andi. %0,%1,0xffff
801    #"
802   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
803   [(set (match_dup 0)
804         (zero_extend:EXTHI (match_dup 1)))
805    (set (match_dup 2)
806         (compare:CC (match_dup 0)
807                     (const_int 0)))]
808   ""
809   [(set_attr "type" "logical")
810    (set_attr "dot" "yes")
811    (set_attr "length" "4,8")])
814 (define_insn "zero_extendsi<mode>2"
815   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
816         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
817   ""
818   "@
819    lwz%U1%X1 %0,%1
820    rldicl %0,%1,0,32
821    lfiwzx %0,%y1
822    lxsiwzx %x0,%y1
823    mtvsrwz %x0,%1
824    mfvsrwz %0,%x1
825    xxextractuw %x0,%x1,4"
826   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
828 (define_insn_and_split "*zero_extendsi<mode>2_dot"
829   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
830         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
831                     (const_int 0)))
832    (clobber (match_scratch:EXTSI 0 "=r,r"))]
833   "rs6000_gen_cell_microcode"
834   "@
835    rldicl. %0,%1,0,32
836    #"
837   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
838   [(set (match_dup 0)
839         (zero_extend:DI (match_dup 1)))
840    (set (match_dup 2)
841         (compare:CC (match_dup 0)
842                     (const_int 0)))]
843   ""
844   [(set_attr "type" "shift")
845    (set_attr "dot" "yes")
846    (set_attr "length" "4,8")])
848 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
849   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
850         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
851                     (const_int 0)))
852    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
853         (zero_extend:EXTSI (match_dup 1)))]
854   "rs6000_gen_cell_microcode"
855   "@
856    rldicl. %0,%1,0,32
857    #"
858   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
859   [(set (match_dup 0)
860         (zero_extend:EXTSI (match_dup 1)))
861    (set (match_dup 2)
862         (compare:CC (match_dup 0)
863                     (const_int 0)))]
864   ""
865   [(set_attr "type" "shift")
866    (set_attr "dot" "yes")
867    (set_attr "length" "4,8")])
870 (define_insn "extendqi<mode>2"
871   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
872         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
873   ""
874   "@
875    extsb %0,%1
876    vextsb2d %0,%1"
877   [(set_attr "type" "exts,vecperm")])
879 (define_insn_and_split "*extendqi<mode>2_dot"
880   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
881         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
882                     (const_int 0)))
883    (clobber (match_scratch:EXTQI 0 "=r,r"))]
884   "rs6000_gen_cell_microcode"
885   "@
886    extsb. %0,%1
887    #"
888   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
889   [(set (match_dup 0)
890         (sign_extend:EXTQI (match_dup 1)))
891    (set (match_dup 2)
892         (compare:CC (match_dup 0)
893                     (const_int 0)))]
894   ""
895   [(set_attr "type" "exts")
896    (set_attr "dot" "yes")
897    (set_attr "length" "4,8")])
899 (define_insn_and_split "*extendqi<mode>2_dot2"
900   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
901         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
902                     (const_int 0)))
903    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
904         (sign_extend:EXTQI (match_dup 1)))]
905   "rs6000_gen_cell_microcode"
906   "@
907    extsb. %0,%1
908    #"
909   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
910   [(set (match_dup 0)
911         (sign_extend:EXTQI (match_dup 1)))
912    (set (match_dup 2)
913         (compare:CC (match_dup 0)
914                     (const_int 0)))]
915   ""
916   [(set_attr "type" "exts")
917    (set_attr "dot" "yes")
918    (set_attr "length" "4,8")])
921 (define_expand "extendhi<mode>2"
922   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
923         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
924   ""
925   "")
927 (define_insn "*extendhi<mode>2"
928   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
929         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
930   "rs6000_gen_cell_microcode || TARGET_VSX_SMALL_INTEGER"
931   "@
932    lha%U1%X1 %0,%1
933    extsh %0,%1
934    #
935    vextsh2d %0,%1"
936   [(set_attr "type" "load,exts,fpload,vecperm")
937    (set_attr "sign_extend" "yes")
938    (set_attr "length" "4,4,8,4")])
940 (define_split
941   [(set (match_operand:EXTHI 0 "altivec_register_operand")
942         (sign_extend:EXTHI
943          (match_operand:HI 1 "indexed_or_indirect_operand")))]
944   "TARGET_P9_VECTOR && reload_completed"
945   [(set (match_dup 2)
946         (match_dup 1))
947    (set (match_dup 0)
948         (sign_extend:EXTHI (match_dup 2)))]
950   operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));
953 (define_insn "*extendhi<mode>2_noload"
954   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
955         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
956   "!rs6000_gen_cell_microcode"
957   "extsh %0,%1"
958   [(set_attr "type" "exts")])
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   "rs6000_gen_cell_microcode"
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   "rs6000_gen_cell_microcode"
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" "=r,r,wl,wu,wj,wK,wH")
1004         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK,wH")))]
1005   ""
1006   "@
1007    lwa%U1%X1 %0,%1
1008    extsw %0,%1
1009    lfiwax %0,%y1
1010    lxsiwax %x0,%y1
1011    mtvsrwa %x0,%1
1012    vextsw2d %0,%1
1013    #"
1014   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm")
1015    (set_attr "sign_extend" "yes")
1016    (set_attr "length" "4,4,4,4,4,4,8")])
1018 (define_split
1019   [(set (match_operand:DI 0 "altivec_register_operand")
1020         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1021   "TARGET_VSX_SMALL_INTEGER && TARGET_P8_VECTOR && !TARGET_P9_VECTOR
1022    && reload_completed"
1023   [(const_int 0)]
1025   rtx dest = operands[0];
1026   rtx src = operands[1];
1027   int dest_regno = REGNO (dest);
1028   int src_regno = REGNO (src);
1029   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1030   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1032   if (VECTOR_ELT_ORDER_BIG)
1033     {
1034       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1035       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1036     }
1037   else
1038     {
1039       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1040       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1041     }
1042   DONE;
1045 (define_insn_and_split "*extendsi<mode>2_dot"
1046   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1047         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1048                     (const_int 0)))
1049    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1050   "rs6000_gen_cell_microcode"
1051   "@
1052    extsw. %0,%1
1053    #"
1054   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1055   [(set (match_dup 0)
1056         (sign_extend:EXTSI (match_dup 1)))
1057    (set (match_dup 2)
1058         (compare:CC (match_dup 0)
1059                     (const_int 0)))]
1060   ""
1061   [(set_attr "type" "exts")
1062    (set_attr "dot" "yes")
1063    (set_attr "length" "4,8")])
1065 (define_insn_and_split "*extendsi<mode>2_dot2"
1066   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1067         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1068                     (const_int 0)))
1069    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1070         (sign_extend:EXTSI (match_dup 1)))]
1071   "rs6000_gen_cell_microcode"
1072   "@
1073    extsw. %0,%1
1074    #"
1075   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1076   [(set (match_dup 0)
1077         (sign_extend:EXTSI (match_dup 1)))
1078    (set (match_dup 2)
1079         (compare:CC (match_dup 0)
1080                     (const_int 0)))]
1081   ""
1082   [(set_attr "type" "exts")
1083    (set_attr "dot" "yes")
1084    (set_attr "length" "4,8")])
1086 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1088 (define_insn "*macchwc"
1089   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1090         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1091                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1092                                        (const_int 16))
1093                                       (sign_extend:SI
1094                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1095                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1096                     (const_int 0)))
1097    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1098         (plus:SI (mult:SI (ashiftrt:SI
1099                            (match_dup 2)
1100                            (const_int 16))
1101                           (sign_extend:SI
1102                            (match_dup 1)))
1103                  (match_dup 4)))]
1104   "TARGET_MULHW"
1105   "macchw. %0,%1,%2"
1106   [(set_attr "type" "halfmul")])
1108 (define_insn "*macchw"
1109   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1110         (plus:SI (mult:SI (ashiftrt:SI
1111                            (match_operand:SI 2 "gpc_reg_operand" "r")
1112                            (const_int 16))
1113                           (sign_extend:SI
1114                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1115                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1116   "TARGET_MULHW"
1117   "macchw %0,%1,%2"
1118   [(set_attr "type" "halfmul")])
1120 (define_insn "*macchwuc"
1121   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1122         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1123                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1124                                        (const_int 16))
1125                                       (zero_extend:SI
1126                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1127                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1128                     (const_int 0)))
1129    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1130         (plus:SI (mult:SI (lshiftrt:SI
1131                            (match_dup 2)
1132                            (const_int 16))
1133                           (zero_extend:SI
1134                            (match_dup 1)))
1135                  (match_dup 4)))]
1136   "TARGET_MULHW"
1137   "macchwu. %0,%1,%2"
1138   [(set_attr "type" "halfmul")])
1140 (define_insn "*macchwu"
1141   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1142         (plus:SI (mult:SI (lshiftrt:SI
1143                            (match_operand:SI 2 "gpc_reg_operand" "r")
1144                            (const_int 16))
1145                           (zero_extend:SI
1146                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1147                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1148   "TARGET_MULHW"
1149   "macchwu %0,%1,%2"
1150   [(set_attr "type" "halfmul")])
1152 (define_insn "*machhwc"
1153   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1154         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1155                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1156                                        (const_int 16))
1157                                       (ashiftrt:SI
1158                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1159                                        (const_int 16)))
1160                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1161                     (const_int 0)))
1162    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1163         (plus:SI (mult:SI (ashiftrt:SI
1164                            (match_dup 1)
1165                            (const_int 16))
1166                           (ashiftrt:SI
1167                            (match_dup 2)
1168                            (const_int 16)))
1169                  (match_dup 4)))]
1170   "TARGET_MULHW"
1171   "machhw. %0,%1,%2"
1172   [(set_attr "type" "halfmul")])
1174 (define_insn "*machhw"
1175   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1176         (plus:SI (mult:SI (ashiftrt:SI
1177                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1178                            (const_int 16))
1179                           (ashiftrt:SI
1180                            (match_operand:SI 2 "gpc_reg_operand" "r")
1181                            (const_int 16)))
1182                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1183   "TARGET_MULHW"
1184   "machhw %0,%1,%2"
1185   [(set_attr "type" "halfmul")])
1187 (define_insn "*machhwuc"
1188   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1189         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1190                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1191                                        (const_int 16))
1192                                       (lshiftrt:SI
1193                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1194                                        (const_int 16)))
1195                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1196                     (const_int 0)))
1197    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1198         (plus:SI (mult:SI (lshiftrt:SI
1199                            (match_dup 1)
1200                            (const_int 16))
1201                           (lshiftrt:SI
1202                            (match_dup 2)
1203                            (const_int 16)))
1204                  (match_dup 4)))]
1205   "TARGET_MULHW"
1206   "machhwu. %0,%1,%2"
1207   [(set_attr "type" "halfmul")])
1209 (define_insn "*machhwu"
1210   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1211         (plus:SI (mult:SI (lshiftrt:SI
1212                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1213                            (const_int 16))
1214                           (lshiftrt:SI
1215                            (match_operand:SI 2 "gpc_reg_operand" "r")
1216                            (const_int 16)))
1217                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1218   "TARGET_MULHW"
1219   "machhwu %0,%1,%2"
1220   [(set_attr "type" "halfmul")])
1222 (define_insn "*maclhwc"
1223   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1224         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1225                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1226                                       (sign_extend:SI
1227                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1228                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1229                     (const_int 0)))
1230    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1231         (plus:SI (mult:SI (sign_extend:SI
1232                            (match_dup 1))
1233                           (sign_extend:SI
1234                            (match_dup 2)))
1235                  (match_dup 4)))]
1236   "TARGET_MULHW"
1237   "maclhw. %0,%1,%2"
1238   [(set_attr "type" "halfmul")])
1240 (define_insn "*maclhw"
1241   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1242         (plus:SI (mult:SI (sign_extend:SI
1243                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1244                           (sign_extend:SI
1245                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1246                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1247   "TARGET_MULHW"
1248   "maclhw %0,%1,%2"
1249   [(set_attr "type" "halfmul")])
1251 (define_insn "*maclhwuc"
1252   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1253         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1254                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1255                                       (zero_extend:SI
1256                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1257                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1258                     (const_int 0)))
1259    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1260         (plus:SI (mult:SI (zero_extend:SI
1261                            (match_dup 1))
1262                           (zero_extend:SI
1263                            (match_dup 2)))
1264                  (match_dup 4)))]
1265   "TARGET_MULHW"
1266   "maclhwu. %0,%1,%2"
1267   [(set_attr "type" "halfmul")])
1269 (define_insn "*maclhwu"
1270   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1271         (plus:SI (mult:SI (zero_extend:SI
1272                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1273                           (zero_extend:SI
1274                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1275                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1276   "TARGET_MULHW"
1277   "maclhwu %0,%1,%2"
1278   [(set_attr "type" "halfmul")])
1280 (define_insn "*nmacchwc"
1281   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1282         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1283                               (mult:SI (ashiftrt:SI
1284                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1285                                         (const_int 16))
1286                                        (sign_extend:SI
1287                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1288                     (const_int 0)))
1289    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1290         (minus:SI (match_dup 4)
1291                   (mult:SI (ashiftrt:SI
1292                             (match_dup 2)
1293                             (const_int 16))
1294                            (sign_extend:SI
1295                             (match_dup 1)))))]
1296   "TARGET_MULHW"
1297   "nmacchw. %0,%1,%2"
1298   [(set_attr "type" "halfmul")])
1300 (define_insn "*nmacchw"
1301   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1302         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1303                   (mult:SI (ashiftrt:SI
1304                             (match_operand:SI 2 "gpc_reg_operand" "r")
1305                             (const_int 16))
1306                            (sign_extend:SI
1307                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1308   "TARGET_MULHW"
1309   "nmacchw %0,%1,%2"
1310   [(set_attr "type" "halfmul")])
1312 (define_insn "*nmachhwc"
1313   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1314         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1315                               (mult:SI (ashiftrt:SI
1316                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1317                                         (const_int 16))
1318                                        (ashiftrt:SI
1319                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1320                                         (const_int 16))))
1321                     (const_int 0)))
1322    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1323         (minus:SI (match_dup 4)
1324                   (mult:SI (ashiftrt:SI
1325                             (match_dup 1)
1326                             (const_int 16))
1327                            (ashiftrt:SI
1328                             (match_dup 2)
1329                             (const_int 16)))))]
1330   "TARGET_MULHW"
1331   "nmachhw. %0,%1,%2"
1332   [(set_attr "type" "halfmul")])
1334 (define_insn "*nmachhw"
1335   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1336         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1337                   (mult:SI (ashiftrt:SI
1338                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1339                             (const_int 16))
1340                            (ashiftrt:SI
1341                             (match_operand:SI 2 "gpc_reg_operand" "r")
1342                             (const_int 16)))))]
1343   "TARGET_MULHW"
1344   "nmachhw %0,%1,%2"
1345   [(set_attr "type" "halfmul")])
1347 (define_insn "*nmaclhwc"
1348   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1349         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1350                               (mult:SI (sign_extend:SI
1351                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1352                                        (sign_extend:SI
1353                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1354                     (const_int 0)))
1355    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1356         (minus:SI (match_dup 4)
1357                   (mult:SI (sign_extend:SI
1358                             (match_dup 1))
1359                            (sign_extend:SI
1360                             (match_dup 2)))))]
1361   "TARGET_MULHW"
1362   "nmaclhw. %0,%1,%2"
1363   [(set_attr "type" "halfmul")])
1365 (define_insn "*nmaclhw"
1366   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1367         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1368                   (mult:SI (sign_extend:SI
1369                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1370                            (sign_extend:SI
1371                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1372   "TARGET_MULHW"
1373   "nmaclhw %0,%1,%2"
1374   [(set_attr "type" "halfmul")])
1376 (define_insn "*mulchwc"
1377   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1378         (compare:CC (mult:SI (ashiftrt:SI
1379                               (match_operand:SI 2 "gpc_reg_operand" "r")
1380                               (const_int 16))
1381                              (sign_extend:SI
1382                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1383                     (const_int 0)))
1384    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1385         (mult:SI (ashiftrt:SI
1386                   (match_dup 2)
1387                   (const_int 16))
1388                  (sign_extend:SI
1389                   (match_dup 1))))]
1390   "TARGET_MULHW"
1391   "mulchw. %0,%1,%2"
1392   [(set_attr "type" "halfmul")])
1394 (define_insn "*mulchw"
1395   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1396         (mult:SI (ashiftrt:SI
1397                   (match_operand:SI 2 "gpc_reg_operand" "r")
1398                   (const_int 16))
1399                  (sign_extend:SI
1400                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1401   "TARGET_MULHW"
1402   "mulchw %0,%1,%2"
1403   [(set_attr "type" "halfmul")])
1405 (define_insn "*mulchwuc"
1406   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1407         (compare:CC (mult:SI (lshiftrt:SI
1408                               (match_operand:SI 2 "gpc_reg_operand" "r")
1409                               (const_int 16))
1410                              (zero_extend:SI
1411                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1412                     (const_int 0)))
1413    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1414         (mult:SI (lshiftrt:SI
1415                   (match_dup 2)
1416                   (const_int 16))
1417                  (zero_extend:SI
1418                   (match_dup 1))))]
1419   "TARGET_MULHW"
1420   "mulchwu. %0,%1,%2"
1421   [(set_attr "type" "halfmul")])
1423 (define_insn "*mulchwu"
1424   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1425         (mult:SI (lshiftrt:SI
1426                   (match_operand:SI 2 "gpc_reg_operand" "r")
1427                   (const_int 16))
1428                  (zero_extend:SI
1429                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1430   "TARGET_MULHW"
1431   "mulchwu %0,%1,%2"
1432   [(set_attr "type" "halfmul")])
1434 (define_insn "*mulhhwc"
1435   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1436         (compare:CC (mult:SI (ashiftrt:SI
1437                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1438                               (const_int 16))
1439                              (ashiftrt:SI
1440                               (match_operand:SI 2 "gpc_reg_operand" "r")
1441                               (const_int 16)))
1442                     (const_int 0)))
1443    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1444         (mult:SI (ashiftrt:SI
1445                   (match_dup 1)
1446                   (const_int 16))
1447                  (ashiftrt:SI
1448                   (match_dup 2)
1449                   (const_int 16))))]
1450   "TARGET_MULHW"
1451   "mulhhw. %0,%1,%2"
1452   [(set_attr "type" "halfmul")])
1454 (define_insn "*mulhhw"
1455   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1456         (mult:SI (ashiftrt:SI
1457                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1458                   (const_int 16))
1459                  (ashiftrt:SI
1460                   (match_operand:SI 2 "gpc_reg_operand" "r")
1461                   (const_int 16))))]
1462   "TARGET_MULHW"
1463   "mulhhw %0,%1,%2"
1464   [(set_attr "type" "halfmul")])
1466 (define_insn "*mulhhwuc"
1467   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1468         (compare:CC (mult:SI (lshiftrt:SI
1469                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1470                               (const_int 16))
1471                              (lshiftrt:SI
1472                               (match_operand:SI 2 "gpc_reg_operand" "r")
1473                               (const_int 16)))
1474                     (const_int 0)))
1475    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1476         (mult:SI (lshiftrt:SI
1477                   (match_dup 1)
1478                   (const_int 16))
1479                  (lshiftrt:SI
1480                   (match_dup 2)
1481                   (const_int 16))))]
1482   "TARGET_MULHW"
1483   "mulhhwu. %0,%1,%2"
1484   [(set_attr "type" "halfmul")])
1486 (define_insn "*mulhhwu"
1487   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1488         (mult:SI (lshiftrt:SI
1489                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1490                   (const_int 16))
1491                  (lshiftrt:SI
1492                   (match_operand:SI 2 "gpc_reg_operand" "r")
1493                   (const_int 16))))]
1494   "TARGET_MULHW"
1495   "mulhhwu %0,%1,%2"
1496   [(set_attr "type" "halfmul")])
1498 (define_insn "*mullhwc"
1499   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1500         (compare:CC (mult:SI (sign_extend:SI
1501                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1502                              (sign_extend:SI
1503                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1504                     (const_int 0)))
1505    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1506         (mult:SI (sign_extend:SI
1507                   (match_dup 1))
1508                  (sign_extend:SI
1509                   (match_dup 2))))]
1510   "TARGET_MULHW"
1511   "mullhw. %0,%1,%2"
1512   [(set_attr "type" "halfmul")])
1514 (define_insn "*mullhw"
1515   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1516         (mult:SI (sign_extend:SI
1517                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1518                  (sign_extend:SI
1519                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1520   "TARGET_MULHW"
1521   "mullhw %0,%1,%2"
1522   [(set_attr "type" "halfmul")])
1524 (define_insn "*mullhwuc"
1525   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1526         (compare:CC (mult:SI (zero_extend:SI
1527                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1528                              (zero_extend:SI
1529                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1530                     (const_int 0)))
1531    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1532         (mult:SI (zero_extend:SI
1533                   (match_dup 1))
1534                  (zero_extend:SI
1535                   (match_dup 2))))]
1536   "TARGET_MULHW"
1537   "mullhwu. %0,%1,%2"
1538   [(set_attr "type" "halfmul")])
1540 (define_insn "*mullhwu"
1541   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1542         (mult:SI (zero_extend:SI
1543                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1544                  (zero_extend:SI
1545                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1546   "TARGET_MULHW"
1547   "mullhwu %0,%1,%2"
1548   [(set_attr "type" "halfmul")])
1550 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1551 (define_insn "dlmzb"
1552   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1553         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1554                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1555                    UNSPEC_DLMZB_CR))
1556    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1557         (unspec:SI [(match_dup 1)
1558                     (match_dup 2)]
1559                    UNSPEC_DLMZB))]
1560   "TARGET_DLMZB"
1561   "dlmzb. %0,%1,%2")
1563 (define_expand "strlensi"
1564   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1565         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1566                     (match_operand:QI 2 "const_int_operand" "")
1567                     (match_operand 3 "const_int_operand" "")]
1568                    UNSPEC_DLMZB_STRLEN))
1569    (clobber (match_scratch:CC 4 "=x"))]
1570   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1572   rtx result = operands[0];
1573   rtx src = operands[1];
1574   rtx search_char = operands[2];
1575   rtx align = operands[3];
1576   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1577   rtx loop_label, end_label, mem, cr0, cond;
1578   if (search_char != const0_rtx
1579       || GET_CODE (align) != CONST_INT
1580       || INTVAL (align) < 8)
1581         FAIL;
1582   word1 = gen_reg_rtx (SImode);
1583   word2 = gen_reg_rtx (SImode);
1584   scratch_dlmzb = gen_reg_rtx (SImode);
1585   scratch_string = gen_reg_rtx (Pmode);
1586   loop_label = gen_label_rtx ();
1587   end_label = gen_label_rtx ();
1588   addr = force_reg (Pmode, XEXP (src, 0));
1589   emit_move_insn (scratch_string, addr);
1590   emit_label (loop_label);
1591   mem = change_address (src, SImode, scratch_string);
1592   emit_move_insn (word1, mem);
1593   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1594   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1595   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1596   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1597   emit_jump_insn (gen_rtx_SET (pc_rtx,
1598                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1599                                                      cond,
1600                                                      gen_rtx_LABEL_REF
1601                                                        (VOIDmode,
1602                                                         end_label),
1603                                                      pc_rtx)));
1604   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1605   emit_jump_insn (gen_rtx_SET (pc_rtx,
1606                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1607   emit_barrier ();
1608   emit_label (end_label);
1609   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1610   emit_insn (gen_subsi3 (result, scratch_string, addr));
1611   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1612   DONE;
1615 ;; Fixed-point arithmetic insns.
1617 (define_expand "add<mode>3"
1618   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1619         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1620                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1621   ""
1623   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1624     {
1625       rtx lo0 = gen_lowpart (SImode, operands[0]);
1626       rtx lo1 = gen_lowpart (SImode, operands[1]);
1627       rtx lo2 = gen_lowpart (SImode, operands[2]);
1628       rtx hi0 = gen_highpart (SImode, operands[0]);
1629       rtx hi1 = gen_highpart (SImode, operands[1]);
1630       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1632       if (!reg_or_short_operand (lo2, SImode))
1633         lo2 = force_reg (SImode, lo2);
1634       if (!adde_operand (hi2, SImode))
1635         hi2 = force_reg (SImode, hi2);
1637       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1638       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1639       DONE;
1640     }
1642   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1643     {
1644       rtx tmp = ((!can_create_pseudo_p ()
1645                   || rtx_equal_p (operands[0], operands[1]))
1646                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1648       HOST_WIDE_INT val = INTVAL (operands[2]);
1649       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1650       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1652       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1653         FAIL;
1655       /* The ordering here is important for the prolog expander.
1656          When space is allocated from the stack, adding 'low' first may
1657          produce a temporary deallocation (which would be bad).  */
1658       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1659       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1660       DONE;
1661     }
1664 (define_insn "*add<mode>3"
1665   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1666         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1667                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1668   ""
1669   "@
1670    add %0,%1,%2
1671    addi %0,%1,%2
1672    addis %0,%1,%v2"
1673   [(set_attr "type" "add")])
1675 (define_insn "addsi3_high"
1676   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1677         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1678                  (high:SI (match_operand 2 "" ""))))]
1679   "TARGET_MACHO && !TARGET_64BIT"
1680   "addis %0,%1,ha16(%2)"
1681   [(set_attr "type" "add")])
1683 (define_insn_and_split "*add<mode>3_dot"
1684   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1685         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1686                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1687                     (const_int 0)))
1688    (clobber (match_scratch:GPR 0 "=r,r"))]
1689   "<MODE>mode == Pmode"
1690   "@
1691    add. %0,%1,%2
1692    #"
1693   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1694   [(set (match_dup 0)
1695         (plus:GPR (match_dup 1)
1696                  (match_dup 2)))
1697    (set (match_dup 3)
1698         (compare:CC (match_dup 0)
1699                     (const_int 0)))]
1700   ""
1701   [(set_attr "type" "add")
1702    (set_attr "dot" "yes")
1703    (set_attr "length" "4,8")])
1705 (define_insn_and_split "*add<mode>3_dot2"
1706   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1707         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1708                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1709                     (const_int 0)))
1710    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1711         (plus:GPR (match_dup 1)
1712                   (match_dup 2)))]
1713   "<MODE>mode == Pmode"
1714   "@
1715    add. %0,%1,%2
1716    #"
1717   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1718   [(set (match_dup 0)
1719         (plus:GPR (match_dup 1)
1720                   (match_dup 2)))
1721    (set (match_dup 3)
1722         (compare:CC (match_dup 0)
1723                     (const_int 0)))]
1724   ""
1725   [(set_attr "type" "add")
1726    (set_attr "dot" "yes")
1727    (set_attr "length" "4,8")])
1729 (define_insn_and_split "*add<mode>3_imm_dot"
1730   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1731         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1732                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1733                     (const_int 0)))
1734    (clobber (match_scratch:GPR 0 "=r,r"))
1735    (clobber (reg:GPR CA_REGNO))]
1736   "<MODE>mode == Pmode"
1737   "@
1738    addic. %0,%1,%2
1739    #"
1740   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1741   [(set (match_dup 0)
1742         (plus:GPR (match_dup 1)
1743                   (match_dup 2)))
1744    (set (match_dup 3)
1745         (compare:CC (match_dup 0)
1746                     (const_int 0)))]
1747   ""
1748   [(set_attr "type" "add")
1749    (set_attr "dot" "yes")
1750    (set_attr "length" "4,8")])
1752 (define_insn_and_split "*add<mode>3_imm_dot2"
1753   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1754         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1755                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1756                     (const_int 0)))
1757    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1758         (plus:GPR (match_dup 1)
1759                   (match_dup 2)))
1760    (clobber (reg:GPR CA_REGNO))]
1761   "<MODE>mode == Pmode"
1762   "@
1763    addic. %0,%1,%2
1764    #"
1765   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1766   [(set (match_dup 0)
1767         (plus:GPR (match_dup 1)
1768                   (match_dup 2)))
1769    (set (match_dup 3)
1770         (compare:CC (match_dup 0)
1771                     (const_int 0)))]
1772   ""
1773   [(set_attr "type" "add")
1774    (set_attr "dot" "yes")
1775    (set_attr "length" "4,8")])
1777 ;; Split an add that we can't do in one insn into two insns, each of which
1778 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1779 ;; add should be last in case the result gets used in an address.
1781 (define_split
1782   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1783         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1784                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1785   ""
1786   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1787    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1789   HOST_WIDE_INT val = INTVAL (operands[2]);
1790   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1791   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1793   operands[4] = GEN_INT (low);
1794   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1795     operands[3] = GEN_INT (rest);
1796   else if (can_create_pseudo_p ())
1797     {
1798       operands[3] = gen_reg_rtx (DImode);
1799       emit_move_insn (operands[3], operands[2]);
1800       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1801       DONE;
1802     }
1803   else
1804     FAIL;
1808 (define_insn "add<mode>3_carry"
1809   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1810         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1811                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1812    (set (reg:P CA_REGNO)
1813         (ltu:P (plus:P (match_dup 1)
1814                        (match_dup 2))
1815                (match_dup 1)))]
1816   ""
1817   "add%I2c %0,%1,%2"
1818   [(set_attr "type" "add")])
1820 (define_insn "*add<mode>3_imm_carry_pos"
1821   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1822         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1823                 (match_operand:P 2 "short_cint_operand" "n")))
1824    (set (reg:P CA_REGNO)
1825         (geu:P (match_dup 1)
1826                (match_operand:P 3 "const_int_operand" "n")))]
1827   "INTVAL (operands[2]) > 0
1828    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1829   "addic %0,%1,%2"
1830   [(set_attr "type" "add")])
1832 (define_insn "*add<mode>3_imm_carry_0"
1833   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1834         (match_operand:P 1 "gpc_reg_operand" "r"))
1835    (set (reg:P CA_REGNO)
1836         (const_int 0))]
1837   ""
1838   "addic %0,%1,0"
1839   [(set_attr "type" "add")])
1841 (define_insn "*add<mode>3_imm_carry_m1"
1842   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1843         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1844                 (const_int -1)))
1845    (set (reg:P CA_REGNO)
1846         (ne:P (match_dup 1)
1847               (const_int 0)))]
1848   ""
1849   "addic %0,%1,-1"
1850   [(set_attr "type" "add")])
1852 (define_insn "*add<mode>3_imm_carry_neg"
1853   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1854         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1855                 (match_operand:P 2 "short_cint_operand" "n")))
1856    (set (reg:P CA_REGNO)
1857         (gtu:P (match_dup 1)
1858                (match_operand:P 3 "const_int_operand" "n")))]
1859   "INTVAL (operands[2]) < 0
1860    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1861   "addic %0,%1,%2"
1862   [(set_attr "type" "add")])
1865 (define_expand "add<mode>3_carry_in"
1866   [(parallel [
1867      (set (match_operand:GPR 0 "gpc_reg_operand")
1868           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1869                               (match_operand:GPR 2 "adde_operand"))
1870                     (reg:GPR CA_REGNO)))
1871      (clobber (reg:GPR CA_REGNO))])]
1872   ""
1874   if (operands[2] == const0_rtx)
1875     {
1876       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1877       DONE;
1878     }
1879   if (operands[2] == constm1_rtx)
1880     {
1881       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1882       DONE;
1883     }
1886 (define_insn "*add<mode>3_carry_in_internal"
1887   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1888         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1889                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1890                   (reg:GPR CA_REGNO)))
1891    (clobber (reg:GPR CA_REGNO))]
1892   ""
1893   "adde %0,%1,%2"
1894   [(set_attr "type" "add")])
1896 (define_insn "add<mode>3_carry_in_0"
1897   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1898         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1899                   (reg:GPR CA_REGNO)))
1900    (clobber (reg:GPR CA_REGNO))]
1901   ""
1902   "addze %0,%1"
1903   [(set_attr "type" "add")])
1905 (define_insn "add<mode>3_carry_in_m1"
1906   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1907         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1908                             (reg:GPR CA_REGNO))
1909                   (const_int -1)))
1910    (clobber (reg:GPR CA_REGNO))]
1911   ""
1912   "addme %0,%1"
1913   [(set_attr "type" "add")])
1916 (define_expand "one_cmpl<mode>2"
1917   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1918         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1919   ""
1921   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1922     {
1923       rs6000_split_logical (operands, NOT, false, false, false);
1924       DONE;
1925     }
1928 (define_insn "*one_cmpl<mode>2"
1929   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1930         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1931   ""
1932   "not %0,%1")
1934 (define_insn_and_split "*one_cmpl<mode>2_dot"
1935   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1936         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1937                     (const_int 0)))
1938    (clobber (match_scratch:GPR 0 "=r,r"))]
1939   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1940   "@
1941    not. %0,%1
1942    #"
1943   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1944   [(set (match_dup 0)
1945         (not:GPR (match_dup 1)))
1946    (set (match_dup 2)
1947         (compare:CC (match_dup 0)
1948                     (const_int 0)))]
1949   ""
1950   [(set_attr "type" "logical")
1951    (set_attr "dot" "yes")
1952    (set_attr "length" "4,8")])
1954 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1955   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1956         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1957                     (const_int 0)))
1958    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1959         (not:GPR (match_dup 1)))]
1960   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1961   "@
1962    not. %0,%1
1963    #"
1964   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1965   [(set (match_dup 0)
1966         (not:GPR (match_dup 1)))
1967    (set (match_dup 2)
1968         (compare:CC (match_dup 0)
1969                     (const_int 0)))]
1970   ""
1971   [(set_attr "type" "logical")
1972    (set_attr "dot" "yes")
1973    (set_attr "length" "4,8")])
1976 (define_expand "sub<mode>3"
1977   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1978         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1979                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1980   ""
1982   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1983     {
1984       rtx lo0 = gen_lowpart (SImode, operands[0]);
1985       rtx lo1 = gen_lowpart (SImode, operands[1]);
1986       rtx lo2 = gen_lowpart (SImode, operands[2]);
1987       rtx hi0 = gen_highpart (SImode, operands[0]);
1988       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1989       rtx hi2 = gen_highpart (SImode, operands[2]);
1991       if (!reg_or_short_operand (lo1, SImode))
1992         lo1 = force_reg (SImode, lo1);
1993       if (!adde_operand (hi1, SImode))
1994         hi1 = force_reg (SImode, hi1);
1996       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1997       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1998       DONE;
1999     }
2001   if (short_cint_operand (operands[1], <MODE>mode))
2002     {
2003       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2004       DONE;
2005     }
2008 (define_insn "*subf<mode>3"
2009   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2010         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2011                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2012   ""
2013   "subf %0,%1,%2"
2014   [(set_attr "type" "add")])
2016 (define_insn_and_split "*subf<mode>3_dot"
2017   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2018         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2019                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2020                     (const_int 0)))
2021    (clobber (match_scratch:GPR 0 "=r,r"))]
2022   "<MODE>mode == Pmode"
2023   "@
2024    subf. %0,%1,%2
2025    #"
2026   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2027   [(set (match_dup 0)
2028         (minus:GPR (match_dup 2)
2029                    (match_dup 1)))
2030    (set (match_dup 3)
2031         (compare:CC (match_dup 0)
2032                     (const_int 0)))]
2033   ""
2034   [(set_attr "type" "add")
2035    (set_attr "dot" "yes")
2036    (set_attr "length" "4,8")])
2038 (define_insn_and_split "*subf<mode>3_dot2"
2039   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2040         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2041                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2042                     (const_int 0)))
2043    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2044         (minus:GPR (match_dup 2)
2045                    (match_dup 1)))]
2046   "<MODE>mode == Pmode"
2047   "@
2048    subf. %0,%1,%2
2049    #"
2050   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2051   [(set (match_dup 0)
2052         (minus:GPR (match_dup 2)
2053                    (match_dup 1)))
2054    (set (match_dup 3)
2055         (compare:CC (match_dup 0)
2056                     (const_int 0)))]
2057   ""
2058   [(set_attr "type" "add")
2059    (set_attr "dot" "yes")
2060    (set_attr "length" "4,8")])
2062 (define_insn "subf<mode>3_imm"
2063   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2064         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2065                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2066    (clobber (reg:GPR CA_REGNO))]
2067   ""
2068   "subfic %0,%1,%2"
2069   [(set_attr "type" "add")])
2071 (define_insn_and_split "subf<mode>3_carry_dot2"
2072   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2073         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2074                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2075                     (const_int 0)))
2076    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2077         (minus:P (match_dup 2)
2078                    (match_dup 1)))
2079    (set (reg:P CA_REGNO)
2080         (leu:P (match_dup 1)
2081                (match_dup 2)))]
2082   "<MODE>mode == Pmode"
2083   "@
2084    subfc. %0,%1,%2
2085    #"
2086   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2087   [(parallel [(set (match_dup 0)
2088                    (minus:P (match_dup 2)
2089                             (match_dup 1)))
2090               (set (reg:P CA_REGNO)
2091                    (leu:P (match_dup 1)
2092                           (match_dup 2)))])
2093    (set (match_dup 3)
2094         (compare:CC (match_dup 0)
2095                     (const_int 0)))]
2096   ""
2097   [(set_attr "type" "add")
2098    (set_attr "dot" "yes")
2099    (set_attr "length" "4,8")])
2101 (define_insn "subf<mode>3_carry"
2102   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2103         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2104                  (match_operand:P 1 "gpc_reg_operand" "r")))
2105    (set (reg:P CA_REGNO)
2106         (leu:P (match_dup 1)
2107                (match_dup 2)))]
2108   ""
2109   "subf%I2c %0,%1,%2"
2110   [(set_attr "type" "add")])
2112 (define_insn "*subf<mode>3_imm_carry_0"
2113   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2114         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2115    (set (reg:P CA_REGNO)
2116         (eq:P (match_dup 1)
2117               (const_int 0)))]
2118   ""
2119   "subfic %0,%1,0"
2120   [(set_attr "type" "add")])
2122 (define_insn "*subf<mode>3_imm_carry_m1"
2123   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2124         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2125    (set (reg:P CA_REGNO)
2126         (const_int 1))]
2127   ""
2128   "subfic %0,%1,-1"
2129   [(set_attr "type" "add")])
2132 (define_expand "subf<mode>3_carry_in"
2133   [(parallel [
2134      (set (match_operand:GPR 0 "gpc_reg_operand")
2135           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2136                               (reg:GPR CA_REGNO))
2137                     (match_operand:GPR 2 "adde_operand")))
2138      (clobber (reg:GPR CA_REGNO))])]
2139   ""
2141   if (operands[2] == const0_rtx)
2142     {
2143       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2144       DONE;
2145     }
2146   if (operands[2] == constm1_rtx)
2147     {
2148       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2149       DONE;
2150     }
2153 (define_insn "*subf<mode>3_carry_in_internal"
2154   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2155         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2156                             (reg:GPR CA_REGNO))
2157                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2158    (clobber (reg:GPR CA_REGNO))]
2159   ""
2160   "subfe %0,%1,%2"
2161   [(set_attr "type" "add")])
2163 (define_insn "subf<mode>3_carry_in_0"
2164   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2165         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2166                   (reg:GPR CA_REGNO)))
2167    (clobber (reg:GPR CA_REGNO))]
2168   ""
2169   "subfze %0,%1"
2170   [(set_attr "type" "add")])
2172 (define_insn "subf<mode>3_carry_in_m1"
2173   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2174         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2175                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2176                   (const_int -2)))
2177    (clobber (reg:GPR CA_REGNO))]
2178   ""
2179   "subfme %0,%1"
2180   [(set_attr "type" "add")])
2182 (define_insn "subf<mode>3_carry_in_xx"
2183   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2184         (plus:GPR (reg:GPR CA_REGNO)
2185                   (const_int -1)))
2186    (clobber (reg:GPR CA_REGNO))]
2187   ""
2188   "subfe %0,%0,%0"
2189   [(set_attr "type" "add")])
2192 (define_insn "neg<mode>2"
2193   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2194         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2195   ""
2196   "neg %0,%1"
2197   [(set_attr "type" "add")])
2199 (define_insn_and_split "*neg<mode>2_dot"
2200   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2201         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2202                     (const_int 0)))
2203    (clobber (match_scratch:GPR 0 "=r,r"))]
2204   "<MODE>mode == Pmode"
2205   "@
2206    neg. %0,%1
2207    #"
2208   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2209   [(set (match_dup 0)
2210         (neg:GPR (match_dup 1)))
2211    (set (match_dup 2)
2212         (compare:CC (match_dup 0)
2213                     (const_int 0)))]
2214   ""
2215   [(set_attr "type" "add")
2216    (set_attr "dot" "yes")
2217    (set_attr "length" "4,8")])
2219 (define_insn_and_split "*neg<mode>2_dot2"
2220   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2221         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2222                     (const_int 0)))
2223    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2224         (neg:GPR (match_dup 1)))]
2225   "<MODE>mode == Pmode"
2226   "@
2227    neg. %0,%1
2228    #"
2229   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2230   [(set (match_dup 0)
2231         (neg:GPR (match_dup 1)))
2232    (set (match_dup 2)
2233         (compare:CC (match_dup 0)
2234                     (const_int 0)))]
2235   ""
2236   [(set_attr "type" "add")
2237    (set_attr "dot" "yes")
2238    (set_attr "length" "4,8")])
2241 (define_insn "clz<mode>2"
2242   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2243         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2244   ""
2245   "cntlz<wd> %0,%1"
2246   [(set_attr "type" "cntlz")])
2248 (define_expand "ctz<mode>2"
2249    [(set (match_operand:GPR 0 "gpc_reg_operand")
2250          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2251   ""
2253   if (TARGET_CTZ)
2254     {
2255       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2256       DONE;
2257     }
2259   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2260   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2261   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2263   if (TARGET_POPCNTD)
2264     {
2265       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2266       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2267       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2268       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2269     }
2270   else
2271     {
2272       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2273       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2274       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2275       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2276     }
2278   DONE;
2281 (define_insn "ctz<mode>2_hw"
2282   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2283         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2284   "TARGET_CTZ"
2285   "cnttz<wd> %0,%1"
2286   [(set_attr "type" "cntlz")])
2288 (define_expand "ffs<mode>2"
2289   [(set (match_operand:GPR 0 "gpc_reg_operand")
2290         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2291   ""
2293   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2294   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2295   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2296   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2297   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2298   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2299   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2300   DONE;
2304 (define_expand "popcount<mode>2"
2305   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2306         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2307   "TARGET_POPCNTB || TARGET_POPCNTD"
2309   rs6000_emit_popcount (operands[0], operands[1]);
2310   DONE;
2313 (define_insn "popcntb<mode>2"
2314   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2315         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2316                     UNSPEC_POPCNTB))]
2317   "TARGET_POPCNTB"
2318   "popcntb %0,%1"
2319   [(set_attr "type" "popcnt")])
2321 (define_insn "popcntd<mode>2"
2322   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2323         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2324   "TARGET_POPCNTD"
2325   "popcnt<wd> %0,%1"
2326   [(set_attr "type" "popcnt")])
2329 (define_expand "parity<mode>2"
2330   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2331         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2332   "TARGET_POPCNTB"
2334   rs6000_emit_parity (operands[0], operands[1]);
2335   DONE;
2338 (define_insn "parity<mode>2_cmpb"
2339   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2340         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2341   "TARGET_CMPB && TARGET_POPCNTB"
2342   "prty<wd> %0,%1"
2343   [(set_attr "type" "popcnt")])
2345 (define_insn "cmpb<mode>3"
2346   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2347         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2348                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2349   "TARGET_CMPB"
2350   "cmpb %0,%1,%2"
2351   [(set_attr "type" "cmp")])
2353 ;; Since the hardware zeros the upper part of the register, save generating the
2354 ;; AND immediate if we are converting to unsigned
2355 (define_insn "*bswap<mode>2_extenddi"
2356   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2357         (zero_extend:DI
2358          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2359   "TARGET_POWERPC64"
2360   "l<wd>brx %0,%y1"
2361   [(set_attr "length" "4")
2362    (set_attr "type" "load")])
2364 (define_insn "*bswaphi2_extendsi"
2365   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2366         (zero_extend:SI
2367          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2368   ""
2369   "lhbrx %0,%y1"
2370   [(set_attr "length" "4")
2371    (set_attr "type" "load")])
2373 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2374 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2375 ;; load with byte swap, which can be slower than doing it in the registers.  It
2376 ;; also prevents certain failures with the RELOAD register allocator.
2378 (define_expand "bswap<mode>2"
2379   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2380    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2381   ""
2383   rtx dest = operands[0];
2384   rtx src = operands[1];
2386   if (!REG_P (dest) && !REG_P (src))
2387     src = force_reg (<MODE>mode, src);
2389   if (MEM_P (src))
2390     emit_insn (gen_bswap<mode>2_load (dest, src));
2391   else if (MEM_P (dest))
2392     emit_insn (gen_bswap<mode>2_store (dest, src));
2393   else
2394     emit_insn (gen_bswap<mode>2_reg (dest, src));
2395   DONE;
2398 (define_insn "bswap<mode>2_load"
2399   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2400         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2401   ""
2402   "l<wd>brx %0,%y1"
2403   [(set_attr "type" "load")])
2405 (define_insn "bswap<mode>2_store"
2406   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2407         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2408   ""
2409   "st<wd>brx %1,%y0"
2410   [(set_attr "type" "store")])
2412 (define_insn_and_split "bswaphi2_reg"
2413   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
2414         (bswap:HI
2415          (match_operand:HI 1 "gpc_reg_operand" "r")))
2416    (clobber (match_scratch:SI 2 "=&r"))]
2417   ""
2418   "#"
2419   "reload_completed"
2420   [(set (match_dup 3)
2421         (and:SI (lshiftrt:SI (match_dup 4)
2422                              (const_int 8))
2423                 (const_int 255)))
2424    (set (match_dup 2)
2425         (and:SI (ashift:SI (match_dup 4)
2426                            (const_int 8))
2427                 (const_int 65280)))             ;; 0xff00
2428    (set (match_dup 3)
2429         (ior:SI (match_dup 3)
2430                 (match_dup 2)))]
2432   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2433   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2435   [(set_attr "length" "12")
2436    (set_attr "type" "*")])
2438 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2439 ;; zero_extract insns do not change for -mlittle.
2440 (define_insn_and_split "bswapsi2_reg"
2441   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
2442         (bswap:SI
2443          (match_operand:SI 1 "gpc_reg_operand" "r")))]
2444   ""
2445   "#"
2446   "reload_completed"
2447   [(set (match_dup 0)                                   ; DABC
2448         (rotate:SI (match_dup 1)
2449                    (const_int 24)))
2450    (set (match_dup 0)                                   ; DCBC
2451         (ior:SI (and:SI (ashift:SI (match_dup 1)
2452                                    (const_int 8))
2453                         (const_int 16711680))
2454                 (and:SI (match_dup 0)
2455                         (const_int -16711681))))
2456    (set (match_dup 0)                                   ; DCBA
2457         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2458                                      (const_int 24))
2459                         (const_int 255))
2460                 (and:SI (match_dup 0)
2461                         (const_int -256))))]
2462   "")
2464 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2465 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2466 ;; complex code.
2468 (define_expand "bswapdi2"
2469   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2470                    (bswap:DI
2471                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2472               (clobber (match_scratch:DI 2 ""))
2473               (clobber (match_scratch:DI 3 ""))])]
2474   ""
2476   rtx dest = operands[0];
2477   rtx src = operands[1];
2479   if (!REG_P (dest) && !REG_P (src))
2480     operands[1] = src = force_reg (DImode, src);
2482   if (TARGET_POWERPC64 && TARGET_LDBRX)
2483     {
2484       if (MEM_P (src))
2485         emit_insn (gen_bswapdi2_load (dest, src));
2486       else if (MEM_P (dest))
2487         emit_insn (gen_bswapdi2_store (dest, src));
2488       else
2489         emit_insn (gen_bswapdi2_reg (dest, src));
2490       DONE;
2491     }
2493   if (!TARGET_POWERPC64)
2494     {
2495       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2496          that uses 64-bit registers needs the same scratch registers as 64-bit
2497          mode.  */
2498       emit_insn (gen_bswapdi2_32bit (dest, src));
2499       DONE;
2500     }
2503 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2504 (define_insn "bswapdi2_load"
2505   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2506         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2507   "TARGET_POWERPC64 && TARGET_LDBRX"
2508   "ldbrx %0,%y1"
2509   [(set_attr "type" "load")])
2511 (define_insn "bswapdi2_store"
2512   [(set (match_operand:DI 0 "memory_operand" "=Z")
2513         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2514   "TARGET_POWERPC64 && TARGET_LDBRX"
2515   "stdbrx %1,%y0"
2516   [(set_attr "type" "store")])
2518 (define_insn "bswapdi2_reg"
2519   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2520         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2521    (clobber (match_scratch:DI 2 "=&r"))
2522    (clobber (match_scratch:DI 3 "=&r"))]
2523   "TARGET_POWERPC64 && TARGET_LDBRX"
2524   "#"
2525   [(set_attr "length" "36")])
2527 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2528 (define_insn "*bswapdi2_64bit"
2529   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2530         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2531    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2532    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2533   "TARGET_POWERPC64 && !TARGET_LDBRX
2534    && (REG_P (operands[0]) || REG_P (operands[1]))
2535    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2536    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2537   "#"
2538   [(set_attr "length" "16,12,36")])
2540 (define_split
2541   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2542         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2543    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2544    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2545   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2546   [(const_int 0)]
2547   "
2549   rtx dest   = operands[0];
2550   rtx src    = operands[1];
2551   rtx op2    = operands[2];
2552   rtx op3    = operands[3];
2553   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2554                                     BYTES_BIG_ENDIAN ? 4 : 0);
2555   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2556                                      BYTES_BIG_ENDIAN ? 4 : 0);
2557   rtx addr1;
2558   rtx addr2;
2559   rtx word1;
2560   rtx word2;
2562   addr1 = XEXP (src, 0);
2563   if (GET_CODE (addr1) == PLUS)
2564     {
2565       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2566       if (TARGET_AVOID_XFORM)
2567         {
2568           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2569           addr2 = op2;
2570         }
2571       else
2572         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2573     }
2574   else if (TARGET_AVOID_XFORM)
2575     {
2576       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2577       addr2 = op2;
2578     }
2579   else
2580     {
2581       emit_move_insn (op2, GEN_INT (4));
2582       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2583     }
2585   word1 = change_address (src, SImode, addr1);
2586   word2 = change_address (src, SImode, addr2);
2588   if (BYTES_BIG_ENDIAN)
2589     {
2590       emit_insn (gen_bswapsi2 (op3_32, word2));
2591       emit_insn (gen_bswapsi2 (dest_32, word1));
2592     }
2593   else
2594     {
2595       emit_insn (gen_bswapsi2 (op3_32, word1));
2596       emit_insn (gen_bswapsi2 (dest_32, word2));
2597     }
2599   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2600   emit_insn (gen_iordi3 (dest, dest, op3));
2601   DONE;
2604 (define_split
2605   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2606         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2607    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2608    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2609   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2610   [(const_int 0)]
2611   "
2613   rtx dest   = operands[0];
2614   rtx src    = operands[1];
2615   rtx op2    = operands[2];
2616   rtx op3    = operands[3];
2617   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2618                                     BYTES_BIG_ENDIAN ? 4 : 0);
2619   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2620                                     BYTES_BIG_ENDIAN ? 4 : 0);
2621   rtx addr1;
2622   rtx addr2;
2623   rtx word1;
2624   rtx word2;
2626   addr1 = XEXP (dest, 0);
2627   if (GET_CODE (addr1) == PLUS)
2628     {
2629       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2630       if (TARGET_AVOID_XFORM)
2631         {
2632           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2633           addr2 = op2;
2634         }
2635       else
2636         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2637     }
2638   else if (TARGET_AVOID_XFORM)
2639     {
2640       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2641       addr2 = op2;
2642     }
2643   else
2644     {
2645       emit_move_insn (op2, GEN_INT (4));
2646       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2647     }
2649   word1 = change_address (dest, SImode, addr1);
2650   word2 = change_address (dest, SImode, addr2);
2652   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2654   if (BYTES_BIG_ENDIAN)
2655     {
2656       emit_insn (gen_bswapsi2 (word1, src_si));
2657       emit_insn (gen_bswapsi2 (word2, op3_si));
2658     }
2659   else
2660     {
2661       emit_insn (gen_bswapsi2 (word2, src_si));
2662       emit_insn (gen_bswapsi2 (word1, op3_si));
2663     }
2664   DONE;
2667 (define_split
2668   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2669         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2670    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2671    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2672   "TARGET_POWERPC64 && reload_completed"
2673   [(const_int 0)]
2674   "
2676   rtx dest    = operands[0];
2677   rtx src     = operands[1];
2678   rtx op2     = operands[2];
2679   rtx op3     = operands[3];
2680   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2681   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2682   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2683   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2684   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2686   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2687   emit_insn (gen_bswapsi2 (dest_si, src_si));
2688   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2689   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2690   emit_insn (gen_iordi3 (dest, dest, op3));
2691   DONE;
2694 (define_insn "bswapdi2_32bit"
2695   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2696         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2697    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2698   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2699   "#"
2700   [(set_attr "length" "16,12,36")])
2702 (define_split
2703   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2704         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2705    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2706   "!TARGET_POWERPC64 && reload_completed"
2707   [(const_int 0)]
2708   "
2710   rtx dest  = operands[0];
2711   rtx src   = operands[1];
2712   rtx op2   = operands[2];
2713   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2714   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2715   rtx addr1;
2716   rtx addr2;
2717   rtx word1;
2718   rtx word2;
2720   addr1 = XEXP (src, 0);
2721   if (GET_CODE (addr1) == PLUS)
2722     {
2723       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2724       if (TARGET_AVOID_XFORM
2725           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2726         {
2727           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2728           addr2 = op2;
2729         }
2730       else
2731         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2732     }
2733   else if (TARGET_AVOID_XFORM
2734            || REGNO (addr1) == REGNO (dest2))
2735     {
2736       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2737       addr2 = op2;
2738     }
2739   else
2740     {
2741       emit_move_insn (op2, GEN_INT (4));
2742       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2743     }
2745   word1 = change_address (src, SImode, addr1);
2746   word2 = change_address (src, SImode, addr2);
2748   emit_insn (gen_bswapsi2 (dest2, word1));
2749   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2750      thus allowing us to omit an early clobber on the output.  */
2751   emit_insn (gen_bswapsi2 (dest1, word2));
2752   DONE;
2755 (define_split
2756   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2757         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2758    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2759   "!TARGET_POWERPC64 && reload_completed"
2760   [(const_int 0)]
2761   "
2763   rtx dest = operands[0];
2764   rtx src  = operands[1];
2765   rtx op2  = operands[2];
2766   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2767   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2768   rtx addr1;
2769   rtx addr2;
2770   rtx word1;
2771   rtx word2;
2773   addr1 = XEXP (dest, 0);
2774   if (GET_CODE (addr1) == PLUS)
2775     {
2776       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2777       if (TARGET_AVOID_XFORM)
2778         {
2779           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2780           addr2 = op2;
2781         }
2782       else
2783         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2784     }
2785   else if (TARGET_AVOID_XFORM)
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 (dest, SImode, addr1);
2797   word2 = change_address (dest, SImode, addr2);
2799   emit_insn (gen_bswapsi2 (word2, src1));
2800   emit_insn (gen_bswapsi2 (word1, src2));
2801   DONE;
2804 (define_split
2805   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2806         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2807    (clobber (match_operand:SI 2 "" ""))]
2808   "!TARGET_POWERPC64 && reload_completed"
2809   [(const_int 0)]
2810   "
2812   rtx dest  = operands[0];
2813   rtx src   = operands[1];
2814   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2815   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2816   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2817   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2819   emit_insn (gen_bswapsi2 (dest1, src2));
2820   emit_insn (gen_bswapsi2 (dest2, src1));
2821   DONE;
2825 (define_insn "mul<mode>3"
2826   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2827         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2828                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2829   ""
2830   "@
2831    mull<wd> %0,%1,%2
2832    mulli %0,%1,%2"
2833    [(set_attr "type" "mul")
2834     (set (attr "size")
2835       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2836                 (const_string "8")
2837              (match_operand:GPR 2 "short_cint_operand" "")
2838                 (const_string "16")]
2839         (const_string "<bits>")))])
2841 (define_insn_and_split "*mul<mode>3_dot"
2842   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2843         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2844                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2845                     (const_int 0)))
2846    (clobber (match_scratch:GPR 0 "=r,r"))]
2847   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2848   "@
2849    mull<wd>. %0,%1,%2
2850    #"
2851   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2852   [(set (match_dup 0)
2853         (mult:GPR (match_dup 1)
2854                   (match_dup 2)))
2855    (set (match_dup 3)
2856         (compare:CC (match_dup 0)
2857                     (const_int 0)))]
2858   ""
2859   [(set_attr "type" "mul")
2860    (set_attr "size" "<bits>")
2861    (set_attr "dot" "yes")
2862    (set_attr "length" "4,8")])
2864 (define_insn_and_split "*mul<mode>3_dot2"
2865   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2866         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2867                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2868                     (const_int 0)))
2869    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2870         (mult:GPR (match_dup 1)
2871                   (match_dup 2)))]
2872   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2873   "@
2874    mull<wd>. %0,%1,%2
2875    #"
2876   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2877   [(set (match_dup 0)
2878         (mult:GPR (match_dup 1)
2879                   (match_dup 2)))
2880    (set (match_dup 3)
2881         (compare:CC (match_dup 0)
2882                     (const_int 0)))]
2883   ""
2884   [(set_attr "type" "mul")
2885    (set_attr "size" "<bits>")
2886    (set_attr "dot" "yes")
2887    (set_attr "length" "4,8")])
2890 (define_expand "<su>mul<mode>3_highpart"
2891   [(set (match_operand:GPR 0 "gpc_reg_operand")
2892         (subreg:GPR
2893           (mult:<DMODE> (any_extend:<DMODE>
2894                           (match_operand:GPR 1 "gpc_reg_operand"))
2895                         (any_extend:<DMODE>
2896                           (match_operand:GPR 2 "gpc_reg_operand")))
2897          0))]
2898   ""
2900   if (<MODE>mode == SImode && TARGET_POWERPC64)
2901     {
2902       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2903                                              operands[2]));
2904       DONE;
2905     }
2907   if (!WORDS_BIG_ENDIAN)
2908     {
2909       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2910                                                  operands[2]));
2911       DONE;
2912     }
2915 (define_insn "*<su>mul<mode>3_highpart"
2916   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2917         (subreg:GPR
2918           (mult:<DMODE> (any_extend:<DMODE>
2919                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2920                         (any_extend:<DMODE>
2921                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2922          0))]
2923   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2924   "mulh<wd><u> %0,%1,%2"
2925   [(set_attr "type" "mul")
2926    (set_attr "size" "<bits>")])
2928 (define_insn "<su>mulsi3_highpart_le"
2929   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2930         (subreg:SI
2931           (mult:DI (any_extend:DI
2932                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2933                    (any_extend:DI
2934                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2935          4))]
2936   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2937   "mulhw<u> %0,%1,%2"
2938   [(set_attr "type" "mul")])
2940 (define_insn "<su>muldi3_highpart_le"
2941   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2942         (subreg:DI
2943           (mult:TI (any_extend:TI
2944                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2945                    (any_extend:TI
2946                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2947          8))]
2948   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2949   "mulhd<u> %0,%1,%2"
2950   [(set_attr "type" "mul")
2951    (set_attr "size" "64")])
2953 (define_insn "<su>mulsi3_highpart_64"
2954   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2955         (truncate:SI
2956           (lshiftrt:DI
2957             (mult:DI (any_extend:DI
2958                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2959                      (any_extend:DI
2960                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2961             (const_int 32))))]
2962   "TARGET_POWERPC64"
2963   "mulhw<u> %0,%1,%2"
2964   [(set_attr "type" "mul")])
2966 (define_expand "<u>mul<mode><dmode>3"
2967   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2968         (mult:<DMODE> (any_extend:<DMODE>
2969                         (match_operand:GPR 1 "gpc_reg_operand"))
2970                       (any_extend:<DMODE>
2971                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2972   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2974   rtx l = gen_reg_rtx (<MODE>mode);
2975   rtx h = gen_reg_rtx (<MODE>mode);
2976   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2977   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2978   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2979   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2980   DONE;
2983 (define_insn "*maddld4"
2984   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2985         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2986                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2987                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2988   "TARGET_MADDLD"
2989   "maddld %0,%1,%2,%3"
2990   [(set_attr "type" "mul")])
2992 (define_insn "udiv<mode>3"
2993   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2994         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2995                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2996   ""
2997   "div<wd>u %0,%1,%2"
2998   [(set_attr "type" "div")
2999    (set_attr "size" "<bits>")])
3002 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3003 ;; modulus.  If it isn't a power of two, force operands into register and do
3004 ;; a normal divide.
3005 (define_expand "div<mode>3"
3006   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3007         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3008                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3009   ""
3011   if (CONST_INT_P (operands[2])
3012       && INTVAL (operands[2]) > 0
3013       && exact_log2 (INTVAL (operands[2])) >= 0)
3014     {
3015       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3016       DONE;
3017     }
3019   operands[2] = force_reg (<MODE>mode, operands[2]);
3022 (define_insn "*div<mode>3"
3023   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3024         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3025                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3026   ""
3027   "div<wd> %0,%1,%2"
3028   [(set_attr "type" "div")
3029    (set_attr "size" "<bits>")])
3031 (define_insn "div<mode>3_sra"
3032   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3033         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3034                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3035    (clobber (reg:GPR CA_REGNO))]
3036   ""
3037   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3038   [(set_attr "type" "two")
3039    (set_attr "length" "8")])
3041 (define_insn_and_split "*div<mode>3_sra_dot"
3042   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3043         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3044                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3045                     (const_int 0)))
3046    (clobber (match_scratch:GPR 0 "=r,r"))
3047    (clobber (reg:GPR CA_REGNO))]
3048   "<MODE>mode == Pmode"
3049   "@
3050    sra<wd>i %0,%1,%p2\;addze. %0,%0
3051    #"
3052   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3053   [(parallel [(set (match_dup 0)
3054                    (div:GPR (match_dup 1)
3055                             (match_dup 2)))
3056               (clobber (reg:GPR CA_REGNO))])
3057    (set (match_dup 3)
3058         (compare:CC (match_dup 0)
3059                     (const_int 0)))]
3060   ""
3061   [(set_attr "type" "two")
3062    (set_attr "length" "8,12")
3063    (set_attr "cell_micro" "not")])
3065 (define_insn_and_split "*div<mode>3_sra_dot2"
3066   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3067         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3068                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3069                     (const_int 0)))
3070    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3071         (div:GPR (match_dup 1)
3072                  (match_dup 2)))
3073    (clobber (reg:GPR CA_REGNO))]
3074   "<MODE>mode == Pmode"
3075   "@
3076    sra<wd>i %0,%1,%p2\;addze. %0,%0
3077    #"
3078   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3079   [(parallel [(set (match_dup 0)
3080                    (div:GPR (match_dup 1)
3081                             (match_dup 2)))
3082               (clobber (reg:GPR CA_REGNO))])
3083    (set (match_dup 3)
3084         (compare:CC (match_dup 0)
3085                     (const_int 0)))]
3086   ""
3087   [(set_attr "type" "two")
3088    (set_attr "length" "8,12")
3089    (set_attr "cell_micro" "not")])
3091 (define_expand "mod<mode>3"
3092   [(set (match_operand:GPR 0 "gpc_reg_operand")
3093         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3094                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3095   ""
3097   int i;
3098   rtx temp1;
3099   rtx temp2;
3101   if (GET_CODE (operands[2]) != CONST_INT
3102       || INTVAL (operands[2]) <= 0
3103       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3104     {
3105       if (!TARGET_MODULO)
3106         FAIL;
3108       operands[2] = force_reg (<MODE>mode, operands[2]);
3109     }
3110   else
3111     {
3112       temp1 = gen_reg_rtx (<MODE>mode);
3113       temp2 = gen_reg_rtx (<MODE>mode);
3115       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3116       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3117       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3118       DONE;
3119     }
3122 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3123 ;; mod, prefer putting the result of mod into a different register
3124 (define_insn "*mod<mode>3"
3125   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3126         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3127                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3128   "TARGET_MODULO"
3129   "mods<wd> %0,%1,%2"
3130   [(set_attr "type" "div")
3131    (set_attr "size" "<bits>")])
3134 (define_insn "umod<mode>3"
3135   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3136         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3137                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3138   "TARGET_MODULO"
3139   "modu<wd> %0,%1,%2"
3140   [(set_attr "type" "div")
3141    (set_attr "size" "<bits>")])
3143 ;; On machines with modulo support, do a combined div/mod the old fashioned
3144 ;; method, since the multiply/subtract is faster than doing the mod instruction
3145 ;; after a divide.
3147 (define_peephole2
3148   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3149         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3150                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3151    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3152         (mod:GPR (match_dup 1)
3153                  (match_dup 2)))]
3154   "TARGET_MODULO
3155    && ! reg_mentioned_p (operands[0], operands[1])
3156    && ! reg_mentioned_p (operands[0], operands[2])
3157    && ! reg_mentioned_p (operands[3], operands[1])
3158    && ! reg_mentioned_p (operands[3], operands[2])"
3159   [(set (match_dup 0)
3160         (div:GPR (match_dup 1)
3161                  (match_dup 2)))
3162    (set (match_dup 3)
3163         (mult:GPR (match_dup 0)
3164                   (match_dup 2)))
3165    (set (match_dup 3)
3166         (minus:GPR (match_dup 1)
3167                    (match_dup 3)))])
3169 (define_peephole2
3170   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3171         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3172                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3173    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3174         (umod:GPR (match_dup 1)
3175                   (match_dup 2)))]
3176   "TARGET_MODULO
3177    && ! reg_mentioned_p (operands[0], operands[1])
3178    && ! reg_mentioned_p (operands[0], operands[2])
3179    && ! reg_mentioned_p (operands[3], operands[1])
3180    && ! reg_mentioned_p (operands[3], operands[2])"
3181   [(set (match_dup 0)
3182         (udiv:GPR (match_dup 1)
3183                   (match_dup 2)))
3184    (set (match_dup 3)
3185         (mult:GPR (match_dup 0)
3186                   (match_dup 2)))
3187    (set (match_dup 3)
3188         (minus:GPR (match_dup 1)
3189                    (match_dup 3)))])
3192 ;; Logical instructions
3193 ;; The logical instructions are mostly combined by using match_operator,
3194 ;; but the plain AND insns are somewhat different because there is no
3195 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3196 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3198 (define_expand "and<mode>3"
3199   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3200         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3201                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3202   ""
3204   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3205     {
3206       rs6000_split_logical (operands, AND, false, false, false);
3207       DONE;
3208     }
3210   if (CONST_INT_P (operands[2]))
3211     {
3212       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3213         {
3214           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3215           DONE;
3216         }
3218       if (logical_const_operand (operands[2], <MODE>mode)
3219           && rs6000_gen_cell_microcode)
3220         {
3221           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3222           DONE;
3223         }
3225       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3226         {
3227           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3228           DONE;
3229         }
3231       operands[2] = force_reg (<MODE>mode, operands[2]);
3232     }
3236 (define_insn "and<mode>3_imm"
3237   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3238         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3239                  (match_operand:GPR 2 "logical_const_operand" "n")))
3240    (clobber (match_scratch:CC 3 "=x"))]
3241   "rs6000_gen_cell_microcode
3242    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3243   "andi%e2. %0,%1,%u2"
3244   [(set_attr "type" "logical")
3245    (set_attr "dot" "yes")])
3247 (define_insn_and_split "*and<mode>3_imm_dot"
3248   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3249         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3250                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3251                     (const_int 0)))
3252    (clobber (match_scratch:GPR 0 "=r,r"))
3253    (clobber (match_scratch:CC 4 "=X,x"))]
3254   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3255    && rs6000_gen_cell_microcode
3256    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3257   "@
3258    andi%e2. %0,%1,%u2
3259    #"
3260   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3261   [(parallel [(set (match_dup 0)
3262                    (and:GPR (match_dup 1)
3263                             (match_dup 2)))
3264               (clobber (match_dup 4))])
3265    (set (match_dup 3)
3266         (compare:CC (match_dup 0)
3267                     (const_int 0)))]
3268   ""
3269   [(set_attr "type" "logical")
3270    (set_attr "dot" "yes")
3271    (set_attr "length" "4,8")])
3273 (define_insn_and_split "*and<mode>3_imm_dot2"
3274   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3275         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3276                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3277                     (const_int 0)))
3278    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3279         (and:GPR (match_dup 1)
3280                  (match_dup 2)))
3281    (clobber (match_scratch:CC 4 "=X,x"))]
3282   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3283    && rs6000_gen_cell_microcode
3284    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3285   "@
3286    andi%e2. %0,%1,%u2
3287    #"
3288   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3289   [(parallel [(set (match_dup 0)
3290                    (and:GPR (match_dup 1)
3291                             (match_dup 2)))
3292               (clobber (match_dup 4))])
3293    (set (match_dup 3)
3294         (compare:CC (match_dup 0)
3295                     (const_int 0)))]
3296   ""
3297   [(set_attr "type" "logical")
3298    (set_attr "dot" "yes")
3299    (set_attr "length" "4,8")])
3301 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3302   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3303         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3304                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3305                     (const_int 0)))
3306    (clobber (match_scratch:GPR 0 "=r,r"))]
3307   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3308    && rs6000_gen_cell_microcode
3309    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3310   "@
3311    andi%e2. %0,%1,%u2
3312    #"
3313   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3314   [(set (match_dup 0)
3315         (and:GPR (match_dup 1)
3316                  (match_dup 2)))
3317    (set (match_dup 3)
3318         (compare:CC (match_dup 0)
3319                     (const_int 0)))]
3320   ""
3321   [(set_attr "type" "logical")
3322    (set_attr "dot" "yes")
3323    (set_attr "length" "4,8")])
3325 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3326   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3327         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3328                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3329                     (const_int 0)))
3330    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3331         (and:GPR (match_dup 1)
3332                  (match_dup 2)))]
3333   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3334    && rs6000_gen_cell_microcode
3335    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3336   "@
3337    andi%e2. %0,%1,%u2
3338    #"
3339   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3340   [(set (match_dup 0)
3341         (and:GPR (match_dup 1)
3342                  (match_dup 2)))
3343    (set (match_dup 3)
3344         (compare:CC (match_dup 0)
3345                     (const_int 0)))]
3346   ""
3347   [(set_attr "type" "logical")
3348    (set_attr "dot" "yes")
3349    (set_attr "length" "4,8")])
3351 (define_insn "*and<mode>3_imm_dot_shifted"
3352   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3353         (compare:CC
3354           (and:GPR
3355             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3356                           (match_operand:SI 4 "const_int_operand" "n"))
3357             (match_operand:GPR 2 "const_int_operand" "n"))
3358           (const_int 0)))
3359    (clobber (match_scratch:GPR 0 "=r"))]
3360   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3361                                    << INTVAL (operands[4])),
3362                           DImode)
3363    && (<MODE>mode == Pmode
3364        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3365    && rs6000_gen_cell_microcode"
3367   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3368   return "andi%e2. %0,%1,%u2";
3370   [(set_attr "type" "logical")
3371    (set_attr "dot" "yes")])
3374 (define_insn "and<mode>3_mask"
3375   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3376         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3377                  (match_operand:GPR 2 "const_int_operand" "n")))]
3378   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3380   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3382   [(set_attr "type" "shift")])
3384 (define_insn_and_split "*and<mode>3_mask_dot"
3385   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3386         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3387                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3388                     (const_int 0)))
3389    (clobber (match_scratch:GPR 0 "=r,r"))]
3390   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3391    && rs6000_gen_cell_microcode
3392    && !logical_const_operand (operands[2], <MODE>mode)
3393    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3395   if (which_alternative == 0)
3396     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3397   else
3398     return "#";
3400   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3401   [(set (match_dup 0)
3402         (and:GPR (match_dup 1)
3403                  (match_dup 2)))
3404    (set (match_dup 3)
3405         (compare:CC (match_dup 0)
3406                     (const_int 0)))]
3407   ""
3408   [(set_attr "type" "shift")
3409    (set_attr "dot" "yes")
3410    (set_attr "length" "4,8")])
3412 (define_insn_and_split "*and<mode>3_mask_dot2"
3413   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3414         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3415                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3416                     (const_int 0)))
3417    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3418         (and:GPR (match_dup 1)
3419                  (match_dup 2)))]
3420   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3421    && rs6000_gen_cell_microcode
3422    && !logical_const_operand (operands[2], <MODE>mode)
3423    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3425   if (which_alternative == 0)
3426     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3427   else
3428     return "#";
3430   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3431   [(set (match_dup 0)
3432         (and:GPR (match_dup 1)
3433                  (match_dup 2)))
3434    (set (match_dup 3)
3435         (compare:CC (match_dup 0)
3436                     (const_int 0)))]
3437   ""
3438   [(set_attr "type" "shift")
3439    (set_attr "dot" "yes")
3440    (set_attr "length" "4,8")])
3443 (define_insn_and_split "*and<mode>3_2insn"
3444   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3445         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3446                  (match_operand:GPR 2 "const_int_operand" "n")))]
3447   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3448    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3449         || (logical_const_operand (operands[2], <MODE>mode)
3450             && rs6000_gen_cell_microcode))"
3451   "#"
3452   "&& 1"
3453   [(pc)]
3455   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3456   DONE;
3458   [(set_attr "type" "shift")
3459    (set_attr "length" "8")])
3461 (define_insn_and_split "*and<mode>3_2insn_dot"
3462   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3463         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3464                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3465                     (const_int 0)))
3466    (clobber (match_scratch:GPR 0 "=r,r"))]
3467   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3468    && rs6000_gen_cell_microcode
3469    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3470    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3471         || (logical_const_operand (operands[2], <MODE>mode)
3472             && rs6000_gen_cell_microcode))"
3473   "#"
3474   "&& reload_completed"
3475   [(pc)]
3477   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3478   DONE;
3480   [(set_attr "type" "shift")
3481    (set_attr "dot" "yes")
3482    (set_attr "length" "8,12")])
3484 (define_insn_and_split "*and<mode>3_2insn_dot2"
3485   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3486         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3487                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3488                     (const_int 0)))
3489    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3490         (and:GPR (match_dup 1)
3491                  (match_dup 2)))]
3492   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3493    && rs6000_gen_cell_microcode
3494    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3495    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3496         || (logical_const_operand (operands[2], <MODE>mode)
3497             && rs6000_gen_cell_microcode))"
3498   "#"
3499   "&& reload_completed"
3500   [(pc)]
3502   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3503   DONE;
3505   [(set_attr "type" "shift")
3506    (set_attr "dot" "yes")
3507    (set_attr "length" "8,12")])
3510 (define_expand "<code><mode>3"
3511   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3512         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3513                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3514   ""
3516   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3517     {
3518       rs6000_split_logical (operands, <CODE>, false, false, false);
3519       DONE;
3520     }
3522   if (non_logical_cint_operand (operands[2], <MODE>mode))
3523     {
3524       rtx tmp = ((!can_create_pseudo_p ()
3525                   || rtx_equal_p (operands[0], operands[1]))
3526                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3528       HOST_WIDE_INT value = INTVAL (operands[2]);
3529       HOST_WIDE_INT lo = value & 0xffff;
3530       HOST_WIDE_INT hi = value - lo;
3532       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3533       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3534       DONE;
3535     }
3537   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3538     operands[2] = force_reg (<MODE>mode, operands[2]);
3541 (define_split
3542   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3543         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3544                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3545   ""
3546   [(set (match_dup 3)
3547         (iorxor:GPR (match_dup 1)
3548                     (match_dup 4)))
3549    (set (match_dup 0)
3550         (iorxor:GPR (match_dup 3)
3551                     (match_dup 5)))]
3553   operands[3] = ((!can_create_pseudo_p ()
3554                   || rtx_equal_p (operands[0], operands[1]))
3555                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3557   HOST_WIDE_INT value = INTVAL (operands[2]);
3558   HOST_WIDE_INT lo = value & 0xffff;
3559   HOST_WIDE_INT hi = value - lo;
3561   operands[4] = GEN_INT (hi);
3562   operands[5] = GEN_INT (lo);
3565 (define_insn "*bool<mode>3_imm"
3566   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3567         (match_operator:GPR 3 "boolean_or_operator"
3568          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3569           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3570   ""
3571   "%q3i%e2 %0,%1,%u2"
3572   [(set_attr "type" "logical")])
3574 (define_insn "*bool<mode>3"
3575   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3576         (match_operator:GPR 3 "boolean_operator"
3577          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3578           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3579   ""
3580   "%q3 %0,%1,%2"
3581   [(set_attr "type" "logical")])
3583 (define_insn_and_split "*bool<mode>3_dot"
3584   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3585         (compare:CC (match_operator:GPR 3 "boolean_operator"
3586          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3587           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3588          (const_int 0)))
3589    (clobber (match_scratch:GPR 0 "=r,r"))]
3590   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3591   "@
3592    %q3. %0,%1,%2
3593    #"
3594   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3595   [(set (match_dup 0)
3596         (match_dup 3))
3597    (set (match_dup 4)
3598         (compare:CC (match_dup 0)
3599                     (const_int 0)))]
3600   ""
3601   [(set_attr "type" "logical")
3602    (set_attr "dot" "yes")
3603    (set_attr "length" "4,8")])
3605 (define_insn_and_split "*bool<mode>3_dot2"
3606   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3607         (compare:CC (match_operator:GPR 3 "boolean_operator"
3608          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3609           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3610          (const_int 0)))
3611    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3612         (match_dup 3))]
3613   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3614   "@
3615    %q3. %0,%1,%2
3616    #"
3617   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3618   [(set (match_dup 0)
3619         (match_dup 3))
3620    (set (match_dup 4)
3621         (compare:CC (match_dup 0)
3622                     (const_int 0)))]
3623   ""
3624   [(set_attr "type" "logical")
3625    (set_attr "dot" "yes")
3626    (set_attr "length" "4,8")])
3629 (define_insn "*boolc<mode>3"
3630   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3631         (match_operator:GPR 3 "boolean_operator"
3632          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3633           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3634   ""
3635   "%q3 %0,%1,%2"
3636   [(set_attr "type" "logical")])
3638 (define_insn_and_split "*boolc<mode>3_dot"
3639   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3640         (compare:CC (match_operator:GPR 3 "boolean_operator"
3641          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3642           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3643          (const_int 0)))
3644    (clobber (match_scratch:GPR 0 "=r,r"))]
3645   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3646   "@
3647    %q3. %0,%1,%2
3648    #"
3649   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3650   [(set (match_dup 0)
3651         (match_dup 3))
3652    (set (match_dup 4)
3653         (compare:CC (match_dup 0)
3654                     (const_int 0)))]
3655   ""
3656   [(set_attr "type" "logical")
3657    (set_attr "dot" "yes")
3658    (set_attr "length" "4,8")])
3660 (define_insn_and_split "*boolc<mode>3_dot2"
3661   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3662         (compare:CC (match_operator:GPR 3 "boolean_operator"
3663          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3664           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3665          (const_int 0)))
3666    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3667         (match_dup 3))]
3668   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3669   "@
3670    %q3. %0,%1,%2
3671    #"
3672   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3673   [(set (match_dup 0)
3674         (match_dup 3))
3675    (set (match_dup 4)
3676         (compare:CC (match_dup 0)
3677                     (const_int 0)))]
3678   ""
3679   [(set_attr "type" "logical")
3680    (set_attr "dot" "yes")
3681    (set_attr "length" "4,8")])
3684 (define_insn "*boolcc<mode>3"
3685   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3686         (match_operator:GPR 3 "boolean_operator"
3687          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3688           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3689   ""
3690   "%q3 %0,%1,%2"
3691   [(set_attr "type" "logical")])
3693 (define_insn_and_split "*boolcc<mode>3_dot"
3694   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3695         (compare:CC (match_operator:GPR 3 "boolean_operator"
3696          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3697           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3698          (const_int 0)))
3699    (clobber (match_scratch:GPR 0 "=r,r"))]
3700   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3701   "@
3702    %q3. %0,%1,%2
3703    #"
3704   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3705   [(set (match_dup 0)
3706         (match_dup 3))
3707    (set (match_dup 4)
3708         (compare:CC (match_dup 0)
3709                     (const_int 0)))]
3710   ""
3711   [(set_attr "type" "logical")
3712    (set_attr "dot" "yes")
3713    (set_attr "length" "4,8")])
3715 (define_insn_and_split "*boolcc<mode>3_dot2"
3716   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3717         (compare:CC (match_operator:GPR 3 "boolean_operator"
3718          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3719           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3720          (const_int 0)))
3721    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3722         (match_dup 3))]
3723   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3724   "@
3725    %q3. %0,%1,%2
3726    #"
3727   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3728   [(set (match_dup 0)
3729         (match_dup 3))
3730    (set (match_dup 4)
3731         (compare:CC (match_dup 0)
3732                     (const_int 0)))]
3733   ""
3734   [(set_attr "type" "logical")
3735    (set_attr "dot" "yes")
3736    (set_attr "length" "4,8")])
3739 ;; TODO: Should have dots of this as well.
3740 (define_insn "*eqv<mode>3"
3741   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3742         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3743                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3744   ""
3745   "eqv %0,%1,%2"
3746   [(set_attr "type" "logical")])
3748 ;; Rotate-and-mask and insert.
3750 (define_insn "*rotl<mode>3_mask"
3751   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3752         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3753                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3754                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3755                  (match_operand:GPR 3 "const_int_operand" "n")))]
3756   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3758   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3760   [(set_attr "type" "shift")
3761    (set_attr "maybe_var_shift" "yes")])
3763 (define_insn_and_split "*rotl<mode>3_mask_dot"
3764   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3765         (compare:CC
3766           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3767                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3768                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3769                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3770           (const_int 0)))
3771    (clobber (match_scratch:GPR 0 "=r,r"))]
3772   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3773    && rs6000_gen_cell_microcode
3774    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3776   if (which_alternative == 0)
3777     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3778   else
3779     return "#";
3781   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3782   [(set (match_dup 0)
3783         (and:GPR (match_dup 4)
3784                  (match_dup 3)))
3785    (set (match_dup 5)
3786         (compare:CC (match_dup 0)
3787                     (const_int 0)))]
3788   ""
3789   [(set_attr "type" "shift")
3790    (set_attr "maybe_var_shift" "yes")
3791    (set_attr "dot" "yes")
3792    (set_attr "length" "4,8")])
3794 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3795   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3796         (compare:CC
3797           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3798                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3799                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3800                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3801           (const_int 0)))
3802    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3803         (and:GPR (match_dup 4)
3804                  (match_dup 3)))]
3805   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3806    && rs6000_gen_cell_microcode
3807    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3809   if (which_alternative == 0)
3810     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3811   else
3812     return "#";
3814   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3815   [(set (match_dup 0)
3816         (and:GPR (match_dup 4)
3817                  (match_dup 3)))
3818    (set (match_dup 5)
3819         (compare:CC (match_dup 0)
3820                     (const_int 0)))]
3821   ""
3822   [(set_attr "type" "shift")
3823    (set_attr "maybe_var_shift" "yes")
3824    (set_attr "dot" "yes")
3825    (set_attr "length" "4,8")])
3827 ; Special case for less-than-0.  We can do it with just one machine
3828 ; instruction, but the generic optimizers do not realise it is cheap.
3829 (define_insn "*lt0_disi"
3830   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3831         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3832                (const_int 0)))]
3833   "TARGET_POWERPC64"
3834   "rlwinm %0,%1,1,31,31"
3835   [(set_attr "type" "shift")])
3839 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3840 ; both are an AND so are the same precedence).
3841 (define_insn "*rotl<mode>3_insert"
3842   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3843         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3844                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3845                             (match_operand:SI 2 "const_int_operand" "n")])
3846                           (match_operand:GPR 3 "const_int_operand" "n"))
3847                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3848                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3849   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3850    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3852   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3854   [(set_attr "type" "insert")])
3855 ; FIXME: this needs an attr "size", so that the scheduler can see the
3856 ; difference between rlwimi and rldimi.  We also might want dot forms,
3857 ; but not for rlwimi on POWER4 and similar processors.
3859 (define_insn "*rotl<mode>3_insert_2"
3860   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3861         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3862                           (match_operand:GPR 6 "const_int_operand" "n"))
3863                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3864                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3865                             (match_operand:SI 2 "const_int_operand" "n")])
3866                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3867   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3868    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3870   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3872   [(set_attr "type" "insert")])
3874 ; There are also some forms without one of the ANDs.
3875 (define_insn "*rotl<mode>3_insert_3"
3876   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3877         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3878                           (match_operand:GPR 4 "const_int_operand" "n"))
3879                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3880                              (match_operand:SI 2 "const_int_operand" "n"))))]
3881   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3883   if (<MODE>mode == SImode)
3884     return "rlwimi %0,%1,%h2,0,31-%h2";
3885   else
3886     return "rldimi %0,%1,%H2,0";
3888   [(set_attr "type" "insert")])
3890 (define_insn "*rotl<mode>3_insert_4"
3891   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3892         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3893                           (match_operand:GPR 4 "const_int_operand" "n"))
3894                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3895                                (match_operand:SI 2 "const_int_operand" "n"))))]
3896   "<MODE>mode == SImode &&
3897    GET_MODE_PRECISION (<MODE>mode)
3898    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3900   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3901                          - INTVAL (operands[2]));
3902   if (<MODE>mode == SImode)
3903     return "rlwimi %0,%1,%h2,32-%h2,31";
3904   else
3905     return "rldimi %0,%1,%H2,64-%H2";
3907   [(set_attr "type" "insert")])
3909 (define_insn "*rotlsi3_insert_5"
3910   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3911         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3912                         (match_operand:SI 2 "const_int_operand" "n,n"))
3913                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3914                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3915   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3916    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3917    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3918   "@
3919    rlwimi %0,%3,0,%4
3920    rlwimi %0,%1,0,%2"
3921   [(set_attr "type" "insert")])
3923 (define_insn "*rotldi3_insert_6"
3924   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3925         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3926                         (match_operand:DI 2 "const_int_operand" "n"))
3927                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3928                         (match_operand:DI 4 "const_int_operand" "n"))))]
3929   "exact_log2 (-UINTVAL (operands[2])) > 0
3930    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3932   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3933   return "rldimi %0,%3,0,%5";
3935   [(set_attr "type" "insert")
3936    (set_attr "size" "64")])
3938 (define_insn "*rotldi3_insert_7"
3939   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3940         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3941                         (match_operand:DI 4 "const_int_operand" "n"))
3942                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3943                         (match_operand:DI 2 "const_int_operand" "n"))))]
3944   "exact_log2 (-UINTVAL (operands[2])) > 0
3945    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3947   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3948   return "rldimi %0,%3,0,%5";
3950   [(set_attr "type" "insert")
3951    (set_attr "size" "64")])
3954 ; This handles the important case of multiple-precision shifts.  There is
3955 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3956 (define_split
3957   [(set (match_operand:GPR 0 "gpc_reg_operand")
3958         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3959                              (match_operand:SI 3 "const_int_operand"))
3960                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3961                                (match_operand:SI 4 "const_int_operand"))))]
3962   "can_create_pseudo_p ()
3963    && INTVAL (operands[3]) + INTVAL (operands[4])
3964       >= GET_MODE_PRECISION (<MODE>mode)"
3965   [(set (match_dup 5)
3966         (lshiftrt:GPR (match_dup 2)
3967                       (match_dup 4)))
3968    (set (match_dup 0)
3969         (ior:GPR (and:GPR (match_dup 5)
3970                           (match_dup 6))
3971                  (ashift:GPR (match_dup 1)
3972                              (match_dup 3))))]
3974   unsigned HOST_WIDE_INT mask = 1;
3975   mask = (mask << INTVAL (operands[3])) - 1;
3976   operands[5] = gen_reg_rtx (<MODE>mode);
3977   operands[6] = GEN_INT (mask);
3980 (define_split
3981   [(set (match_operand:GPR 0 "gpc_reg_operand")
3982         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3983                                (match_operand:SI 4 "const_int_operand"))
3984                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3985                              (match_operand:SI 3 "const_int_operand"))))]
3986   "can_create_pseudo_p ()
3987    && INTVAL (operands[3]) + INTVAL (operands[4])
3988       >= GET_MODE_PRECISION (<MODE>mode)"
3989   [(set (match_dup 5)
3990         (lshiftrt:GPR (match_dup 2)
3991                       (match_dup 4)))
3992    (set (match_dup 0)
3993         (ior:GPR (and:GPR (match_dup 5)
3994                           (match_dup 6))
3995                  (ashift:GPR (match_dup 1)
3996                              (match_dup 3))))]
3998   unsigned HOST_WIDE_INT mask = 1;
3999   mask = (mask << INTVAL (operands[3])) - 1;
4000   operands[5] = gen_reg_rtx (<MODE>mode);
4001   operands[6] = GEN_INT (mask);
4005 ; Another important case is setting some bits to 1; we can do that with
4006 ; an insert instruction, in many cases.
4007 (define_insn_and_split "*ior<mode>_mask"
4008   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4009         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4010                  (match_operand:GPR 2 "const_int_operand" "n")))
4011    (clobber (match_scratch:GPR 3 "=r"))]
4012   "!logical_const_operand (operands[2], <MODE>mode)
4013    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4014   "#"
4015   "&& 1"
4016   [(set (match_dup 3)
4017         (const_int -1))
4018    (set (match_dup 0)
4019         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4020                                       (match_dup 4))
4021                           (match_dup 2))
4022                  (and:GPR (match_dup 1)
4023                           (match_dup 5))))]
4025   int nb, ne;
4026   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4027   if (GET_CODE (operands[3]) == SCRATCH)
4028     operands[3] = gen_reg_rtx (<MODE>mode);
4029   operands[4] = GEN_INT (ne);
4030   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4032   [(set_attr "type" "two")
4033    (set_attr "length" "8")])
4036 ;; Now the simple shifts.
4038 (define_insn "rotl<mode>3"
4039   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4040         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4041                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4042   ""
4043   "rotl<wd>%I2 %0,%1,%<hH>2"
4044   [(set_attr "type" "shift")
4045    (set_attr "maybe_var_shift" "yes")])
4047 (define_insn "*rotlsi3_64"
4048   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4049         (zero_extend:DI
4050             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4051                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4052   "TARGET_POWERPC64"
4053   "rotlw%I2 %0,%1,%h2"
4054   [(set_attr "type" "shift")
4055    (set_attr "maybe_var_shift" "yes")])
4057 (define_insn_and_split "*rotl<mode>3_dot"
4058   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4059         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4060                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4061                     (const_int 0)))
4062    (clobber (match_scratch:GPR 0 "=r,r"))]
4063   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4064   "@
4065    rotl<wd>%I2. %0,%1,%<hH>2
4066    #"
4067   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4068   [(set (match_dup 0)
4069         (rotate:GPR (match_dup 1)
4070                     (match_dup 2)))
4071    (set (match_dup 3)
4072         (compare:CC (match_dup 0)
4073                     (const_int 0)))]
4074   ""
4075   [(set_attr "type" "shift")
4076    (set_attr "maybe_var_shift" "yes")
4077    (set_attr "dot" "yes")
4078    (set_attr "length" "4,8")])
4080 (define_insn_and_split "*rotl<mode>3_dot2"
4081   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4082         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4083                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4084                     (const_int 0)))
4085    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4086         (rotate:GPR (match_dup 1)
4087                     (match_dup 2)))]
4088   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4089   "@
4090    rotl<wd>%I2. %0,%1,%<hH>2
4091    #"
4092   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4093   [(set (match_dup 0)
4094         (rotate:GPR (match_dup 1)
4095                     (match_dup 2)))
4096    (set (match_dup 3)
4097         (compare:CC (match_dup 0)
4098                     (const_int 0)))]
4099   ""
4100   [(set_attr "type" "shift")
4101    (set_attr "maybe_var_shift" "yes")
4102    (set_attr "dot" "yes")
4103    (set_attr "length" "4,8")])
4106 (define_insn "ashl<mode>3"
4107   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4108         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4109                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4110   ""
4111   "sl<wd>%I2 %0,%1,%<hH>2"
4112   [(set_attr "type" "shift")
4113    (set_attr "maybe_var_shift" "yes")])
4115 (define_insn "*ashlsi3_64"
4116   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4117         (zero_extend:DI
4118             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4119                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4120   "TARGET_POWERPC64"
4121   "slw%I2 %0,%1,%h2"
4122   [(set_attr "type" "shift")
4123    (set_attr "maybe_var_shift" "yes")])
4125 (define_insn_and_split "*ashl<mode>3_dot"
4126   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4127         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4128                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4129                     (const_int 0)))
4130    (clobber (match_scratch:GPR 0 "=r,r"))]
4131   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4132   "@
4133    sl<wd>%I2. %0,%1,%<hH>2
4134    #"
4135   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4136   [(set (match_dup 0)
4137         (ashift: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")])
4148 (define_insn_and_split "*ashl<mode>3_dot2"
4149   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4150         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4151                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4152                     (const_int 0)))
4153    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4154         (ashift:GPR (match_dup 1)
4155                     (match_dup 2)))]
4156   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4157   "@
4158    sl<wd>%I2. %0,%1,%<hH>2
4159    #"
4160   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4161   [(set (match_dup 0)
4162         (ashift:GPR (match_dup 1)
4163                     (match_dup 2)))
4164    (set (match_dup 3)
4165         (compare:CC (match_dup 0)
4166                     (const_int 0)))]
4167   ""
4168   [(set_attr "type" "shift")
4169    (set_attr "maybe_var_shift" "yes")
4170    (set_attr "dot" "yes")
4171    (set_attr "length" "4,8")])
4173 ;; Pretend we have a memory form of extswsli until register allocation is done
4174 ;; so that we use LWZ to load the value from memory, instead of LWA.
4175 (define_insn_and_split "ashdi3_extswsli"
4176   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4177         (ashift:DI
4178          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4179          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4180   "TARGET_EXTSWSLI"
4181   "@
4182    extswsli %0,%1,%2
4183    #"
4184   "&& reload_completed && MEM_P (operands[1])"
4185   [(set (match_dup 3)
4186         (match_dup 1))
4187    (set (match_dup 0)
4188         (ashift:DI (sign_extend:DI (match_dup 3))
4189                    (match_dup 2)))]
4191   operands[3] = gen_lowpart (SImode, operands[0]);
4193   [(set_attr "type" "shift")
4194    (set_attr "maybe_var_shift" "no")])
4197 (define_insn_and_split "ashdi3_extswsli_dot"
4198   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4199         (compare:CC
4200          (ashift:DI
4201           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4202           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4203          (const_int 0)))
4204    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4205   "TARGET_EXTSWSLI"
4206   "@
4207    extswsli. %0,%1,%2
4208    #
4209    #
4210    #"
4211   "&& reload_completed
4212    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4213        || memory_operand (operands[1], SImode))"
4214   [(pc)]
4216   rtx dest = operands[0];
4217   rtx src = operands[1];
4218   rtx shift = operands[2];
4219   rtx cr = operands[3];
4220   rtx src2;
4222   if (!MEM_P (src))
4223     src2 = src;
4224   else
4225     {
4226       src2 = gen_lowpart (SImode, dest);
4227       emit_move_insn (src2, src);
4228     }
4230   if (REGNO (cr) == CR0_REGNO)
4231     {
4232       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4233       DONE;
4234     }
4236   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4237   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4238   DONE;
4240   [(set_attr "type" "shift")
4241    (set_attr "maybe_var_shift" "no")
4242    (set_attr "dot" "yes")
4243    (set_attr "length" "4,8,8,12")])
4245 (define_insn_and_split "ashdi3_extswsli_dot2"
4246   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4247         (compare:CC
4248          (ashift:DI
4249           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4250           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4251          (const_int 0)))
4252    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4253         (ashift:DI (sign_extend:DI (match_dup 1))
4254                    (match_dup 2)))]
4255   "TARGET_EXTSWSLI"
4256   "@
4257    extswsli. %0,%1,%2
4258    #
4259    #
4260    #"
4261   "&& reload_completed
4262    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4263        || memory_operand (operands[1], SImode))"
4264   [(pc)]
4266   rtx dest = operands[0];
4267   rtx src = operands[1];
4268   rtx shift = operands[2];
4269   rtx cr = operands[3];
4270   rtx src2;
4272   if (!MEM_P (src))
4273     src2 = src;
4274   else
4275     {
4276       src2 = gen_lowpart (SImode, dest);
4277       emit_move_insn (src2, src);
4278     }
4280   if (REGNO (cr) == CR0_REGNO)
4281     {
4282       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4283       DONE;
4284     }
4286   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4287   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4288   DONE;
4290   [(set_attr "type" "shift")
4291    (set_attr "maybe_var_shift" "no")
4292    (set_attr "dot" "yes")
4293    (set_attr "length" "4,8,8,12")])
4295 (define_insn "lshr<mode>3"
4296   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4297         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4298                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4299   ""
4300   "sr<wd>%I2 %0,%1,%<hH>2"
4301   [(set_attr "type" "shift")
4302    (set_attr "maybe_var_shift" "yes")])
4304 (define_insn "*lshrsi3_64"
4305   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4306         (zero_extend:DI
4307             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4308                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4309   "TARGET_POWERPC64"
4310   "srw%I2 %0,%1,%h2"
4311   [(set_attr "type" "shift")
4312    (set_attr "maybe_var_shift" "yes")])
4314 (define_insn_and_split "*lshr<mode>3_dot"
4315   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4316         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4317                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4318                     (const_int 0)))
4319    (clobber (match_scratch:GPR 0 "=r,r"))]
4320   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4321   "@
4322    sr<wd>%I2. %0,%1,%<hH>2
4323    #"
4324   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4325   [(set (match_dup 0)
4326         (lshiftrt:GPR (match_dup 1)
4327                       (match_dup 2)))
4328    (set (match_dup 3)
4329         (compare:CC (match_dup 0)
4330                     (const_int 0)))]
4331   ""
4332   [(set_attr "type" "shift")
4333    (set_attr "maybe_var_shift" "yes")
4334    (set_attr "dot" "yes")
4335    (set_attr "length" "4,8")])
4337 (define_insn_and_split "*lshr<mode>3_dot2"
4338   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4339         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4340                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4341                     (const_int 0)))
4342    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4343         (lshiftrt:GPR (match_dup 1)
4344                       (match_dup 2)))]
4345   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4346   "@
4347    sr<wd>%I2. %0,%1,%<hH>2
4348    #"
4349   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4350   [(set (match_dup 0)
4351         (lshiftrt:GPR (match_dup 1)
4352                       (match_dup 2)))
4353    (set (match_dup 3)
4354         (compare:CC (match_dup 0)
4355                     (const_int 0)))]
4356   ""
4357   [(set_attr "type" "shift")
4358    (set_attr "maybe_var_shift" "yes")
4359    (set_attr "dot" "yes")
4360    (set_attr "length" "4,8")])
4363 (define_insn "ashr<mode>3"
4364   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4365         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4366                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4367    (clobber (reg:GPR CA_REGNO))]
4368   ""
4369   "sra<wd>%I2 %0,%1,%<hH>2"
4370   [(set_attr "type" "shift")
4371    (set_attr "maybe_var_shift" "yes")])
4373 (define_insn "*ashrsi3_64"
4374   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4375         (sign_extend:DI
4376             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4377                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4378    (clobber (reg:SI CA_REGNO))]
4379   "TARGET_POWERPC64"
4380   "sraw%I2 %0,%1,%h2"
4381   [(set_attr "type" "shift")
4382    (set_attr "maybe_var_shift" "yes")])
4384 (define_insn_and_split "*ashr<mode>3_dot"
4385   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4386         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4387                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4388                     (const_int 0)))
4389    (clobber (match_scratch:GPR 0 "=r,r"))
4390    (clobber (reg:GPR CA_REGNO))]
4391   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4392   "@
4393    sra<wd>%I2. %0,%1,%<hH>2
4394    #"
4395   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4396   [(parallel [(set (match_dup 0)
4397                    (ashiftrt:GPR (match_dup 1)
4398                                  (match_dup 2)))
4399               (clobber (reg:GPR CA_REGNO))])
4400    (set (match_dup 3)
4401         (compare:CC (match_dup 0)
4402                     (const_int 0)))]
4403   ""
4404   [(set_attr "type" "shift")
4405    (set_attr "maybe_var_shift" "yes")
4406    (set_attr "dot" "yes")
4407    (set_attr "length" "4,8")])
4409 (define_insn_and_split "*ashr<mode>3_dot2"
4410   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4411         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4412                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4413                     (const_int 0)))
4414    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4415         (ashiftrt:GPR (match_dup 1)
4416                       (match_dup 2)))
4417    (clobber (reg:GPR CA_REGNO))]
4418   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4419   "@
4420    sra<wd>%I2. %0,%1,%<hH>2
4421    #"
4422   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4423   [(parallel [(set (match_dup 0)
4424                    (ashiftrt:GPR (match_dup 1)
4425                                  (match_dup 2)))
4426               (clobber (reg:GPR CA_REGNO))])
4427    (set (match_dup 3)
4428         (compare:CC (match_dup 0)
4429                     (const_int 0)))]
4430   ""
4431   [(set_attr "type" "shift")
4432    (set_attr "maybe_var_shift" "yes")
4433    (set_attr "dot" "yes")
4434    (set_attr "length" "4,8")])
4436 ;; Builtins to replace a division to generate FRE reciprocal estimate
4437 ;; instructions and the necessary fixup instructions
4438 (define_expand "recip<mode>3"
4439   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4440    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4441    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4442   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4444    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4445    DONE;
4448 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4449 ;; hardware division.  This is only done before register allocation and with
4450 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4451 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4452 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4453 (define_split
4454   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4455         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4456                     (match_operand 2 "gpc_reg_operand" "")))]
4457   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4458    && can_create_pseudo_p () && flag_finite_math_only
4459    && !flag_trapping_math && flag_reciprocal_math"
4460   [(const_int 0)]
4462   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4463   DONE;
4466 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4467 ;; appropriate fixup.
4468 (define_expand "rsqrt<mode>2"
4469   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4470    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4471   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4473   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4474   DONE;
4477 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4478 ;; modes here, and also add in conditional vsx/power8-vector support to access
4479 ;; values in the traditional Altivec registers if the appropriate
4480 ;; -mupper-regs-{df,sf} option is enabled.
4482 (define_expand "abs<mode>2"
4483   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4484         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4485   "TARGET_<MODE>_INSN"
4486   "")
4488 (define_insn "*abs<mode>2_fpr"
4489   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4490         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4491   "TARGET_<MODE>_FPR"
4492   "@
4493    fabs %0,%1
4494    xsabsdp %x0,%x1"
4495   [(set_attr "type" "fpsimple")
4496    (set_attr "fp_type" "fp_addsub_<Fs>")])
4498 (define_insn "*nabs<mode>2_fpr"
4499   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4500         (neg:SFDF
4501          (abs:SFDF
4502           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4503   "TARGET_<MODE>_FPR"
4504   "@
4505    fnabs %0,%1
4506    xsnabsdp %x0,%x1"
4507   [(set_attr "type" "fpsimple")
4508    (set_attr "fp_type" "fp_addsub_<Fs>")])
4510 (define_expand "neg<mode>2"
4511   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4512         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4513   "TARGET_<MODE>_INSN"
4514   "")
4516 (define_insn "*neg<mode>2_fpr"
4517   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4518         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4519   "TARGET_<MODE>_FPR"
4520   "@
4521    fneg %0,%1
4522    xsnegdp %x0,%x1"
4523   [(set_attr "type" "fpsimple")
4524    (set_attr "fp_type" "fp_addsub_<Fs>")])
4526 (define_expand "add<mode>3"
4527   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4528         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4529                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4530   "TARGET_<MODE>_INSN"
4531   "")
4533 (define_insn "*add<mode>3_fpr"
4534   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4535         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4536                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4537   "TARGET_<MODE>_FPR"
4538   "@
4539    fadd<Ftrad> %0,%1,%2
4540    xsadd<Fvsx> %x0,%x1,%x2"
4541   [(set_attr "type" "fp")
4542    (set_attr "fp_type" "fp_addsub_<Fs>")])
4544 (define_expand "sub<mode>3"
4545   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4546         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4547                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4548   "TARGET_<MODE>_INSN"
4549   "")
4551 (define_insn "*sub<mode>3_fpr"
4552   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4553         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4554                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4555   "TARGET_<MODE>_FPR"
4556   "@
4557    fsub<Ftrad> %0,%1,%2
4558    xssub<Fvsx> %x0,%x1,%x2"
4559   [(set_attr "type" "fp")
4560    (set_attr "fp_type" "fp_addsub_<Fs>")])
4562 (define_expand "mul<mode>3"
4563   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4564         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4565                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4566   "TARGET_<MODE>_INSN"
4567   "")
4569 (define_insn "*mul<mode>3_fpr"
4570   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4571         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4572                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4573   "TARGET_<MODE>_FPR"
4574   "@
4575    fmul<Ftrad> %0,%1,%2
4576    xsmul<Fvsx> %x0,%x1,%x2"
4577   [(set_attr "type" "dmul")
4578    (set_attr "fp_type" "fp_mul_<Fs>")])
4580 (define_expand "div<mode>3"
4581   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4582         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4583                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4584   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4586   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4587       && can_create_pseudo_p () && flag_finite_math_only
4588       && !flag_trapping_math && flag_reciprocal_math)
4589     {
4590       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4591       DONE;
4592     }
4595 (define_insn "*div<mode>3_fpr"
4596   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4597         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4598                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4599   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4600   "@
4601    fdiv<Ftrad> %0,%1,%2
4602    xsdiv<Fvsx> %x0,%x1,%x2"
4603   [(set_attr "type" "<Fs>div")
4604    (set_attr "fp_type" "fp_div_<Fs>")])
4606 (define_insn "*sqrt<mode>2_internal"
4607   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4608         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4609   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4610    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4611   "@
4612    fsqrt<Ftrad> %0,%1
4613    xssqrt<Fvsx> %x0,%x1"
4614   [(set_attr "type" "<Fs>sqrt")
4615    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4617 (define_expand "sqrt<mode>2"
4618   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4619         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4620   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4621    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4623   if (<MODE>mode == SFmode
4624       && TARGET_RECIP_PRECISION
4625       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4626       && !optimize_function_for_size_p (cfun)
4627       && flag_finite_math_only && !flag_trapping_math
4628       && flag_unsafe_math_optimizations)
4629     {
4630       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4631       DONE;
4632     }
4635 ;; Floating point reciprocal approximation
4636 (define_insn "fre<Fs>"
4637   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4638         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4639                      UNSPEC_FRES))]
4640   "TARGET_<FFRE>"
4641   "@
4642    fre<Ftrad> %0,%1
4643    xsre<Fvsx> %x0,%x1"
4644   [(set_attr "type" "fp")])
4646 (define_insn "*rsqrt<mode>2"
4647   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4648         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4649                      UNSPEC_RSQRT))]
4650   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4651   "@
4652    frsqrte<Ftrad> %0,%1
4653    xsrsqrte<Fvsx> %x0,%x1"
4654   [(set_attr "type" "fp")])
4656 ;; Floating point comparisons
4657 (define_insn "*cmp<mode>_fpr"
4658   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4659         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4660                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4661   "TARGET_<MODE>_FPR"
4662   "@
4663    fcmpu %0,%1,%2
4664    xscmpudp %0,%x1,%x2"
4665   [(set_attr "type" "fpcompare")])
4667 ;; Floating point conversions
4668 (define_expand "extendsfdf2"
4669   [(set (match_operand:DF 0 "gpc_reg_operand")
4670         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand")))]
4671   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4673   if (HONOR_SNANS (SFmode))
4674     operands[1] = force_reg (SFmode, operands[1]);
4677 (define_insn_and_split "*extendsfdf2_fpr"
4678   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4679         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4680   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4681    && !HONOR_SNANS (SFmode)"
4682   "@
4683    #
4684    fmr %0,%1
4685    lfs%U1%X1 %0,%1
4686    #
4687    xscpsgndp %x0,%x1,%x1
4688    lxsspx %x0,%y1
4689    lxssp %0,%1"
4690   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4691   [(const_int 0)]
4693   emit_note (NOTE_INSN_DELETED);
4694   DONE;
4696   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4698 (define_insn "*extendsfdf2_snan"
4699   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4700         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4701   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4702    && HONOR_SNANS (SFmode)"
4703   "@
4704    frsp %0,%1
4705    xsrsp %x0,%x1"
4706   [(set_attr "type" "fp")])
4708 (define_expand "truncdfsf2"
4709   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4710         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4711   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4712   "")
4714 (define_insn "*truncdfsf2_fpr"
4715   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4716         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4717   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4718   "@
4719    frsp %0,%1
4720    xsrsp %x0,%x1"
4721   [(set_attr "type" "fp")])
4723 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4724 ;; builtins.c and optabs.c that are not correct for IBM long double
4725 ;; when little-endian.
4726 (define_expand "signbit<mode>2"
4727   [(set (match_dup 2)
4728         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4729    (set (match_dup 3)
4730         (subreg:DI (match_dup 2) 0))
4731    (set (match_dup 4)
4732         (match_dup 5))
4733    (set (match_operand:SI 0 "gpc_reg_operand" "")
4734         (match_dup 6))]
4735   "TARGET_HARD_FLOAT
4736    && (TARGET_FPRS || TARGET_E500_DOUBLE)
4737    && (!FLOAT128_IEEE_P (<MODE>mode)
4738        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4740   if (FLOAT128_IEEE_P (<MODE>mode))
4741     {
4742       if (<MODE>mode == KFmode)
4743         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4744       else if (<MODE>mode == TFmode)
4745         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4746       else
4747         gcc_unreachable ();
4748       DONE;
4749     }
4750   operands[2] = gen_reg_rtx (DFmode);
4751   operands[3] = gen_reg_rtx (DImode);
4752   if (TARGET_POWERPC64)
4753     {
4754       operands[4] = gen_reg_rtx (DImode);
4755       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4756       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4757                                     WORDS_BIG_ENDIAN ? 4 : 0);
4758     }
4759   else
4760     {
4761       operands[4] = gen_reg_rtx (SImode);
4762       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4763                                     WORDS_BIG_ENDIAN ? 0 : 4);
4764       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4765     }
4768 (define_expand "copysign<mode>3"
4769   [(set (match_dup 3)
4770         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4771    (set (match_dup 4)
4772         (neg:SFDF (abs:SFDF (match_dup 1))))
4773    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4774         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4775                                (match_dup 5))
4776                          (match_dup 3)
4777                          (match_dup 4)))]
4778   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4779    && ((TARGET_PPC_GFXOPT
4780         && !HONOR_NANS (<MODE>mode)
4781         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4782        || TARGET_CMPB
4783        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4785   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4786     {
4787       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4788                                              operands[2]));
4789       DONE;
4790     }
4792    operands[3] = gen_reg_rtx (<MODE>mode);
4793    operands[4] = gen_reg_rtx (<MODE>mode);
4794    operands[5] = CONST0_RTX (<MODE>mode);
4795   })
4797 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4798 ;; and load.
4799 (define_insn_and_split "signbit<mode>2_dm"
4800   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4801         (unspec:SI
4802          [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4803          UNSPEC_SIGNBIT))]
4804   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4805   "#"
4806   "&& reload_completed"
4807   [(const_int 0)]
4809   rs6000_split_signbit (operands[0], operands[1]);
4810   DONE;
4812  [(set_attr "length" "8,8,4")
4813   (set_attr "type" "mftgpr,load,integer")])
4815 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4816   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4817         (any_extend:DI
4818          (unspec:SI
4819           [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4820           UNSPEC_SIGNBIT)))]
4821   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4822   "#"
4823   "&& reload_completed"
4824   [(const_int 0)]
4826   rs6000_split_signbit (operands[0], operands[1]);
4827   DONE;
4829  [(set_attr "length" "8,8,4")
4830   (set_attr "type" "mftgpr,load,integer")])
4832 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4833 ;; point types, which makes normal SUBREG's problematical. Instead use a
4834 ;; special pattern to avoid using a normal movdi.
4835 (define_insn "signbit<mode>2_dm2"
4836   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4837         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4838                     (const_int 0)]
4839                    UNSPEC_SIGNBIT))]
4840   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4841   "mfvsrd %0,%x1"
4842  [(set_attr "type" "mftgpr")])
4845 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4846 ;; compiler from optimizing -0.0
4847 (define_insn "copysign<mode>3_fcpsgn"
4848   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4849         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4850                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4851                      UNSPEC_COPYSIGN))]
4852   "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4853   "@
4854    fcpsgn %0,%2,%1
4855    xscpsgndp %x0,%x2,%x1"
4856   [(set_attr "type" "fpsimple")])
4858 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4859 ;; fsel instruction and some auxiliary computations.  Then we just have a
4860 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4861 ;; combine.
4862 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4863 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4864 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4865 ;; define_splits to make them if made by combine.  On VSX machines we have the
4866 ;; min/max instructions.
4868 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4869 ;; to allow either DF/SF to use only traditional registers.
4871 (define_expand "s<minmax><mode>3"
4872   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4873         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4874                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4875   "TARGET_MINMAX_<MODE>"
4877   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4878   DONE;
4881 (define_insn "*s<minmax><mode>3_vsx"
4882   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4883         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4884                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4885   "TARGET_VSX && TARGET_<MODE>_FPR"
4887   return (TARGET_P9_MINMAX
4888           ? "xs<minmax>cdp %x0,%x1,%x2"
4889           : "xs<minmax>dp %x0,%x1,%x2");
4891   [(set_attr "type" "fp")])
4893 ;; The conditional move instructions allow us to perform max and min operations
4894 ;; even when we don't have the appropriate max/min instruction using the FSEL
4895 ;; instruction.
4897 (define_insn_and_split "*s<minmax><mode>3_fpr"
4898   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4899         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4900                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4901   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4902   "#"
4903   "&& 1"
4904   [(const_int 0)]
4906   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4907   DONE;
4910 (define_expand "mov<mode>cc"
4911    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4912          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4913                            (match_operand:GPR 2 "gpc_reg_operand" "")
4914                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4915   "TARGET_ISEL<sel>"
4916   "
4918   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4919     DONE;
4920   else
4921     FAIL;
4924 ;; We use the BASE_REGS for the isel input operands because, if rA is
4925 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4926 ;; because we may switch the operands and rB may end up being rA.
4928 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4929 ;; leave out the mode in operand 4 and use one pattern, but reload can
4930 ;; change the mode underneath our feet and then gets confused trying
4931 ;; to reload the value.
4932 (define_insn "isel_signed_<mode>"
4933   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4934         (if_then_else:GPR
4935          (match_operator 1 "scc_comparison_operator"
4936                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4937                           (const_int 0)])
4938          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4939          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4940   "TARGET_ISEL<sel>"
4941   "*
4942 { return output_isel (operands); }"
4943   [(set_attr "type" "isel")
4944    (set_attr "length" "4")])
4946 (define_insn "isel_unsigned_<mode>"
4947   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4948         (if_then_else:GPR
4949          (match_operator 1 "scc_comparison_operator"
4950                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4951                           (const_int 0)])
4952          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4953          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4954   "TARGET_ISEL<sel>"
4955   "*
4956 { return output_isel (operands); }"
4957   [(set_attr "type" "isel")
4958    (set_attr "length" "4")])
4960 ;; These patterns can be useful for combine; they let combine know that
4961 ;; isel can handle reversed comparisons so long as the operands are
4962 ;; registers.
4964 (define_insn "*isel_reversed_signed_<mode>"
4965   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4966         (if_then_else:GPR
4967          (match_operator 1 "scc_rev_comparison_operator"
4968                          [(match_operand:CC 4 "cc_reg_operand" "y")
4969                           (const_int 0)])
4970          (match_operand:GPR 2 "gpc_reg_operand" "b")
4971          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4972   "TARGET_ISEL<sel>"
4973   "*
4974 { return output_isel (operands); }"
4975   [(set_attr "type" "isel")
4976    (set_attr "length" "4")])
4978 (define_insn "*isel_reversed_unsigned_<mode>"
4979   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4980         (if_then_else:GPR
4981          (match_operator 1 "scc_rev_comparison_operator"
4982                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4983                           (const_int 0)])
4984          (match_operand:GPR 2 "gpc_reg_operand" "b")
4985          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4986   "TARGET_ISEL<sel>"
4987   "*
4988 { return output_isel (operands); }"
4989   [(set_attr "type" "isel")
4990    (set_attr "length" "4")])
4992 ;; Floating point conditional move
4993 (define_expand "mov<mode>cc"
4994    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4995          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4996                             (match_operand:SFDF 2 "gpc_reg_operand" "")
4997                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4998   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4999   "
5001   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5002     DONE;
5003   else
5004     FAIL;
5007 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5008   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5009         (if_then_else:SFDF
5010          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5011              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5012          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5013          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5014   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5015   "fsel %0,%1,%2,%3"
5016   [(set_attr "type" "fp")])
5018 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5019   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5020         (if_then_else:SFDF
5021          (match_operator:CCFP 1 "fpmask_comparison_operator"
5022                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5023                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5024          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5025          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5026    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5027   "TARGET_P9_MINMAX"
5028   "#"
5029   ""
5030   [(set (match_dup 6)
5031         (if_then_else:V2DI (match_dup 1)
5032                            (match_dup 7)
5033                            (match_dup 8)))
5034    (set (match_dup 0)
5035         (if_then_else:SFDF (ne (match_dup 6)
5036                                (match_dup 8))
5037                            (match_dup 4)
5038                            (match_dup 5)))]
5040   if (GET_CODE (operands[6]) == SCRATCH)
5041     operands[6] = gen_reg_rtx (V2DImode);
5043   operands[7] = CONSTM1_RTX (V2DImode);
5044   operands[8] = CONST0_RTX (V2DImode);
5046  [(set_attr "length" "8")
5047   (set_attr "type" "vecperm")])
5049 ;; Handle inverting the fpmask comparisons.
5050 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5051   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5052         (if_then_else:SFDF
5053          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5054                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5055                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5056          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5057          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5058    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5059   "TARGET_P9_MINMAX"
5060   "#"
5061   "&& 1"
5062   [(set (match_dup 6)
5063         (if_then_else:V2DI (match_dup 9)
5064                            (match_dup 7)
5065                            (match_dup 8)))
5066    (set (match_dup 0)
5067         (if_then_else:SFDF (ne (match_dup 6)
5068                                (match_dup 8))
5069                            (match_dup 5)
5070                            (match_dup 4)))]
5072   rtx op1 = operands[1];
5073   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5075   if (GET_CODE (operands[6]) == SCRATCH)
5076     operands[6] = gen_reg_rtx (V2DImode);
5078   operands[7] = CONSTM1_RTX (V2DImode);
5079   operands[8] = CONST0_RTX (V2DImode);
5081   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5083  [(set_attr "length" "8")
5084   (set_attr "type" "vecperm")])
5086 (define_insn "*fpmask<mode>"
5087   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5088         (if_then_else:V2DI
5089          (match_operator:CCFP 1 "fpmask_comparison_operator"
5090                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5091                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5092          (match_operand:V2DI 4 "all_ones_constant" "")
5093          (match_operand:V2DI 5 "zero_constant" "")))]
5094   "TARGET_P9_MINMAX"
5095   "xscmp%V1dp %x0,%x2,%x3"
5096   [(set_attr "type" "fpcompare")])
5098 (define_insn "*xxsel<mode>"
5099   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5100         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5101                                (match_operand:V2DI 2 "zero_constant" ""))
5102                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5103                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5104   "TARGET_P9_MINMAX"
5105   "xxsel %x0,%x4,%x3,%x1"
5106   [(set_attr "type" "vecmove")])
5109 ;; Conversions to and from floating-point.
5111 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5112 ; don't want to support putting SImode in FPR registers.
5113 (define_insn "lfiwax"
5114   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5115         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5116                    UNSPEC_LFIWAX))]
5117   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5118   "@
5119    lfiwax %0,%y1
5120    lxsiwax %x0,%y1
5121    mtvsrwa %x0,%1
5122    vextsw2d %0,%1"
5123   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5125 ; This split must be run before register allocation because it allocates the
5126 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5127 ; it earlier to allow for the combiner to merge insns together where it might
5128 ; not be needed and also in case the insns are deleted as dead code.
5130 (define_insn_and_split "floatsi<mode>2_lfiwax"
5131   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5132         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5133    (clobber (match_scratch:DI 2 "=wi"))]
5134   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5135    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5136   "#"
5137   ""
5138   [(pc)]
5139   "
5141   rtx dest = operands[0];
5142   rtx src = operands[1];
5143   rtx tmp;
5145   if (!MEM_P (src) && TARGET_POWERPC64
5146       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5147     tmp = convert_to_mode (DImode, src, false);
5148   else
5149     {
5150       tmp = operands[2];
5151       if (GET_CODE (tmp) == SCRATCH)
5152         tmp = gen_reg_rtx (DImode);
5153       if (MEM_P (src))
5154         {
5155           src = rs6000_address_for_fpconvert (src);
5156           emit_insn (gen_lfiwax (tmp, src));
5157         }
5158       else
5159         {
5160           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5161           emit_move_insn (stack, src);
5162           emit_insn (gen_lfiwax (tmp, stack));
5163         }
5164     }
5165   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5166   DONE;
5168   [(set_attr "length" "12")
5169    (set_attr "type" "fpload")])
5171 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5172   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5173         (float:SFDF
5174          (sign_extend:DI
5175           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5176    (clobber (match_scratch:DI 2 "=wi"))]
5177   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5178    && <SI_CONVERT_FP>"
5179   "#"
5180   ""
5181   [(pc)]
5182   "
5184   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5185   if (GET_CODE (operands[2]) == SCRATCH)
5186     operands[2] = gen_reg_rtx (DImode);
5187   if (TARGET_VSX_SMALL_INTEGER)
5188     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5189   else
5190     emit_insn (gen_lfiwax (operands[2], operands[1]));
5191   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5192   DONE;
5194   [(set_attr "length" "8")
5195    (set_attr "type" "fpload")])
5197 (define_insn "lfiwzx"
5198   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5199         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5200                    UNSPEC_LFIWZX))]
5201   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5202   "@
5203    lfiwzx %0,%y1
5204    lxsiwzx %x0,%y1
5205    mtvsrwz %x0,%1
5206    xxextractuw %x0,%x1,4"
5207   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5209 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5210   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5211         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5212    (clobber (match_scratch:DI 2 "=wi"))]
5213   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5214    && <SI_CONVERT_FP>"
5215   "#"
5216   ""
5217   [(pc)]
5218   "
5220   rtx dest = operands[0];
5221   rtx src = operands[1];
5222   rtx tmp;
5224   if (!MEM_P (src) && TARGET_POWERPC64
5225       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5226     tmp = convert_to_mode (DImode, src, true);
5227   else
5228     {
5229       tmp = operands[2];
5230       if (GET_CODE (tmp) == SCRATCH)
5231         tmp = gen_reg_rtx (DImode);
5232       if (MEM_P (src))
5233         {
5234           src = rs6000_address_for_fpconvert (src);
5235           emit_insn (gen_lfiwzx (tmp, src));
5236         }
5237       else
5238         {
5239           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5240           emit_move_insn (stack, src);
5241           emit_insn (gen_lfiwzx (tmp, stack));
5242         }
5243     }
5244   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5245   DONE;
5247   [(set_attr "length" "12")
5248    (set_attr "type" "fpload")])
5250 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5251   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5252         (unsigned_float:SFDF
5253          (zero_extend:DI
5254           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5255    (clobber (match_scratch:DI 2 "=wi"))]
5256   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5257    && <SI_CONVERT_FP>"
5258   "#"
5259   ""
5260   [(pc)]
5261   "
5263   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5264   if (GET_CODE (operands[2]) == SCRATCH)
5265     operands[2] = gen_reg_rtx (DImode);
5266   if (TARGET_VSX_SMALL_INTEGER)
5267     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5268   else
5269     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5270   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5271   DONE;
5273   [(set_attr "length" "8")
5274    (set_attr "type" "fpload")])
5276 ; For each of these conversions, there is a define_expand, a define_insn
5277 ; with a '#' template, and a define_split (with C code).  The idea is
5278 ; to allow constant folding with the template of the define_insn,
5279 ; then to have the insns split later (between sched1 and final).
5281 (define_expand "floatsidf2"
5282   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5283                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5284               (use (match_dup 2))
5285               (use (match_dup 3))
5286               (clobber (match_dup 4))
5287               (clobber (match_dup 5))
5288               (clobber (match_dup 6))])]
5289   "TARGET_HARD_FLOAT 
5290    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5291   "
5293   if (TARGET_E500_DOUBLE)
5294     {
5295       if (!REG_P (operands[1]))
5296         operands[1] = force_reg (SImode, operands[1]);
5297       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5298       DONE;
5299     }
5300   else if (TARGET_LFIWAX && TARGET_FCFID)
5301     {
5302       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5303       DONE;
5304     }
5305   else if (TARGET_FCFID)
5306     {
5307       rtx dreg = operands[1];
5308       if (!REG_P (dreg))
5309         dreg = force_reg (SImode, dreg);
5310       dreg = convert_to_mode (DImode, dreg, false);
5311       emit_insn (gen_floatdidf2 (operands[0], dreg));
5312       DONE;
5313     }
5315   if (!REG_P (operands[1]))
5316     operands[1] = force_reg (SImode, operands[1]);
5317   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5318   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5319   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5320   operands[5] = gen_reg_rtx (DFmode);
5321   operands[6] = gen_reg_rtx (SImode);
5324 (define_insn_and_split "*floatsidf2_internal"
5325   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5326         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5327    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5328    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5329    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5330    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5331    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5332   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5333   "#"
5334   ""
5335   [(pc)]
5336   "
5338   rtx lowword, highword;
5339   gcc_assert (MEM_P (operands[4]));
5340   highword = adjust_address (operands[4], SImode, 0);
5341   lowword = adjust_address (operands[4], SImode, 4);
5342   if (! WORDS_BIG_ENDIAN)
5343     std::swap (lowword, highword);
5345   emit_insn (gen_xorsi3 (operands[6], operands[1],
5346                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5347   emit_move_insn (lowword, operands[6]);
5348   emit_move_insn (highword, operands[2]);
5349   emit_move_insn (operands[5], operands[4]);
5350   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5351   DONE;
5353   [(set_attr "length" "24")
5354    (set_attr "type" "fp")])
5356 ;; If we don't have a direct conversion to single precision, don't enable this
5357 ;; conversion for 32-bit without fast math, because we don't have the insn to
5358 ;; generate the fixup swizzle to avoid double rounding problems.
5359 (define_expand "floatunssisf2"
5360   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5361         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5362   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5363    && (!TARGET_FPRS
5364        || (TARGET_FPRS
5365            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5366                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5367                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5368   "
5370   if (!TARGET_FPRS)
5371     {
5372       if (!REG_P (operands[1]))
5373         operands[1] = force_reg (SImode, operands[1]);
5374     }
5375   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5376     {
5377       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5378       DONE;
5379     }
5380   else
5381     {
5382       rtx dreg = operands[1];
5383       if (!REG_P (dreg))
5384         dreg = force_reg (SImode, dreg);
5385       dreg = convert_to_mode (DImode, dreg, true);
5386       emit_insn (gen_floatdisf2 (operands[0], dreg));
5387       DONE;
5388     }
5391 (define_expand "floatunssidf2"
5392   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5393                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5394               (use (match_dup 2))
5395               (use (match_dup 3))
5396               (clobber (match_dup 4))
5397               (clobber (match_dup 5))])]
5398   "TARGET_HARD_FLOAT
5399    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5400   "
5402   if (TARGET_E500_DOUBLE)
5403     {
5404       if (!REG_P (operands[1]))
5405         operands[1] = force_reg (SImode, operands[1]);
5406       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5407       DONE;
5408     }
5409   else if (TARGET_LFIWZX && TARGET_FCFID)
5410     {
5411       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5412       DONE;
5413     }
5414   else if (TARGET_FCFID)
5415     {
5416       rtx dreg = operands[1];
5417       if (!REG_P (dreg))
5418         dreg = force_reg (SImode, dreg);
5419       dreg = convert_to_mode (DImode, dreg, true);
5420       emit_insn (gen_floatdidf2 (operands[0], dreg));
5421       DONE;
5422     }
5424   if (!REG_P (operands[1]))
5425     operands[1] = force_reg (SImode, operands[1]);
5426   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5427   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5428   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5429   operands[5] = gen_reg_rtx (DFmode);
5432 (define_insn_and_split "*floatunssidf2_internal"
5433   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5434         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5435    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5436    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5437    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5438    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5439   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5440    && !(TARGET_FCFID && TARGET_POWERPC64)"
5441   "#"
5442   ""
5443   [(pc)]
5444   "
5446   rtx lowword, highword;
5447   gcc_assert (MEM_P (operands[4]));
5448   highword = adjust_address (operands[4], SImode, 0);
5449   lowword = adjust_address (operands[4], SImode, 4);
5450   if (! WORDS_BIG_ENDIAN)
5451     std::swap (lowword, highword);
5453   emit_move_insn (lowword, operands[1]);
5454   emit_move_insn (highword, operands[2]);
5455   emit_move_insn (operands[5], operands[4]);
5456   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5457   DONE;
5459   [(set_attr "length" "20")
5460    (set_attr "type" "fp")])
5462 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5463 ;; vector registers.  These insns favor doing the sign/zero extension in
5464 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5465 ;; extension and then a direct move.
5467 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5468   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5469                    (float:FP_ISA3
5470                     (match_operand:QHI 1 "input_operand")))
5471               (clobber (match_scratch:DI 2))
5472               (clobber (match_scratch:DI 3))
5473               (clobber (match_scratch:<QHI:MODE> 4))])]
5474   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5475    && TARGET_VSX_SMALL_INTEGER"
5477   if (MEM_P (operands[1]))
5478     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5481 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5482   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5483         (float:FP_ISA3
5484          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5485    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5486    (clobber (match_scratch:DI 3 "=X,r,X"))
5487    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5488   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5489    && TARGET_UPPER_REGS_DI && TARGET_VSX_SMALL_INTEGER"
5490   "#"
5491   "&& reload_completed"
5492   [(const_int 0)]
5494   rtx result = operands[0];
5495   rtx input = operands[1];
5496   rtx di = operands[2];
5498   if (!MEM_P (input))
5499     {
5500       rtx tmp = operands[3];
5501       if (altivec_register_operand (input, <QHI:MODE>mode))
5502         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5503       else if (GET_CODE (tmp) == SCRATCH)
5504         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5505       else
5506         {
5507           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5508           emit_move_insn (di, tmp);
5509         }
5510     }
5511   else
5512     {
5513       rtx tmp = operands[4];
5514       emit_move_insn (tmp, input);
5515       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5516     }
5518   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5519   DONE;
5522 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5523   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5524                    (unsigned_float:FP_ISA3
5525                     (match_operand:QHI 1 "input_operand" "")))
5526               (clobber (match_scratch:DI 2 ""))
5527               (clobber (match_scratch:DI 3 ""))])]
5528   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5529    && TARGET_VSX_SMALL_INTEGER"
5531   if (MEM_P (operands[1]))
5532     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5535 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5536   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5537         (unsigned_float:FP_ISA3
5538          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5539    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5540    (clobber (match_scratch:DI 3 "=X,r,X"))]
5541   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5542    && TARGET_VSX_SMALL_INTEGER"
5543   "#"
5544   "&& reload_completed"
5545   [(const_int 0)]
5547   rtx result = operands[0];
5548   rtx input = operands[1];
5549   rtx di = operands[2];
5551   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5552     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5553   else
5554     {
5555       rtx tmp = operands[3];
5556       if (GET_CODE (tmp) == SCRATCH)
5557         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5558       else
5559         {
5560           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5561           emit_move_insn (di, tmp);
5562         }
5563     }
5565   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5566   DONE;
5569 (define_expand "fix_trunc<mode>si2"
5570   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5571         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5572   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5573   "
5575   if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER)
5576     {
5577       rtx src = force_reg (<MODE>mode, operands[1]);
5579       if (TARGET_STFIWX)
5580         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5581       else
5582         {
5583           rtx tmp = gen_reg_rtx (DImode);
5584           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5585           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5586                                                       tmp, stack));
5587         }
5588       DONE;
5589     }
5592 ; Like the convert to float patterns, this insn must be split before
5593 ; register allocation so that it can allocate the memory slot if it
5594 ; needed
5595 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5596   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5597         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5598    (clobber (match_scratch:DI 2 "=d"))]
5599   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5600    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5601    && TARGET_STFIWX && can_create_pseudo_p ()
5602    && !TARGET_VSX_SMALL_INTEGER"
5603   "#"
5604   ""
5605   [(pc)]
5607   rtx dest = operands[0];
5608   rtx src = operands[1];
5609   rtx tmp = operands[2];
5611   if (GET_CODE (tmp) == SCRATCH)
5612     tmp = gen_reg_rtx (DImode);
5614   emit_insn (gen_fctiwz_<mode> (tmp, src));
5615   if (MEM_P (dest))
5616     {
5617       dest = rs6000_address_for_fpconvert (dest);
5618       emit_insn (gen_stfiwx (dest, tmp));
5619       DONE;
5620     }
5621   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5622     {
5623       dest = gen_lowpart (DImode, dest);
5624       emit_move_insn (dest, tmp);
5625       DONE;
5626     }
5627   else
5628     {
5629       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5630       emit_insn (gen_stfiwx (stack, tmp));
5631       emit_move_insn (dest, stack);
5632       DONE;
5633     }
5635   [(set_attr "length" "12")
5636    (set_attr "type" "fp")])
5638 (define_insn_and_split "fix_trunc<mode>si2_internal"
5639   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5640         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5641    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5642    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5643   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5644    && !TARGET_VSX_SMALL_INTEGER"
5645   "#"
5646   ""
5647   [(pc)]
5648   "
5650   rtx lowword;
5651   gcc_assert (MEM_P (operands[3]));
5652   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5654   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5655   emit_move_insn (operands[3], operands[2]);
5656   emit_move_insn (operands[0], lowword);
5657   DONE;
5659   [(set_attr "length" "16")
5660    (set_attr "type" "fp")])
5662 (define_expand "fix_trunc<mode>di2"
5663   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5664         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5665   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5666    && TARGET_FCFID"
5667   "")
5669 (define_insn "*fix_trunc<mode>di2_fctidz"
5670   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5671         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5672   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5673     && TARGET_FCFID"
5674   "@
5675    fctidz %0,%1
5676    xscvdpsxds %x0,%x1"
5677   [(set_attr "type" "fp")])
5679 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5680   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5681                    (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5682               (clobber (match_scratch:DI 2))])]
5683   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5684    && TARGET_VSX_SMALL_INTEGER"
5686   if (MEM_P (operands[0]))
5687     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5690 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5691   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5692         (fix:QHI
5693          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5694    (clobber (match_scratch:DI 2 "=X,wi"))]
5695   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5696    && TARGET_VSX_SMALL_INTEGER"
5697   "#"
5698   "&& reload_completed"
5699   [(const_int 0)]
5701   rtx dest = operands[0];
5702   rtx src = operands[1];
5704   if (vsx_register_operand (dest, <QHI:MODE>mode))
5705     {
5706       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5707       emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5708     }
5709   else
5710     {
5711       rtx tmp = operands[2];
5712       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5714       emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5715       emit_move_insn (dest, tmp2);
5716     }
5717   DONE;
5720 (define_expand "fixuns_trunc<mode>si2"
5721   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5722         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5723   "TARGET_HARD_FLOAT
5724    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5725        || <E500_CONVERT>)"
5726   "
5728   if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER)
5729     {
5730       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5731       DONE;
5732     }
5735 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5736   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5737         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5738    (clobber (match_scratch:DI 2 "=d"))]
5739   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5740    && TARGET_STFIWX && can_create_pseudo_p ()
5741    && !TARGET_VSX_SMALL_INTEGER"
5742   "#"
5743   ""
5744   [(pc)]
5746   rtx dest = operands[0];
5747   rtx src = operands[1];
5748   rtx tmp = operands[2];
5750   if (GET_CODE (tmp) == SCRATCH)
5751     tmp = gen_reg_rtx (DImode);
5753   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5754   if (MEM_P (dest))
5755     {
5756       dest = rs6000_address_for_fpconvert (dest);
5757       emit_insn (gen_stfiwx (dest, tmp));
5758       DONE;
5759     }
5760   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5761     {
5762       dest = gen_lowpart (DImode, dest);
5763       emit_move_insn (dest, tmp);
5764       DONE;
5765     }
5766   else
5767     {
5768       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5769       emit_insn (gen_stfiwx (stack, tmp));
5770       emit_move_insn (dest, stack);
5771       DONE;
5772     }
5774   [(set_attr "length" "12")
5775    (set_attr "type" "fp")])
5777 (define_insn "fixuns_trunc<mode>di2"
5778   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5779         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5780   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ"
5781   "@
5782    fctiduz %0,%1
5783    xscvdpuxds %x0,%x1"
5784   [(set_attr "type" "fp")])
5786 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5787   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5788                    (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5789               (clobber (match_scratch:DI 2))])]
5790   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5791    && TARGET_VSX_SMALL_INTEGER"
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    && TARGET_VSX_SMALL_INTEGER"
5804   "#"
5805   "&& reload_completed"
5806   [(const_int 0)]
5808   rtx dest = operands[0];
5809   rtx src = operands[1];
5811   if (vsx_register_operand (dest, <QHI:MODE>mode))
5812     {
5813       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5814       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5815     }
5816   else
5817     {
5818       rtx tmp = operands[2];
5819       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5821       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5822       emit_move_insn (dest, tmp2);
5823     }
5824   DONE;
5827 ;; If -mvsx-small-integer, we can represent the FIX operation directly.  On
5828 ;; older machines, we have to use an UNSPEC to produce a SImode and move it
5829 ;; to another location, since SImode is not allowed in vector registers.
5830 (define_insn "*fctiw<u>z_<mode>_smallint"
5831   [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5832         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5833   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5834    && TARGET_VSX_SMALL_INTEGER"
5835   "@
5836    fctiw<u>z %0,%1
5837    xscvdp<su>xws %x0,%x1"
5838   [(set_attr "type" "fp")])
5840 ;; Combiner pattern to prevent moving the result of converting a floating point
5841 ;; value to 32-bit integer to GPR in order to save it.
5842 (define_insn_and_split "*fctiw<u>z_<mode>_mem"
5843   [(set (match_operand:SI 0 "memory_operand" "=Z")
5844         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5845    (clobber (match_scratch:SI 2 "=wa"))]
5846   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5847    && TARGET_VSX_SMALL_INTEGER"
5848   "#"
5849   "&& reload_completed"
5850   [(set (match_dup 2)
5851         (any_fix:SI (match_dup 1)))
5852    (set (match_dup 0)
5853         (match_dup 2))])
5855 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5856 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5857 ;; because the first makes it clear that operand 0 is not live
5858 ;; before the instruction.
5859 (define_insn "fctiwz_<mode>"
5860   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5861         (unspec:DI [(fix:SI
5862                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5863                    UNSPEC_FCTIWZ))]
5864   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5865   "@
5866    fctiwz %0,%1
5867    xscvdpsxws %x0,%x1"
5868   [(set_attr "type" "fp")])
5870 (define_insn "fctiwuz_<mode>"
5871   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5872         (unspec:DI [(unsigned_fix:SI
5873                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5874                    UNSPEC_FCTIWUZ))]
5875   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5876   "@
5877    fctiwuz %0,%1
5878    xscvdpuxws %x0,%x1"
5879   [(set_attr "type" "fp")])
5881 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5882 ;; since the friz instruction does not truncate the value if the floating
5883 ;; point value is < LONG_MIN or > LONG_MAX.
5884 (define_insn "*friz"
5885   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5886         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5887   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5888    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5889   "@
5890    friz %0,%1
5891    xsrdpiz %x0,%x1"
5892   [(set_attr "type" "fp")])
5894 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5895 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5896 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5897 ;; extend it, store it back on the stack from the GPR, load it back into the
5898 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5899 ;; disable using store and load to sign/zero extend the value.
5900 (define_insn_and_split "*round32<mode>2_fprs"
5901   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5902         (float:SFDF
5903          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5904    (clobber (match_scratch:DI 2 "=d"))
5905    (clobber (match_scratch:DI 3 "=d"))]
5906   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5907    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5908    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5909   "#"
5910   ""
5911   [(pc)]
5913   rtx dest = operands[0];
5914   rtx src = operands[1];
5915   rtx tmp1 = operands[2];
5916   rtx tmp2 = operands[3];
5917   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5919   if (GET_CODE (tmp1) == SCRATCH)
5920     tmp1 = gen_reg_rtx (DImode);
5921   if (GET_CODE (tmp2) == SCRATCH)
5922     tmp2 = gen_reg_rtx (DImode);
5924   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5925   emit_insn (gen_stfiwx (stack, tmp1));
5926   emit_insn (gen_lfiwax (tmp2, stack));
5927   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5928   DONE;
5930   [(set_attr "type" "fpload")
5931    (set_attr "length" "16")])
5933 (define_insn_and_split "*roundu32<mode>2_fprs"
5934   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5935         (unsigned_float:SFDF
5936          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5937    (clobber (match_scratch:DI 2 "=d"))
5938    (clobber (match_scratch:DI 3 "=d"))]
5939   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5940    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5941    && can_create_pseudo_p ()"
5942   "#"
5943   ""
5944   [(pc)]
5946   rtx dest = operands[0];
5947   rtx src = operands[1];
5948   rtx tmp1 = operands[2];
5949   rtx tmp2 = operands[3];
5950   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5952   if (GET_CODE (tmp1) == SCRATCH)
5953     tmp1 = gen_reg_rtx (DImode);
5954   if (GET_CODE (tmp2) == SCRATCH)
5955     tmp2 = gen_reg_rtx (DImode);
5957   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5958   emit_insn (gen_stfiwx (stack, tmp1));
5959   emit_insn (gen_lfiwzx (tmp2, stack));
5960   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5961   DONE;
5963   [(set_attr "type" "fpload")
5964    (set_attr "length" "16")])
5966 ;; No VSX equivalent to fctid
5967 (define_insn "lrint<mode>di2"
5968   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5969         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5970                    UNSPEC_FCTID))]
5971   "TARGET_<MODE>_FPR && TARGET_FPRND"
5972   "fctid %0,%1"
5973   [(set_attr "type" "fp")])
5975 (define_insn "btrunc<mode>2"
5976   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5977         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5978                      UNSPEC_FRIZ))]
5979   "TARGET_<MODE>_FPR && TARGET_FPRND"
5980   "@
5981    friz %0,%1
5982    xsrdpiz %x0,%x1"
5983   [(set_attr "type" "fp")
5984    (set_attr "fp_type" "fp_addsub_<Fs>")])
5986 (define_insn "ceil<mode>2"
5987   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5988         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5989                      UNSPEC_FRIP))]
5990   "TARGET_<MODE>_FPR && TARGET_FPRND"
5991   "@
5992    frip %0,%1
5993    xsrdpip %x0,%x1"
5994   [(set_attr "type" "fp")
5995    (set_attr "fp_type" "fp_addsub_<Fs>")])
5997 (define_insn "floor<mode>2"
5998   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5999         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6000                      UNSPEC_FRIM))]
6001   "TARGET_<MODE>_FPR && TARGET_FPRND"
6002   "@
6003    frim %0,%1
6004    xsrdpim %x0,%x1"
6005   [(set_attr "type" "fp")
6006    (set_attr "fp_type" "fp_addsub_<Fs>")])
6008 ;; No VSX equivalent to frin
6009 (define_insn "round<mode>2"
6010   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6011         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6012                      UNSPEC_FRIN))]
6013   "TARGET_<MODE>_FPR && TARGET_FPRND"
6014   "frin %0,%1"
6015   [(set_attr "type" "fp")
6016    (set_attr "fp_type" "fp_addsub_<Fs>")])
6018 (define_insn "*xsrdpi<mode>2"
6019   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6020         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6021                      UNSPEC_XSRDPI))]
6022   "TARGET_<MODE>_FPR && TARGET_VSX"
6023   "xsrdpi %x0,%x1"
6024   [(set_attr "type" "fp")
6025    (set_attr "fp_type" "fp_addsub_<Fs>")])
6027 (define_expand "lround<mode>di2"
6028   [(set (match_dup 2)
6029         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
6030                      UNSPEC_XSRDPI))
6031    (set (match_operand:DI 0 "gpc_reg_operand" "")
6032         (unspec:DI [(match_dup 2)]
6033                    UNSPEC_FCTID))]
6034   "TARGET_<MODE>_FPR && TARGET_VSX"
6036   operands[2] = gen_reg_rtx (<MODE>mode);
6039 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6040 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6041 ; is only generated for Power8 or later.
6042 (define_insn "stfiwx"
6043   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6044         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6045                    UNSPEC_STFIWX))]
6046   "TARGET_PPC_GFXOPT"
6047   "@
6048    stfiwx %1,%y0
6049    stxsiwx %x1,%y0"
6050   [(set_attr "type" "fpstore")])
6052 ;; If we don't have a direct conversion to single precision, don't enable this
6053 ;; conversion for 32-bit without fast math, because we don't have the insn to
6054 ;; generate the fixup swizzle to avoid double rounding problems.
6055 (define_expand "floatsisf2"
6056   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6057         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6058   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6059    && (!TARGET_FPRS
6060        || (TARGET_FPRS
6061            && ((TARGET_FCFIDS && TARGET_LFIWAX)
6062                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6063                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
6064   "
6066   if (!TARGET_FPRS)
6067     {
6068       if (!REG_P (operands[1]))
6069         operands[1] = force_reg (SImode, operands[1]);
6070     }
6071   else if (TARGET_FCFIDS && TARGET_LFIWAX)
6072     {
6073       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6074       DONE;
6075     }
6076   else if (TARGET_FCFID && TARGET_LFIWAX)
6077     {
6078       rtx dfreg = gen_reg_rtx (DFmode);
6079       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6080       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6081       DONE;
6082     }
6083   else
6084     {
6085       rtx dreg = operands[1];
6086       if (!REG_P (dreg))
6087         dreg = force_reg (SImode, dreg);
6088       dreg = convert_to_mode (DImode, dreg, false);
6089       emit_insn (gen_floatdisf2 (operands[0], dreg));
6090       DONE;
6091     }
6094 (define_expand "floatdidf2"
6095   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6096         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6097   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6098   "")
6100 (define_insn "*floatdidf2_fpr"
6101   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6102         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6103   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6104   "@
6105    fcfid %0,%1
6106    xscvsxddp %x0,%x1"
6107   [(set_attr "type" "fp")])
6109 ; Allow the combiner to merge source memory operands to the conversion so that
6110 ; the optimizer/register allocator doesn't try to load the value too early in a
6111 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6112 ; hit.  We will split after reload to avoid the trip through the GPRs
6114 (define_insn_and_split "*floatdidf2_mem"
6115   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6116         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6117    (clobber (match_scratch:DI 2 "=d,wi"))]
6118   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6119   "#"
6120   "&& reload_completed"
6121   [(set (match_dup 2) (match_dup 1))
6122    (set (match_dup 0) (float:DF (match_dup 2)))]
6123   ""
6124   [(set_attr "length" "8")
6125    (set_attr "type" "fpload")])
6127 (define_expand "floatunsdidf2"
6128   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6129         (unsigned_float:DF
6130          (match_operand:DI 1 "gpc_reg_operand" "")))]
6131   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6132   "")
6134 (define_insn "*floatunsdidf2_fcfidu"
6135   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6136         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6137   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6138   "@
6139    fcfidu %0,%1
6140    xscvuxddp %x0,%x1"
6141   [(set_attr "type" "fp")
6142    (set_attr "length" "4")])
6144 (define_insn_and_split "*floatunsdidf2_mem"
6145   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6146         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6147    (clobber (match_scratch:DI 2 "=d,wi"))]
6148   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6149   "#"
6150   "&& reload_completed"
6151   [(set (match_dup 2) (match_dup 1))
6152    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6153   ""
6154   [(set_attr "length" "8")
6155    (set_attr "type" "fpload")])
6157 (define_expand "floatdisf2"
6158   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6159         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6160   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6161    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6162   "
6164   if (!TARGET_FCFIDS)
6165     {
6166       rtx val = operands[1];
6167       if (!flag_unsafe_math_optimizations)
6168         {
6169           rtx label = gen_label_rtx ();
6170           val = gen_reg_rtx (DImode);
6171           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6172           emit_label (label);
6173         }
6174       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6175       DONE;
6176     }
6179 (define_insn "floatdisf2_fcfids"
6180   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6181         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6182   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6183    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6184   "@
6185    fcfids %0,%1
6186    xscvsxdsp %x0,%x1"
6187   [(set_attr "type" "fp")])
6189 (define_insn_and_split "*floatdisf2_mem"
6190   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6191         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6192    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6193   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6194    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6195   "#"
6196   "&& reload_completed"
6197   [(pc)]
6198   "
6200   emit_move_insn (operands[2], operands[1]);
6201   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6202   DONE;
6204   [(set_attr "length" "8")])
6206 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6207 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6208 ;; from double rounding.
6209 ;; Instead of creating a new cpu type for two FP operations, just use fp
6210 (define_insn_and_split "floatdisf2_internal1"
6211   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6212         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6213    (clobber (match_scratch:DF 2 "=d"))]
6214   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6215    && !TARGET_FCFIDS"
6216   "#"
6217   "&& reload_completed"
6218   [(set (match_dup 2)
6219         (float:DF (match_dup 1)))
6220    (set (match_dup 0)
6221         (float_truncate:SF (match_dup 2)))]
6222   ""
6223   [(set_attr "length" "8")
6224    (set_attr "type" "fp")])
6226 ;; Twiddles bits to avoid double rounding.
6227 ;; Bits that might be truncated when converting to DFmode are replaced
6228 ;; by a bit that won't be lost at that stage, but is below the SFmode
6229 ;; rounding position.
6230 (define_expand "floatdisf2_internal2"
6231   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6232                                               (const_int 53)))
6233               (clobber (reg:DI CA_REGNO))])
6234    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6235                                            (const_int 2047)))
6236    (set (match_dup 3) (plus:DI (match_dup 3)
6237                                (const_int 1)))
6238    (set (match_dup 0) (plus:DI (match_dup 0)
6239                                (const_int 2047)))
6240    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6241                                      (const_int 2)))
6242    (set (match_dup 0) (ior:DI (match_dup 0)
6243                               (match_dup 1)))
6244    (set (match_dup 0) (and:DI (match_dup 0)
6245                               (const_int -2048)))
6246    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6247                            (label_ref (match_operand:DI 2 "" ""))
6248                            (pc)))
6249    (set (match_dup 0) (match_dup 1))]
6250   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6251    && !TARGET_FCFIDS"
6252   "
6254   operands[3] = gen_reg_rtx (DImode);
6255   operands[4] = gen_reg_rtx (CCUNSmode);
6258 (define_expand "floatunsdisf2"
6259   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6260         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6261   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6262    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6263   "")
6265 (define_insn "floatunsdisf2_fcfidus"
6266   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6267         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6268   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6269    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6270   "@
6271    fcfidus %0,%1
6272    xscvuxdsp %x0,%x1"
6273   [(set_attr "type" "fp")])
6275 (define_insn_and_split "*floatunsdisf2_mem"
6276   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6277         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6278    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6279   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6280    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6281   "#"
6282   "&& reload_completed"
6283   [(pc)]
6284   "
6286   emit_move_insn (operands[2], operands[1]);
6287   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6288   DONE;
6290   [(set_attr "length" "8")
6291    (set_attr "type" "fpload")])
6293 ;; Define the TImode operations that can be done in a small number
6294 ;; of instructions.  The & constraints are to prevent the register
6295 ;; allocator from allocating registers that overlap with the inputs
6296 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6297 ;; also allow for the output being the same as one of the inputs.
6299 (define_expand "addti3"
6300   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6301         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6302                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6303   "TARGET_64BIT"
6305   rtx lo0 = gen_lowpart (DImode, operands[0]);
6306   rtx lo1 = gen_lowpart (DImode, operands[1]);
6307   rtx lo2 = gen_lowpart (DImode, operands[2]);
6308   rtx hi0 = gen_highpart (DImode, operands[0]);
6309   rtx hi1 = gen_highpart (DImode, operands[1]);
6310   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6312   if (!reg_or_short_operand (lo2, DImode))
6313     lo2 = force_reg (DImode, lo2);
6314   if (!adde_operand (hi2, DImode))
6315     hi2 = force_reg (DImode, hi2);
6317   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6318   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6319   DONE;
6322 (define_expand "subti3"
6323   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6324         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6325                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6326   "TARGET_64BIT"
6328   rtx lo0 = gen_lowpart (DImode, operands[0]);
6329   rtx lo1 = gen_lowpart (DImode, operands[1]);
6330   rtx lo2 = gen_lowpart (DImode, operands[2]);
6331   rtx hi0 = gen_highpart (DImode, operands[0]);
6332   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6333   rtx hi2 = gen_highpart (DImode, operands[2]);
6335   if (!reg_or_short_operand (lo1, DImode))
6336     lo1 = force_reg (DImode, lo1);
6337   if (!adde_operand (hi1, DImode))
6338     hi1 = force_reg (DImode, hi1);
6340   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6341   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6342   DONE;
6345 ;; 128-bit logical operations expanders
6347 (define_expand "and<mode>3"
6348   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6349         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6350                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6351   ""
6352   "")
6354 (define_expand "ior<mode>3"
6355   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6356         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6357                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6358   ""
6359   "")
6361 (define_expand "xor<mode>3"
6362   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6363         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6364                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6365   ""
6366   "")
6368 (define_expand "one_cmpl<mode>2"
6369   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6370         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6371   ""
6372   "")
6374 (define_expand "nor<mode>3"
6375   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6376         (and:BOOL_128
6377          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6378          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6379   ""
6380   "")
6382 (define_expand "andc<mode>3"
6383   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6384         (and:BOOL_128
6385          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6386          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6387   ""
6388   "")
6390 ;; Power8 vector logical instructions.
6391 (define_expand "eqv<mode>3"
6392   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6393         (not:BOOL_128
6394          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6395                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6396   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6397   "")
6399 ;; Rewrite nand into canonical form
6400 (define_expand "nand<mode>3"
6401   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6402         (ior:BOOL_128
6403          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6404          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6405   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6406   "")
6408 ;; The canonical form is to have the negated element first, so we need to
6409 ;; reverse arguments.
6410 (define_expand "orc<mode>3"
6411   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6412         (ior:BOOL_128
6413          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6414          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6415   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6416   "")
6418 ;; 128-bit logical operations insns and split operations
6419 (define_insn_and_split "*and<mode>3_internal"
6420   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6421         (and:BOOL_128
6422          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6423          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6424   ""
6426   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6427     return "xxland %x0,%x1,%x2";
6429   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6430     return "vand %0,%1,%2";
6432   return "#";
6434   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6435   [(const_int 0)]
6437   rs6000_split_logical (operands, AND, false, false, false);
6438   DONE;
6440   [(set (attr "type")
6441       (if_then_else
6442         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6443         (const_string "veclogical")
6444         (const_string "integer")))
6445    (set (attr "length")
6446       (if_then_else
6447         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6448         (const_string "4")
6449         (if_then_else
6450          (match_test "TARGET_POWERPC64")
6451          (const_string "8")
6452          (const_string "16"))))])
6454 ;; 128-bit IOR/XOR
6455 (define_insn_and_split "*bool<mode>3_internal"
6456   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6457         (match_operator:BOOL_128 3 "boolean_or_operator"
6458          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6459           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6460   ""
6462   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6463     return "xxl%q3 %x0,%x1,%x2";
6465   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6466     return "v%q3 %0,%1,%2";
6468   return "#";
6470   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6471   [(const_int 0)]
6473   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6474   DONE;
6476   [(set (attr "type")
6477       (if_then_else
6478         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6479         (const_string "veclogical")
6480         (const_string "integer")))
6481    (set (attr "length")
6482       (if_then_else
6483         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6484         (const_string "4")
6485         (if_then_else
6486          (match_test "TARGET_POWERPC64")
6487          (const_string "8")
6488          (const_string "16"))))])
6490 ;; 128-bit ANDC/ORC
6491 (define_insn_and_split "*boolc<mode>3_internal1"
6492   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6493         (match_operator:BOOL_128 3 "boolean_operator"
6494          [(not:BOOL_128
6495            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6496           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6497   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6499   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6500     return "xxl%q3 %x0,%x1,%x2";
6502   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6503     return "v%q3 %0,%1,%2";
6505   return "#";
6507   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6508    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6509   [(const_int 0)]
6511   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6512   DONE;
6514   [(set (attr "type")
6515       (if_then_else
6516         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6517         (const_string "veclogical")
6518         (const_string "integer")))
6519    (set (attr "length")
6520       (if_then_else
6521         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6522         (const_string "4")
6523         (if_then_else
6524          (match_test "TARGET_POWERPC64")
6525          (const_string "8")
6526          (const_string "16"))))])
6528 (define_insn_and_split "*boolc<mode>3_internal2"
6529   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6530         (match_operator:TI2 3 "boolean_operator"
6531          [(not:TI2
6532            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6533           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6534   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6535   "#"
6536   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6537   [(const_int 0)]
6539   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6540   DONE;
6542   [(set_attr "type" "integer")
6543    (set (attr "length")
6544         (if_then_else
6545          (match_test "TARGET_POWERPC64")
6546          (const_string "8")
6547          (const_string "16")))])
6549 ;; 128-bit NAND/NOR
6550 (define_insn_and_split "*boolcc<mode>3_internal1"
6551   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6552         (match_operator:BOOL_128 3 "boolean_operator"
6553          [(not:BOOL_128
6554            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6555           (not:BOOL_128
6556            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6557   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6559   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6560     return "xxl%q3 %x0,%x1,%x2";
6562   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6563     return "v%q3 %0,%1,%2";
6565   return "#";
6567   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6568    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6569   [(const_int 0)]
6571   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6572   DONE;
6574   [(set (attr "type")
6575       (if_then_else
6576         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6577         (const_string "veclogical")
6578         (const_string "integer")))
6579    (set (attr "length")
6580       (if_then_else
6581         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6582         (const_string "4")
6583         (if_then_else
6584          (match_test "TARGET_POWERPC64")
6585          (const_string "8")
6586          (const_string "16"))))])
6588 (define_insn_and_split "*boolcc<mode>3_internal2"
6589   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6590         (match_operator:TI2 3 "boolean_operator"
6591          [(not:TI2
6592            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6593           (not:TI2
6594            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6595   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6596   "#"
6597   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6598   [(const_int 0)]
6600   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6601   DONE;
6603   [(set_attr "type" "integer")
6604    (set (attr "length")
6605         (if_then_else
6606          (match_test "TARGET_POWERPC64")
6607          (const_string "8")
6608          (const_string "16")))])
6611 ;; 128-bit EQV
6612 (define_insn_and_split "*eqv<mode>3_internal1"
6613   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6614         (not:BOOL_128
6615          (xor:BOOL_128
6616           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6617           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6618   "TARGET_P8_VECTOR"
6620   if (vsx_register_operand (operands[0], <MODE>mode))
6621     return "xxleqv %x0,%x1,%x2";
6623   return "#";
6625   "TARGET_P8_VECTOR && reload_completed
6626    && int_reg_operand (operands[0], <MODE>mode)"
6627   [(const_int 0)]
6629   rs6000_split_logical (operands, XOR, true, false, false);
6630   DONE;
6632   [(set (attr "type")
6633       (if_then_else
6634         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6635         (const_string "veclogical")
6636         (const_string "integer")))
6637    (set (attr "length")
6638       (if_then_else
6639         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6640         (const_string "4")
6641         (if_then_else
6642          (match_test "TARGET_POWERPC64")
6643          (const_string "8")
6644          (const_string "16"))))])
6646 (define_insn_and_split "*eqv<mode>3_internal2"
6647   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6648         (not:TI2
6649          (xor:TI2
6650           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6651           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6652   "!TARGET_P8_VECTOR"
6653   "#"
6654   "reload_completed && !TARGET_P8_VECTOR"
6655   [(const_int 0)]
6657   rs6000_split_logical (operands, XOR, true, false, false);
6658   DONE;
6660   [(set_attr "type" "integer")
6661    (set (attr "length")
6662         (if_then_else
6663          (match_test "TARGET_POWERPC64")
6664          (const_string "8")
6665          (const_string "16")))])
6667 ;; 128-bit one's complement
6668 (define_insn_and_split "*one_cmpl<mode>3_internal"
6669   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6670         (not:BOOL_128
6671           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6672   ""
6674   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6675     return "xxlnor %x0,%x1,%x1";
6677   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6678     return "vnor %0,%1,%1";
6680   return "#";
6682   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6683   [(const_int 0)]
6685   rs6000_split_logical (operands, NOT, false, false, false);
6686   DONE;
6688   [(set (attr "type")
6689       (if_then_else
6690         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6691         (const_string "veclogical")
6692         (const_string "integer")))
6693    (set (attr "length")
6694       (if_then_else
6695         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6696         (const_string "4")
6697         (if_then_else
6698          (match_test "TARGET_POWERPC64")
6699          (const_string "8")
6700          (const_string "16"))))])
6703 ;; Now define ways of moving data around.
6705 ;; Set up a register with a value from the GOT table
6707 (define_expand "movsi_got"
6708   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6709         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6710                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6711   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6712   "
6714   if (GET_CODE (operands[1]) == CONST)
6715     {
6716       rtx offset = const0_rtx;
6717       HOST_WIDE_INT value;
6719       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6720       value = INTVAL (offset);
6721       if (value != 0)
6722         {
6723           rtx tmp = (!can_create_pseudo_p ()
6724                      ? operands[0]
6725                      : gen_reg_rtx (Pmode));
6726           emit_insn (gen_movsi_got (tmp, operands[1]));
6727           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6728           DONE;
6729         }
6730     }
6732   operands[2] = rs6000_got_register (operands[1]);
6735 (define_insn "*movsi_got_internal"
6736   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6737         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6738                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6739                    UNSPEC_MOVSI_GOT))]
6740   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6741   "lwz %0,%a1@got(%2)"
6742   [(set_attr "type" "load")])
6744 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6745 ;; didn't get allocated to a hard register.
6746 (define_split
6747   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6748         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6749                     (match_operand:SI 2 "memory_operand" "")]
6750                    UNSPEC_MOVSI_GOT))]
6751   "DEFAULT_ABI == ABI_V4
6752     && flag_pic == 1
6753     && (reload_in_progress || reload_completed)"
6754   [(set (match_dup 0) (match_dup 2))
6755    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6756                                  UNSPEC_MOVSI_GOT))]
6757   "")
6759 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6760 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6761 ;; and this is even supposed to be faster, but it is simpler not to get
6762 ;; integers in the TOC.
6763 (define_insn "movsi_low"
6764   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6765         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6766                            (match_operand 2 "" ""))))]
6767   "TARGET_MACHO && ! TARGET_64BIT"
6768   "lwz %0,lo16(%2)(%1)"
6769   [(set_attr "type" "load")
6770    (set_attr "length" "4")])
6772 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6773 ;;              STW          STFIWX       STXSIWX      LI           LIS
6774 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6775 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6776 ;;              MF%1         MT%0         MT%0         NOP
6777 (define_insn "*movsi_internal1"
6778   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6779                 "=r,         r,           r,           ?*wI,        ?*wH,
6780                  m,          ?Z,          ?Z,          r,           r,
6781                  r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6782                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6783                  r,          *c*l,        *h,          *h")
6785         (match_operand:SI 1 "input_operand"
6786                 "r,          U,           m,           Z,           Z,
6787                  r,          wI,          wH,          I,           L,
6788                  n,          wIwH,        O,           wM,          wB,
6789                  O,          wM,          wS,          r,           wIwH,
6790                  *h,         r,           r,           0"))]
6792   "!TARGET_SINGLE_FPU &&
6793    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6794   "@
6795    mr %0,%1
6796    la %0,%a1
6797    lwz%U1%X1 %0,%1
6798    lfiwzx %0,%y1
6799    lxsiwzx %x0,%y1
6800    stw%U0%X0 %1,%0
6801    stfiwx %1,%y0
6802    stxsiwx %x1,%y0
6803    li %0,%1
6804    lis %0,%v1
6805    #
6806    xxlor %x0,%x1,%x1
6807    xxspltib %x0,0
6808    xxspltib %x0,255
6809    vspltisw %0,%1
6810    xxlxor %x0,%x0,%x0
6811    xxlorc %x0,%x0,%x0
6812    #
6813    mtvsrwz %x0,%1
6814    mfvsrwz %0,%x1
6815    mf%1 %0
6816    mt%0 %1
6817    mt%0 %1
6818    nop"
6819   [(set_attr "type"
6820                 "*,          *,           load,        fpload,      fpload,
6821                  store,      fpstore,     fpstore,     *,           *,
6822                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6823                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6824                  *,           *,           *,           *")
6826    (set_attr "length"
6827                 "4,          4,           4,           4,           4,
6828                  4,          4,           4,           4,           4,
6829                  8,          4,           4,           4,           4,
6830                  4,          4,           8,           4,           4,
6831                  4,          4,           4,           4")])
6833 (define_insn "*movsi_internal1_single"
6834   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6835         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6836   "TARGET_SINGLE_FPU &&
6837    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6838   "@
6839    mr %0,%1
6840    la %0,%a1
6841    lwz%U1%X1 %0,%1
6842    stw%U0%X0 %1,%0
6843    li %0,%1
6844    lis %0,%v1
6845    #
6846    mf%1 %0
6847    mt%0 %1
6848    mt%0 %1
6849    nop
6850    stfs%U0%X0 %1,%0
6851    lfs%U1%X1 %0,%1"
6852   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6853    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6855 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6856 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6858 ;; Because SF values are actually stored as DF values within the vector
6859 ;; registers, we need to convert the value to the vector SF format when
6860 ;; we need to use the bits in a union or similar cases.  We only need
6861 ;; to do this transformation when the value is a vector register.  Loads,
6862 ;; stores, and transfers within GPRs are assumed to be safe.
6864 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6865 ;; no alternatives, because the call is created as part of secondary_reload,
6866 ;; and operand #2's register class is used to allocate the temporary register.
6867 ;; This function is called before reload, and it creates the temporary as
6868 ;; needed.
6870 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6871 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  MTVSRWZ
6872 ;;              VSX->VSX
6874 (define_insn_and_split "movsi_from_sf"
6875   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6876                 "=r,         r,           ?*wI,        ?*wH,     m,
6877                  m,          wY,          Z,           r,        wIwH,
6878                  ?wK")
6880         (unspec:SI [(match_operand:SF 1 "input_operand"
6881                 "r,          m,           Z,           Z,        r,
6882                  f,          wb,          wu,          wIwH,     r,
6883                  wK")]
6884                     UNSPEC_SI_FROM_SF))
6886    (clobber (match_scratch:V4SF 2
6887                 "=X,         X,           X,           X,        X,
6888                  X,          X,           X,           wa,       X,
6889                  wa"))]
6891   "TARGET_NO_SF_SUBREG
6892    && (register_operand (operands[0], SImode)
6893        || register_operand (operands[1], SFmode))"
6894   "@
6895    mr %0,%1
6896    lwz%U1%X1 %0,%1
6897    lfiwzx %0,%y1
6898    lxsiwzx %x0,%y1
6899    stw%U0%X0 %1,%0
6900    stfs%U0%X0 %1,%0
6901    stxssp %1,%0
6902    stxsspx %x1,%y0
6903    #
6904    mtvsrwz %x0,%1
6905    #"
6906   "&& reload_completed
6907    && register_operand (operands[0], SImode)
6908    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6909   [(const_int 0)]
6911   rtx op0 = operands[0];
6912   rtx op1 = operands[1];
6913   rtx op2 = operands[2];
6914   rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
6916   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6918   if (int_reg_operand (op0, SImode))
6919     {
6920       emit_insn (gen_p8_mfvsrd_4_disf (op0_di, op2));
6921       emit_insn (gen_lshrdi3 (op0_di, op0_di, GEN_INT (32)));
6922     }
6923   else
6924     {
6925       rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6926       rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6927       emit_insn (gen_vextract4b (op0_di, op1_v16qi, byte_off));
6928     }
6930   DONE;
6932   [(set_attr "type"
6933                 "*,          load,        fpload,      fpload,   store,
6934                  fpstore,    fpstore,     fpstore,     mftgpr,   mffgpr,
6935                  veclogical")
6937    (set_attr "length"
6938                 "4,          4,           4,           4,        4,
6939                  4,          4,           4,           12,       4,
6940                  8")])
6942 ;; movsi_from_sf with zero extension
6944 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6945 ;;              MTVSRWZ      VSX->VSX
6947 (define_insn_and_split "*movdi_from_sf_zero_ext"
6948   [(set (match_operand:DI 0 "gpc_reg_operand"
6949                 "=r,         r,           ?*wI,        ?*wH,     r,
6950                 wIwH,        ?wK")
6952         (zero_extend:DI
6953          (unspec:SI [(match_operand:SF 1 "input_operand"
6954                 "r,          m,           Z,           Z,        wIwH,
6955                  r,          wK")]
6956                     UNSPEC_SI_FROM_SF)))
6958    (clobber (match_scratch:V4SF 2
6959                 "=X,         X,           X,           X,        wa,
6960                  X,          wa"))]
6962   "TARGET_DIRECT_MOVE_64BIT
6963    && (register_operand (operands[0], DImode)
6964        || register_operand (operands[1], SImode))"
6965   "@
6966    rldicl %0,%1,0,32
6967    lwz%U1%X1 %0,%1
6968    lfiwzx %0,%y1
6969    lxsiwzx %x0,%y1
6970    #
6971    mtvsrwz %x0,%1
6972    #"
6973   "&& reload_completed
6974    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6975   [(const_int 0)]
6977   rtx op0 = operands[0];
6978   rtx op1 = operands[1];
6979   rtx op2 = operands[2];
6981   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6983   if (int_reg_operand (op0, DImode))
6984     {
6985       emit_insn (gen_p8_mfvsrd_4_disf (op0, op2));
6986       emit_insn (gen_lshrdi3 (op0, op0, GEN_INT (32)));
6987     }
6988   else
6989     {
6990       rtx op0_si = gen_rtx_REG (SImode, REGNO (op0));
6991       rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6992       rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6993       emit_insn (gen_vextract4b (op0_si, op1_v16qi, byte_off));
6994     }
6996   DONE;
6998   [(set_attr "type"
6999                 "*,          load,        fpload,      fpload,  mftgpr,
7000                  mffgpr,     veclogical")
7002    (set_attr "length"
7003                 "4,          4,           4,           4,        12,
7004                  4,          8")])
7006 ;; Split a load of a large constant into the appropriate two-insn
7007 ;; sequence.
7009 (define_split
7010   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7011         (match_operand:SI 1 "const_int_operand" ""))]
7012   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7013    && (INTVAL (operands[1]) & 0xffff) != 0"
7014   [(set (match_dup 0)
7015         (match_dup 2))
7016    (set (match_dup 0)
7017         (ior:SI (match_dup 0)
7018                 (match_dup 3)))]
7019   "
7021   if (rs6000_emit_set_const (operands[0], operands[1]))
7022     DONE;
7023   else
7024     FAIL;
7027 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7028 (define_split
7029   [(set (match_operand:DI 0 "altivec_register_operand")
7030         (match_operand:DI 1 "xxspltib_constant_split"))]
7031   "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
7032   [(const_int 0)]
7034   rtx op0 = operands[0];
7035   rtx op1 = operands[1];
7036   int r = REGNO (op0);
7037   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7039   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7040   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7041   DONE;
7044 (define_insn "*mov<mode>_internal2"
7045   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7046         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7047                     (const_int 0)))
7048    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7049   ""
7050   "@
7051    cmp<wd>i %2,%0,0
7052    mr. %0,%1
7053    #"
7054   [(set_attr "type" "cmp,logical,cmp")
7055    (set_attr "dot" "yes")
7056    (set_attr "length" "4,4,8")])
7058 (define_split
7059   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
7060         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
7061                     (const_int 0)))
7062    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
7063   "reload_completed"
7064   [(set (match_dup 0) (match_dup 1))
7065    (set (match_dup 2)
7066         (compare:CC (match_dup 0)
7067                     (const_int 0)))]
7068   "")
7070 (define_expand "mov<mode>"
7071   [(set (match_operand:INT 0 "general_operand" "")
7072         (match_operand:INT 1 "any_operand" ""))]
7073   ""
7074   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7076 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7077 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7078 ;;              MTVSRWZ     MF%1       MT%1       NOP
7079 (define_insn "*mov<mode>_internal"
7080   [(set (match_operand:QHI 0 "nonimmediate_operand"
7081                 "=r,        r,         ?*wJwK,    m,         Z,         r,
7082                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7083                  ?*wJwK,    r,         *c*l,      *h")
7085         (match_operand:QHI 1 "input_operand"
7086                 "r,         m,         Z,         r,         wJwK,      i,
7087                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7088                  r,         *h,        r,         0"))]
7090   "gpc_reg_operand (operands[0], <MODE>mode)
7091    || gpc_reg_operand (operands[1], <MODE>mode)"
7092   "@
7093    mr %0,%1
7094    l<wd>z%U1%X1 %0,%1
7095    lxsi<wd>zx %x0,%y1
7096    st<wd>%U0%X0 %1,%0
7097    stxsi<wd>x %x1,%y0
7098    li %0,%1
7099    xxlor %x0,%x1,%x1
7100    xxspltib %x0,0
7101    xxspltib %x0,255
7102    vspltis<wd> %0,%1
7103    #
7104    mfvsrwz %0,%x1
7105    mtvsrwz %x0,%1
7106    mf%1 %0
7107    mt%0 %1
7108    nop"
7109   [(set_attr "type"
7110                 "*,         load,      fpload,    store,     fpstore,   *,
7111                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7112                  mffgpr,    mfjmpr,    mtjmpr,    *")
7114    (set_attr "length"
7115                 "4,         4,         4,         4,         4,         4,
7116                  4,         4,         4,         4,         8,         4,
7117                  4,         4,         4,         4")])
7120 ;; Here is how to move condition codes around.  When we store CC data in
7121 ;; an integer register or memory, we store just the high-order 4 bits.
7122 ;; This lets us not shift in the most common case of CR0.
7123 (define_expand "movcc"
7124   [(set (match_operand:CC 0 "nonimmediate_operand" "")
7125         (match_operand:CC 1 "nonimmediate_operand" ""))]
7126   ""
7127   "")
7129 (define_insn "*movcc_internal1"
7130   [(set (match_operand:CC 0 "nonimmediate_operand"
7131                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7132         (match_operand:CC 1 "general_operand"
7133                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7134   "register_operand (operands[0], CCmode)
7135    || register_operand (operands[1], CCmode)"
7136   "@
7137    mcrf %0,%1
7138    mtcrf 128,%1
7139    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7140    crxor %0,%0,%0
7141    mfcr %0%Q1
7142    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7143    mr %0,%1
7144    li %0,%1
7145    mf%1 %0
7146    mt%0 %1
7147    lwz%U1%X1 %0,%1
7148    stw%U0%X0 %1,%0"
7149   [(set (attr "type")
7150      (cond [(eq_attr "alternative" "0,3")
7151                 (const_string "cr_logical")
7152             (eq_attr "alternative" "1,2")
7153                 (const_string "mtcr")
7154             (eq_attr "alternative" "6,7")
7155                 (const_string "integer")
7156             (eq_attr "alternative" "8")
7157                 (const_string "mfjmpr")
7158             (eq_attr "alternative" "9")
7159                 (const_string "mtjmpr")
7160             (eq_attr "alternative" "10")
7161                 (const_string "load")
7162             (eq_attr "alternative" "11")
7163                 (const_string "store")
7164             (match_test "TARGET_MFCRF")
7165                 (const_string "mfcrf")
7166            ]
7167         (const_string "mfcr")))
7168    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7170 ;; For floating-point, we normally deal with the floating-point registers
7171 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7172 ;; can produce floating-point values in fixed-point registers.  Unless the
7173 ;; value is a simple constant or already in memory, we deal with this by
7174 ;; allocating memory and copying the value explicitly via that memory location.
7176 ;; Move 32-bit binary/decimal floating point
7177 (define_expand "mov<mode>"
7178   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7179         (match_operand:FMOVE32 1 "any_operand" ""))]
7180   "<fmove_ok>"
7181   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7183 (define_split
7184   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7185         (match_operand:FMOVE32 1 "const_double_operand" ""))]
7186   "reload_completed
7187    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7188        || (GET_CODE (operands[0]) == SUBREG
7189            && GET_CODE (SUBREG_REG (operands[0])) == REG
7190            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7191   [(set (match_dup 2) (match_dup 3))]
7192   "
7194   long l;
7196   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7198   if (! TARGET_POWERPC64)
7199     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7200   else
7201     operands[2] = gen_lowpart (SImode, operands[0]);
7203   operands[3] = gen_int_mode (l, SImode);
7206 ;; Originally, we tried to keep movsf and movsd common, but the differences
7207 ;; addressing was making it rather difficult to hide with mode attributes.  In
7208 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7209 ;; before the VSX stores meant that the register allocator would tend to do a
7210 ;; direct move to the GPR (which involves conversion from scalar to
7211 ;; vector/memory formats) to save values in the traditional Altivec registers,
7212 ;; while SDmode had problems on power6 if the GPR store was not first due to
7213 ;; the power6 not having an integer store operation.
7215 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7216 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7217 ;;      MR           MT<x>      MF<x>       NOP
7219 (define_insn "movsf_hardfloat"
7220   [(set (match_operand:SF 0 "nonimmediate_operand"
7221          "=!r,       f,         wb,         wu,        m,         wY,
7222           Z,         m,         ww,         !r,        f,         ww,
7223           !r,        *c*l,      !r,         *h")
7224         (match_operand:SF 1 "input_operand"
7225          "m,         m,         wY,         Z,         f,         wb,
7226           wu,        r,         j,          j,         f,         ww,
7227           r,         r,         *h,         0"))]
7228   "(register_operand (operands[0], SFmode)
7229    || register_operand (operands[1], SFmode))
7230    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7231    && (TARGET_ALLOW_SF_SUBREG
7232        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7233   "@
7234    lwz%U1%X1 %0,%1
7235    lfs%U1%X1 %0,%1
7236    lxssp %0,%1
7237    lxsspx %x0,%y1
7238    stfs%U0%X0 %1,%0
7239    stxssp %1,%0
7240    stxsspx %x1,%y0
7241    stw%U0%X0 %1,%0
7242    xxlxor %x0,%x0,%x0
7243    li %0,0
7244    fmr %0,%1
7245    xscpsgndp %x0,%x1,%x1
7246    mr %0,%1
7247    mt%0 %1
7248    mf%1 %0
7249    nop"
7250   [(set_attr "type"
7251         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7252          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7253          *,          mtjmpr,    mfjmpr,     *")])
7255 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7256 ;;      FMR          MR         MT%0       MF%1       NOP
7257 (define_insn "movsd_hardfloat"
7258   [(set (match_operand:SD 0 "nonimmediate_operand"
7259          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7260           f,         !r,        *c*l,      !r,        *h")
7261         (match_operand:SD 1 "input_operand"
7262          "m,         Z,         r,         wx,        r,         wh,
7263           f,         r,         r,         *h,        0"))]
7264   "(register_operand (operands[0], SDmode)
7265    || register_operand (operands[1], SDmode))
7266    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
7267   "@
7268    lwz%U1%X1 %0,%1
7269    lfiwzx %0,%y1
7270    stw%U0%X0 %1,%0
7271    stfiwx %1,%y0
7272    mtvsrwz %x0,%1
7273    mfvsrwz %0,%x1
7274    fmr %0,%1
7275    mr %0,%1
7276    mt%0 %1
7277    mf%1 %0
7278    nop"
7279   [(set_attr "type"
7280         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7281          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7283 (define_insn "*mov<mode>_softfloat"
7284   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7285         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7286   "(gpc_reg_operand (operands[0], <MODE>mode)
7287    || gpc_reg_operand (operands[1], <MODE>mode))
7288    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
7289   "@
7290    mr %0,%1
7291    mt%0 %1
7292    mf%1 %0
7293    lwz%U1%X1 %0,%1
7294    stw%U0%X0 %1,%0
7295    li %0,%1
7296    lis %0,%v1
7297    #
7298    #
7299    nop"
7300   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7301    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7303 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7304 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7306 ;; Because SF values are actually stored as DF values within the vector
7307 ;; registers, we need to convert the value to the vector SF format when
7308 ;; we need to use the bits in a union or similar cases.  We only need
7309 ;; to do this transformation when the value is a vector register.  Loads,
7310 ;; stores, and transfers within GPRs are assumed to be safe.
7312 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7313 ;; no alternatives, because the call is created as part of secondary_reload,
7314 ;; and operand #2's register class is used to allocate the temporary register.
7315 ;; This function is called before reload, and it creates the temporary as
7316 ;; needed.
7318 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7319 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7320 (define_insn_and_split "movsf_from_si"
7321   [(set (match_operand:SF 0 "rs6000_nonimmediate_operand"
7322             "=!r,       f,         wb,        wu,        m,         Z,
7323              Z,         wy,        ?r,        !r")
7325         (unspec:SF [(match_operand:SI 1 "input_operand" 
7326             "m,         m,         wY,        Z,         r,         f,
7327              wu,        r,         wy,        r")]
7328                    UNSPEC_SF_FROM_SI))
7330    (clobber (match_scratch:DI 2
7331             "=X,        X,         X,         X,         X,         X,
7332              X,         r,         X,         X"))]
7334   "TARGET_NO_SF_SUBREG
7335    && (register_operand (operands[0], SFmode)
7336        || register_operand (operands[1], SImode))"
7337   "@
7338    lwz%U1%X1 %0,%1
7339    lfs%U1%X1 %0,%1
7340    lxssp %0,%1
7341    lxsspx %x0,%y1
7342    stw%U0%X0 %1,%0
7343    stfiwx %1,%y0
7344    stxsiwx %x1,%y0
7345    #
7346    mfvsrwz %0,%x1
7347    mr %0,%1"
7349   "&& reload_completed
7350    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7351    && int_reg_operand_not_pseudo (operands[1], SImode)"
7352   [(const_int 0)]
7354   rtx op0 = operands[0];
7355   rtx op1 = operands[1];
7356   rtx op2 = operands[2];
7357   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7359   /* Move SF value to upper 32-bits for xscvspdpn.  */
7360   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7361   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7362   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7363   DONE;
7365   [(set_attr "length"
7366             "4,          4,         4,         4,         4,         4,
7367              4,          12,        4,         4")
7368    (set_attr "type"
7369             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7370              fpstore,    vecfloat,  mffgpr,    *")])
7373 ;; Move 64-bit binary/decimal floating point
7374 (define_expand "mov<mode>"
7375   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7376         (match_operand:FMOVE64 1 "any_operand" ""))]
7377   ""
7378   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7380 (define_split
7381   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7382         (match_operand:FMOVE64 1 "const_int_operand" ""))]
7383   "! TARGET_POWERPC64 && reload_completed
7384    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7385        || (GET_CODE (operands[0]) == SUBREG
7386            && GET_CODE (SUBREG_REG (operands[0])) == REG
7387            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7388   [(set (match_dup 2) (match_dup 4))
7389    (set (match_dup 3) (match_dup 1))]
7390   "
7392   int endian = (WORDS_BIG_ENDIAN == 0);
7393   HOST_WIDE_INT value = INTVAL (operands[1]);
7395   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7396   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7397   operands[4] = GEN_INT (value >> 32);
7398   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7401 (define_split
7402   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7403         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7404   "! TARGET_POWERPC64 && reload_completed
7405    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7406        || (GET_CODE (operands[0]) == SUBREG
7407            && GET_CODE (SUBREG_REG (operands[0])) == REG
7408            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7409   [(set (match_dup 2) (match_dup 4))
7410    (set (match_dup 3) (match_dup 5))]
7411   "
7413   int endian = (WORDS_BIG_ENDIAN == 0);
7414   long l[2];
7416   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7418   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7419   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7420   operands[4] = gen_int_mode (l[endian], SImode);
7421   operands[5] = gen_int_mode (l[1 - endian], SImode);
7424 (define_split
7425   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7426         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7427   "TARGET_POWERPC64 && reload_completed
7428    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7429        || (GET_CODE (operands[0]) == SUBREG
7430            && GET_CODE (SUBREG_REG (operands[0])) == REG
7431            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7432   [(set (match_dup 2) (match_dup 3))]
7433   "
7435   int endian = (WORDS_BIG_ENDIAN == 0);
7436   long l[2];
7437   HOST_WIDE_INT val;
7439   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7441   operands[2] = gen_lowpart (DImode, operands[0]);
7442   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7443   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7444          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7446   operands[3] = gen_int_mode (val, DImode);
7449 ;; Don't have reload use general registers to load a constant.  It is
7450 ;; less efficient than loading the constant into an FP register, since
7451 ;; it will probably be used there.
7453 ;; The move constraints are ordered to prefer floating point registers before
7454 ;; general purpose registers to avoid doing a store and a load to get the value
7455 ;; into a floating point register when it is needed for a floating point
7456 ;; operation.  Prefer traditional floating point registers over VSX registers,
7457 ;; since the D-form version of the memory instructions does not need a GPR for
7458 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7459 ;; registers.
7461 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7462 ;; except for 0.0 which can be created on VSX with an xor instruction.
7464 (define_insn "*mov<mode>_hardfloat32"
7465   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7466         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7467   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7468    && (gpc_reg_operand (operands[0], <MODE>mode)
7469        || gpc_reg_operand (operands[1], <MODE>mode))"
7470   "@
7471    stfd%U0%X0 %1,%0
7472    lfd%U1%X1 %0,%1
7473    fmr %0,%1
7474    lxsd%U1x %x0,%y1
7475    stxsd%U0x %x1,%y0
7476    lxsd %0,%1
7477    stxsd %1,%0
7478    xxlor %x0,%x1,%x1
7479    xxlxor %x0,%x0,%x0
7480    #
7481    #
7482    #
7483    #"
7484   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7485    (set_attr "size" "64")
7486    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7488 (define_insn "*mov<mode>_softfloat32"
7489   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7490         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7491   "! TARGET_POWERPC64 
7492    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
7493        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
7494        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
7495    && (gpc_reg_operand (operands[0], <MODE>mode)
7496        || gpc_reg_operand (operands[1], <MODE>mode))"
7497   "#"
7498   [(set_attr "type" "store,load,two,*,*,*")
7499    (set_attr "length" "8,8,8,8,12,16")])
7501 ; ld/std require word-aligned displacements -> 'Y' constraint.
7502 ; List Y->r and r->Y before r->r for reload.
7503 (define_insn "*mov<mode>_hardfloat64"
7504   [(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>")
7505         (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"))]
7506   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7507    && (gpc_reg_operand (operands[0], <MODE>mode)
7508        || gpc_reg_operand (operands[1], <MODE>mode))"
7509   "@
7510    stfd%U0%X0 %1,%0
7511    lfd%U1%X1 %0,%1
7512    fmr %0,%1
7513    lxsd %0,%1
7514    stxsd %1,%0
7515    lxsd%U1x %x0,%y1
7516    stxsd%U0x %x1,%y0
7517    xxlor %x0,%x1,%x1
7518    xxlxor %x0,%x0,%x0
7519    li %0,0
7520    std%U0%X0 %1,%0
7521    ld%U1%X1 %0,%1
7522    mr %0,%1
7523    mt%0 %1
7524    mf%1 %0
7525    nop
7526    mftgpr %0,%1
7527    mffgpr %0,%1
7528    mfvsrd %0,%x1
7529    mtvsrd %x0,%1"
7530   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7531    (set_attr "size" "64")
7532    (set_attr "length" "4")])
7534 (define_insn "*mov<mode>_softfloat64"
7535   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7536         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7537   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7538    && (gpc_reg_operand (operands[0], <MODE>mode)
7539        || gpc_reg_operand (operands[1], <MODE>mode))"
7540   "@
7541    std%U0%X0 %1,%0
7542    ld%U1%X1 %0,%1
7543    mr %0,%1
7544    mt%0 %1
7545    mf%1 %0
7546    #
7547    #
7548    #
7549    nop"
7550   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7551    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7553 (define_expand "mov<mode>"
7554   [(set (match_operand:FMOVE128 0 "general_operand" "")
7555         (match_operand:FMOVE128 1 "any_operand" ""))]
7556   ""
7557   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7559 ;; It's important to list Y->r and r->Y before r->r because otherwise
7560 ;; reload, given m->r, will try to pick r->r and reload it, which
7561 ;; doesn't make progress.
7563 ;; We can't split little endian direct moves of TDmode, because the words are
7564 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7565 ;; problematical.  Don't allow direct move for this case.
7567 (define_insn_and_split "*mov<mode>_64bit_dm"
7568   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7569         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7570   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7571    && FLOAT128_2REG_P (<MODE>mode)
7572    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7573    && (gpc_reg_operand (operands[0], <MODE>mode)
7574        || gpc_reg_operand (operands[1], <MODE>mode))"
7575   "#"
7576   "&& reload_completed"
7577   [(pc)]
7578 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7579   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7581 (define_insn_and_split "*movtd_64bit_nodm"
7582   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7583         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7584   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7585    && (gpc_reg_operand (operands[0], TDmode)
7586        || gpc_reg_operand (operands[1], TDmode))"
7587   "#"
7588   "&& reload_completed"
7589   [(pc)]
7590 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7591   [(set_attr "length" "8,8,8,12,12,8")])
7593 (define_insn_and_split "*mov<mode>_32bit"
7594   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7595         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7596   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7597    && (FLOAT128_2REG_P (<MODE>mode)
7598        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7599        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7600    && (gpc_reg_operand (operands[0], <MODE>mode)
7601        || gpc_reg_operand (operands[1], <MODE>mode))"
7602   "#"
7603   "&& reload_completed"
7604   [(pc)]
7605 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7606   [(set_attr "length" "8,8,8,8,20,20,16")])
7608 (define_insn_and_split "*mov<mode>_softfloat"
7609   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7610         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7611   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7612    && (gpc_reg_operand (operands[0], <MODE>mode)
7613        || gpc_reg_operand (operands[1], <MODE>mode))"
7614   "#"
7615   "&& reload_completed"
7616   [(pc)]
7617 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7618   [(set_attr "length" "20,20,16")])
7620 (define_expand "extenddf<mode>2"
7621   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7622         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7623   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7624    && TARGET_LONG_DOUBLE_128"
7626   if (FLOAT128_IEEE_P (<MODE>mode))
7627     rs6000_expand_float128_convert (operands[0], operands[1], false);
7628   else if (TARGET_E500_DOUBLE)
7629     {
7630       gcc_assert (<MODE>mode == TFmode);
7631       emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7632     }
7633   else if (TARGET_VSX)
7634     {
7635       if (<MODE>mode == TFmode)
7636         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7637       else if (<MODE>mode == IFmode)
7638         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7639       else
7640         gcc_unreachable ();
7641     }
7642    else
7643     {
7644       rtx zero = gen_reg_rtx (DFmode);
7645       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7647       if (<MODE>mode == TFmode)
7648         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7649       else if (<MODE>mode == IFmode)
7650         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7651       else
7652         gcc_unreachable ();
7653     }
7654   DONE;
7657 ;; Allow memory operands for the source to be created by the combiner.
7658 (define_insn_and_split "extenddf<mode>2_fprs"
7659   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7660         (float_extend:IBM128
7661          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7662    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7663   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7664    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7665   "#"
7666   "&& reload_completed"
7667   [(set (match_dup 3) (match_dup 1))
7668    (set (match_dup 4) (match_dup 2))]
7670   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7671   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7673   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7674   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7677 (define_insn_and_split "extenddf<mode>2_vsx"
7678   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7679         (float_extend:IBM128
7680          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7681   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7682   "#"
7683   "&& reload_completed"
7684   [(set (match_dup 2) (match_dup 1))
7685    (set (match_dup 3) (match_dup 4))]
7687   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7688   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7690   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7691   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7692   operands[4] = CONST0_RTX (DFmode);
7695 (define_expand "extendsf<mode>2"
7696   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7697         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7698   "TARGET_HARD_FLOAT
7699    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7700    && TARGET_LONG_DOUBLE_128"
7702   if (FLOAT128_IEEE_P (<MODE>mode))
7703     rs6000_expand_float128_convert (operands[0], operands[1], false);
7704   else
7705     {
7706       rtx tmp = gen_reg_rtx (DFmode);
7707       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7708       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7709     }
7710   DONE;
7713 (define_expand "trunc<mode>df2"
7714   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7715         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7716   "TARGET_HARD_FLOAT
7717    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7718    && TARGET_LONG_DOUBLE_128"
7720   if (FLOAT128_IEEE_P (<MODE>mode))
7721     {
7722       rs6000_expand_float128_convert (operands[0], operands[1], false);
7723       DONE;
7724     }
7727 (define_insn_and_split "trunc<mode>df2_internal1"
7728   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7729         (float_truncate:DF
7730          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7731   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7732    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7733   "@
7734    #
7735    fmr %0,%1"
7736   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7737   [(const_int 0)]
7739   emit_note (NOTE_INSN_DELETED);
7740   DONE;
7742   [(set_attr "type" "fpsimple")])
7744 (define_insn "trunc<mode>df2_internal2"
7745   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7746         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7747   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7748    && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7749   "fadd %0,%1,%L1"
7750   [(set_attr "type" "fp")
7751    (set_attr "fp_type" "fp_addsub_d")])
7753 (define_expand "trunc<mode>sf2"
7754   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7755         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7756   "TARGET_HARD_FLOAT
7757    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7758    && TARGET_LONG_DOUBLE_128"
7760   if (FLOAT128_IEEE_P (<MODE>mode))
7761     rs6000_expand_float128_convert (operands[0], operands[1], false);
7762   else if (TARGET_E500_DOUBLE)
7763     {
7764       gcc_assert (<MODE>mode == TFmode);
7765       emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7766     }
7767   else if (<MODE>mode == TFmode)
7768     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7769   else if (<MODE>mode == IFmode)
7770     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7771   else
7772     gcc_unreachable ();
7773   DONE;
7776 (define_insn_and_split "trunc<mode>sf2_fprs"
7777   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7778         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7779    (clobber (match_scratch:DF 2 "=d"))]
7780   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
7781    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7782   "#"
7783   "&& reload_completed"
7784   [(set (match_dup 2)
7785         (float_truncate:DF (match_dup 1)))
7786    (set (match_dup 0)
7787         (float_truncate:SF (match_dup 2)))]
7788   "")
7790 (define_expand "floatsi<mode>2"
7791   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7792                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7793               (clobber (match_scratch:DI 2))])]
7794   "TARGET_HARD_FLOAT
7795    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7796    && TARGET_LONG_DOUBLE_128"
7798   rtx op0 = operands[0];
7799   rtx op1 = operands[1];
7801   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7802     ;
7803   else if (FLOAT128_IEEE_P (<MODE>mode))
7804     {
7805       rs6000_expand_float128_convert (op0, op1, false);
7806       DONE;
7807     }
7808   else
7809     {
7810       rtx tmp = gen_reg_rtx (DFmode);
7811       expand_float (tmp, op1, false);
7812       if (<MODE>mode == TFmode)
7813         emit_insn (gen_extenddftf2 (op0, tmp));
7814       else if (<MODE>mode == IFmode)
7815         emit_insn (gen_extenddfif2 (op0, tmp));
7816       else
7817         gcc_unreachable ();
7818       DONE;
7819     }
7822 ; fadd, but rounding towards zero.
7823 ; This is probably not the optimal code sequence.
7824 (define_insn "fix_trunc_helper<mode>"
7825   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7826         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7827                    UNSPEC_FIX_TRUNC_TF))
7828    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7829   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7830    && FLOAT128_IBM_P (<MODE>mode)"
7831   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7832   [(set_attr "type" "fp")
7833    (set_attr "length" "20")])
7835 (define_expand "fix_trunc<mode>si2"
7836   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7837         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7838   "TARGET_HARD_FLOAT
7839    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7841   rtx op0 = operands[0];
7842   rtx op1 = operands[1];
7844   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7845     ;
7846   else
7847     {
7848       if (FLOAT128_IEEE_P (<MODE>mode))
7849         rs6000_expand_float128_convert (op0, op1, false);
7850       else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7851         emit_insn (gen_spe_fix_trunctfsi2 (op0, op1));
7852       else if (<MODE>mode == TFmode)
7853         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7854       else if (<MODE>mode == IFmode)
7855         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7856       else
7857         gcc_unreachable ();
7858       DONE;
7859     }
7862 (define_expand "fix_trunc<mode>si2_fprs"
7863   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7864                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7865               (clobber (match_dup 2))
7866               (clobber (match_dup 3))
7867               (clobber (match_dup 4))
7868               (clobber (match_dup 5))])]
7869   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7871   operands[2] = gen_reg_rtx (DFmode);
7872   operands[3] = gen_reg_rtx (DFmode);
7873   operands[4] = gen_reg_rtx (DImode);
7874   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7877 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7878   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7879         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7880    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7881    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7882    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7883    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7884   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7885   "#"
7886   ""
7887   [(pc)]
7889   rtx lowword;
7890   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7891                                          operands[3]));
7893   gcc_assert (MEM_P (operands[5]));
7894   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7896   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7897   emit_move_insn (operands[5], operands[4]);
7898   emit_move_insn (operands[0], lowword);
7899   DONE;
7902 (define_expand "fix_trunc<mode>di2"
7903   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7904         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7905   "TARGET_FLOAT128_TYPE"
7907   if (!TARGET_FLOAT128_HW)
7908     {
7909       rs6000_expand_float128_convert (operands[0], operands[1], false);
7910       DONE;
7911     }
7914 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7915   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7916         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7917   "TARGET_FLOAT128_TYPE"
7919   rs6000_expand_float128_convert (operands[0], operands[1], true);
7920   DONE;
7923 (define_expand "floatdi<mode>2"
7924   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7925         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7926   "TARGET_FLOAT128_TYPE"
7928   if (!TARGET_FLOAT128_HW)
7929     {
7930       rs6000_expand_float128_convert (operands[0], operands[1], false);
7931       DONE;
7932     }
7935 (define_expand "floatunsdi<IEEE128:mode>2"
7936   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7937         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7938   "TARGET_FLOAT128_TYPE"
7940   if (!TARGET_FLOAT128_HW)
7941     {
7942       rs6000_expand_float128_convert (operands[0], operands[1], true);
7943       DONE;
7944     }
7947 (define_expand "floatuns<IEEE128:mode>2"
7948   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7949         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7950   "TARGET_FLOAT128_TYPE"
7952   rtx op0 = operands[0];
7953   rtx op1 = operands[1];
7955   if (TARGET_FLOAT128_HW)
7956     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7957   else
7958     rs6000_expand_float128_convert (op0, op1, true);
7959   DONE;
7962 (define_expand "neg<mode>2"
7963   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7964         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7965   "FLOAT128_IEEE_P (<MODE>mode)
7966    || (FLOAT128_IBM_P (<MODE>mode)
7967        && TARGET_HARD_FLOAT
7968        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7969   "
7971   if (FLOAT128_IEEE_P (<MODE>mode))
7972     {
7973       if (TARGET_FLOAT128_HW)
7974         {
7975           if (<MODE>mode == TFmode)
7976             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7977           else if (<MODE>mode == KFmode)
7978             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7979           else
7980             gcc_unreachable ();
7981         }
7982       else if (TARGET_FLOAT128_TYPE)
7983         {
7984           if (<MODE>mode == TFmode)
7985             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7986           else if (<MODE>mode == KFmode)
7987             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7988           else
7989             gcc_unreachable ();
7990         }
7991       else
7992         {
7993           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7994           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7995                                                 <MODE>mode, 1,
7996                                                 operands[1], <MODE>mode);
7998           if (target && !rtx_equal_p (target, operands[0]))
7999             emit_move_insn (operands[0], target);
8000         }
8001       DONE;
8002     }
8005 (define_insn "neg<mode>2_internal"
8006   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8007         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8008   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
8009   "*
8011   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8012     return \"fneg %L0,%L1\;fneg %0,%1\";
8013   else
8014     return \"fneg %0,%1\;fneg %L0,%L1\";
8016   [(set_attr "type" "fpsimple")
8017    (set_attr "length" "8")])
8019 (define_expand "abs<mode>2"
8020   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
8021         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
8022   "FLOAT128_IEEE_P (<MODE>mode)
8023    || (FLOAT128_IBM_P (<MODE>mode)
8024        && TARGET_HARD_FLOAT
8025        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
8026   "
8028   rtx label;
8030   if (FLOAT128_IEEE_P (<MODE>mode))
8031     {
8032       if (TARGET_FLOAT128_HW)
8033         {
8034           if (<MODE>mode == TFmode)
8035             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
8036           else if (<MODE>mode == KFmode)
8037             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
8038           else
8039             FAIL;
8040           DONE;
8041         }
8042       else if (TARGET_FLOAT128_TYPE)
8043         {
8044           if (<MODE>mode == TFmode)
8045             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8046           else if (<MODE>mode == KFmode)
8047             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8048           else
8049             FAIL;
8050           DONE;
8051         }
8052       else
8053         FAIL;
8054     }
8056   label = gen_label_rtx ();
8057   if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
8058     {
8059       if (flag_finite_math_only && !flag_trapping_math)
8060         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
8061       else
8062         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
8063     }
8064   else if (<MODE>mode == TFmode)
8065     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8066   else if (<MODE>mode == TFmode)
8067     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8068   else
8069     FAIL;
8070   emit_label (label);
8071   DONE;
8074 (define_expand "abs<mode>2_internal"
8075   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
8076         (match_operand:IBM128 1 "gpc_reg_operand" ""))
8077    (set (match_dup 3) (match_dup 5))
8078    (set (match_dup 5) (abs:DF (match_dup 5)))
8079    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8080    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8081                            (label_ref (match_operand 2 "" ""))
8082                            (pc)))
8083    (set (match_dup 6) (neg:DF (match_dup 6)))]
8084   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
8085    && TARGET_LONG_DOUBLE_128"
8086   "
8088   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8089   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8090   operands[3] = gen_reg_rtx (DFmode);
8091   operands[4] = gen_reg_rtx (CCFPmode);
8092   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8093   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8097 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8098 ;; register
8100 (define_expand "ieee_128bit_negative_zero"
8101   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
8102   "TARGET_FLOAT128_TYPE"
8104   rtvec v = rtvec_alloc (16);
8105   int i, high;
8107   for (i = 0; i < 16; i++)
8108     RTVEC_ELT (v, i) = const0_rtx;
8110   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8111   RTVEC_ELT (v, high) = GEN_INT (0x80);
8113   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8114   DONE;
8117 ;; IEEE 128-bit negate
8119 ;; We have 2 insns here for negate and absolute value.  The first uses
8120 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8121 ;; insns, and second insn after the first split pass loads up the bit to
8122 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8123 ;; neg/abs to create the constant just once.
8125 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8126   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8127         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8128    (clobber (match_scratch:V16QI 2 "=v"))]
8129   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8130   "#"
8131   "&& 1"
8132   [(parallel [(set (match_dup 0)
8133                    (neg:IEEE128 (match_dup 1)))
8134               (use (match_dup 2))])]
8136   if (GET_CODE (operands[2]) == SCRATCH)
8137     operands[2] = gen_reg_rtx (V16QImode);
8139   operands[3] = gen_reg_rtx (V16QImode);
8140   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8142   [(set_attr "length" "8")
8143    (set_attr "type" "vecsimple")])
8145 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8146   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8147         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8148    (use (match_operand:V16QI 2 "register_operand" "v"))]
8149   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8150   "xxlxor %x0,%x1,%x2"
8151   [(set_attr "type" "veclogical")])
8153 ;; IEEE 128-bit absolute value
8154 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8155   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8156         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8157    (clobber (match_scratch:V16QI 2 "=v"))]
8158   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8159   "#"
8160   "&& 1"
8161   [(parallel [(set (match_dup 0)
8162                    (abs:IEEE128 (match_dup 1)))
8163               (use (match_dup 2))])]
8165   if (GET_CODE (operands[2]) == SCRATCH)
8166     operands[2] = gen_reg_rtx (V16QImode);
8168   operands[3] = gen_reg_rtx (V16QImode);
8169   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8171   [(set_attr "length" "8")
8172    (set_attr "type" "vecsimple")])
8174 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8175   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8176         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8177    (use (match_operand:V16QI 2 "register_operand" "v"))]
8178   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8179   "xxlandc %x0,%x1,%x2"
8180   [(set_attr "type" "veclogical")])
8182 ;; IEEE 128-bit negative absolute value
8183 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8184   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8185         (neg:IEEE128
8186          (abs:IEEE128
8187           (match_operand:IEEE128 1 "register_operand" "wa"))))
8188    (clobber (match_scratch:V16QI 2 "=v"))]
8189   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8190    && FLOAT128_IEEE_P (<MODE>mode)"
8191   "#"
8192   "&& 1"
8193   [(parallel [(set (match_dup 0)
8194                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8195               (use (match_dup 2))])]
8197   if (GET_CODE (operands[2]) == SCRATCH)
8198     operands[2] = gen_reg_rtx (V16QImode);
8200   operands[3] = gen_reg_rtx (V16QImode);
8201   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8203   [(set_attr "length" "8")
8204    (set_attr "type" "vecsimple")])
8206 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8207   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8208         (neg:IEEE128
8209          (abs:IEEE128
8210           (match_operand:IEEE128 1 "register_operand" "wa"))))
8211    (use (match_operand:V16QI 2 "register_operand" "v"))]
8212   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8213   "xxlor %x0,%x1,%x2"
8214   [(set_attr "type" "veclogical")])
8216 ;; Float128 conversion functions.  These expand to library function calls.
8217 ;; We use expand to convert from IBM double double to IEEE 128-bit
8218 ;; and trunc for the opposite.
8219 (define_expand "extendiftf2"
8220   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8221         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8222   "TARGET_FLOAT128_TYPE"
8224   rs6000_expand_float128_convert (operands[0], operands[1], false);
8225   DONE;
8228 (define_expand "extendifkf2"
8229   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8230         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8231   "TARGET_FLOAT128_TYPE"
8233   rs6000_expand_float128_convert (operands[0], operands[1], false);
8234   DONE;
8237 (define_expand "extendtfkf2"
8238   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8239         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8240   "TARGET_FLOAT128_TYPE"
8242   rs6000_expand_float128_convert (operands[0], operands[1], false);
8243   DONE;
8246 (define_expand "trunciftf2"
8247   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8248         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8249   "TARGET_FLOAT128_TYPE"
8251   rs6000_expand_float128_convert (operands[0], operands[1], false);
8252   DONE;
8255 (define_expand "truncifkf2"
8256   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8257         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8258   "TARGET_FLOAT128_TYPE"
8260   rs6000_expand_float128_convert (operands[0], operands[1], false);
8261   DONE;
8264 (define_expand "trunckftf2"
8265   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8266         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8267   "TARGET_FLOAT128_TYPE"
8269   rs6000_expand_float128_convert (operands[0], operands[1], false);
8270   DONE;
8273 (define_expand "trunctfif2"
8274   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8275         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8276   "TARGET_FLOAT128_TYPE"
8278   rs6000_expand_float128_convert (operands[0], operands[1], false);
8279   DONE;
8283 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8284 ;; must have 3 arguments, and scratch register constraint must be a single
8285 ;; constraint.
8287 ;; Reload patterns to support gpr load/store with misaligned mem.
8288 ;; and multiple gpr load/store at offset >= 0xfffc
8289 (define_expand "reload_<mode>_store"
8290   [(parallel [(match_operand 0 "memory_operand" "=m")
8291               (match_operand 1 "gpc_reg_operand" "r")
8292               (match_operand:GPR 2 "register_operand" "=&b")])]
8293   ""
8295   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8296   DONE;
8299 (define_expand "reload_<mode>_load"
8300   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8301               (match_operand 1 "memory_operand" "m")
8302               (match_operand:GPR 2 "register_operand" "=b")])]
8303   ""
8305   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8306   DONE;
8310 ;; Reload patterns for various types using the vector registers.  We may need
8311 ;; an additional base register to convert the reg+offset addressing to reg+reg
8312 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8313 ;; index register for gpr registers.
8314 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8315   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8316               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8317               (match_operand:P 2 "register_operand" "=b")])]
8318   "<P:tptrsize>"
8320   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8321   DONE;
8324 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8325   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8326               (match_operand:RELOAD 1 "memory_operand" "m")
8327               (match_operand:P 2 "register_operand" "=b")])]
8328   "<P:tptrsize>"
8330   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8331   DONE;
8335 ;; Reload sometimes tries to move the address to a GPR, and can generate
8336 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8337 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8339 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8340   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8341         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8342                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8343                (const_int -16)))]
8344   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
8345   "#"
8346   "&& reload_completed"
8347   [(set (match_dup 0)
8348         (plus:P (match_dup 1)
8349                 (match_dup 2)))
8350    (set (match_dup 0)
8351         (and:P (match_dup 0)
8352                (const_int -16)))])
8354 ;; Power8 merge instructions to allow direct move to/from floating point
8355 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8356 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8357 ;; value, since it is allocated in reload and not all of the flow information
8358 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8359 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8360 ;; schedule other instructions between the two instructions.
8362 (define_insn "p8_fmrgow_<mode>"
8363   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8364         (unspec:FMOVE64X [
8365                 (match_operand:DF 1 "register_operand" "d")
8366                 (match_operand:DF 2 "register_operand" "d")]
8367                          UNSPEC_P8V_FMRGOW))]
8368   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8369   "fmrgow %0,%1,%2"
8370   [(set_attr "type" "fpsimple")])
8372 (define_insn "p8_mtvsrwz"
8373   [(set (match_operand:DF 0 "register_operand" "=d")
8374         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8375                    UNSPEC_P8V_MTVSRWZ))]
8376   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8377   "mtvsrwz %x0,%1"
8378   [(set_attr "type" "mftgpr")])
8380 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8381   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8382         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8383                          UNSPEC_P8V_RELOAD_FROM_GPR))
8384    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8385   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8386   "#"
8387   "&& reload_completed"
8388   [(const_int 0)]
8390   rtx dest = operands[0];
8391   rtx src = operands[1];
8392   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8393   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8394   rtx gpr_hi_reg = gen_highpart (SImode, src);
8395   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8397   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8398   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8399   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8400   DONE;
8402   [(set_attr "length" "12")
8403    (set_attr "type" "three")])
8405 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8406 (define_insn "p8_mtvsrd_df"
8407   [(set (match_operand:DF 0 "register_operand" "=wa")
8408         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8409                    UNSPEC_P8V_MTVSRD))]
8410   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8411   "mtvsrd %x0,%1"
8412   [(set_attr "type" "mftgpr")])
8414 (define_insn "p8_xxpermdi_<mode>"
8415   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8416         (unspec:FMOVE128_GPR [
8417                 (match_operand:DF 1 "register_operand" "wa")
8418                 (match_operand:DF 2 "register_operand" "wa")]
8419                 UNSPEC_P8V_XXPERMDI))]
8420   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8421   "xxpermdi %x0,%x1,%x2,0"
8422   [(set_attr "type" "vecperm")])
8424 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8425   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8426         (unspec:FMOVE128_GPR
8427          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8428          UNSPEC_P8V_RELOAD_FROM_GPR))
8429    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8430   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8431   "#"
8432   "&& reload_completed"
8433   [(const_int 0)]
8435   rtx dest = operands[0];
8436   rtx src = operands[1];
8437   /* You might think that we could use op0 as one temp and a DF clobber
8438      as op2, but you'd be wrong.  Secondary reload move patterns don't
8439      check for overlap of the clobber and the destination.  */
8440   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8441   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8442   rtx gpr_hi_reg = gen_highpart (DImode, src);
8443   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8445   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8446   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8447   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8448   DONE;
8450   [(set_attr "length" "12")
8451    (set_attr "type" "three")])
8453 (define_split
8454   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8455         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8456   "reload_completed
8457    && (int_reg_operand (operands[0], <MODE>mode)
8458        || int_reg_operand (operands[1], <MODE>mode))
8459    && (!TARGET_DIRECT_MOVE_128
8460        || (!vsx_register_operand (operands[0], <MODE>mode)
8461            && !vsx_register_operand (operands[1], <MODE>mode)))"
8462   [(pc)]
8463 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8465 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8466 ;; type is stored internally as double precision in the VSX registers, we have
8467 ;; to convert it from the vector format.
8468 (define_insn "p8_mtvsrd_sf"
8469   [(set (match_operand:SF 0 "register_operand" "=wa")
8470         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8471                    UNSPEC_P8V_MTVSRD))]
8472   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8473   "mtvsrd %x0,%1"
8474   [(set_attr "type" "mftgpr")])
8476 (define_insn_and_split "reload_vsx_from_gprsf"
8477   [(set (match_operand:SF 0 "register_operand" "=wa")
8478         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8479                    UNSPEC_P8V_RELOAD_FROM_GPR))
8480    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8481   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8482   "#"
8483   "&& reload_completed"
8484   [(const_int 0)]
8486   rtx op0 = operands[0];
8487   rtx op1 = operands[1];
8488   rtx op2 = operands[2];
8489   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8491   /* Move SF value to upper 32-bits for xscvspdpn.  */
8492   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8493   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8494   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8495   DONE;
8497   [(set_attr "length" "8")
8498    (set_attr "type" "two")])
8500 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8501 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8502 ;; and then doing a move of that.
8503 (define_insn "p8_mfvsrd_3_<mode>"
8504   [(set (match_operand:DF 0 "register_operand" "=r")
8505         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8506                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8507   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8508   "mfvsrd %0,%x1"
8509   [(set_attr "type" "mftgpr")])
8511 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8512   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8513         (unspec:FMOVE128_GPR
8514          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8515          UNSPEC_P8V_RELOAD_FROM_VSX))
8516    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8517   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8518   "#"
8519   "&& reload_completed"
8520   [(const_int 0)]
8522   rtx dest = operands[0];
8523   rtx src = operands[1];
8524   rtx tmp = operands[2];
8525   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8526   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8528   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8529   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8530   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8531   DONE;
8533   [(set_attr "length" "12")
8534    (set_attr "type" "three")])
8536 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8537 ;; type is stored internally as double precision, we have to convert it to the
8538 ;; vector format.
8540 (define_insn_and_split "reload_gpr_from_vsxsf"
8541   [(set (match_operand:SF 0 "register_operand" "=r")
8542         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8543                    UNSPEC_P8V_RELOAD_FROM_VSX))
8544    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8545   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8546   "#"
8547   "&& reload_completed"
8548   [(const_int 0)]
8550   rtx op0 = operands[0];
8551   rtx op1 = operands[1];
8552   rtx op2 = operands[2];
8553   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8555   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8556   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8557   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8558   DONE;
8560   [(set_attr "length" "12")
8561    (set_attr "type" "three")])
8563 (define_insn "p8_mfvsrd_4_disf"
8564   [(set (match_operand:DI 0 "register_operand" "=r")
8565         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8566                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8567   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8568   "mfvsrd %0,%x1"
8569   [(set_attr "type" "mftgpr")])
8572 ;; Next come the multi-word integer load and store and the load and store
8573 ;; multiple insns.
8575 ;; List r->r after r->Y, otherwise reload will try to reload a
8576 ;; non-offsettable address by using r->r which won't make progress.
8577 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8578 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8580 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8581 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8582 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8583 ;;        AVX const  
8585 (define_insn "*movdi_internal32"
8586   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8587          "=Y,        r,         r,         ^m,        ^d,         ^d,
8588           r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8589           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8590           *wv")
8592         (match_operand:DI 1 "input_operand"
8593           "r,        Y,         r,         d,         m,          d,
8594            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8595            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8596            wB"))]
8598   "! TARGET_POWERPC64
8599    && (gpc_reg_operand (operands[0], DImode)
8600        || gpc_reg_operand (operands[1], DImode))"
8601   "@
8602    #
8603    #
8604    #
8605    stfd%U0%X0 %1,%0
8606    lfd%U1%X1 %0,%1
8607    fmr %0,%1
8608    #
8609    stxsd %1,%0
8610    stxsdx %x1,%y0
8611    lxsd %0,%1
8612    lxsdx %x0,%y1
8613    xxlor %x0,%x1,%x1
8614    xxspltib %x0,0
8615    xxspltib %x0,255
8616    vspltisw %0,%1
8617    xxlxor %x0,%x0,%x0
8618    xxlorc %x0,%x0,%x0
8619    #
8620    #"
8621   [(set_attr "type"
8622                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8623                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8624                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8625                 vecsimple")
8626    (set_attr "size" "64")])
8628 (define_split
8629   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8630         (match_operand:DI 1 "const_int_operand" ""))]
8631   "! TARGET_POWERPC64 && reload_completed
8632    && gpr_or_gpr_p (operands[0], operands[1])
8633    && !direct_move_p (operands[0], operands[1])"
8634   [(set (match_dup 2) (match_dup 4))
8635    (set (match_dup 3) (match_dup 1))]
8636   "
8638   HOST_WIDE_INT value = INTVAL (operands[1]);
8639   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8640                                        DImode);
8641   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8642                                        DImode);
8643   operands[4] = GEN_INT (value >> 32);
8644   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8647 (define_split
8648   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8649         (match_operand:DIFD 1 "input_operand" ""))]
8650   "reload_completed && !TARGET_POWERPC64
8651    && gpr_or_gpr_p (operands[0], operands[1])
8652    && !direct_move_p (operands[0], operands[1])"
8653   [(pc)]
8654 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8656 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8657 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8658 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8659 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8660 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8661 (define_insn "*movdi_internal64"
8662   [(set (match_operand:DI 0 "nonimmediate_operand"
8663                "=Y,        r,         r,         r,         r,          r,
8664                 ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
8665                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8666                 *wi,       *wv,       *wv,       r,         *h,         *h,
8667                 ?*r,       ?*wg,      ?*r,       ?*wj")
8669         (match_operand:DI 1 "input_operand"
8670                 "r,        Y,         r,         I,         L,          nF,
8671                  d,        m,         d,         wb,        wv,         wY,
8672                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8673                  wM,       wS,        wB,        *h,        r,          0,
8674                  wg,       r,         wj,        r"))]
8676   "TARGET_POWERPC64
8677    && (gpc_reg_operand (operands[0], DImode)
8678        || gpc_reg_operand (operands[1], DImode))"
8679   "@
8680    std%U0%X0 %1,%0
8681    ld%U1%X1 %0,%1
8682    mr %0,%1
8683    li %0,%1
8684    lis %0,%v1
8685    #
8686    stfd%U0%X0 %1,%0
8687    lfd%U1%X1 %0,%1
8688    fmr %0,%1
8689    stxsd %1,%0
8690    stxsdx %x1,%y0
8691    lxsd %0,%1
8692    lxsdx %x0,%y1
8693    xxlor %x0,%x1,%x1
8694    xxspltib %x0,0
8695    xxspltib %x0,255
8696    #
8697    xxlxor %x0,%x0,%x0
8698    xxlorc %x0,%x0,%x0
8699    #
8700    #
8701    mf%1 %0
8702    mt%0 %1
8703    nop
8704    mftgpr %0,%1
8705    mffgpr %0,%1
8706    mfvsrd %0,%x1
8707    mtvsrd %x0,%1"
8708   [(set_attr "type"
8709                "store,      load,       *,         *,         *,         *,
8710                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8711                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8712                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8713                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8715    (set_attr "size" "64")
8716    (set_attr "length"
8717                "4,         4,         4,         4,         4,          20,
8718                 4,         4,         4,         4,         4,          4,
8719                 4,         4,         4,         4,         4,          8,
8720                 8,         4,         4,         4,         4,          4,
8721                 4,         4,         4,         4")])
8723 ; Some DImode loads are best done as a load of -1 followed by a mask
8724 ; instruction.
8725 (define_split
8726   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8727         (match_operand:DI 1 "const_int_operand"))]
8728   "TARGET_POWERPC64
8729    && num_insns_constant (operands[1], DImode) > 1
8730    && rs6000_is_valid_and_mask (operands[1], DImode)"
8731   [(set (match_dup 0)
8732         (const_int -1))
8733    (set (match_dup 0)
8734         (and:DI (match_dup 0)
8735                 (match_dup 1)))]
8736   "")
8738 ;; Split a load of a large constant into the appropriate five-instruction
8739 ;; sequence.  Handle anything in a constant number of insns.
8740 ;; When non-easy constants can go in the TOC, this should use
8741 ;; easy_fp_constant predicate.
8742 (define_split
8743   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8744         (match_operand:DI 1 "const_int_operand" ""))]
8745   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8746   [(set (match_dup 0) (match_dup 2))
8747    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8748   "
8750   if (rs6000_emit_set_const (operands[0], operands[1]))
8751     DONE;
8752   else
8753     FAIL;
8756 (define_split
8757   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8758         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8759   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8760   [(set (match_dup 0) (match_dup 2))
8761    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8762   "
8764   if (rs6000_emit_set_const (operands[0], operands[1]))
8765     DONE;
8766   else
8767     FAIL;
8770 (define_split
8771   [(set (match_operand:DI 0 "altivec_register_operand" "")
8772         (match_operand:DI 1 "s5bit_cint_operand" ""))]
8773   "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8774   [(const_int 0)]
8776   rtx op0 = operands[0];
8777   rtx op1 = operands[1];
8778   int r = REGNO (op0);
8779   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8781   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8782   if (op1 != const0_rtx && op1 != constm1_rtx)
8783     {
8784       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8785       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8786     }
8787   DONE;
8790 ;; Split integer constants that can be loaded with XXSPLTIB and a
8791 ;; sign extend operation.
8792 (define_split
8793   [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8794         (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8795   "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8796   [(const_int 0)]
8798   rtx op0 = operands[0];
8799   rtx op1 = operands[1];
8800   int r = REGNO (op0);
8801   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8803   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8804   if (<MODE>mode == DImode)
8805     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8806   else if (<MODE>mode == SImode)
8807     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8808   else if (<MODE>mode == HImode)
8809     {
8810       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8811       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8812     }
8813   DONE;
8817 ;; TImode/PTImode is similar, except that we usually want to compute the
8818 ;; address into a register and use lsi/stsi (the exception is during reload).
8820 (define_insn "*mov<mode>_string"
8821   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8822         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8823   "! TARGET_POWERPC64
8824    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8825    && (gpc_reg_operand (operands[0], <MODE>mode)
8826        || gpc_reg_operand (operands[1], <MODE>mode))"
8827   "*
8829   switch (which_alternative)
8830     {
8831     default:
8832       gcc_unreachable ();
8833     case 0:
8834       if (TARGET_STRING)
8835         return \"stswi %1,%P0,16\";
8836       /* FALLTHRU */
8837     case 1:
8838       return \"#\";
8839     case 2:
8840       /* If the address is not used in the output, we can use lsi.  Otherwise,
8841          fall through to generating four loads.  */
8842       if (TARGET_STRING
8843           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8844         return \"lswi %0,%P1,16\";
8845       /* fall through */
8846     case 3:
8847     case 4:
8848     case 5:
8849       return \"#\";
8850     }
8852   [(set_attr "type" "store,store,load,load,*,*")
8853    (set_attr "update" "yes")
8854    (set_attr "indexed" "yes")
8855    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8856                                           (const_string "always")
8857                                           (const_string "conditional")))])
8859 (define_insn "*mov<mode>_ppc64"
8860   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8861         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8862   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8863    && (gpc_reg_operand (operands[0], <MODE>mode)
8864        || gpc_reg_operand (operands[1], <MODE>mode)))"
8866   return rs6000_output_move_128bit (operands);
8868   [(set_attr "type" "store,store,load,load,*,*")
8869    (set_attr "length" "8")])
8871 (define_split
8872   [(set (match_operand:TI2 0 "int_reg_operand" "")
8873         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8874   "TARGET_POWERPC64
8875    && (VECTOR_MEM_NONE_P (<MODE>mode)
8876        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8877   [(set (match_dup 2) (match_dup 4))
8878    (set (match_dup 3) (match_dup 5))]
8879   "
8881   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8882                                        <MODE>mode);
8883   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8884                                        <MODE>mode);
8885   if (CONST_WIDE_INT_P (operands[1]))
8886     {
8887       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8888       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8889     }
8890   else if (CONST_INT_P (operands[1]))
8891     {
8892       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8893       operands[5] = operands[1];
8894     }
8895   else
8896     FAIL;
8899 (define_split
8900   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8901         (match_operand:TI2 1 "input_operand" ""))]
8902   "reload_completed
8903    && gpr_or_gpr_p (operands[0], operands[1])
8904    && !direct_move_p (operands[0], operands[1])
8905    && !quad_load_store_p (operands[0], operands[1])"
8906   [(pc)]
8907 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8909 (define_expand "load_multiple"
8910   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8911                           (match_operand:SI 1 "" ""))
8912                      (use (match_operand:SI 2 "" ""))])]
8913   "TARGET_STRING && !TARGET_POWERPC64"
8914   "
8916   int regno;
8917   int count;
8918   rtx op1;
8919   int i;
8921   /* Support only loading a constant number of fixed-point registers from
8922      memory and only bother with this if more than two; the machine
8923      doesn't support more than eight.  */
8924   if (GET_CODE (operands[2]) != CONST_INT
8925       || INTVAL (operands[2]) <= 2
8926       || INTVAL (operands[2]) > 8
8927       || GET_CODE (operands[1]) != MEM
8928       || GET_CODE (operands[0]) != REG
8929       || REGNO (operands[0]) >= 32)
8930     FAIL;
8932   count = INTVAL (operands[2]);
8933   regno = REGNO (operands[0]);
8935   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8936   op1 = replace_equiv_address (operands[1],
8937                                force_reg (SImode, XEXP (operands[1], 0)));
8939   for (i = 0; i < count; i++)
8940     XVECEXP (operands[3], 0, i)
8941       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8942                      adjust_address_nv (op1, SImode, i * 4));
8945 (define_insn "*ldmsi8"
8946   [(match_parallel 0 "load_multiple_operation"
8947     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8948           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8949      (set (match_operand:SI 3 "gpc_reg_operand" "")
8950           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8951      (set (match_operand:SI 4 "gpc_reg_operand" "")
8952           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8953      (set (match_operand:SI 5 "gpc_reg_operand" "")
8954           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8955      (set (match_operand:SI 6 "gpc_reg_operand" "")
8956           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8957      (set (match_operand:SI 7 "gpc_reg_operand" "")
8958           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8959      (set (match_operand:SI 8 "gpc_reg_operand" "")
8960           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8961      (set (match_operand:SI 9 "gpc_reg_operand" "")
8962           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8963   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8964   "*
8965 { return rs6000_output_load_multiple (operands); }"
8966   [(set_attr "type" "load")
8967    (set_attr "update" "yes")
8968    (set_attr "indexed" "yes")
8969    (set_attr "length" "32")])
8971 (define_insn "*ldmsi7"
8972   [(match_parallel 0 "load_multiple_operation"
8973     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8974           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8975      (set (match_operand:SI 3 "gpc_reg_operand" "")
8976           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8977      (set (match_operand:SI 4 "gpc_reg_operand" "")
8978           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8979      (set (match_operand:SI 5 "gpc_reg_operand" "")
8980           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8981      (set (match_operand:SI 6 "gpc_reg_operand" "")
8982           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8983      (set (match_operand:SI 7 "gpc_reg_operand" "")
8984           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8985      (set (match_operand:SI 8 "gpc_reg_operand" "")
8986           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8987   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8988   "*
8989 { return rs6000_output_load_multiple (operands); }"
8990   [(set_attr "type" "load")
8991    (set_attr "update" "yes")
8992    (set_attr "indexed" "yes")
8993    (set_attr "length" "32")])
8995 (define_insn "*ldmsi6"
8996   [(match_parallel 0 "load_multiple_operation"
8997     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8998           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8999      (set (match_operand:SI 3 "gpc_reg_operand" "")
9000           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9001      (set (match_operand:SI 4 "gpc_reg_operand" "")
9002           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9003      (set (match_operand:SI 5 "gpc_reg_operand" "")
9004           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9005      (set (match_operand:SI 6 "gpc_reg_operand" "")
9006           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
9007      (set (match_operand:SI 7 "gpc_reg_operand" "")
9008           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
9009   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9010   "*
9011 { return rs6000_output_load_multiple (operands); }"
9012   [(set_attr "type" "load")
9013    (set_attr "update" "yes")
9014    (set_attr "indexed" "yes")
9015    (set_attr "length" "32")])
9017 (define_insn "*ldmsi5"
9018   [(match_parallel 0 "load_multiple_operation"
9019     [(set (match_operand:SI 2 "gpc_reg_operand" "")
9020           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9021      (set (match_operand:SI 3 "gpc_reg_operand" "")
9022           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9023      (set (match_operand:SI 4 "gpc_reg_operand" "")
9024           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9025      (set (match_operand:SI 5 "gpc_reg_operand" "")
9026           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9027      (set (match_operand:SI 6 "gpc_reg_operand" "")
9028           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
9029   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9030   "*
9031 { return rs6000_output_load_multiple (operands); }"
9032   [(set_attr "type" "load")
9033    (set_attr "update" "yes")
9034    (set_attr "indexed" "yes")
9035    (set_attr "length" "32")])
9037 (define_insn "*ldmsi4"
9038   [(match_parallel 0 "load_multiple_operation"
9039     [(set (match_operand:SI 2 "gpc_reg_operand" "")
9040           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9041      (set (match_operand:SI 3 "gpc_reg_operand" "")
9042           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9043      (set (match_operand:SI 4 "gpc_reg_operand" "")
9044           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9045      (set (match_operand:SI 5 "gpc_reg_operand" "")
9046           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
9047   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9048   "*
9049 { return rs6000_output_load_multiple (operands); }"
9050   [(set_attr "type" "load")
9051    (set_attr "update" "yes")
9052    (set_attr "indexed" "yes")
9053    (set_attr "length" "32")])
9055 (define_insn "*ldmsi3"
9056   [(match_parallel 0 "load_multiple_operation"
9057     [(set (match_operand:SI 2 "gpc_reg_operand" "")
9058           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9059      (set (match_operand:SI 3 "gpc_reg_operand" "")
9060           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9061      (set (match_operand:SI 4 "gpc_reg_operand" "")
9062           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
9063   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
9064   "*
9065 { return rs6000_output_load_multiple (operands); }"
9066   [(set_attr "type" "load")
9067    (set_attr "update" "yes")
9068    (set_attr "indexed" "yes")
9069    (set_attr "length" "32")])
9071 (define_expand "store_multiple"
9072   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
9073                           (match_operand:SI 1 "" ""))
9074                      (clobber (scratch:SI))
9075                      (use (match_operand:SI 2 "" ""))])]
9076   "TARGET_STRING && !TARGET_POWERPC64"
9077   "
9079   int regno;
9080   int count;
9081   rtx to;
9082   rtx op0;
9083   int i;
9085   /* Support only storing a constant number of fixed-point registers to
9086      memory and only bother with this if more than two; the machine
9087      doesn't support more than eight.  */
9088   if (GET_CODE (operands[2]) != CONST_INT
9089       || INTVAL (operands[2]) <= 2
9090       || INTVAL (operands[2]) > 8
9091       || GET_CODE (operands[0]) != MEM
9092       || GET_CODE (operands[1]) != REG
9093       || REGNO (operands[1]) >= 32)
9094     FAIL;
9096   count = INTVAL (operands[2]);
9097   regno = REGNO (operands[1]);
9099   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
9100   to = force_reg (SImode, XEXP (operands[0], 0));
9101   op0 = replace_equiv_address (operands[0], to);
9103   XVECEXP (operands[3], 0, 0)
9104     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
9105   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
9106                                                  gen_rtx_SCRATCH (SImode));
9108   for (i = 1; i < count; i++)
9109     XVECEXP (operands[3], 0, i + 1)
9110       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
9111                      gen_rtx_REG (SImode, regno + i));
9114 (define_insn "*stmsi8"
9115   [(match_parallel 0 "store_multiple_operation"
9116     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9117           (match_operand:SI 2 "gpc_reg_operand" "r"))
9118      (clobber (match_scratch:SI 3 "=X"))
9119      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9120           (match_operand:SI 4 "gpc_reg_operand" "r"))
9121      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9122           (match_operand:SI 5 "gpc_reg_operand" "r"))
9123      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9124           (match_operand:SI 6 "gpc_reg_operand" "r"))
9125      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9126           (match_operand:SI 7 "gpc_reg_operand" "r"))
9127      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9128           (match_operand:SI 8 "gpc_reg_operand" "r"))
9129      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9130           (match_operand:SI 9 "gpc_reg_operand" "r"))
9131      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9132           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9133   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9134   "stswi %2,%1,%O0"
9135   [(set_attr "type" "store")
9136    (set_attr "update" "yes")
9137    (set_attr "indexed" "yes")
9138    (set_attr "cell_micro" "always")])
9140 (define_insn "*stmsi7"
9141   [(match_parallel 0 "store_multiple_operation"
9142     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9143           (match_operand:SI 2 "gpc_reg_operand" "r"))
9144      (clobber (match_scratch:SI 3 "=X"))
9145      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9146           (match_operand:SI 4 "gpc_reg_operand" "r"))
9147      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9148           (match_operand:SI 5 "gpc_reg_operand" "r"))
9149      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9150           (match_operand:SI 6 "gpc_reg_operand" "r"))
9151      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9152           (match_operand:SI 7 "gpc_reg_operand" "r"))
9153      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9154           (match_operand:SI 8 "gpc_reg_operand" "r"))
9155      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9156           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9157   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9158   "stswi %2,%1,%O0"
9159   [(set_attr "type" "store")
9160    (set_attr "update" "yes")
9161    (set_attr "indexed" "yes")
9162    (set_attr "cell_micro" "always")])
9164 (define_insn "*stmsi6"
9165   [(match_parallel 0 "store_multiple_operation"
9166     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9167           (match_operand:SI 2 "gpc_reg_operand" "r"))
9168      (clobber (match_scratch:SI 3 "=X"))
9169      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9170           (match_operand:SI 4 "gpc_reg_operand" "r"))
9171      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9172           (match_operand:SI 5 "gpc_reg_operand" "r"))
9173      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9174           (match_operand:SI 6 "gpc_reg_operand" "r"))
9175      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9176           (match_operand:SI 7 "gpc_reg_operand" "r"))
9177      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9178           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9179   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9180   "stswi %2,%1,%O0"
9181   [(set_attr "type" "store")
9182    (set_attr "update" "yes")
9183    (set_attr "indexed" "yes")
9184    (set_attr "cell_micro" "always")])
9186 (define_insn "*stmsi5"
9187   [(match_parallel 0 "store_multiple_operation"
9188     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9189           (match_operand:SI 2 "gpc_reg_operand" "r"))
9190      (clobber (match_scratch:SI 3 "=X"))
9191      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9192           (match_operand:SI 4 "gpc_reg_operand" "r"))
9193      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9194           (match_operand:SI 5 "gpc_reg_operand" "r"))
9195      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9196           (match_operand:SI 6 "gpc_reg_operand" "r"))
9197      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9198           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9199   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9200   "stswi %2,%1,%O0"
9201   [(set_attr "type" "store")
9202    (set_attr "update" "yes")
9203    (set_attr "indexed" "yes")
9204    (set_attr "cell_micro" "always")])
9206 (define_insn "*stmsi4"
9207   [(match_parallel 0 "store_multiple_operation"
9208     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9209           (match_operand:SI 2 "gpc_reg_operand" "r"))
9210      (clobber (match_scratch:SI 3 "=X"))
9211      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9212           (match_operand:SI 4 "gpc_reg_operand" "r"))
9213      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9214           (match_operand:SI 5 "gpc_reg_operand" "r"))
9215      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9216           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9217   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9218   "stswi %2,%1,%O0"
9219   [(set_attr "type" "store")
9220    (set_attr "update" "yes")
9221    (set_attr "indexed" "yes")
9222    (set_attr "cell_micro" "always")])
9224 (define_insn "*stmsi3"
9225   [(match_parallel 0 "store_multiple_operation"
9226     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9227           (match_operand:SI 2 "gpc_reg_operand" "r"))
9228      (clobber (match_scratch:SI 3 "=X"))
9229      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9230           (match_operand:SI 4 "gpc_reg_operand" "r"))
9231      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9232           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9233   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9234   "stswi %2,%1,%O0"
9235   [(set_attr "type" "store")
9236    (set_attr "update" "yes")
9237    (set_attr "indexed" "yes")
9238    (set_attr "cell_micro" "always")])
9240 (define_expand "setmemsi"
9241   [(parallel [(set (match_operand:BLK 0 "" "")
9242                    (match_operand 2 "const_int_operand" ""))
9243               (use (match_operand:SI 1 "" ""))
9244               (use (match_operand:SI 3 "" ""))])]
9245   ""
9246   "
9248   /* If value to set is not zero, use the library routine.  */
9249   if (operands[2] != const0_rtx)
9250     FAIL;
9252   if (expand_block_clear (operands))
9253     DONE;
9254   else
9255     FAIL;
9258 ;; String compare N insn.
9259 ;; Argument 0 is the target (result)
9260 ;; Argument 1 is the destination
9261 ;; Argument 2 is the source
9262 ;; Argument 3 is the length
9263 ;; Argument 4 is the alignment
9265 (define_expand "cmpstrnsi"
9266   [(parallel [(set (match_operand:SI 0)
9267                (compare:SI (match_operand:BLK 1)
9268                            (match_operand:BLK 2)))
9269               (use (match_operand:SI 3))
9270               (use (match_operand:SI 4))])]
9271   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9273   if (optimize_insn_for_size_p ())
9274     FAIL;
9276   if (expand_strn_compare (operands, 0))
9277     DONE;
9278   else  
9279     FAIL;
9282 ;; String compare insn.
9283 ;; Argument 0 is the target (result)
9284 ;; Argument 1 is the destination
9285 ;; Argument 2 is the source
9286 ;; Argument 3 is the alignment
9288 (define_expand "cmpstrsi"
9289   [(parallel [(set (match_operand:SI 0)
9290                (compare:SI (match_operand:BLK 1)
9291                            (match_operand:BLK 2)))
9292               (use (match_operand:SI 3))])]
9293   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9295   if (optimize_insn_for_size_p ())
9296     FAIL;
9298   if (expand_strn_compare (operands, 1))
9299     DONE;
9300   else  
9301     FAIL;
9304 ;; Block compare insn.
9305 ;; Argument 0 is the target (result)
9306 ;; Argument 1 is the destination
9307 ;; Argument 2 is the source
9308 ;; Argument 3 is the length
9309 ;; Argument 4 is the alignment
9311 (define_expand "cmpmemsi"
9312   [(parallel [(set (match_operand:SI 0)
9313                (compare:SI (match_operand:BLK 1)
9314                            (match_operand:BLK 2)))
9315               (use (match_operand:SI 3))
9316               (use (match_operand:SI 4))])]
9317   "TARGET_POPCNTD"
9319   if (expand_block_compare (operands))
9320     DONE;
9321   else
9322     FAIL;
9325 ;; String/block move insn.
9326 ;; Argument 0 is the destination
9327 ;; Argument 1 is the source
9328 ;; Argument 2 is the length
9329 ;; Argument 3 is the alignment
9331 (define_expand "movmemsi"
9332   [(parallel [(set (match_operand:BLK 0 "" "")
9333                    (match_operand:BLK 1 "" ""))
9334               (use (match_operand:SI 2 "" ""))
9335               (use (match_operand:SI 3 "" ""))])]
9336   ""
9337   "
9339   if (expand_block_move (operands))
9340     DONE;
9341   else
9342     FAIL;
9345 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
9346 ;; register allocator doesn't have a clue about allocating 8 word registers.
9347 ;; rD/rS = r5 is preferred, efficient form.
9348 (define_expand "movmemsi_8reg"
9349   [(parallel [(set (match_operand 0 "" "")
9350                    (match_operand 1 "" ""))
9351               (use (match_operand 2 "" ""))
9352               (use (match_operand 3 "" ""))
9353               (clobber (reg:SI  5))
9354               (clobber (reg:SI  6))
9355               (clobber (reg:SI  7))
9356               (clobber (reg:SI  8))
9357               (clobber (reg:SI  9))
9358               (clobber (reg:SI 10))
9359               (clobber (reg:SI 11))
9360               (clobber (reg:SI 12))
9361               (clobber (match_scratch:SI 4 ""))])]
9362   "TARGET_STRING"
9363   "")
9365 (define_insn ""
9366   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9367         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9368    (use (match_operand:SI 2 "immediate_operand" "i"))
9369    (use (match_operand:SI 3 "immediate_operand" "i"))
9370    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9371    (clobber (reg:SI  6))
9372    (clobber (reg:SI  7))
9373    (clobber (reg:SI  8))
9374    (clobber (reg:SI  9))
9375    (clobber (reg:SI 10))
9376    (clobber (reg:SI 11))
9377    (clobber (reg:SI 12))
9378    (clobber (match_scratch:SI 5 "=X"))]
9379   "TARGET_STRING
9380    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9381        || INTVAL (operands[2]) == 0)
9382    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9383    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9384    && REGNO (operands[4]) == 5"
9385   "lswi %4,%1,%2\;stswi %4,%0,%2"
9386   [(set_attr "type" "store")
9387    (set_attr "update" "yes")
9388    (set_attr "indexed" "yes")
9389    (set_attr "cell_micro" "always")
9390    (set_attr "length" "8")])
9392 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
9393 ;; register allocator doesn't have a clue about allocating 6 word registers.
9394 ;; rD/rS = r5 is preferred, efficient form.
9395 (define_expand "movmemsi_6reg"
9396   [(parallel [(set (match_operand 0 "" "")
9397                    (match_operand 1 "" ""))
9398               (use (match_operand 2 "" ""))
9399               (use (match_operand 3 "" ""))
9400               (clobber (reg:SI  5))
9401               (clobber (reg:SI  6))
9402               (clobber (reg:SI  7))
9403               (clobber (reg:SI  8))
9404               (clobber (reg:SI  9))
9405               (clobber (reg:SI 10))
9406               (clobber (match_scratch:SI 4 ""))])]
9407   "TARGET_STRING"
9408   "")
9410 (define_insn ""
9411   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9412         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9413    (use (match_operand:SI 2 "immediate_operand" "i"))
9414    (use (match_operand:SI 3 "immediate_operand" "i"))
9415    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9416    (clobber (reg:SI  6))
9417    (clobber (reg:SI  7))
9418    (clobber (reg:SI  8))
9419    (clobber (reg:SI  9))
9420    (clobber (reg:SI 10))
9421    (clobber (match_scratch:SI 5 "=X"))]
9422   "TARGET_STRING
9423    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9424    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9425    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9426    && REGNO (operands[4]) == 5"
9427   "lswi %4,%1,%2\;stswi %4,%0,%2"
9428   [(set_attr "type" "store")
9429    (set_attr "update" "yes")
9430    (set_attr "indexed" "yes")
9431    (set_attr "cell_micro" "always")
9432    (set_attr "length" "8")])
9434 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9435 ;; problems with TImode.
9436 ;; rD/rS = r5 is preferred, efficient form.
9437 (define_expand "movmemsi_4reg"
9438   [(parallel [(set (match_operand 0 "" "")
9439                    (match_operand 1 "" ""))
9440               (use (match_operand 2 "" ""))
9441               (use (match_operand 3 "" ""))
9442               (clobber (reg:SI 5))
9443               (clobber (reg:SI 6))
9444               (clobber (reg:SI 7))
9445               (clobber (reg:SI 8))
9446               (clobber (match_scratch:SI 4 ""))])]
9447   "TARGET_STRING"
9448   "")
9450 (define_insn ""
9451   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9452         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9453    (use (match_operand:SI 2 "immediate_operand" "i"))
9454    (use (match_operand:SI 3 "immediate_operand" "i"))
9455    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9456    (clobber (reg:SI 6))
9457    (clobber (reg:SI 7))
9458    (clobber (reg:SI 8))
9459    (clobber (match_scratch:SI 5 "=X"))]
9460   "TARGET_STRING
9461    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9462    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9463    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9464    && REGNO (operands[4]) == 5"
9465   "lswi %4,%1,%2\;stswi %4,%0,%2"
9466   [(set_attr "type" "store")
9467    (set_attr "update" "yes")
9468    (set_attr "indexed" "yes")
9469    (set_attr "cell_micro" "always")
9470    (set_attr "length" "8")])
9472 ;; Move up to 8 bytes at a time.
9473 (define_expand "movmemsi_2reg"
9474   [(parallel [(set (match_operand 0 "" "")
9475                    (match_operand 1 "" ""))
9476               (use (match_operand 2 "" ""))
9477               (use (match_operand 3 "" ""))
9478               (clobber (match_scratch:DI 4 ""))
9479               (clobber (match_scratch:SI 5 ""))])]
9480   "TARGET_STRING && ! TARGET_POWERPC64"
9481   "")
9483 (define_insn ""
9484   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9485         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9486    (use (match_operand:SI 2 "immediate_operand" "i"))
9487    (use (match_operand:SI 3 "immediate_operand" "i"))
9488    (clobber (match_scratch:DI 4 "=&r"))
9489    (clobber (match_scratch:SI 5 "=X"))]
9490   "TARGET_STRING && ! TARGET_POWERPC64
9491    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9492   "lswi %4,%1,%2\;stswi %4,%0,%2"
9493   [(set_attr "type" "store")
9494    (set_attr "update" "yes")
9495    (set_attr "indexed" "yes")
9496    (set_attr "cell_micro" "always")
9497    (set_attr "length" "8")])
9499 ;; Move up to 4 bytes at a time.
9500 (define_expand "movmemsi_1reg"
9501   [(parallel [(set (match_operand 0 "" "")
9502                    (match_operand 1 "" ""))
9503               (use (match_operand 2 "" ""))
9504               (use (match_operand 3 "" ""))
9505               (clobber (match_scratch:SI 4 ""))
9506               (clobber (match_scratch:SI 5 ""))])]
9507   "TARGET_STRING"
9508   "")
9510 (define_insn ""
9511   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9512         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9513    (use (match_operand:SI 2 "immediate_operand" "i"))
9514    (use (match_operand:SI 3 "immediate_operand" "i"))
9515    (clobber (match_scratch:SI 4 "=&r"))
9516    (clobber (match_scratch:SI 5 "=X"))]
9517   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9518   "lswi %4,%1,%2\;stswi %4,%0,%2"
9519   [(set_attr "type" "store")
9520    (set_attr "update" "yes")
9521    (set_attr "indexed" "yes")
9522    (set_attr "cell_micro" "always")
9523    (set_attr "length" "8")])
9525 ;; Define insns that do load or store with update.  Some of these we can
9526 ;; get by using pre-decrement or pre-increment, but the hardware can also
9527 ;; do cases where the increment is not the size of the object.
9529 ;; In all these cases, we use operands 0 and 1 for the register being
9530 ;; incremented because those are the operands that local-alloc will
9531 ;; tie and these are the pair most likely to be tieable (and the ones
9532 ;; that will benefit the most).
9534 (define_insn "*movdi_update1"
9535   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9536         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9537                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9538    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9539         (plus:DI (match_dup 1) (match_dup 2)))]
9540   "TARGET_POWERPC64 && TARGET_UPDATE
9541    && (!avoiding_indexed_address_p (DImode)
9542        || !gpc_reg_operand (operands[2], DImode))"
9543   "@
9544    ldux %3,%0,%2
9545    ldu %3,%2(%0)"
9546   [(set_attr "type" "load")
9547    (set_attr "update" "yes")
9548    (set_attr "indexed" "yes,no")])
9550 (define_insn "movdi_<mode>_update"
9551   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9552                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9553         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9554    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9555         (plus:P (match_dup 1) (match_dup 2)))]
9556   "TARGET_POWERPC64 && TARGET_UPDATE
9557    && (!avoiding_indexed_address_p (Pmode)
9558        || !gpc_reg_operand (operands[2], Pmode)
9559        || (REG_P (operands[0])
9560            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9561   "@
9562    stdux %3,%0,%2
9563    stdu %3,%2(%0)"
9564   [(set_attr "type" "store")
9565    (set_attr "update" "yes")
9566    (set_attr "indexed" "yes,no")])
9568 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9569 ;; needed for stack allocation, even if the user passes -mno-update.
9570 (define_insn "movdi_<mode>_update_stack"
9571   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9572                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9573         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9574    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9575         (plus:P (match_dup 1) (match_dup 2)))]
9576   "TARGET_POWERPC64"
9577   "@
9578    stdux %3,%0,%2
9579    stdu %3,%2(%0)"
9580   [(set_attr "type" "store")
9581    (set_attr "update" "yes")
9582    (set_attr "indexed" "yes,no")])
9584 (define_insn "*movsi_update1"
9585   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9586         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9587                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9588    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9589         (plus:SI (match_dup 1) (match_dup 2)))]
9590   "TARGET_UPDATE
9591    && (!avoiding_indexed_address_p (SImode)
9592        || !gpc_reg_operand (operands[2], SImode))"
9593   "@
9594    lwzux %3,%0,%2
9595    lwzu %3,%2(%0)"
9596   [(set_attr "type" "load")
9597    (set_attr "update" "yes")
9598    (set_attr "indexed" "yes,no")])
9600 (define_insn "*movsi_update2"
9601   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9602         (sign_extend:DI
9603          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9604                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9605    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9606         (plus:DI (match_dup 1) (match_dup 2)))]
9607   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9608    && !avoiding_indexed_address_p (DImode)"
9609   "lwaux %3,%0,%2"
9610   [(set_attr "type" "load")
9611    (set_attr "sign_extend" "yes")
9612    (set_attr "update" "yes")
9613    (set_attr "indexed" "yes")])
9615 (define_insn "movsi_update"
9616   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9617                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9618         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9619    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9620         (plus:SI (match_dup 1) (match_dup 2)))]
9621   "TARGET_UPDATE
9622    && (!avoiding_indexed_address_p (SImode)
9623        || !gpc_reg_operand (operands[2], SImode)
9624        || (REG_P (operands[0])
9625            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9626   "@
9627    stwux %3,%0,%2
9628    stwu %3,%2(%0)"
9629   [(set_attr "type" "store")
9630    (set_attr "update" "yes")
9631    (set_attr "indexed" "yes,no")])
9633 ;; This is an unconditional pattern; needed for stack allocation, even
9634 ;; if the user passes -mno-update.
9635 (define_insn "movsi_update_stack"
9636   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9637                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9638         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9639    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9640         (plus:SI (match_dup 1) (match_dup 2)))]
9641   ""
9642   "@
9643    stwux %3,%0,%2
9644    stwu %3,%2(%0)"
9645   [(set_attr "type" "store")
9646    (set_attr "update" "yes")
9647    (set_attr "indexed" "yes,no")])
9649 (define_insn "*movhi_update1"
9650   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9651         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9652                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9653    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9654         (plus:SI (match_dup 1) (match_dup 2)))]
9655   "TARGET_UPDATE
9656    && (!avoiding_indexed_address_p (SImode)
9657        || !gpc_reg_operand (operands[2], SImode))"
9658   "@
9659    lhzux %3,%0,%2
9660    lhzu %3,%2(%0)"
9661   [(set_attr "type" "load")
9662    (set_attr "update" "yes")
9663    (set_attr "indexed" "yes,no")])
9665 (define_insn "*movhi_update2"
9666   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9667         (zero_extend:SI
9668          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9669                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9670    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9671         (plus:SI (match_dup 1) (match_dup 2)))]
9672   "TARGET_UPDATE
9673    && (!avoiding_indexed_address_p (SImode)
9674        || !gpc_reg_operand (operands[2], SImode))"
9675   "@
9676    lhzux %3,%0,%2
9677    lhzu %3,%2(%0)"
9678   [(set_attr "type" "load")
9679    (set_attr "update" "yes")
9680    (set_attr "indexed" "yes,no")])
9682 (define_insn "*movhi_update3"
9683   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9684         (sign_extend:SI
9685          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9686                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9687    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9688         (plus:SI (match_dup 1) (match_dup 2)))]
9689   "TARGET_UPDATE && rs6000_gen_cell_microcode
9690    && (!avoiding_indexed_address_p (SImode)
9691        || !gpc_reg_operand (operands[2], SImode))"
9692   "@
9693    lhaux %3,%0,%2
9694    lhau %3,%2(%0)"
9695   [(set_attr "type" "load")
9696    (set_attr "sign_extend" "yes")
9697    (set_attr "update" "yes")
9698    (set_attr "indexed" "yes,no")])
9700 (define_insn "*movhi_update4"
9701   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9702                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9703         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9704    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9705         (plus:SI (match_dup 1) (match_dup 2)))]
9706   "TARGET_UPDATE
9707    && (!avoiding_indexed_address_p (SImode)
9708        || !gpc_reg_operand (operands[2], SImode))"
9709   "@
9710    sthux %3,%0,%2
9711    sthu %3,%2(%0)"
9712   [(set_attr "type" "store")
9713    (set_attr "update" "yes")
9714    (set_attr "indexed" "yes,no")])
9716 (define_insn "*movqi_update1"
9717   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9718         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9719                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9720    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9721         (plus:SI (match_dup 1) (match_dup 2)))]
9722   "TARGET_UPDATE
9723    && (!avoiding_indexed_address_p (SImode)
9724        || !gpc_reg_operand (operands[2], SImode))"
9725   "@
9726    lbzux %3,%0,%2
9727    lbzu %3,%2(%0)"
9728   [(set_attr "type" "load")
9729    (set_attr "update" "yes")
9730    (set_attr "indexed" "yes,no")])
9732 (define_insn "*movqi_update2"
9733   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9734         (zero_extend:SI
9735          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9736                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9737    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9738         (plus:SI (match_dup 1) (match_dup 2)))]
9739   "TARGET_UPDATE
9740    && (!avoiding_indexed_address_p (SImode)
9741        || !gpc_reg_operand (operands[2], SImode))"
9742   "@
9743    lbzux %3,%0,%2
9744    lbzu %3,%2(%0)"
9745   [(set_attr "type" "load")
9746    (set_attr "update" "yes")
9747    (set_attr "indexed" "yes,no")])
9749 (define_insn "*movqi_update3"
9750   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9751                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9752         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9753    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9754         (plus:SI (match_dup 1) (match_dup 2)))]
9755   "TARGET_UPDATE
9756    && (!avoiding_indexed_address_p (SImode)
9757        || !gpc_reg_operand (operands[2], SImode))"
9758   "@
9759    stbux %3,%0,%2
9760    stbu %3,%2(%0)"
9761   [(set_attr "type" "store")
9762    (set_attr "update" "yes")
9763    (set_attr "indexed" "yes,no")])
9765 (define_insn "*movsf_update1"
9766   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9767         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9768                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9769    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9770         (plus:SI (match_dup 1) (match_dup 2)))]
9771   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9772    && (!avoiding_indexed_address_p (SImode)
9773        || !gpc_reg_operand (operands[2], SImode))"
9774   "@
9775    lfsux %3,%0,%2
9776    lfsu %3,%2(%0)"
9777   [(set_attr "type" "fpload")
9778    (set_attr "update" "yes")
9779    (set_attr "indexed" "yes,no")])
9781 (define_insn "*movsf_update2"
9782   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9783                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9784         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9785    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9786         (plus:SI (match_dup 1) (match_dup 2)))]
9787   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9788    && (!avoiding_indexed_address_p (SImode)
9789        || !gpc_reg_operand (operands[2], SImode))"
9790   "@
9791    stfsux %3,%0,%2
9792    stfsu %3,%2(%0)"
9793   [(set_attr "type" "fpstore")
9794    (set_attr "update" "yes")
9795    (set_attr "indexed" "yes,no")])
9797 (define_insn "*movsf_update3"
9798   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9799         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9800                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9801    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9802         (plus:SI (match_dup 1) (match_dup 2)))]
9803   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9804    && (!avoiding_indexed_address_p (SImode)
9805        || !gpc_reg_operand (operands[2], SImode))"
9806   "@
9807    lwzux %3,%0,%2
9808    lwzu %3,%2(%0)"
9809   [(set_attr "type" "load")
9810    (set_attr "update" "yes")
9811    (set_attr "indexed" "yes,no")])
9813 (define_insn "*movsf_update4"
9814   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9815                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9816         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9817    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9818         (plus:SI (match_dup 1) (match_dup 2)))]
9819   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9820    && (!avoiding_indexed_address_p (SImode)
9821        || !gpc_reg_operand (operands[2], SImode))"
9822   "@
9823    stwux %3,%0,%2
9824    stwu %3,%2(%0)"
9825   [(set_attr "type" "store")
9826    (set_attr "update" "yes")
9827    (set_attr "indexed" "yes,no")])
9829 (define_insn "*movdf_update1"
9830   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9831         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9832                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9833    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9834         (plus:SI (match_dup 1) (match_dup 2)))]
9835   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9836    && (!avoiding_indexed_address_p (SImode)
9837        || !gpc_reg_operand (operands[2], SImode))"
9838   "@
9839    lfdux %3,%0,%2
9840    lfdu %3,%2(%0)"
9841   [(set_attr "type" "fpload")
9842    (set_attr "update" "yes")
9843    (set_attr "indexed" "yes,no")
9844    (set_attr "size" "64")])
9846 (define_insn "*movdf_update2"
9847   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9848                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9849         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9850    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9851         (plus:SI (match_dup 1) (match_dup 2)))]
9852   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9853    && (!avoiding_indexed_address_p (SImode)
9854        || !gpc_reg_operand (operands[2], SImode))"
9855   "@
9856    stfdux %3,%0,%2
9857    stfdu %3,%2(%0)"
9858   [(set_attr "type" "fpstore")
9859    (set_attr "update" "yes")
9860    (set_attr "indexed" "yes,no")])
9863 ;; After inserting conditional returns we can sometimes have
9864 ;; unnecessary register moves.  Unfortunately we cannot have a
9865 ;; modeless peephole here, because some single SImode sets have early
9866 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9867 ;; sequences, using get_attr_length here will smash the operands
9868 ;; array.  Neither is there an early_cobbler_p predicate.
9869 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9870 ;; Also this optimization interferes with scalars going into
9871 ;; altivec registers (the code does reloading through the FPRs).
9872 (define_peephole2
9873   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9874         (match_operand:DF 1 "any_operand" ""))
9875    (set (match_operand:DF 2 "gpc_reg_operand" "")
9876         (match_dup 0))]
9877   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9878    && !TARGET_UPPER_REGS_DF
9879    && peep2_reg_dead_p (2, operands[0])"
9880   [(set (match_dup 2) (match_dup 1))])
9882 (define_peephole2
9883   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9884         (match_operand:SF 1 "any_operand" ""))
9885    (set (match_operand:SF 2 "gpc_reg_operand" "")
9886         (match_dup 0))]
9887   "!TARGET_UPPER_REGS_SF
9888    && peep2_reg_dead_p (2, operands[0])"
9889   [(set (match_dup 2) (match_dup 1))])
9892 ;; TLS support.
9894 ;; Mode attributes for different ABIs.
9895 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9896 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9897 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9898 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9900 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9901   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9902         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9903               (match_operand 4 "" "g")))
9904    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9905                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9906                    UNSPEC_TLSGD)
9907    (clobber (reg:SI LR_REGNO))]
9908   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9910   if (TARGET_CMODEL != CMODEL_SMALL)
9911     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9912            "bl %z3\;nop";
9913   else
9914     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9916   "&& TARGET_TLS_MARKERS"
9917   [(set (match_dup 0)
9918         (unspec:TLSmode [(match_dup 1)
9919                          (match_dup 2)]
9920                         UNSPEC_TLSGD))
9921    (parallel [(set (match_dup 0)
9922                    (call (mem:TLSmode (match_dup 3))
9923                          (match_dup 4)))
9924               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9925               (clobber (reg:SI LR_REGNO))])]
9926   ""
9927   [(set_attr "type" "two")
9928    (set (attr "length")
9929      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9930                    (const_int 16)
9931                    (const_int 12)))])
9933 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9934   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9935         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9936               (match_operand 4 "" "g")))
9937    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9938                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9939                    UNSPEC_TLSGD)
9940    (clobber (reg:SI LR_REGNO))]
9941   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9943   if (flag_pic)
9944     {
9945       if (TARGET_SECURE_PLT && flag_pic == 2)
9946         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9947       else
9948         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9949     }
9950   else
9951     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9953   "&& TARGET_TLS_MARKERS"
9954   [(set (match_dup 0)
9955         (unspec:TLSmode [(match_dup 1)
9956                          (match_dup 2)]
9957                         UNSPEC_TLSGD))
9958    (parallel [(set (match_dup 0)
9959                    (call (mem:TLSmode (match_dup 3))
9960                          (match_dup 4)))
9961               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9962               (clobber (reg:SI LR_REGNO))])]
9963   ""
9964   [(set_attr "type" "two")
9965    (set_attr "length" "8")])
9967 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9968   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9969         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9970                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9971                         UNSPEC_TLSGD))]
9972   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9973   "addi %0,%1,%2@got@tlsgd"
9974   "&& TARGET_CMODEL != CMODEL_SMALL"
9975   [(set (match_dup 3)
9976         (high:TLSmode
9977             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9978    (set (match_dup 0)
9979         (lo_sum:TLSmode (match_dup 3)
9980             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9981   "
9983   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9985   [(set (attr "length")
9986      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9987                    (const_int 8)
9988                    (const_int 4)))])
9990 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9991   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9992      (high:TLSmode
9993        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9994                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9995                        UNSPEC_TLSGD)))]
9996   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9997   "addis %0,%1,%2@got@tlsgd@ha"
9998   [(set_attr "length" "4")])
10000 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
10001   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10002      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10003        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10004                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10005                        UNSPEC_TLSGD)))]
10006   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10007   "addi %0,%1,%2@got@tlsgd@l"
10008   [(set_attr "length" "4")])
10010 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
10011   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10012         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10013               (match_operand 2 "" "g")))
10014    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
10015                    UNSPEC_TLSGD)
10016    (clobber (reg:SI LR_REGNO))]
10017   "HAVE_AS_TLS && TARGET_TLS_MARKERS
10018    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10019   "bl %z1(%3@tlsgd)\;nop"
10020   [(set_attr "type" "branch")
10021    (set_attr "length" "8")])
10023 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
10024   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10025         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10026               (match_operand 2 "" "g")))
10027    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
10028                    UNSPEC_TLSGD)
10029    (clobber (reg:SI LR_REGNO))]
10030   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10032   if (flag_pic)
10033     {
10034       if (TARGET_SECURE_PLT && flag_pic == 2)
10035         return "bl %z1+32768(%3@tlsgd)@plt";
10036       return "bl %z1(%3@tlsgd)@plt";
10037     }
10038   return "bl %z1(%3@tlsgd)";
10040   [(set_attr "type" "branch")
10041    (set_attr "length" "4")])
10043 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
10044   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10045         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10046               (match_operand 3 "" "g")))
10047    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10048                    UNSPEC_TLSLD)
10049    (clobber (reg:SI LR_REGNO))]
10050   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10052   if (TARGET_CMODEL != CMODEL_SMALL)
10053     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
10054            "bl %z2\;nop";
10055   else
10056     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
10058   "&& TARGET_TLS_MARKERS"
10059   [(set (match_dup 0)
10060         (unspec:TLSmode [(match_dup 1)]
10061                         UNSPEC_TLSLD))
10062    (parallel [(set (match_dup 0)
10063                    (call (mem:TLSmode (match_dup 2))
10064                          (match_dup 3)))
10065               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10066               (clobber (reg:SI LR_REGNO))])]
10067   ""
10068   [(set_attr "type" "two")
10069    (set (attr "length")
10070      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10071                    (const_int 16)
10072                    (const_int 12)))])
10074 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
10075   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10076         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10077               (match_operand 3 "" "g")))
10078    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10079                    UNSPEC_TLSLD)
10080    (clobber (reg:SI LR_REGNO))]
10081   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
10083   if (flag_pic)
10084     {
10085       if (TARGET_SECURE_PLT && flag_pic == 2)
10086         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
10087       else
10088         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
10089     }
10090   else
10091     return "addi %0,%1,%&@got@tlsld\;bl %z2";
10093   "&& TARGET_TLS_MARKERS"
10094   [(set (match_dup 0)
10095         (unspec:TLSmode [(match_dup 1)]
10096                         UNSPEC_TLSLD))
10097    (parallel [(set (match_dup 0)
10098                    (call (mem:TLSmode (match_dup 2))
10099                          (match_dup 3)))
10100               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10101               (clobber (reg:SI LR_REGNO))])]
10102   ""
10103   [(set_attr "length" "8")])
10105 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
10106   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10107         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10108                         UNSPEC_TLSLD))]
10109   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10110   "addi %0,%1,%&@got@tlsld"
10111   "&& TARGET_CMODEL != CMODEL_SMALL"
10112   [(set (match_dup 2)
10113         (high:TLSmode
10114             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10115    (set (match_dup 0)
10116         (lo_sum:TLSmode (match_dup 2)
10117             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10118   "
10120   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10122   [(set (attr "length")
10123      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10124                    (const_int 8)
10125                    (const_int 4)))])
10127 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10128   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10129      (high:TLSmode
10130        (unspec:TLSmode [(const_int 0)
10131                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10132                        UNSPEC_TLSLD)))]
10133   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10134   "addis %0,%1,%&@got@tlsld@ha"
10135   [(set_attr "length" "4")])
10137 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10138   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10139      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10140        (unspec:TLSmode [(const_int 0)
10141                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10142                        UNSPEC_TLSLD)))]
10143   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10144   "addi %0,%1,%&@got@tlsld@l"
10145   [(set_attr "length" "4")])
10147 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10148   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10149         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10150               (match_operand 2 "" "g")))
10151    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10152    (clobber (reg:SI LR_REGNO))]
10153   "HAVE_AS_TLS && TARGET_TLS_MARKERS
10154    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10155   "bl %z1(%&@tlsld)\;nop"
10156   [(set_attr "type" "branch")
10157    (set_attr "length" "8")])
10159 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10160   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10161         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10162               (match_operand 2 "" "g")))
10163    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10164    (clobber (reg:SI LR_REGNO))]
10165   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10167   if (flag_pic)
10168     {
10169       if (TARGET_SECURE_PLT && flag_pic == 2)
10170         return "bl %z1+32768(%&@tlsld)@plt";
10171       return "bl %z1(%&@tlsld)@plt";
10172     }
10173   return "bl %z1(%&@tlsld)";
10175   [(set_attr "type" "branch")
10176    (set_attr "length" "4")])
10178 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10179   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10180         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10181                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10182                         UNSPEC_TLSDTPREL))]
10183   "HAVE_AS_TLS"
10184   "addi %0,%1,%2@dtprel")
10186 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10187   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10188         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10189                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10190                         UNSPEC_TLSDTPRELHA))]
10191   "HAVE_AS_TLS"
10192   "addis %0,%1,%2@dtprel@ha")
10194 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10195   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10196         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10197                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10198                         UNSPEC_TLSDTPRELLO))]
10199   "HAVE_AS_TLS"
10200   "addi %0,%1,%2@dtprel@l")
10202 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10203   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10204         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10205                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10206                         UNSPEC_TLSGOTDTPREL))]
10207   "HAVE_AS_TLS"
10208   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10209   "&& TARGET_CMODEL != CMODEL_SMALL"
10210   [(set (match_dup 3)
10211         (high:TLSmode
10212             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10213    (set (match_dup 0)
10214         (lo_sum:TLSmode (match_dup 3)
10215             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10216   "
10218   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10220   [(set (attr "length")
10221      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10222                    (const_int 8)
10223                    (const_int 4)))])
10225 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10226   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10227      (high:TLSmode
10228        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10229                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10230                        UNSPEC_TLSGOTDTPREL)))]
10231   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10232   "addis %0,%1,%2@got@dtprel@ha"
10233   [(set_attr "length" "4")])
10235 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10236   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10237      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10238          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10239                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10240                          UNSPEC_TLSGOTDTPREL)))]
10241   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10242   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10243   [(set_attr "length" "4")])
10245 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10246   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10247         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10248                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10249                         UNSPEC_TLSTPREL))]
10250   "HAVE_AS_TLS"
10251   "addi %0,%1,%2@tprel")
10253 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10254   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10255         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10256                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10257                         UNSPEC_TLSTPRELHA))]
10258   "HAVE_AS_TLS"
10259   "addis %0,%1,%2@tprel@ha")
10261 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10262   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10263         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10264                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10265                         UNSPEC_TLSTPRELLO))]
10266   "HAVE_AS_TLS"
10267   "addi %0,%1,%2@tprel@l")
10269 ;; "b" output constraint here and on tls_tls input to support linker tls
10270 ;; optimization.  The linker may edit the instructions emitted by a
10271 ;; tls_got_tprel/tls_tls pair to addis,addi.
10272 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10273   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10274         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10275                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10276                         UNSPEC_TLSGOTTPREL))]
10277   "HAVE_AS_TLS"
10278   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10279   "&& TARGET_CMODEL != CMODEL_SMALL"
10280   [(set (match_dup 3)
10281         (high:TLSmode
10282             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10283    (set (match_dup 0)
10284         (lo_sum:TLSmode (match_dup 3)
10285             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10286   "
10288   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10290   [(set (attr "length")
10291      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10292                    (const_int 8)
10293                    (const_int 4)))])
10295 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10296   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10297      (high:TLSmode
10298        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10299                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10300                        UNSPEC_TLSGOTTPREL)))]
10301   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10302   "addis %0,%1,%2@got@tprel@ha"
10303   [(set_attr "length" "4")])
10305 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10306   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10307      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10308          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10309                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10310                          UNSPEC_TLSGOTTPREL)))]
10311   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10312   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10313   [(set_attr "length" "4")])
10315 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10316   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10317         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10318                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10319                         UNSPEC_TLSTLS))]
10320   "TARGET_ELF && HAVE_AS_TLS"
10321   "add %0,%1,%2@tls")
10323 (define_expand "tls_get_tpointer"
10324   [(set (match_operand:SI 0 "gpc_reg_operand" "")
10325         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10326   "TARGET_XCOFF && HAVE_AS_TLS"
10327   "
10329   emit_insn (gen_tls_get_tpointer_internal ());
10330   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10331   DONE;
10334 (define_insn "tls_get_tpointer_internal"
10335   [(set (reg:SI 3)
10336         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10337    (clobber (reg:SI LR_REGNO))]
10338   "TARGET_XCOFF && HAVE_AS_TLS"
10339   "bla __get_tpointer")
10341 (define_expand "tls_get_addr<mode>"
10342   [(set (match_operand:P 0 "gpc_reg_operand" "")
10343         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10344                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10345   "TARGET_XCOFF && HAVE_AS_TLS"
10346   "
10348   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10349   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10350   emit_insn (gen_tls_get_addr_internal<mode> ());
10351   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10352   DONE;
10355 (define_insn "tls_get_addr_internal<mode>"
10356   [(set (reg:P 3)
10357         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10358    (clobber (reg:P 0))
10359    (clobber (reg:P 4))
10360    (clobber (reg:P 5))
10361    (clobber (reg:P 11))
10362    (clobber (reg:CC CR0_REGNO))
10363    (clobber (reg:P LR_REGNO))]
10364   "TARGET_XCOFF && HAVE_AS_TLS"
10365   "bla __tls_get_addr")
10367 ;; Next come insns related to the calling sequence.
10369 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10370 ;; We move the back-chain and decrement the stack pointer.
10372 (define_expand "allocate_stack"
10373   [(set (match_operand 0 "gpc_reg_operand" "")
10374         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10375    (set (reg 1)
10376         (minus (reg 1) (match_dup 1)))]
10377   ""
10378   "
10379 { rtx chain = gen_reg_rtx (Pmode);
10380   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10381   rtx neg_op0;
10382   rtx insn, par, set, mem;
10384   emit_move_insn (chain, stack_bot);
10386   /* Check stack bounds if necessary.  */
10387   if (crtl->limit_stack)
10388     {
10389       rtx available;
10390       available = expand_binop (Pmode, sub_optab,
10391                                 stack_pointer_rtx, stack_limit_rtx,
10392                                 NULL_RTX, 1, OPTAB_WIDEN);
10393       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10394     }
10396   if (GET_CODE (operands[1]) != CONST_INT
10397       || INTVAL (operands[1]) < -32767
10398       || INTVAL (operands[1]) > 32768)
10399     {
10400       neg_op0 = gen_reg_rtx (Pmode);
10401       if (TARGET_32BIT)
10402         emit_insn (gen_negsi2 (neg_op0, operands[1]));
10403       else
10404         emit_insn (gen_negdi2 (neg_op0, operands[1]));
10405     }
10406   else
10407     neg_op0 = GEN_INT (- INTVAL (operands[1]));
10409   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10410                                        : gen_movdi_di_update_stack))
10411                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10412                          chain));
10413   /* Since we didn't use gen_frame_mem to generate the MEM, grab
10414      it now and set the alias set/attributes. The above gen_*_update
10415      calls will generate a PARALLEL with the MEM set being the first
10416      operation. */
10417   par = PATTERN (insn);
10418   gcc_assert (GET_CODE (par) == PARALLEL);
10419   set = XVECEXP (par, 0, 0);
10420   gcc_assert (GET_CODE (set) == SET);
10421   mem = SET_DEST (set);
10422   gcc_assert (MEM_P (mem));
10423   MEM_NOTRAP_P (mem) = 1;
10424   set_mem_alias_set (mem, get_frame_alias_set ());
10426   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10427   DONE;
10430 ;; These patterns say how to save and restore the stack pointer.  We need not
10431 ;; save the stack pointer at function level since we are careful to
10432 ;; preserve the backchain.  At block level, we have to restore the backchain
10433 ;; when we restore the stack pointer.
10435 ;; For nonlocal gotos, we must save both the stack pointer and its
10436 ;; backchain and restore both.  Note that in the nonlocal case, the
10437 ;; save area is a memory location.
10439 (define_expand "save_stack_function"
10440   [(match_operand 0 "any_operand" "")
10441    (match_operand 1 "any_operand" "")]
10442   ""
10443   "DONE;")
10445 (define_expand "restore_stack_function"
10446   [(match_operand 0 "any_operand" "")
10447    (match_operand 1 "any_operand" "")]
10448   ""
10449   "DONE;")
10451 ;; Adjust stack pointer (op0) to a new value (op1).
10452 ;; First copy old stack backchain to new location, and ensure that the
10453 ;; scheduler won't reorder the sp assignment before the backchain write.
10454 (define_expand "restore_stack_block"
10455   [(set (match_dup 2) (match_dup 3))
10456    (set (match_dup 4) (match_dup 2))
10457    (match_dup 5)
10458    (set (match_operand 0 "register_operand" "")
10459         (match_operand 1 "register_operand" ""))]
10460   ""
10461   "
10463   rtvec p;
10465   operands[1] = force_reg (Pmode, operands[1]);
10466   operands[2] = gen_reg_rtx (Pmode);
10467   operands[3] = gen_frame_mem (Pmode, operands[0]);
10468   operands[4] = gen_frame_mem (Pmode, operands[1]);
10469   p = rtvec_alloc (1);
10470   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10471                                   const0_rtx);
10472   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10475 (define_expand "save_stack_nonlocal"
10476   [(set (match_dup 3) (match_dup 4))
10477    (set (match_operand 0 "memory_operand" "") (match_dup 3))
10478    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10479   ""
10480   "
10482   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10484   /* Copy the backchain to the first word, sp to the second.  */
10485   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10486   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10487   operands[3] = gen_reg_rtx (Pmode);
10488   operands[4] = gen_frame_mem (Pmode, operands[1]);
10491 (define_expand "restore_stack_nonlocal"
10492   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10493    (set (match_dup 3) (match_dup 4))
10494    (set (match_dup 5) (match_dup 2))
10495    (match_dup 6)
10496    (set (match_operand 0 "register_operand" "") (match_dup 3))]
10497   ""
10498   "
10500   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10501   rtvec p;
10503   /* Restore the backchain from the first word, sp from the second.  */
10504   operands[2] = gen_reg_rtx (Pmode);
10505   operands[3] = gen_reg_rtx (Pmode);
10506   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10507   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10508   operands[5] = gen_frame_mem (Pmode, operands[3]);
10509   p = rtvec_alloc (1);
10510   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10511                                   const0_rtx);
10512   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10515 ;; TOC register handling.
10517 ;; Code to initialize the TOC register...
10519 (define_insn "load_toc_aix_si"
10520   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10521                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10522               (use (reg:SI 2))])]
10523   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10524   "*
10526   char buf[30];
10527   extern int need_toc_init;
10528   need_toc_init = 1;
10529   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10530   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10531   operands[2] = gen_rtx_REG (Pmode, 2);
10532   return \"lwz %0,%1(%2)\";
10534   [(set_attr "type" "load")
10535    (set_attr "update" "no")
10536    (set_attr "indexed" "no")])
10538 (define_insn "load_toc_aix_di"
10539   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10540                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10541               (use (reg:DI 2))])]
10542   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10543   "*
10545   char buf[30];
10546   extern int need_toc_init;
10547   need_toc_init = 1;
10548   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10549                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10550   if (TARGET_ELF)
10551     strcat (buf, \"@toc\");
10552   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10553   operands[2] = gen_rtx_REG (Pmode, 2);
10554   return \"ld %0,%1(%2)\";
10556   [(set_attr "type" "load")
10557    (set_attr "update" "no")
10558    (set_attr "indexed" "no")])
10560 (define_insn "load_toc_v4_pic_si"
10561   [(set (reg:SI LR_REGNO)
10562         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10563   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10564   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10565   [(set_attr "type" "branch")
10566    (set_attr "length" "4")])
10568 (define_expand "load_toc_v4_PIC_1"
10569   [(parallel [(set (reg:SI LR_REGNO)
10570                    (match_operand:SI 0 "immediate_operand" "s"))
10571               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10572   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10573    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10574   "")
10576 (define_insn "load_toc_v4_PIC_1_normal"
10577   [(set (reg:SI LR_REGNO)
10578         (match_operand:SI 0 "immediate_operand" "s"))
10579    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10580   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10581    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10582   "bcl 20,31,%0\\n%0:"
10583   [(set_attr "type" "branch")
10584    (set_attr "length" "4")
10585    (set_attr "cannot_copy" "yes")])
10587 (define_insn "load_toc_v4_PIC_1_476"
10588   [(set (reg:SI LR_REGNO)
10589         (match_operand:SI 0 "immediate_operand" "s"))
10590    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10591   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10592    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10593   "*
10595   char name[32];
10596   static char templ[32];
10598   get_ppc476_thunk_name (name);
10599   sprintf (templ, \"bl %s\\n%%0:\", name);
10600   return templ;
10602   [(set_attr "type" "branch")
10603    (set_attr "length" "4")
10604    (set_attr "cannot_copy" "yes")])
10606 (define_expand "load_toc_v4_PIC_1b"
10607   [(parallel [(set (reg:SI LR_REGNO)
10608                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10609                                (label_ref (match_operand 1 "" ""))]
10610                            UNSPEC_TOCPTR))
10611               (match_dup 1)])]
10612   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10613   "")
10615 (define_insn "load_toc_v4_PIC_1b_normal"
10616   [(set (reg:SI LR_REGNO)
10617         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10618                     (label_ref (match_operand 1 "" ""))]
10619                 UNSPEC_TOCPTR))
10620    (match_dup 1)]
10621   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10622   "bcl 20,31,$+8\;.long %0-$"
10623   [(set_attr "type" "branch")
10624    (set_attr "length" "8")])
10626 (define_insn "load_toc_v4_PIC_1b_476"
10627   [(set (reg:SI LR_REGNO)
10628         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10629                     (label_ref (match_operand 1 "" ""))]
10630                 UNSPEC_TOCPTR))
10631    (match_dup 1)]
10632   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10633   "*
10635   char name[32];
10636   static char templ[32];
10638   get_ppc476_thunk_name (name);
10639   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10640   return templ;
10642   [(set_attr "type" "branch")
10643    (set_attr "length" "16")])
10645 (define_insn "load_toc_v4_PIC_2"
10646   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10647         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10648                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10649                              (match_operand:SI 3 "immediate_operand" "s")))))]
10650   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10651   "lwz %0,%2-%3(%1)"
10652   [(set_attr "type" "load")])
10654 (define_insn "load_toc_v4_PIC_3b"
10655   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10656         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10657                  (high:SI
10658                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10659                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10660   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10661   "addis %0,%1,%2-%3@ha")
10663 (define_insn "load_toc_v4_PIC_3c"
10664   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10665         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10666                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10667                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10668   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10669   "addi %0,%1,%2-%3@l")
10671 ;; If the TOC is shared over a translation unit, as happens with all
10672 ;; the kinds of PIC that we support, we need to restore the TOC
10673 ;; pointer only when jumping over units of translation.
10674 ;; On Darwin, we need to reload the picbase.
10676 (define_expand "builtin_setjmp_receiver"
10677   [(use (label_ref (match_operand 0 "" "")))]
10678   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10679    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10680    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10681   "
10683 #if TARGET_MACHO
10684   if (DEFAULT_ABI == ABI_DARWIN)
10685     {
10686       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10687       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10688       rtx tmplabrtx;
10689       char tmplab[20];
10691       crtl->uses_pic_offset_table = 1;
10692       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10693                                   CODE_LABEL_NUMBER (operands[0]));
10694       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10696       emit_insn (gen_load_macho_picbase (tmplabrtx));
10697       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10698       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10699     }
10700   else
10701 #endif
10702     rs6000_emit_load_toc_table (FALSE);
10703   DONE;
10706 ;; Largetoc support
10707 (define_insn "*largetoc_high"
10708   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10709         (high:DI
10710           (unspec [(match_operand:DI 1 "" "")
10711                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10712                   UNSPEC_TOCREL)))]
10713    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10714    "addis %0,%2,%1@toc@ha")
10716 (define_insn "*largetoc_high_aix<mode>"
10717   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10718         (high:P
10719           (unspec [(match_operand:P 1 "" "")
10720                    (match_operand:P 2 "gpc_reg_operand" "b")]
10721                   UNSPEC_TOCREL)))]
10722    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10723    "addis %0,%1@u(%2)")
10725 (define_insn "*largetoc_high_plus"
10726   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10727         (high:DI
10728           (plus:DI
10729             (unspec [(match_operand:DI 1 "" "")
10730                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10731                     UNSPEC_TOCREL)
10732             (match_operand:DI 3 "add_cint_operand" "n"))))]
10733    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10734    "addis %0,%2,%1+%3@toc@ha")
10736 (define_insn "*largetoc_high_plus_aix<mode>"
10737   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10738         (high:P
10739           (plus:P
10740             (unspec [(match_operand:P 1 "" "")
10741                      (match_operand:P 2 "gpc_reg_operand" "b")]
10742                     UNSPEC_TOCREL)
10743             (match_operand:P 3 "add_cint_operand" "n"))))]
10744    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10745    "addis %0,%1+%3@u(%2)")
10747 (define_insn "*largetoc_low"
10748   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10749         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10750                    (match_operand:DI 2 "" "")))]
10751    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10752    "addi %0,%1,%2@l")
10754 (define_insn "*largetoc_low_aix<mode>"
10755   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10756         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10757                    (match_operand:P 2 "" "")))]
10758    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10759    "la %0,%2@l(%1)")
10761 (define_insn_and_split "*tocref<mode>"
10762   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10763         (match_operand:P 1 "small_toc_ref" "R"))]
10764    "TARGET_TOC"
10765    "la %0,%a1"
10766    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10767   [(set (match_dup 0) (high:P (match_dup 1)))
10768    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10770 ;; Elf specific ways of loading addresses for non-PIC code.
10771 ;; The output of this could be r0, but we make a very strong
10772 ;; preference for a base register because it will usually
10773 ;; be needed there.
10774 (define_insn "elf_high"
10775   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10776         (high:SI (match_operand 1 "" "")))]
10777   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10778   "lis %0,%1@ha")
10780 (define_insn "elf_low"
10781   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10782         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10783                    (match_operand 2 "" "")))]
10784    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10785    "la %0,%2@l(%1)")
10787 ;; Call and call_value insns
10788 (define_expand "call"
10789   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10790                     (match_operand 1 "" ""))
10791               (use (match_operand 2 "" ""))
10792               (clobber (reg:SI LR_REGNO))])]
10793   ""
10794   "
10796 #if TARGET_MACHO
10797   if (MACHOPIC_INDIRECT)
10798     operands[0] = machopic_indirect_call_target (operands[0]);
10799 #endif
10801   gcc_assert (GET_CODE (operands[0]) == MEM);
10802   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10804   operands[0] = XEXP (operands[0], 0);
10806   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10807     {
10808       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10809       DONE;
10810     }
10812   if (GET_CODE (operands[0]) != SYMBOL_REF
10813       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10814     {
10815       if (INTVAL (operands[2]) & CALL_LONG)
10816         operands[0] = rs6000_longcall_ref (operands[0]);
10818       switch (DEFAULT_ABI)
10819         {
10820         case ABI_V4:
10821         case ABI_DARWIN:
10822           operands[0] = force_reg (Pmode, operands[0]);
10823           break;
10825         default:
10826           gcc_unreachable ();
10827         }
10828     }
10831 (define_expand "call_value"
10832   [(parallel [(set (match_operand 0 "" "")
10833                    (call (mem:SI (match_operand 1 "address_operand" ""))
10834                          (match_operand 2 "" "")))
10835               (use (match_operand 3 "" ""))
10836               (clobber (reg:SI LR_REGNO))])]
10837   ""
10838   "
10840 #if TARGET_MACHO
10841   if (MACHOPIC_INDIRECT)
10842     operands[1] = machopic_indirect_call_target (operands[1]);
10843 #endif
10845   gcc_assert (GET_CODE (operands[1]) == MEM);
10846   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10848   operands[1] = XEXP (operands[1], 0);
10850   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10851     {
10852       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10853       DONE;
10854     }
10856   if (GET_CODE (operands[1]) != SYMBOL_REF
10857       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10858     {
10859       if (INTVAL (operands[3]) & CALL_LONG)
10860         operands[1] = rs6000_longcall_ref (operands[1]);
10862       switch (DEFAULT_ABI)
10863         {
10864         case ABI_V4:
10865         case ABI_DARWIN:
10866           operands[1] = force_reg (Pmode, operands[1]);
10867           break;
10869         default:
10870           gcc_unreachable ();
10871         }
10872     }
10875 ;; Call to function in current module.  No TOC pointer reload needed.
10876 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10877 ;; either the function was not prototyped, or it was prototyped as a
10878 ;; variable argument function.  It is > 0 if FP registers were passed
10879 ;; and < 0 if they were not.
10881 (define_insn "*call_local32"
10882   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10883          (match_operand 1 "" "g,g"))
10884    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10885    (clobber (reg:SI LR_REGNO))]
10886   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10887   "*
10889   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10890     output_asm_insn (\"crxor 6,6,6\", operands);
10892   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10893     output_asm_insn (\"creqv 6,6,6\", operands);
10895   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10897   [(set_attr "type" "branch")
10898    (set_attr "length" "4,8")])
10900 (define_insn "*call_local64"
10901   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10902          (match_operand 1 "" "g,g"))
10903    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10904    (clobber (reg:SI LR_REGNO))]
10905   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10906   "*
10908   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10909     output_asm_insn (\"crxor 6,6,6\", operands);
10911   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10912     output_asm_insn (\"creqv 6,6,6\", operands);
10914   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10916   [(set_attr "type" "branch")
10917    (set_attr "length" "4,8")])
10919 (define_insn "*call_value_local32"
10920   [(set (match_operand 0 "" "")
10921         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10922               (match_operand 2 "" "g,g")))
10923    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10924    (clobber (reg:SI LR_REGNO))]
10925   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10926   "*
10928   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10929     output_asm_insn (\"crxor 6,6,6\", operands);
10931   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10932     output_asm_insn (\"creqv 6,6,6\", operands);
10934   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10936   [(set_attr "type" "branch")
10937    (set_attr "length" "4,8")])
10940 (define_insn "*call_value_local64"
10941   [(set (match_operand 0 "" "")
10942         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10943               (match_operand 2 "" "g,g")))
10944    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10945    (clobber (reg:SI LR_REGNO))]
10946   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10947   "*
10949   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10950     output_asm_insn (\"crxor 6,6,6\", operands);
10952   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10953     output_asm_insn (\"creqv 6,6,6\", operands);
10955   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10957   [(set_attr "type" "branch")
10958    (set_attr "length" "4,8")])
10961 ;; A function pointer under System V is just a normal pointer
10962 ;; operands[0] is the function pointer
10963 ;; operands[1] is the stack size to clean up
10964 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10965 ;; which indicates how to set cr1
10967 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10968   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10969          (match_operand 1 "" "g,g,g,g"))
10970    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10971    (clobber (reg:SI LR_REGNO))]
10972   "DEFAULT_ABI == ABI_V4
10973    || DEFAULT_ABI == ABI_DARWIN"
10975   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10976     output_asm_insn ("crxor 6,6,6", operands);
10978   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10979     output_asm_insn ("creqv 6,6,6", operands);
10981   return "b%T0l";
10983   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10984    (set_attr "length" "4,4,8,8")])
10986 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10987   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10988          (match_operand 1 "" "g,g"))
10989    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10990    (clobber (reg:SI LR_REGNO))]
10991   "(DEFAULT_ABI == ABI_DARWIN
10992    || (DEFAULT_ABI == ABI_V4
10993        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10995   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10996     output_asm_insn ("crxor 6,6,6", operands);
10998   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10999     output_asm_insn ("creqv 6,6,6", operands);
11001 #if TARGET_MACHO
11002   return output_call(insn, operands, 0, 2);
11003 #else
11004   if (DEFAULT_ABI == ABI_V4 && flag_pic)
11005     {
11006       gcc_assert (!TARGET_SECURE_PLT);
11007       return "bl %z0@plt";
11008     }
11009   else
11010     return "bl %z0";
11011 #endif
11013   "DEFAULT_ABI == ABI_V4
11014    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11015    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11016   [(parallel [(call (mem:SI (match_dup 0))
11017                     (match_dup 1))
11018               (use (match_dup 2))
11019               (use (match_dup 3))
11020               (clobber (reg:SI LR_REGNO))])]
11022   operands[3] = pic_offset_table_rtx;
11024   [(set_attr "type" "branch,branch")
11025    (set_attr "length" "4,8")])
11027 (define_insn "*call_nonlocal_sysv_secure<mode>"
11028   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11029          (match_operand 1 "" "g,g"))
11030    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11031    (use (match_operand:SI 3 "register_operand" "r,r"))
11032    (clobber (reg:SI LR_REGNO))]
11033   "(DEFAULT_ABI == ABI_V4
11034     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11035     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11037   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11038     output_asm_insn ("crxor 6,6,6", operands);
11040   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11041     output_asm_insn ("creqv 6,6,6", operands);
11043   if (flag_pic == 2)
11044     /* The magic 32768 offset here and in the other sysv call insns
11045        corresponds to the offset of r30 in .got2, as given by LCTOC1.
11046        See sysv4.h:toc_section.  */
11047     return "bl %z0+32768@plt";
11048   else
11049     return "bl %z0@plt";
11051   [(set_attr "type" "branch,branch")
11052    (set_attr "length" "4,8")])
11054 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11055   [(set (match_operand 0 "" "")
11056         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
11057               (match_operand 2 "" "g,g,g,g")))
11058    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
11059    (clobber (reg:SI LR_REGNO))]
11060   "DEFAULT_ABI == ABI_V4
11061    || DEFAULT_ABI == ABI_DARWIN"
11063   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11064     output_asm_insn ("crxor 6,6,6", operands);
11066   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11067     output_asm_insn ("creqv 6,6,6", operands);
11069   return "b%T1l";
11071   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
11072    (set_attr "length" "4,4,8,8")])
11074 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
11075   [(set (match_operand 0 "" "")
11076         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11077               (match_operand 2 "" "g,g")))
11078    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11079    (clobber (reg:SI LR_REGNO))]
11080   "(DEFAULT_ABI == ABI_DARWIN
11081    || (DEFAULT_ABI == ABI_V4
11082        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11084   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11085     output_asm_insn ("crxor 6,6,6", operands);
11087   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11088     output_asm_insn ("creqv 6,6,6", operands);
11090 #if TARGET_MACHO
11091   return output_call(insn, operands, 1, 3);
11092 #else
11093   if (DEFAULT_ABI == ABI_V4 && flag_pic)
11094     {
11095       gcc_assert (!TARGET_SECURE_PLT);
11096       return "bl %z1@plt";
11097     }
11098   else
11099     return "bl %z1";
11100 #endif
11102   "DEFAULT_ABI == ABI_V4
11103    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11104    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11105   [(parallel [(set (match_dup 0)
11106                    (call (mem:SI (match_dup 1))
11107                          (match_dup 2)))
11108               (use (match_dup 3))
11109               (use (match_dup 4))
11110               (clobber (reg:SI LR_REGNO))])]
11112   operands[4] = pic_offset_table_rtx;
11114   [(set_attr "type" "branch,branch")
11115    (set_attr "length" "4,8")])
11117 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11118   [(set (match_operand 0 "" "")
11119         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11120               (match_operand 2 "" "g,g")))
11121    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11122    (use (match_operand:SI 4 "register_operand" "r,r"))
11123    (clobber (reg:SI LR_REGNO))]
11124   "(DEFAULT_ABI == ABI_V4
11125     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11126     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11128   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11129     output_asm_insn ("crxor 6,6,6", operands);
11131   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11132     output_asm_insn ("creqv 6,6,6", operands);
11134   if (flag_pic == 2)
11135     return "bl %z1+32768@plt";
11136   else
11137     return "bl %z1@plt";
11139   [(set_attr "type" "branch,branch")
11140    (set_attr "length" "4,8")])
11143 ;; Call to AIX abi function in the same module.
11145 (define_insn "*call_local_aix<mode>"
11146   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11147          (match_operand 1 "" "g"))
11148    (clobber (reg:P LR_REGNO))]
11149   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11150   "bl %z0"
11151   [(set_attr "type" "branch")
11152    (set_attr "length" "4")])
11154 (define_insn "*call_value_local_aix<mode>"
11155   [(set (match_operand 0 "" "")
11156         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11157               (match_operand 2 "" "g")))
11158    (clobber (reg:P LR_REGNO))]
11159   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11160   "bl %z1"
11161   [(set_attr "type" "branch")
11162    (set_attr "length" "4")])
11164 ;; Call to AIX abi function which may be in another module.
11165 ;; Restore the TOC pointer (r2) after the call.
11167 (define_insn "*call_nonlocal_aix<mode>"
11168   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11169          (match_operand 1 "" "g"))
11170    (clobber (reg:P LR_REGNO))]
11171   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11172   "bl %z0\;nop"
11173   [(set_attr "type" "branch")
11174    (set_attr "length" "8")])
11176 (define_insn "*call_value_nonlocal_aix<mode>"
11177   [(set (match_operand 0 "" "")
11178         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11179               (match_operand 2 "" "g")))
11180    (clobber (reg:P LR_REGNO))]
11181   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11182   "bl %z1\;nop"
11183   [(set_attr "type" "branch")
11184    (set_attr "length" "8")])
11186 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11187 ;; Operand0 is the addresss of the function to call
11188 ;; Operand2 is the location in the function descriptor to load r2 from
11189 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11191 (define_insn "*call_indirect_aix<mode>"
11192   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11193          (match_operand 1 "" "g,g"))
11194    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11195    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11196    (clobber (reg:P LR_REGNO))]
11197   "DEFAULT_ABI == ABI_AIX"
11198   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11199   [(set_attr "type" "jmpreg")
11200    (set_attr "length" "12")])
11202 (define_insn "*call_value_indirect_aix<mode>"
11203   [(set (match_operand 0 "" "")
11204         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11205               (match_operand 2 "" "g,g")))
11206    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11207    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11208    (clobber (reg:P LR_REGNO))]
11209   "DEFAULT_ABI == ABI_AIX"
11210   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11211   [(set_attr "type" "jmpreg")
11212    (set_attr "length" "12")])
11214 ;; Call to indirect functions with the ELFv2 ABI.
11215 ;; Operand0 is the addresss of the function to call
11216 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11218 (define_insn "*call_indirect_elfv2<mode>"
11219   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11220          (match_operand 1 "" "g,g"))
11221    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11222    (clobber (reg:P LR_REGNO))]
11223   "DEFAULT_ABI == ABI_ELFv2"
11224   "b%T0l\;<ptrload> 2,%2(1)"
11225   [(set_attr "type" "jmpreg")
11226    (set_attr "length" "8")])
11228 (define_insn "*call_value_indirect_elfv2<mode>"
11229   [(set (match_operand 0 "" "")
11230         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11231               (match_operand 2 "" "g,g")))
11232    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11233    (clobber (reg:P LR_REGNO))]
11234   "DEFAULT_ABI == ABI_ELFv2"
11235   "b%T1l\;<ptrload> 2,%3(1)"
11236   [(set_attr "type" "jmpreg")
11237    (set_attr "length" "8")])
11240 ;; Call subroutine returning any type.
11241 (define_expand "untyped_call"
11242   [(parallel [(call (match_operand 0 "" "")
11243                     (const_int 0))
11244               (match_operand 1 "" "")
11245               (match_operand 2 "" "")])]
11246   ""
11247   "
11249   int i;
11251   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11253   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11254     {
11255       rtx set = XVECEXP (operands[2], 0, i);
11256       emit_move_insn (SET_DEST (set), SET_SRC (set));
11257     }
11259   /* The optimizer does not know that the call sets the function value
11260      registers we stored in the result block.  We avoid problems by
11261      claiming that all hard registers are used and clobbered at this
11262      point.  */
11263   emit_insn (gen_blockage ());
11265   DONE;
11268 ;; sibling call patterns
11269 (define_expand "sibcall"
11270   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11271                     (match_operand 1 "" ""))
11272               (use (match_operand 2 "" ""))
11273               (simple_return)])]
11274   ""
11275   "
11277 #if TARGET_MACHO
11278   if (MACHOPIC_INDIRECT)
11279     operands[0] = machopic_indirect_call_target (operands[0]);
11280 #endif
11282   gcc_assert (GET_CODE (operands[0]) == MEM);
11283   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11285   operands[0] = XEXP (operands[0], 0);
11287   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11288     {
11289       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11290       DONE;
11291     }
11294 (define_expand "sibcall_value"
11295   [(parallel [(set (match_operand 0 "register_operand" "")
11296                 (call (mem:SI (match_operand 1 "address_operand" ""))
11297                       (match_operand 2 "" "")))
11298               (use (match_operand 3 "" ""))
11299               (simple_return)])]
11300   ""
11301   "
11303 #if TARGET_MACHO
11304   if (MACHOPIC_INDIRECT)
11305     operands[1] = machopic_indirect_call_target (operands[1]);
11306 #endif
11308   gcc_assert (GET_CODE (operands[1]) == MEM);
11309   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11311   operands[1] = XEXP (operands[1], 0);
11313   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11314     {
11315       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11316       DONE;
11317     }
11320 (define_insn "*sibcall_local32"
11321   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11322          (match_operand 1 "" "g,g"))
11323    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11324    (simple_return)]
11325   "(INTVAL (operands[2]) & CALL_LONG) == 0"
11326   "*
11328   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11329     output_asm_insn (\"crxor 6,6,6\", operands);
11331   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11332     output_asm_insn (\"creqv 6,6,6\", operands);
11334   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11336   [(set_attr "type" "branch")
11337    (set_attr "length" "4,8")])
11339 (define_insn "*sibcall_local64"
11340   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11341          (match_operand 1 "" "g,g"))
11342    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11343    (simple_return)]
11344   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11345   "*
11347   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11348     output_asm_insn (\"crxor 6,6,6\", operands);
11350   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11351     output_asm_insn (\"creqv 6,6,6\", operands);
11353   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11355   [(set_attr "type" "branch")
11356    (set_attr "length" "4,8")])
11358 (define_insn "*sibcall_value_local32"
11359   [(set (match_operand 0 "" "")
11360         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11361               (match_operand 2 "" "g,g")))
11362    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11363    (simple_return)]
11364   "(INTVAL (operands[3]) & CALL_LONG) == 0"
11365   "*
11367   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11368     output_asm_insn (\"crxor 6,6,6\", operands);
11370   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11371     output_asm_insn (\"creqv 6,6,6\", operands);
11373   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11375   [(set_attr "type" "branch")
11376    (set_attr "length" "4,8")])
11378 (define_insn "*sibcall_value_local64"
11379   [(set (match_operand 0 "" "")
11380         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11381               (match_operand 2 "" "g,g")))
11382    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11383    (simple_return)]
11384   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11385   "*
11387   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11388     output_asm_insn (\"crxor 6,6,6\", operands);
11390   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11391     output_asm_insn (\"creqv 6,6,6\", operands);
11393   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11395   [(set_attr "type" "branch")
11396    (set_attr "length" "4,8")])
11398 (define_insn "*sibcall_nonlocal_sysv<mode>"
11399   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11400          (match_operand 1 "" ""))
11401    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11402    (simple_return)]
11403   "(DEFAULT_ABI == ABI_DARWIN
11404     || DEFAULT_ABI == ABI_V4)
11405    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11406   "*
11408   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11409     output_asm_insn (\"crxor 6,6,6\", operands);
11411   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11412     output_asm_insn (\"creqv 6,6,6\", operands);
11414   if (which_alternative >= 2)
11415     return \"b%T0\";
11416   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11417     {
11418       gcc_assert (!TARGET_SECURE_PLT);
11419       return \"b %z0@plt\";
11420     }
11421   else
11422     return \"b %z0\";
11424   [(set_attr "type" "branch")
11425    (set_attr "length" "4,8,4,8")])
11427 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11428   [(set (match_operand 0 "" "")
11429         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11430               (match_operand 2 "" "")))
11431    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11432    (simple_return)]
11433   "(DEFAULT_ABI == ABI_DARWIN
11434     || DEFAULT_ABI == ABI_V4)
11435    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11436   "*
11438   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11439     output_asm_insn (\"crxor 6,6,6\", operands);
11441   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11442     output_asm_insn (\"creqv 6,6,6\", operands);
11444   if (which_alternative >= 2)
11445     return \"b%T1\";
11446   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11447     {
11448       gcc_assert (!TARGET_SECURE_PLT);
11449       return \"b %z1@plt\";
11450     }
11451   else
11452     return \"b %z1\";
11454   [(set_attr "type" "branch")
11455    (set_attr "length" "4,8,4,8")])
11457 ;; AIX ABI sibling call patterns.
11459 (define_insn "*sibcall_aix<mode>"
11460   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11461          (match_operand 1 "" "g,g"))
11462    (simple_return)]
11463   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11464   "@
11465    b %z0
11466    b%T0"
11467   [(set_attr "type" "branch")
11468    (set_attr "length" "4")])
11470 (define_insn "*sibcall_value_aix<mode>"
11471   [(set (match_operand 0 "" "")
11472         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11473               (match_operand 2 "" "g,g")))
11474    (simple_return)]
11475   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11476   "@
11477    b %z1
11478    b%T1"
11479   [(set_attr "type" "branch")
11480    (set_attr "length" "4")])
11482 (define_expand "sibcall_epilogue"
11483   [(use (const_int 0))]
11484   ""
11486   if (!TARGET_SCHED_PROLOG)
11487     emit_insn (gen_blockage ());
11488   rs6000_emit_epilogue (TRUE);
11489   DONE;
11492 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11493 ;; all of memory.  This blocks insns from being moved across this point.
11495 (define_insn "blockage"
11496   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11497   ""
11498   "")
11500 (define_expand "probe_stack_address"
11501   [(use (match_operand 0 "address_operand"))]
11502   ""
11504   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11505   MEM_VOLATILE_P (operands[0]) = 1;
11507   if (TARGET_64BIT)
11508     emit_insn (gen_probe_stack_di (operands[0]));
11509   else
11510     emit_insn (gen_probe_stack_si (operands[0]));
11511   DONE;
11514 (define_insn "probe_stack_<mode>"
11515   [(set (match_operand:P 0 "memory_operand" "=m")
11516         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11517   ""
11519   operands[1] = gen_rtx_REG (Pmode, 0);
11520   return "st<wd>%U0%X0 %1,%0";
11522   [(set_attr "type" "store")
11523    (set (attr "update")
11524         (if_then_else (match_operand 0 "update_address_mem")
11525                       (const_string "yes")
11526                       (const_string "no")))
11527    (set (attr "indexed")
11528         (if_then_else (match_operand 0 "indexed_address_mem")
11529                       (const_string "yes")
11530                       (const_string "no")))
11531    (set_attr "length" "4")])
11533 (define_insn "probe_stack_range<P:mode>"
11534   [(set (match_operand:P 0 "register_operand" "=r")
11535         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11536                             (match_operand:P 2 "register_operand" "r")]
11537                            UNSPECV_PROBE_STACK_RANGE))]
11538   ""
11539   "* return output_probe_stack_range (operands[0], operands[2]);"
11540   [(set_attr "type" "three")])
11542 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11543 ;; signed & unsigned, and one type of branch.
11545 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11546 ;; insns, and branches.
11548 (define_expand "cbranch<mode>4"
11549   [(use (match_operator 0 "rs6000_cbranch_operator"
11550          [(match_operand:GPR 1 "gpc_reg_operand" "")
11551           (match_operand:GPR 2 "reg_or_short_operand" "")]))
11552    (use (match_operand 3 ""))]
11553   ""
11554   "
11556   /* Take care of the possibility that operands[2] might be negative but
11557      this might be a logical operation.  That insn doesn't exist.  */
11558   if (GET_CODE (operands[2]) == CONST_INT
11559       && INTVAL (operands[2]) < 0)
11560     {
11561       operands[2] = force_reg (<MODE>mode, operands[2]);
11562       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11563                                     GET_MODE (operands[0]),
11564                                     operands[1], operands[2]);
11565    }
11567   rs6000_emit_cbranch (<MODE>mode, operands);
11568   DONE;
11571 (define_expand "cbranch<mode>4"
11572   [(use (match_operator 0 "rs6000_cbranch_operator"
11573          [(match_operand:FP 1 "gpc_reg_operand" "")
11574           (match_operand:FP 2 "gpc_reg_operand" "")]))
11575    (use (match_operand 3 ""))]
11576   ""
11577   "
11579   rs6000_emit_cbranch (<MODE>mode, operands);
11580   DONE;
11583 (define_expand "cstore<mode>4_signed"
11584   [(use (match_operator 1 "signed_comparison_operator"
11585          [(match_operand:P 2 "gpc_reg_operand")
11586           (match_operand:P 3 "gpc_reg_operand")]))
11587    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11588   ""
11590   enum rtx_code cond_code = GET_CODE (operands[1]);
11592   rtx op0 = operands[0];
11593   rtx op1 = operands[2];
11594   rtx op2 = operands[3];
11596   if (cond_code == GE || cond_code == LT)
11597     {
11598       cond_code = swap_condition (cond_code);
11599       std::swap (op1, op2);
11600     }
11602   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11603   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11604   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11606   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11607   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11608   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11610   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11612   if (cond_code == LE)
11613     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11614   else
11615     {
11616       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11617       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11618       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11619     }
11621   DONE;
11624 (define_expand "cstore<mode>4_unsigned"
11625   [(use (match_operator 1 "unsigned_comparison_operator"
11626          [(match_operand:P 2 "gpc_reg_operand")
11627           (match_operand:P 3 "reg_or_short_operand")]))
11628    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11629   ""
11631   enum rtx_code cond_code = GET_CODE (operands[1]);
11633   rtx op0 = operands[0];
11634   rtx op1 = operands[2];
11635   rtx op2 = operands[3];
11637   if (cond_code == GEU || cond_code == LTU)
11638     {
11639       cond_code = swap_condition (cond_code);
11640       std::swap (op1, op2);
11641     }
11643   if (!gpc_reg_operand (op1, <MODE>mode))
11644     op1 = force_reg (<MODE>mode, op1);
11645   if (!reg_or_short_operand (op2, <MODE>mode))
11646     op2 = force_reg (<MODE>mode, op2);
11648   rtx tmp = gen_reg_rtx (<MODE>mode);
11649   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11651   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11652   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11654   if (cond_code == LEU)
11655     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11656   else
11657     emit_insn (gen_neg<mode>2 (op0, tmp2));
11659   DONE;
11662 (define_expand "cstore_si_as_di"
11663   [(use (match_operator 1 "unsigned_comparison_operator"
11664          [(match_operand:SI 2 "gpc_reg_operand")
11665           (match_operand:SI 3 "reg_or_short_operand")]))
11666    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11667   ""
11669   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11670   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11672   operands[2] = force_reg (SImode, operands[2]);
11673   operands[3] = force_reg (SImode, operands[3]);
11674   rtx op1 = gen_reg_rtx (DImode);
11675   rtx op2 = gen_reg_rtx (DImode);
11676   convert_move (op1, operands[2], uns_flag);
11677   convert_move (op2, operands[3], uns_flag);
11679   if (cond_code == GT || cond_code == LE)
11680     {
11681       cond_code = swap_condition (cond_code);
11682       std::swap (op1, op2);
11683     }
11685   rtx tmp = gen_reg_rtx (DImode);
11686   rtx tmp2 = gen_reg_rtx (DImode);
11687   emit_insn (gen_subdi3 (tmp, op1, op2));
11688   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11690   rtx tmp3;
11691   switch (cond_code)
11692     {
11693     default:
11694       gcc_unreachable ();
11695     case LT:
11696       tmp3 = tmp2;
11697       break;
11698     case GE:
11699       tmp3 = gen_reg_rtx (DImode);
11700       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11701       break;
11702     }
11704   convert_move (operands[0], tmp3, 1);
11706   DONE;
11709 (define_expand "cstore<mode>4_signed_imm"
11710   [(use (match_operator 1 "signed_comparison_operator"
11711          [(match_operand:GPR 2 "gpc_reg_operand")
11712           (match_operand:GPR 3 "immediate_operand")]))
11713    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11714   ""
11716   bool invert = false;
11718   enum rtx_code cond_code = GET_CODE (operands[1]);
11720   rtx op0 = operands[0];
11721   rtx op1 = operands[2];
11722   HOST_WIDE_INT val = INTVAL (operands[3]);
11724   if (cond_code == GE || cond_code == GT)
11725     {
11726       cond_code = reverse_condition (cond_code);
11727       invert = true;
11728     }
11730   if (cond_code == LE)
11731     val++;
11733   rtx tmp = gen_reg_rtx (<MODE>mode);
11734   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11735   rtx x = gen_reg_rtx (<MODE>mode);
11736   if (val < 0)
11737     emit_insn (gen_and<mode>3 (x, op1, tmp));
11738   else
11739     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11741   if (invert)
11742     {
11743       rtx tmp = gen_reg_rtx (<MODE>mode);
11744       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11745       x = tmp;
11746     }
11748   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11749   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11751   DONE;
11754 (define_expand "cstore<mode>4_unsigned_imm"
11755   [(use (match_operator 1 "unsigned_comparison_operator"
11756          [(match_operand:GPR 2 "gpc_reg_operand")
11757           (match_operand:GPR 3 "immediate_operand")]))
11758    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11759   ""
11761   bool invert = false;
11763   enum rtx_code cond_code = GET_CODE (operands[1]);
11765   rtx op0 = operands[0];
11766   rtx op1 = operands[2];
11767   HOST_WIDE_INT val = INTVAL (operands[3]);
11769   if (cond_code == GEU || cond_code == GTU)
11770     {
11771       cond_code = reverse_condition (cond_code);
11772       invert = true;
11773     }
11775   if (cond_code == LEU)
11776     val++;
11778   rtx tmp = gen_reg_rtx (<MODE>mode);
11779   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11780   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11781   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11782   rtx x = gen_reg_rtx (<MODE>mode);
11783   if (val < 0)
11784     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11785   else
11786     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11788   if (invert)
11789     {
11790       rtx tmp = gen_reg_rtx (<MODE>mode);
11791       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11792       x = tmp;
11793     }
11795   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11796   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11798   DONE;
11801 (define_expand "cstore<mode>4"
11802   [(use (match_operator 1 "rs6000_cbranch_operator"
11803          [(match_operand:GPR 2 "gpc_reg_operand")
11804           (match_operand:GPR 3 "reg_or_short_operand")]))
11805    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11806   ""
11808   /* Use ISEL if the user asked for it.  */
11809   if (TARGET_ISEL)
11810     rs6000_emit_sISEL (<MODE>mode, operands);
11812   /* Expanding EQ and NE directly to some machine instructions does not help
11813      but does hurt combine.  So don't.  */
11814   else if (GET_CODE (operands[1]) == EQ)
11815     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11816   else if (<MODE>mode == Pmode
11817            && GET_CODE (operands[1]) == NE)
11818     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11819   else if (GET_CODE (operands[1]) == NE)
11820     {
11821       rtx tmp = gen_reg_rtx (<MODE>mode);
11822       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11823       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11824     }
11826   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11827      etc. combinations magically work out just right.  */
11828   else if (<MODE>mode == Pmode
11829            && unsigned_comparison_operator (operands[1], VOIDmode))
11830     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11831                                            operands[2], operands[3]));
11833   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11834   else if (<MODE>mode == SImode && Pmode == DImode)
11835     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11836                                     operands[2], operands[3]));
11838   /* For signed comparisons against a constant, we can do some simple
11839      bit-twiddling.  */
11840   else if (signed_comparison_operator (operands[1], VOIDmode)
11841            && CONST_INT_P (operands[3]))
11842     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11843                                              operands[2], operands[3]));
11845   /* And similarly for unsigned comparisons.  */
11846   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11847            && CONST_INT_P (operands[3]))
11848     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11849                                                operands[2], operands[3]));
11851   /* We also do not want to use mfcr for signed comparisons.  */
11852   else if (<MODE>mode == Pmode
11853            && signed_comparison_operator (operands[1], VOIDmode))
11854     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11855                                          operands[2], operands[3]));
11857   /* Everything else, use the mfcr brute force.  */
11858   else
11859     rs6000_emit_sCOND (<MODE>mode, operands);
11861   DONE;
11864 (define_expand "cstore<mode>4"
11865   [(use (match_operator 1 "rs6000_cbranch_operator"
11866          [(match_operand:FP 2 "gpc_reg_operand")
11867           (match_operand:FP 3 "gpc_reg_operand")]))
11868    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11869   ""
11871   rs6000_emit_sCOND (<MODE>mode, operands);
11872   DONE;
11876 (define_expand "stack_protect_set"
11877   [(match_operand 0 "memory_operand")
11878    (match_operand 1 "memory_operand")]
11879   ""
11881   if (rs6000_stack_protector_guard == SSP_TLS)
11882     {
11883       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11884       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11885       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11886       operands[1] = gen_rtx_MEM (Pmode, addr);
11887     }
11889   if (TARGET_64BIT)
11890     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11891   else
11892     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11894   DONE;
11897 (define_insn "stack_protect_setsi"
11898   [(set (match_operand:SI 0 "memory_operand" "=m")
11899         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11900    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11901   "TARGET_32BIT"
11902   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11903   [(set_attr "type" "three")
11904    (set_attr "length" "12")])
11906 (define_insn "stack_protect_setdi"
11907   [(set (match_operand:DI 0 "memory_operand" "=Y")
11908         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11909    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11910   "TARGET_64BIT"
11911   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11912   [(set_attr "type" "three")
11913    (set_attr "length" "12")])
11915 (define_expand "stack_protect_test"
11916   [(match_operand 0 "memory_operand")
11917    (match_operand 1 "memory_operand")
11918    (match_operand 2 "")]
11919   ""
11921   rtx guard = operands[1];
11923   if (rs6000_stack_protector_guard == SSP_TLS)
11924     {
11925       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11926       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11927       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11928       guard = gen_rtx_MEM (Pmode, addr);
11929     }
11931   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11932   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11933   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11934   emit_jump_insn (jump);
11936   DONE;
11939 (define_insn "stack_protect_testsi"
11940   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11941         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11942                       (match_operand:SI 2 "memory_operand" "m,m")]
11943                      UNSPEC_SP_TEST))
11944    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11945    (clobber (match_scratch:SI 3 "=&r,&r"))]
11946   "TARGET_32BIT"
11947   "@
11948    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11949    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11950   [(set_attr "length" "16,20")])
11952 (define_insn "stack_protect_testdi"
11953   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11954         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11955                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11956                      UNSPEC_SP_TEST))
11957    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11958    (clobber (match_scratch:DI 3 "=&r,&r"))]
11959   "TARGET_64BIT"
11960   "@
11961    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11962    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11963   [(set_attr "length" "16,20")])
11966 ;; Here are the actual compare insns.
11967 (define_insn "*cmp<mode>_signed"
11968   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11969         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11970                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11971   ""
11972   "cmp<wd>%I2 %0,%1,%2"
11973   [(set_attr "type" "cmp")])
11975 (define_insn "*cmp<mode>_unsigned"
11976   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11977         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11978                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11979   ""
11980   "cmpl<wd>%I2 %0,%1,%2"
11981   [(set_attr "type" "cmp")])
11983 ;; If we are comparing a register for equality with a large constant,
11984 ;; we can do this with an XOR followed by a compare.  But this is profitable
11985 ;; only if the large constant is only used for the comparison (and in this
11986 ;; case we already have a register to reuse as scratch).
11988 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11989 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11991 (define_peephole2
11992   [(set (match_operand:SI 0 "register_operand")
11993         (match_operand:SI 1 "logical_const_operand" ""))
11994    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11995                        [(match_dup 0)
11996                         (match_operand:SI 2 "logical_const_operand" "")]))
11997    (set (match_operand:CC 4 "cc_reg_operand" "")
11998         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11999                     (match_dup 0)))
12000    (set (pc)
12001         (if_then_else (match_operator 6 "equality_operator"
12002                        [(match_dup 4) (const_int 0)])
12003                       (match_operand 7 "" "")
12004                       (match_operand 8 "" "")))]
12005   "peep2_reg_dead_p (3, operands[0])
12006    && peep2_reg_dead_p (4, operands[4])
12007    && REGNO (operands[0]) != REGNO (operands[5])"
12008  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
12009   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
12010   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
12013   /* Get the constant we are comparing against, and see what it looks like
12014      when sign-extended from 16 to 32 bits.  Then see what constant we could
12015      XOR with SEXTC to get the sign-extended value.  */
12016   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
12017                                               SImode,
12018                                               operands[1], operands[2]);
12019   HOST_WIDE_INT c = INTVAL (cnst);
12020   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
12021   HOST_WIDE_INT xorv = c ^ sextc;
12023   operands[9] = GEN_INT (xorv);
12024   operands[10] = GEN_INT (sextc);
12027 ;; The following two insns don't exist as single insns, but if we provide
12028 ;; them, we can swap an add and compare, which will enable us to overlap more
12029 ;; of the required delay between a compare and branch.  We generate code for
12030 ;; them by splitting.
12032 (define_insn ""
12033   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
12034         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
12035                     (match_operand:SI 2 "short_cint_operand" "i")))
12036    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12037         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12038   ""
12039   "#"
12040   [(set_attr "length" "8")])
12042 (define_insn ""
12043   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
12044         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
12045                        (match_operand:SI 2 "u_short_cint_operand" "i")))
12046    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12047         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12048   ""
12049   "#"
12050   [(set_attr "length" "8")])
12052 (define_split
12053   [(set (match_operand:CC 3 "cc_reg_operand" "")
12054         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
12055                     (match_operand:SI 2 "short_cint_operand" "")))
12056    (set (match_operand:SI 0 "gpc_reg_operand" "")
12057         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12058   ""
12059   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
12060    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12062 (define_split
12063   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
12064         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
12065                        (match_operand:SI 2 "u_short_cint_operand" "")))
12066    (set (match_operand:SI 0 "gpc_reg_operand" "")
12067         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12068   ""
12069   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
12070    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12072 ;; Only need to compare second words if first words equal
12073 (define_insn "*cmp<mode>_internal1"
12074   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12075         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12076                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12077   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12078    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12079   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12080   [(set_attr "type" "fpcompare")
12081    (set_attr "length" "12")])
12083 (define_insn_and_split "*cmp<mode>_internal2"
12084   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12085         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12086                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12087     (clobber (match_scratch:DF 3 "=d"))
12088     (clobber (match_scratch:DF 4 "=d"))
12089     (clobber (match_scratch:DF 5 "=d"))
12090     (clobber (match_scratch:DF 6 "=d"))
12091     (clobber (match_scratch:DF 7 "=d"))
12092     (clobber (match_scratch:DF 8 "=d"))
12093     (clobber (match_scratch:DF 9 "=d"))
12094     (clobber (match_scratch:DF 10 "=d"))
12095     (clobber (match_scratch:GPR 11 "=b"))]
12096   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12097    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12098   "#"
12099   "&& reload_completed"
12100   [(set (match_dup 3) (match_dup 14))
12101    (set (match_dup 4) (match_dup 15))
12102    (set (match_dup 9) (abs:DF (match_dup 5)))
12103    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12104    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12105                            (label_ref (match_dup 12))
12106                            (pc)))
12107    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12108    (set (pc) (label_ref (match_dup 13)))
12109    (match_dup 12)
12110    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12111    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12112    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12113    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12114    (match_dup 13)]
12116   REAL_VALUE_TYPE rv;
12117   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12118   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12120   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12121   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12122   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12123   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12124   operands[12] = gen_label_rtx ();
12125   operands[13] = gen_label_rtx ();
12126   real_inf (&rv);
12127   operands[14] = force_const_mem (DFmode,
12128                                   const_double_from_real_value (rv, DFmode));
12129   operands[15] = force_const_mem (DFmode,
12130                                   const_double_from_real_value (dconst0,
12131                                                                 DFmode));
12132   if (TARGET_TOC)
12133     {
12134       rtx tocref;
12135       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12136       operands[14] = gen_const_mem (DFmode, tocref);
12137       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12138       operands[15] = gen_const_mem (DFmode, tocref);
12139       set_mem_alias_set (operands[14], get_TOC_alias_set ());
12140       set_mem_alias_set (operands[15], get_TOC_alias_set ());
12141     }
12144 ;; Now we have the scc insns.  We can do some combinations because of the
12145 ;; way the machine works.
12147 ;; Note that this is probably faster if we can put an insn between the
12148 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
12149 ;; cases the insns below which don't use an intermediate CR field will
12150 ;; be used instead.
12151 (define_insn ""
12152   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12153         (match_operator:SI 1 "scc_comparison_operator"
12154                            [(match_operand 2 "cc_reg_operand" "y")
12155                             (const_int 0)]))]
12156   ""
12157   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12158   [(set (attr "type")
12159      (cond [(match_test "TARGET_MFCRF")
12160                 (const_string "mfcrf")
12161            ]
12162         (const_string "mfcr")))
12163    (set_attr "length" "8")])
12165 ;; Same as above, but get the GT bit.
12166 (define_insn "move_from_CR_gt_bit"
12167   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12168         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
12169   "TARGET_HARD_FLOAT && !TARGET_FPRS"
12170   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
12171   [(set_attr "type" "mfcr")
12172    (set_attr "length" "8")])
12174 ;; Same as above, but get the OV/ORDERED bit.
12175 (define_insn "move_from_CR_ov_bit"
12176   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12177         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12178                    UNSPEC_MV_CR_OV))]
12179   "TARGET_ISEL"
12180   "mfcr %0\;rlwinm %0,%0,%t1,1"
12181   [(set_attr "type" "mfcr")
12182    (set_attr "length" "8")])
12184 (define_insn ""
12185   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12186         (match_operator:DI 1 "scc_comparison_operator"
12187                            [(match_operand 2 "cc_reg_operand" "y")
12188                             (const_int 0)]))]
12189   "TARGET_POWERPC64"
12190   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12191   [(set (attr "type")
12192      (cond [(match_test "TARGET_MFCRF")
12193                 (const_string "mfcrf")
12194            ]
12195         (const_string "mfcr")))
12196    (set_attr "length" "8")])
12198 (define_insn ""
12199   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12200         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12201                                        [(match_operand 2 "cc_reg_operand" "y,y")
12202                                         (const_int 0)])
12203                     (const_int 0)))
12204    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12205         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12206   "TARGET_32BIT"
12207   "@
12208    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12209    #"
12210   [(set_attr "type" "shift")
12211    (set_attr "dot" "yes")
12212    (set_attr "length" "8,16")])
12214 (define_split
12215   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12216         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12217                                        [(match_operand 2 "cc_reg_operand" "")
12218                                         (const_int 0)])
12219                     (const_int 0)))
12220    (set (match_operand:SI 3 "gpc_reg_operand" "")
12221         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12222   "TARGET_32BIT && reload_completed"
12223   [(set (match_dup 3)
12224         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12225    (set (match_dup 0)
12226         (compare:CC (match_dup 3)
12227                     (const_int 0)))]
12228   "")
12230 (define_insn ""
12231   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12232         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12233                                       [(match_operand 2 "cc_reg_operand" "y")
12234                                        (const_int 0)])
12235                    (match_operand:SI 3 "const_int_operand" "n")))]
12236   ""
12237   "*
12239   int is_bit = ccr_bit (operands[1], 1);
12240   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12241   int count;
12243   if (is_bit >= put_bit)
12244     count = is_bit - put_bit;
12245   else
12246     count = 32 - (put_bit - is_bit);
12248   operands[4] = GEN_INT (count);
12249   operands[5] = GEN_INT (put_bit);
12251   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12253   [(set (attr "type")
12254      (cond [(match_test "TARGET_MFCRF")
12255                 (const_string "mfcrf")
12256            ]
12257         (const_string "mfcr")))
12258    (set_attr "length" "8")])
12260 (define_insn ""
12261   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12262         (compare:CC
12263          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12264                                        [(match_operand 2 "cc_reg_operand" "y,y")
12265                                         (const_int 0)])
12266                     (match_operand:SI 3 "const_int_operand" "n,n"))
12267          (const_int 0)))
12268    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12269         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12270                    (match_dup 3)))]
12271   ""
12272   "*
12274   int is_bit = ccr_bit (operands[1], 1);
12275   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12276   int count;
12278   /* Force split for non-cc0 compare.  */
12279   if (which_alternative == 1)
12280      return \"#\";
12282   if (is_bit >= put_bit)
12283     count = is_bit - put_bit;
12284   else
12285     count = 32 - (put_bit - is_bit);
12287   operands[5] = GEN_INT (count);
12288   operands[6] = GEN_INT (put_bit);
12290   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12292   [(set_attr "type" "shift")
12293    (set_attr "dot" "yes")
12294    (set_attr "length" "8,16")])
12296 (define_split
12297   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12298         (compare:CC
12299          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12300                                        [(match_operand 2 "cc_reg_operand" "")
12301                                         (const_int 0)])
12302                     (match_operand:SI 3 "const_int_operand" ""))
12303          (const_int 0)))
12304    (set (match_operand:SI 4 "gpc_reg_operand" "")
12305         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12306                    (match_dup 3)))]
12307   "reload_completed"
12308   [(set (match_dup 4)
12309         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12310                    (match_dup 3)))
12311    (set (match_dup 0)
12312         (compare:CC (match_dup 4)
12313                     (const_int 0)))]
12314   "")
12317 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12318                               (DI "rKJI")])
12320 (define_insn_and_split "eq<mode>3"
12321   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12322         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12323                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12324    (clobber (match_scratch:GPR 3 "=r"))
12325    (clobber (match_scratch:GPR 4 "=r"))]
12326   ""
12327   "#"
12328   ""
12329   [(set (match_dup 4)
12330         (clz:GPR (match_dup 3)))
12331    (set (match_dup 0)
12332         (lshiftrt:GPR (match_dup 4)
12333                       (match_dup 5)))]
12335   operands[3] = rs6000_emit_eqne (<MODE>mode,
12336                                   operands[1], operands[2], operands[3]);
12338   if (GET_CODE (operands[4]) == SCRATCH)
12339     operands[4] = gen_reg_rtx (<MODE>mode);
12341   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12343   [(set (attr "length")
12344         (if_then_else (match_test "operands[2] == const0_rtx")
12345                       (const_string "8")
12346                       (const_string "12")))])
12348 (define_insn_and_split "ne<mode>3"
12349   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12350         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12351               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12352    (clobber (match_scratch:P 3 "=r"))
12353    (clobber (match_scratch:P 4 "=r"))
12354    (clobber (reg:P CA_REGNO))]
12355   "!TARGET_ISEL"
12356   "#"
12357   ""
12358   [(parallel [(set (match_dup 4)
12359                    (plus:P (match_dup 3)
12360                            (const_int -1)))
12361               (set (reg:P CA_REGNO)
12362                    (ne:P (match_dup 3)
12363                          (const_int 0)))])
12364    (parallel [(set (match_dup 0)
12365                    (plus:P (plus:P (not:P (match_dup 4))
12366                                    (reg:P CA_REGNO))
12367                            (match_dup 3)))
12368               (clobber (reg:P CA_REGNO))])]
12370   operands[3] = rs6000_emit_eqne (<MODE>mode,
12371                                   operands[1], operands[2], operands[3]);
12373   if (GET_CODE (operands[4]) == SCRATCH)
12374     operands[4] = gen_reg_rtx (<MODE>mode);
12376   [(set (attr "length")
12377         (if_then_else (match_test "operands[2] == const0_rtx")
12378                       (const_string "8")
12379                       (const_string "12")))])
12381 (define_insn_and_split "*neg_eq_<mode>"
12382   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12383         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12384                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12385    (clobber (match_scratch:P 3 "=r"))
12386    (clobber (match_scratch:P 4 "=r"))
12387    (clobber (reg:P CA_REGNO))]
12388   ""
12389   "#"
12390   ""
12391   [(parallel [(set (match_dup 4)
12392                    (plus:P (match_dup 3)
12393                            (const_int -1)))
12394               (set (reg:P CA_REGNO)
12395                    (ne:P (match_dup 3)
12396                          (const_int 0)))])
12397    (parallel [(set (match_dup 0)
12398                    (plus:P (reg:P CA_REGNO)
12399                            (const_int -1)))
12400               (clobber (reg:P CA_REGNO))])]
12402   operands[3] = rs6000_emit_eqne (<MODE>mode,
12403                                   operands[1], operands[2], operands[3]);
12405   if (GET_CODE (operands[4]) == SCRATCH)
12406     operands[4] = gen_reg_rtx (<MODE>mode);
12408   [(set (attr "length")
12409         (if_then_else (match_test "operands[2] == const0_rtx")
12410                       (const_string "8")
12411                       (const_string "12")))])
12413 (define_insn_and_split "*neg_ne_<mode>"
12414   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12415         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12416                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12417    (clobber (match_scratch:P 3 "=r"))
12418    (clobber (match_scratch:P 4 "=r"))
12419    (clobber (reg:P CA_REGNO))]
12420   ""
12421   "#"
12422   ""
12423   [(parallel [(set (match_dup 4)
12424                    (neg:P (match_dup 3)))
12425               (set (reg:P CA_REGNO)
12426                    (eq:P (match_dup 3)
12427                          (const_int 0)))])
12428    (parallel [(set (match_dup 0)
12429                    (plus:P (reg:P CA_REGNO)
12430                            (const_int -1)))
12431               (clobber (reg:P CA_REGNO))])]
12433   operands[3] = rs6000_emit_eqne (<MODE>mode,
12434                                   operands[1], operands[2], operands[3]);
12436   if (GET_CODE (operands[4]) == SCRATCH)
12437     operands[4] = gen_reg_rtx (<MODE>mode);
12439   [(set (attr "length")
12440         (if_then_else (match_test "operands[2] == const0_rtx")
12441                       (const_string "8")
12442                       (const_string "12")))])
12444 (define_insn_and_split "*plus_eq_<mode>"
12445   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12446         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12447                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12448                 (match_operand:P 3 "gpc_reg_operand" "r")))
12449    (clobber (match_scratch:P 4 "=r"))
12450    (clobber (match_scratch:P 5 "=r"))
12451    (clobber (reg:P CA_REGNO))]
12452   ""
12453   "#"
12454   ""
12455   [(parallel [(set (match_dup 5)
12456                    (neg:P (match_dup 4)))
12457               (set (reg:P CA_REGNO)
12458                    (eq:P (match_dup 4)
12459                          (const_int 0)))])
12460    (parallel [(set (match_dup 0)
12461                    (plus:P (match_dup 3)
12462                            (reg:P CA_REGNO)))
12463               (clobber (reg:P CA_REGNO))])]
12465   operands[4] = rs6000_emit_eqne (<MODE>mode,
12466                                   operands[1], operands[2], operands[4]);
12468   if (GET_CODE (operands[5]) == SCRATCH)
12469     operands[5] = gen_reg_rtx (<MODE>mode);
12471   [(set (attr "length")
12472         (if_then_else (match_test "operands[2] == const0_rtx")
12473                       (const_string "8")
12474                       (const_string "12")))])
12476 (define_insn_and_split "*plus_ne_<mode>"
12477   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12478         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12479                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12480                 (match_operand:P 3 "gpc_reg_operand" "r")))
12481    (clobber (match_scratch:P 4 "=r"))
12482    (clobber (match_scratch:P 5 "=r"))
12483    (clobber (reg:P CA_REGNO))]
12484   ""
12485   "#"
12486   ""
12487   [(parallel [(set (match_dup 5)
12488                    (plus:P (match_dup 4)
12489                            (const_int -1)))
12490               (set (reg:P CA_REGNO)
12491                    (ne:P (match_dup 4)
12492                          (const_int 0)))])
12493    (parallel [(set (match_dup 0)
12494                    (plus:P (match_dup 3)
12495                            (reg:P CA_REGNO)))
12496               (clobber (reg:P CA_REGNO))])]
12498   operands[4] = rs6000_emit_eqne (<MODE>mode,
12499                                   operands[1], operands[2], operands[4]);
12501   if (GET_CODE (operands[5]) == SCRATCH)
12502     operands[5] = gen_reg_rtx (<MODE>mode);
12504   [(set (attr "length")
12505         (if_then_else (match_test "operands[2] == const0_rtx")
12506                       (const_string "8")
12507                       (const_string "12")))])
12509 (define_insn_and_split "*minus_eq_<mode>"
12510   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12511         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12512                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12513                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12514    (clobber (match_scratch:P 4 "=r"))
12515    (clobber (match_scratch:P 5 "=r"))
12516    (clobber (reg:P CA_REGNO))]
12517   ""
12518   "#"
12519   ""
12520   [(parallel [(set (match_dup 5)
12521                    (plus:P (match_dup 4)
12522                            (const_int -1)))
12523               (set (reg:P CA_REGNO)
12524                    (ne:P (match_dup 4)
12525                          (const_int 0)))])
12526    (parallel [(set (match_dup 0)
12527                    (plus:P (plus:P (match_dup 3)
12528                                    (reg:P CA_REGNO))
12529                            (const_int -1)))
12530               (clobber (reg:P CA_REGNO))])]
12532   operands[4] = rs6000_emit_eqne (<MODE>mode,
12533                                   operands[1], operands[2], operands[4]);
12535   if (GET_CODE (operands[5]) == SCRATCH)
12536     operands[5] = gen_reg_rtx (<MODE>mode);
12538   [(set (attr "length")
12539         (if_then_else (match_test "operands[2] == const0_rtx")
12540                       (const_string "8")
12541                       (const_string "12")))])
12543 (define_insn_and_split "*minus_ne_<mode>"
12544   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12545         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12546                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12547                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12548    (clobber (match_scratch:P 4 "=r"))
12549    (clobber (match_scratch:P 5 "=r"))
12550    (clobber (reg:P CA_REGNO))]
12551   ""
12552   "#"
12553   ""
12554   [(parallel [(set (match_dup 5)
12555                    (neg:P (match_dup 4)))
12556               (set (reg:P CA_REGNO)
12557                    (eq:P (match_dup 4)
12558                          (const_int 0)))])
12559    (parallel [(set (match_dup 0)
12560                    (plus:P (plus:P (match_dup 3)
12561                                    (reg:P CA_REGNO))
12562                            (const_int -1)))
12563               (clobber (reg:P CA_REGNO))])]
12565   operands[4] = rs6000_emit_eqne (<MODE>mode,
12566                                   operands[1], operands[2], operands[4]);
12568   if (GET_CODE (operands[5]) == SCRATCH)
12569     operands[5] = gen_reg_rtx (<MODE>mode);
12571   [(set (attr "length")
12572         (if_then_else (match_test "operands[2] == const0_rtx")
12573                       (const_string "8")
12574                       (const_string "12")))])
12576 (define_insn_and_split "*eqsi3_ext<mode>"
12577   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12578         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12579                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12580    (clobber (match_scratch:SI 3 "=r"))
12581    (clobber (match_scratch:SI 4 "=r"))]
12582   ""
12583   "#"
12584   ""
12585   [(set (match_dup 4)
12586         (clz:SI (match_dup 3)))
12587    (set (match_dup 0)
12588         (zero_extend:EXTSI
12589           (lshiftrt:SI (match_dup 4)
12590                        (const_int 5))))]
12592   operands[3] = rs6000_emit_eqne (SImode,
12593                                   operands[1], operands[2], operands[3]);
12595   if (GET_CODE (operands[4]) == SCRATCH)
12596     operands[4] = gen_reg_rtx (SImode);
12598   [(set (attr "length")
12599         (if_then_else (match_test "operands[2] == const0_rtx")
12600                       (const_string "8")
12601                       (const_string "12")))])
12603 (define_insn_and_split "*nesi3_ext<mode>"
12604   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12605         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12606                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12607    (clobber (match_scratch:SI 3 "=r"))
12608    (clobber (match_scratch:SI 4 "=r"))
12609    (clobber (match_scratch:EXTSI 5 "=r"))]
12610   ""
12611   "#"
12612   ""
12613   [(set (match_dup 4)
12614         (clz:SI (match_dup 3)))
12615    (set (match_dup 5)
12616         (zero_extend:EXTSI
12617           (lshiftrt:SI (match_dup 4)
12618                        (const_int 5))))
12619    (set (match_dup 0)
12620         (xor:EXTSI (match_dup 5)
12621                    (const_int 1)))]
12623   operands[3] = rs6000_emit_eqne (SImode,
12624                                   operands[1], operands[2], operands[3]);
12626   if (GET_CODE (operands[4]) == SCRATCH)
12627     operands[4] = gen_reg_rtx (SImode);
12628   if (GET_CODE (operands[5]) == SCRATCH)
12629     operands[5] = gen_reg_rtx (<MODE>mode);
12631   [(set (attr "length")
12632         (if_then_else (match_test "operands[2] == const0_rtx")
12633                       (const_string "12")
12634                       (const_string "16")))])
12636 ;; Define both directions of branch and return.  If we need a reload
12637 ;; register, we'd rather use CR0 since it is much easier to copy a
12638 ;; register CC value to there.
12640 (define_insn ""
12641   [(set (pc)
12642         (if_then_else (match_operator 1 "branch_comparison_operator"
12643                                       [(match_operand 2
12644                                                       "cc_reg_operand" "y")
12645                                        (const_int 0)])
12646                       (label_ref (match_operand 0 "" ""))
12647                       (pc)))]
12648   ""
12649   "*
12651   return output_cbranch (operands[1], \"%l0\", 0, insn);
12653   [(set_attr "type" "branch")])
12655 (define_insn ""
12656   [(set (pc)
12657         (if_then_else (match_operator 0 "branch_comparison_operator"
12658                                       [(match_operand 1
12659                                                       "cc_reg_operand" "y")
12660                                        (const_int 0)])
12661                       (any_return)
12662                       (pc)))]
12663   "<return_pred>"
12664   "*
12666   return output_cbranch (operands[0], NULL, 0, insn);
12668   [(set_attr "type" "jmpreg")
12669    (set_attr "length" "4")])
12671 (define_insn ""
12672   [(set (pc)
12673         (if_then_else (match_operator 1 "branch_comparison_operator"
12674                                       [(match_operand 2
12675                                                       "cc_reg_operand" "y")
12676                                        (const_int 0)])
12677                       (pc)
12678                       (label_ref (match_operand 0 "" ""))))]
12679   ""
12680   "*
12682   return output_cbranch (operands[1], \"%l0\", 1, insn);
12684   [(set_attr "type" "branch")])
12686 (define_insn ""
12687   [(set (pc)
12688         (if_then_else (match_operator 0 "branch_comparison_operator"
12689                                       [(match_operand 1
12690                                                       "cc_reg_operand" "y")
12691                                        (const_int 0)])
12692                       (pc)
12693                       (any_return)))]
12694   "<return_pred>"
12695   "*
12697   return output_cbranch (operands[0], NULL, 1, insn);
12699   [(set_attr "type" "jmpreg")
12700    (set_attr "length" "4")])
12702 ;; Logic on condition register values.
12704 ; This pattern matches things like
12705 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12706 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12707 ;                                  (const_int 1)))
12708 ; which are generated by the branch logic.
12709 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12711 (define_insn "*cceq_ior_compare"
12712   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12713         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12714                         [(match_operator:SI 2
12715                                       "branch_positive_comparison_operator"
12716                                       [(match_operand 3
12717                                                       "cc_reg_operand" "y,y")
12718                                        (const_int 0)])
12719                          (match_operator:SI 4
12720                                       "branch_positive_comparison_operator"
12721                                       [(match_operand 5
12722                                                       "cc_reg_operand" "0,y")
12723                                        (const_int 0)])])
12724                       (const_int 1)))]
12725   ""
12726   "cr%q1 %E0,%j2,%j4"
12727   [(set_attr "type" "cr_logical,delayed_cr")])
12729 ; Why is the constant -1 here, but 1 in the previous pattern?
12730 ; Because ~1 has all but the low bit set.
12731 (define_insn ""
12732   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12733         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12734                         [(not:SI (match_operator:SI 2
12735                                       "branch_positive_comparison_operator"
12736                                       [(match_operand 3
12737                                                       "cc_reg_operand" "y,y")
12738                                        (const_int 0)]))
12739                          (match_operator:SI 4
12740                                 "branch_positive_comparison_operator"
12741                                 [(match_operand 5
12742                                                 "cc_reg_operand" "0,y")
12743                                  (const_int 0)])])
12744                       (const_int -1)))]
12745   ""
12746   "cr%q1 %E0,%j2,%j4"
12747   [(set_attr "type" "cr_logical,delayed_cr")])
12749 (define_insn "*cceq_rev_compare"
12750   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12751         (compare:CCEQ (match_operator:SI 1
12752                                       "branch_positive_comparison_operator"
12753                                       [(match_operand 2
12754                                                       "cc_reg_operand" "0,y")
12755                                        (const_int 0)])
12756                       (const_int 0)))]
12757   ""
12758   "crnot %E0,%j1"
12759   [(set_attr "type" "cr_logical,delayed_cr")])
12761 ;; If we are comparing the result of two comparisons, this can be done
12762 ;; using creqv or crxor.
12764 (define_insn_and_split ""
12765   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12766         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12767                               [(match_operand 2 "cc_reg_operand" "y")
12768                                (const_int 0)])
12769                       (match_operator 3 "branch_comparison_operator"
12770                               [(match_operand 4 "cc_reg_operand" "y")
12771                                (const_int 0)])))]
12772   ""
12773   "#"
12774   ""
12775   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12776                                     (match_dup 5)))]
12777   "
12779   int positive_1, positive_2;
12781   positive_1 = branch_positive_comparison_operator (operands[1],
12782                                                     GET_MODE (operands[1]));
12783   positive_2 = branch_positive_comparison_operator (operands[3],
12784                                                     GET_MODE (operands[3]));
12786   if (! positive_1)
12787     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12788                                                             GET_CODE (operands[1])),
12789                                   SImode,
12790                                   operands[2], const0_rtx);
12791   else if (GET_MODE (operands[1]) != SImode)
12792     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12793                                   operands[2], const0_rtx);
12795   if (! positive_2)
12796     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12797                                                             GET_CODE (operands[3])),
12798                                   SImode,
12799                                   operands[4], const0_rtx);
12800   else if (GET_MODE (operands[3]) != SImode)
12801     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12802                                   operands[4], const0_rtx);
12804   if (positive_1 == positive_2)
12805     {
12806       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12807       operands[5] = constm1_rtx;
12808     }
12809   else
12810     {
12811       operands[5] = const1_rtx;
12812     }
12815 ;; Unconditional branch and return.
12817 (define_insn "jump"
12818   [(set (pc)
12819         (label_ref (match_operand 0 "" "")))]
12820   ""
12821   "b %l0"
12822   [(set_attr "type" "branch")])
12824 (define_insn "<return_str>return"
12825   [(any_return)]
12826   "<return_pred>"
12827   "blr"
12828   [(set_attr "type" "jmpreg")])
12830 (define_expand "indirect_jump"
12831   [(set (pc) (match_operand 0 "register_operand" ""))])
12833 (define_insn "*indirect_jump<mode>"
12834   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12835   ""
12836   "@
12837    bctr
12838    blr"
12839   [(set_attr "type" "jmpreg")])
12841 ;; Table jump for switch statements:
12842 (define_expand "tablejump"
12843   [(use (match_operand 0 "" ""))
12844    (use (label_ref (match_operand 1 "" "")))]
12845   ""
12846   "
12848   if (TARGET_32BIT)
12849     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12850   else
12851     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12852   DONE;
12855 (define_expand "tablejumpsi"
12856   [(set (match_dup 3)
12857         (plus:SI (match_operand:SI 0 "" "")
12858                  (match_dup 2)))
12859    (parallel [(set (pc) (match_dup 3))
12860               (use (label_ref (match_operand 1 "" "")))])]
12861   "TARGET_32BIT"
12862   "
12863 { operands[0] = force_reg (SImode, operands[0]);
12864   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12865   operands[3] = gen_reg_rtx (SImode);
12868 (define_expand "tablejumpdi"
12869   [(set (match_dup 4)
12870         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12871    (set (match_dup 3)
12872         (plus:DI (match_dup 4)
12873                  (match_dup 2)))
12874    (parallel [(set (pc) (match_dup 3))
12875               (use (label_ref (match_operand 1 "" "")))])]
12876   "TARGET_64BIT"
12877   "
12878 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12879   operands[3] = gen_reg_rtx (DImode);
12880   operands[4] = gen_reg_rtx (DImode);
12883 (define_insn "*tablejump<mode>_internal1"
12884   [(set (pc)
12885         (match_operand:P 0 "register_operand" "c,*l"))
12886    (use (label_ref (match_operand 1 "" "")))]
12887   ""
12888   "@
12889    bctr
12890    blr"
12891   [(set_attr "type" "jmpreg")])
12893 (define_insn "nop"
12894   [(unspec [(const_int 0)] UNSPEC_NOP)]
12895   ""
12896   "nop")
12898 (define_insn "group_ending_nop"
12899   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12900   ""
12901   "*
12903   if (rs6000_cpu_attr == CPU_POWER6)
12904     return \"ori 1,1,0\";
12905   return \"ori 2,2,0\";
12908 ;; Define the subtract-one-and-jump insns, starting with the template
12909 ;; so loop.c knows what to generate.
12911 (define_expand "doloop_end"
12912   [(use (match_operand 0 "" ""))        ; loop pseudo
12913    (use (match_operand 1 "" ""))]       ; label
12914   ""
12915   "
12917   if (TARGET_64BIT)
12918     {
12919       if (GET_MODE (operands[0]) != DImode)
12920         FAIL;
12921       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12922     }
12923   else
12924     {
12925       if (GET_MODE (operands[0]) != SImode)
12926         FAIL;
12927       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12928     }
12929   DONE;
12932 (define_expand "ctr<mode>"
12933   [(parallel [(set (pc)
12934                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
12935                                      (const_int 1))
12936                                  (label_ref (match_operand 1 "" ""))
12937                                  (pc)))
12938               (set (match_dup 0)
12939                    (plus:P (match_dup 0)
12940                             (const_int -1)))
12941               (clobber (match_scratch:CC 2 ""))
12942               (clobber (match_scratch:P 3 ""))])]
12943   ""
12944   "")
12946 ;; We need to be able to do this for any operand, including MEM, or we
12947 ;; will cause reload to blow up since we don't allow output reloads on
12948 ;; JUMP_INSNs.
12949 ;; For the length attribute to be calculated correctly, the
12950 ;; label MUST be operand 0.
12951 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12952 ;; the ctr<mode> insns.
12954 (define_insn "ctr<mode>_internal1"
12955   [(set (pc)
12956         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12957                           (const_int 1))
12958                       (label_ref (match_operand 0 "" ""))
12959                       (pc)))
12960    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12961         (plus:P (match_dup 1)
12962                  (const_int -1)))
12963    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12964    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12965   ""
12966   "*
12968   if (which_alternative != 0)
12969     return \"#\";
12970   else if (get_attr_length (insn) == 4)
12971     return \"bdnz %l0\";
12972   else
12973     return \"bdz $+8\;b %l0\";
12975   [(set_attr "type" "branch")
12976    (set_attr "length" "*,16,20,20")])
12978 (define_insn "ctr<mode>_internal2"
12979   [(set (pc)
12980         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12981                           (const_int 1))
12982                       (pc)
12983                       (label_ref (match_operand 0 "" ""))))
12984    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12985         (plus:P (match_dup 1)
12986                  (const_int -1)))
12987    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12988    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12989   ""
12990   "*
12992   if (which_alternative != 0)
12993     return \"#\";
12994   else if (get_attr_length (insn) == 4)
12995     return \"bdz %l0\";
12996   else
12997     return \"bdnz $+8\;b %l0\";
12999   [(set_attr "type" "branch")
13000    (set_attr "length" "*,16,20,20")])
13002 ;; Similar but use EQ
13004 (define_insn "ctr<mode>_internal3"
13005   [(set (pc)
13006         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13007                           (const_int 1))
13008                       (label_ref (match_operand 0 "" ""))
13009                       (pc)))
13010    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13011         (plus:P (match_dup 1)
13012                  (const_int -1)))
13013    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13014    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13015   ""
13016   "*
13018   if (which_alternative != 0)
13019     return \"#\";
13020   else if (get_attr_length (insn) == 4)
13021     return \"bdz %l0\";
13022   else
13023     return \"bdnz $+8\;b %l0\";
13025   [(set_attr "type" "branch")
13026    (set_attr "length" "*,16,20,20")])
13028 (define_insn "ctr<mode>_internal4"
13029   [(set (pc)
13030         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13031                           (const_int 1))
13032                       (pc)
13033                       (label_ref (match_operand 0 "" ""))))
13034    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13035         (plus:P (match_dup 1)
13036                  (const_int -1)))
13037    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13038    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13039   ""
13040   "*
13042   if (which_alternative != 0)
13043     return \"#\";
13044   else if (get_attr_length (insn) == 4)
13045     return \"bdnz %l0\";
13046   else
13047     return \"bdz $+8\;b %l0\";
13049   [(set_attr "type" "branch")
13050    (set_attr "length" "*,16,20,20")])
13052 ;; Now the splitters if we could not allocate the CTR register
13054 (define_split
13055   [(set (pc)
13056         (if_then_else (match_operator 2 "comparison_operator"
13057                                       [(match_operand:P 1 "gpc_reg_operand" "")
13058                                        (const_int 1)])
13059                       (match_operand 5 "" "")
13060                       (match_operand 6 "" "")))
13061    (set (match_operand:P 0 "int_reg_operand" "")
13062         (plus:P (match_dup 1) (const_int -1)))
13063    (clobber (match_scratch:CC 3 ""))
13064    (clobber (match_scratch:P 4 ""))]
13065   "reload_completed"
13066   [(set (match_dup 3)
13067         (compare:CC (match_dup 1)
13068                     (const_int 1)))
13069    (set (match_dup 0)
13070         (plus:P (match_dup 1)
13071                 (const_int -1)))
13072    (set (pc) (if_then_else (match_dup 7)
13073                            (match_dup 5)
13074                            (match_dup 6)))]
13075   "
13076 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13077                                 operands[3], const0_rtx); }")
13079 (define_split
13080   [(set (pc)
13081         (if_then_else (match_operator 2 "comparison_operator"
13082                                       [(match_operand:P 1 "gpc_reg_operand" "")
13083                                        (const_int 1)])
13084                       (match_operand 5 "" "")
13085                       (match_operand 6 "" "")))
13086    (set (match_operand:P 0 "nonimmediate_operand" "")
13087         (plus:P (match_dup 1) (const_int -1)))
13088    (clobber (match_scratch:CC 3 ""))
13089    (clobber (match_scratch:P 4 ""))]
13090   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
13091   [(set (match_dup 3)
13092         (compare:CC (match_dup 1)
13093                     (const_int 1)))
13094    (set (match_dup 4)
13095         (plus:P (match_dup 1)
13096                 (const_int -1)))
13097    (set (match_dup 0)
13098         (match_dup 4))
13099    (set (pc) (if_then_else (match_dup 7)
13100                            (match_dup 5)
13101                            (match_dup 6)))]
13102   "
13103 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13104                                 operands[3], const0_rtx); }")
13106 (define_insn "trap"
13107   [(trap_if (const_int 1) (const_int 0))]
13108   ""
13109   "trap"
13110   [(set_attr "type" "trap")])
13112 (define_expand "ctrap<mode>4"
13113   [(trap_if (match_operator 0 "ordered_comparison_operator"
13114                             [(match_operand:GPR 1 "register_operand")
13115                              (match_operand:GPR 2 "reg_or_short_operand")])
13116             (match_operand 3 "zero_constant" ""))]
13117   ""
13118   "")
13120 (define_insn ""
13121   [(trap_if (match_operator 0 "ordered_comparison_operator"
13122                             [(match_operand:GPR 1 "register_operand" "r")
13123                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13124             (const_int 0))]
13125   ""
13126   "t<wd>%V0%I2 %1,%2"
13127   [(set_attr "type" "trap")])
13129 ;; Insns related to generating the function prologue and epilogue.
13131 (define_expand "prologue"
13132   [(use (const_int 0))]
13133   ""
13135   rs6000_emit_prologue ();
13136   if (!TARGET_SCHED_PROLOG)
13137     emit_insn (gen_blockage ());
13138   DONE;
13141 (define_insn "*movesi_from_cr_one"
13142   [(match_parallel 0 "mfcr_operation"
13143                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13144                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13145                                      (match_operand 3 "immediate_operand" "n")]
13146                           UNSPEC_MOVESI_FROM_CR))])]
13147   "TARGET_MFCRF"
13148   "*
13150   int mask = 0;
13151   int i;
13152   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13153   {
13154     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13155     operands[4] = GEN_INT (mask);
13156     output_asm_insn (\"mfcr %1,%4\", operands);
13157   }
13158   return \"\";
13160   [(set_attr "type" "mfcrf")])
13162 (define_insn "movesi_from_cr"
13163   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13164         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
13165                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13166                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
13167                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
13168                    UNSPEC_MOVESI_FROM_CR))]
13169   ""
13170   "mfcr %0"
13171   [(set_attr "type" "mfcr")])
13173 (define_insn "*crsave"
13174   [(match_parallel 0 "crsave_operation"
13175                    [(set (match_operand:SI 1 "memory_operand" "=m")
13176                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13177   ""
13178   "stw %2,%1"
13179   [(set_attr "type" "store")])
13181 (define_insn "*stmw"
13182   [(match_parallel 0 "stmw_operation"
13183                    [(set (match_operand:SI 1 "memory_operand" "=m")
13184                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13185   "TARGET_MULTIPLE"
13186   "stmw %2,%1"
13187   [(set_attr "type" "store")
13188    (set_attr "update" "yes")
13189    (set_attr "indexed" "yes")])
13191 ; The following comment applies to:
13192 ;     save_gpregs_*
13193 ;     save_fpregs_*
13194 ;     restore_gpregs*
13195 ;     return_and_restore_gpregs*
13196 ;     return_and_restore_fpregs*
13197 ;     return_and_restore_fpregs_aix*
13199 ; The out-of-line save / restore functions expects one input argument.
13200 ; Since those are not standard call_insn's, we must avoid using
13201 ; MATCH_OPERAND for that argument. That way the register rename
13202 ; optimization will not try to rename this register.
13203 ; Each pattern is repeated for each possible register number used in 
13204 ; various ABIs (r11, r1, and for some functions r12)
13206 (define_insn "*save_gpregs_<mode>_r11"
13207   [(match_parallel 0 "any_parallel_operand"
13208                    [(clobber (reg:P LR_REGNO))
13209                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13210                     (use (reg:P 11))
13211                     (set (match_operand:P 2 "memory_operand" "=m")
13212                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13213   ""
13214   "bl %1"
13215   [(set_attr "type" "branch")
13216    (set_attr "length" "4")])
13218 (define_insn "*save_gpregs_<mode>_r12"
13219   [(match_parallel 0 "any_parallel_operand"
13220                    [(clobber (reg:P LR_REGNO))
13221                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13222                     (use (reg:P 12))
13223                     (set (match_operand:P 2 "memory_operand" "=m")
13224                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13225   ""
13226   "bl %1"
13227   [(set_attr "type" "branch")
13228    (set_attr "length" "4")])
13230 (define_insn "*save_gpregs_<mode>_r1"
13231   [(match_parallel 0 "any_parallel_operand"
13232                    [(clobber (reg:P LR_REGNO))
13233                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13234                     (use (reg:P 1))
13235                     (set (match_operand:P 2 "memory_operand" "=m")
13236                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13237   ""
13238   "bl %1"
13239   [(set_attr "type" "branch")
13240    (set_attr "length" "4")])
13242 (define_insn "*save_fpregs_<mode>_r11"
13243   [(match_parallel 0 "any_parallel_operand"
13244                    [(clobber (reg:P LR_REGNO))
13245                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13246                     (use (reg:P 11))
13247                     (set (match_operand:DF 2 "memory_operand" "=m")
13248                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13249   ""
13250   "bl %1"
13251   [(set_attr "type" "branch")
13252    (set_attr "length" "4")])
13254 (define_insn "*save_fpregs_<mode>_r12"
13255   [(match_parallel 0 "any_parallel_operand"
13256                    [(clobber (reg:P LR_REGNO))
13257                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13258                     (use (reg:P 12))
13259                     (set (match_operand:DF 2 "memory_operand" "=m")
13260                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13261   ""
13262   "bl %1"
13263   [(set_attr "type" "branch")
13264    (set_attr "length" "4")])
13266 (define_insn "*save_fpregs_<mode>_r1"
13267   [(match_parallel 0 "any_parallel_operand"
13268                    [(clobber (reg:P LR_REGNO))
13269                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13270                     (use (reg:P 1))
13271                     (set (match_operand:DF 2 "memory_operand" "=m")
13272                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13273   ""
13274   "bl %1"
13275   [(set_attr "type" "branch")
13276    (set_attr "length" "4")])
13278 ; This is to explain that changes to the stack pointer should
13279 ; not be moved over loads from or stores to stack memory.
13280 (define_insn "stack_tie"
13281   [(match_parallel 0 "tie_operand"
13282                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13283   ""
13284   ""
13285   [(set_attr "length" "0")])
13287 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13288 ; stay behind all restores from the stack, it cannot be reordered to before
13289 ; one.  See PR77687.  This insn is an add or mr, and a stack_tie on the
13290 ; operands of that.
13291 (define_insn "stack_restore_tie"
13292   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13293         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13294                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13295    (set (mem:BLK (match_dup 0)) (const_int 0))
13296    (set (mem:BLK (match_dup 1)) (const_int 0))]
13297   "TARGET_32BIT"
13298   "@
13299    mr %0,%1
13300    add%I2 %0,%1,%2"
13301   [(set_attr "type" "*,add")])
13303 (define_expand "epilogue"
13304   [(use (const_int 0))]
13305   ""
13307   if (!TARGET_SCHED_PROLOG)
13308     emit_insn (gen_blockage ());
13309   rs6000_emit_epilogue (FALSE);
13310   DONE;
13313 ; On some processors, doing the mtcrf one CC register at a time is
13314 ; faster (like on the 604e).  On others, doing them all at once is
13315 ; faster; for instance, on the 601 and 750.
13317 (define_expand "movsi_to_cr_one"
13318   [(set (match_operand:CC 0 "cc_reg_operand" "")
13319         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13320                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13321   ""
13322   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13324 (define_insn "*movsi_to_cr"
13325   [(match_parallel 0 "mtcrf_operation"
13326                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13327                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13328                                      (match_operand 3 "immediate_operand" "n")]
13329                                     UNSPEC_MOVESI_TO_CR))])]
13330  ""
13331  "*
13333   int mask = 0;
13334   int i;
13335   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13336     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13337   operands[4] = GEN_INT (mask);
13338   return \"mtcrf %4,%2\";
13340   [(set_attr "type" "mtcr")])
13342 (define_insn "*mtcrfsi"
13343   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13344         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13345                     (match_operand 2 "immediate_operand" "n")]
13346                    UNSPEC_MOVESI_TO_CR))]
13347   "GET_CODE (operands[0]) == REG
13348    && CR_REGNO_P (REGNO (operands[0]))
13349    && GET_CODE (operands[2]) == CONST_INT
13350    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13351   "mtcrf %R0,%1"
13352   [(set_attr "type" "mtcr")])
13354 ; The load-multiple instructions have similar properties.
13355 ; Note that "load_multiple" is a name known to the machine-independent
13356 ; code that actually corresponds to the PowerPC load-string.
13358 (define_insn "*lmw"
13359   [(match_parallel 0 "lmw_operation"
13360                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13361                          (match_operand:SI 2 "memory_operand" "m"))])]
13362   "TARGET_MULTIPLE"
13363   "lmw %1,%2"
13364   [(set_attr "type" "load")
13365    (set_attr "update" "yes")
13366    (set_attr "indexed" "yes")
13367    (set_attr "cell_micro" "always")])
13369 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13370 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13372 ; The following comment applies to:
13373 ;     save_gpregs_*
13374 ;     save_fpregs_*
13375 ;     restore_gpregs*
13376 ;     return_and_restore_gpregs*
13377 ;     return_and_restore_fpregs*
13378 ;     return_and_restore_fpregs_aix*
13380 ; The out-of-line save / restore functions expects one input argument.
13381 ; Since those are not standard call_insn's, we must avoid using
13382 ; MATCH_OPERAND for that argument. That way the register rename
13383 ; optimization will not try to rename this register.
13384 ; Each pattern is repeated for each possible register number used in 
13385 ; various ABIs (r11, r1, and for some functions r12)
13387 (define_insn "*restore_gpregs_<mode>_r11"
13388  [(match_parallel 0 "any_parallel_operand"
13389                   [(clobber (reg:P LR_REGNO))
13390                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13391                    (use (reg:P 11))
13392                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13393                         (match_operand:P 3 "memory_operand" "m"))])]
13394  ""
13395  "bl %1"
13396  [(set_attr "type" "branch")
13397   (set_attr "length" "4")])
13399 (define_insn "*restore_gpregs_<mode>_r12"
13400  [(match_parallel 0 "any_parallel_operand"
13401                   [(clobber (reg:P LR_REGNO))
13402                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13403                    (use (reg:P 12))
13404                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13405                         (match_operand:P 3 "memory_operand" "m"))])]
13406  ""
13407  "bl %1"
13408  [(set_attr "type" "branch")
13409   (set_attr "length" "4")])
13411 (define_insn "*restore_gpregs_<mode>_r1"
13412  [(match_parallel 0 "any_parallel_operand"
13413                   [(clobber (reg:P LR_REGNO))
13414                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13415                    (use (reg:P 1))
13416                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13417                         (match_operand:P 3 "memory_operand" "m"))])]
13418  ""
13419  "bl %1"
13420  [(set_attr "type" "branch")
13421   (set_attr "length" "4")])
13423 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13424  [(match_parallel 0 "any_parallel_operand"
13425                   [(return)
13426                    (clobber (reg:P LR_REGNO))
13427                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13428                    (use (reg:P 11))
13429                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13430                         (match_operand:P 3 "memory_operand" "m"))])]
13431  ""
13432  "b %1"
13433  [(set_attr "type" "branch")
13434   (set_attr "length" "4")])
13436 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13437  [(match_parallel 0 "any_parallel_operand"
13438                   [(return)
13439                    (clobber (reg:P LR_REGNO))
13440                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13441                    (use (reg:P 12))
13442                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13443                         (match_operand:P 3 "memory_operand" "m"))])]
13444  ""
13445  "b %1"
13446  [(set_attr "type" "branch")
13447   (set_attr "length" "4")])
13449 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13450  [(match_parallel 0 "any_parallel_operand"
13451                   [(return)
13452                    (clobber (reg:P LR_REGNO))
13453                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13454                    (use (reg:P 1))
13455                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13456                         (match_operand:P 3 "memory_operand" "m"))])]
13457  ""
13458  "b %1"
13459  [(set_attr "type" "branch")
13460   (set_attr "length" "4")])
13462 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13463  [(match_parallel 0 "any_parallel_operand"
13464                   [(return)
13465                    (clobber (reg:P LR_REGNO))
13466                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13467                    (use (reg:P 11))
13468                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13469                         (match_operand:DF 3 "memory_operand" "m"))])]
13470  ""
13471  "b %1"
13472  [(set_attr "type" "branch")
13473   (set_attr "length" "4")])
13475 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13476  [(match_parallel 0 "any_parallel_operand"
13477                   [(return)
13478                    (clobber (reg:P LR_REGNO))
13479                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13480                    (use (reg:P 12))
13481                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13482                         (match_operand:DF 3 "memory_operand" "m"))])]
13483  ""
13484  "b %1"
13485  [(set_attr "type" "branch")
13486   (set_attr "length" "4")])
13488 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13489  [(match_parallel 0 "any_parallel_operand"
13490                   [(return)
13491                    (clobber (reg:P LR_REGNO))
13492                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13493                    (use (reg:P 1))
13494                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13495                         (match_operand:DF 3 "memory_operand" "m"))])]
13496  ""
13497  "b %1"
13498  [(set_attr "type" "branch")
13499   (set_attr "length" "4")])
13501 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13502  [(match_parallel 0 "any_parallel_operand"
13503                   [(return)
13504                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13505                    (use (reg:P 11))
13506                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13507                         (match_operand:DF 3 "memory_operand" "m"))])]
13508  ""
13509  "b %1"
13510  [(set_attr "type" "branch")
13511   (set_attr "length" "4")])
13513 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13514  [(match_parallel 0 "any_parallel_operand"
13515                   [(return)
13516                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13517                    (use (reg:P 1))
13518                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13519                         (match_operand:DF 3 "memory_operand" "m"))])]
13520  ""
13521  "b %1"
13522  [(set_attr "type" "branch")
13523   (set_attr "length" "4")])
13525 ; This is used in compiling the unwind routines.
13526 (define_expand "eh_return"
13527   [(use (match_operand 0 "general_operand" ""))]
13528   ""
13529   "
13531   if (TARGET_32BIT)
13532     emit_insn (gen_eh_set_lr_si (operands[0]));
13533   else
13534     emit_insn (gen_eh_set_lr_di (operands[0]));
13535   DONE;
13538 ; We can't expand this before we know where the link register is stored.
13539 (define_insn "eh_set_lr_<mode>"
13540   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13541                     UNSPECV_EH_RR)
13542    (clobber (match_scratch:P 1 "=&b"))]
13543   ""
13544   "#")
13546 (define_split
13547   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13548    (clobber (match_scratch 1 ""))]
13549   "reload_completed"
13550   [(const_int 0)]
13551   "
13553   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13554   DONE;
13557 (define_insn "prefetch"
13558   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13559              (match_operand:SI 1 "const_int_operand" "n")
13560              (match_operand:SI 2 "const_int_operand" "n"))]
13561   ""
13562   "*
13564   if (GET_CODE (operands[0]) == REG)
13565     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13566   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13568   [(set_attr "type" "load")])
13570 ;; Handle -fsplit-stack.
13572 (define_expand "split_stack_prologue"
13573   [(const_int 0)]
13574   ""
13576   rs6000_expand_split_stack_prologue ();
13577   DONE;
13580 (define_expand "load_split_stack_limit"
13581   [(set (match_operand 0)
13582         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13583   ""
13585   emit_insn (gen_rtx_SET (operands[0],
13586                           gen_rtx_UNSPEC (Pmode,
13587                                           gen_rtvec (1, const0_rtx),
13588                                           UNSPEC_STACK_CHECK)));
13589   DONE;
13592 (define_insn "load_split_stack_limit_di"
13593   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13594         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13595   "TARGET_64BIT"
13596   "ld %0,-0x7040(13)"
13597   [(set_attr "type" "load")
13598    (set_attr "update" "no")
13599    (set_attr "indexed" "no")])
13601 (define_insn "load_split_stack_limit_si"
13602   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13603         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13604   "!TARGET_64BIT"
13605   "lwz %0,-0x7020(2)"
13606   [(set_attr "type" "load")
13607    (set_attr "update" "no")
13608    (set_attr "indexed" "no")])
13610 ;; A return instruction which the middle-end doesn't see.
13611 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13612 ;; after the call to __morestack.
13613 (define_insn "split_stack_return"
13614   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13615   ""
13616   "blr"
13617   [(set_attr "type" "jmpreg")])
13619 ;; If there are operand 0 bytes available on the stack, jump to
13620 ;; operand 1.
13621 (define_expand "split_stack_space_check"
13622   [(set (match_dup 2)
13623         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13624    (set (match_dup 3)
13625         (minus (reg STACK_POINTER_REGNUM)
13626                (match_operand 0)))
13627    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13628    (set (pc) (if_then_else
13629               (geu (match_dup 4) (const_int 0))
13630               (label_ref (match_operand 1))
13631               (pc)))]
13632   ""
13634   rs6000_split_stack_space_check (operands[0], operands[1]);
13635   DONE;
13638 (define_insn "bpermd_<mode>"
13639   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13640         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13641                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13642   "TARGET_POPCNTD"
13643   "bpermd %0,%1,%2"
13644   [(set_attr "type" "popcnt")])
13647 ;; Builtin fma support.  Handle 
13648 ;; Note that the conditions for expansion are in the FMA_F iterator.
13650 (define_expand "fma<mode>4"
13651   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13652         (fma:FMA_F
13653           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13654           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13655           (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13656   ""
13657   "")
13659 (define_insn "*fma<mode>4_fpr"
13660   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13661         (fma:SFDF
13662           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13663           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13664           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13665   "TARGET_<MODE>_FPR"
13666   "@
13667    fmadd<Ftrad> %0,%1,%2,%3
13668    xsmadda<Fvsx> %x0,%x1,%x2
13669    xsmaddm<Fvsx> %x0,%x1,%x3"
13670   [(set_attr "type" "fp")
13671    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13673 ; Altivec only has fma and nfms.
13674 (define_expand "fms<mode>4"
13675   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13676         (fma:FMA_F
13677           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13678           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13679           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13680   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13681   "")
13683 (define_insn "*fms<mode>4_fpr"
13684   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13685         (fma:SFDF
13686          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13687          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13688          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13689   "TARGET_<MODE>_FPR"
13690   "@
13691    fmsub<Ftrad> %0,%1,%2,%3
13692    xsmsuba<Fvsx> %x0,%x1,%x2
13693    xsmsubm<Fvsx> %x0,%x1,%x3"
13694   [(set_attr "type" "fp")
13695    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13697 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13698 (define_expand "fnma<mode>4"
13699   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13700         (neg:FMA_F
13701           (fma:FMA_F
13702             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13703             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13704             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13705   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13706   "")
13708 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13709 (define_expand "fnms<mode>4"
13710   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13711         (neg:FMA_F
13712           (fma:FMA_F
13713             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13714             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13715             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13716   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13717   "")
13719 ; Not an official optab name, but used from builtins.
13720 (define_expand "nfma<mode>4"
13721   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13722         (neg:FMA_F
13723           (fma:FMA_F
13724             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13725             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13726             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13727   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13728   "")
13730 (define_insn "*nfma<mode>4_fpr"
13731   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13732         (neg:SFDF
13733          (fma:SFDF
13734           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13735           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13736           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13737   "TARGET_<MODE>_FPR"
13738   "@
13739    fnmadd<Ftrad> %0,%1,%2,%3
13740    xsnmadda<Fvsx> %x0,%x1,%x2
13741    xsnmaddm<Fvsx> %x0,%x1,%x3"
13742   [(set_attr "type" "fp")
13743    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13745 ; Not an official optab name, but used from builtins.
13746 (define_expand "nfms<mode>4"
13747   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13748         (neg:FMA_F
13749           (fma:FMA_F
13750             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13751             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13752             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13753   ""
13754   "")
13756 (define_insn "*nfmssf4_fpr"
13757   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13758         (neg:SFDF
13759          (fma:SFDF
13760           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13761           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13762           (neg:SFDF
13763            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13764   "TARGET_<MODE>_FPR"
13765   "@
13766    fnmsub<Ftrad> %0,%1,%2,%3
13767    xsnmsuba<Fvsx> %x0,%x1,%x2
13768    xsnmsubm<Fvsx> %x0,%x1,%x3"
13769   [(set_attr "type" "fp")
13770    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13773 (define_expand "rs6000_get_timebase"
13774   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13775   ""
13777   if (TARGET_POWERPC64)
13778     emit_insn (gen_rs6000_mftb_di (operands[0]));
13779   else
13780     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13781   DONE;
13784 (define_insn "rs6000_get_timebase_ppc32"
13785   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13786         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13787    (clobber (match_scratch:SI 1 "=r"))
13788    (clobber (match_scratch:CC 2 "=y"))]
13789   "!TARGET_POWERPC64"
13791   if (WORDS_BIG_ENDIAN)
13792     if (TARGET_MFCRF)
13793       {
13794         return "mfspr %0,269\;"
13795                "mfspr %L0,268\;"
13796                "mfspr %1,269\;"
13797                "cmpw %2,%0,%1\;"
13798                "bne- %2,$-16";
13799       }
13800     else
13801       {
13802         return "mftbu %0\;"
13803                "mftb %L0\;"
13804                "mftbu %1\;"
13805                "cmpw %2,%0,%1\;"
13806                "bne- %2,$-16";
13807       }
13808   else
13809     if (TARGET_MFCRF)
13810       {
13811         return "mfspr %L0,269\;"
13812                "mfspr %0,268\;"
13813                "mfspr %1,269\;"
13814                "cmpw %2,%L0,%1\;"
13815                "bne- %2,$-16";
13816       }
13817     else
13818       {
13819         return "mftbu %L0\;"
13820                "mftb %0\;"
13821                "mftbu %1\;"
13822                "cmpw %2,%L0,%1\;"
13823                "bne- %2,$-16";
13824       }
13826   [(set_attr "length" "20")])
13828 (define_insn "rs6000_mftb_<mode>"
13829   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13830         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13831   ""
13833   if (TARGET_MFCRF)
13834     return "mfspr %0,268";
13835   else
13836     return "mftb %0";
13840 (define_insn "rs6000_mffs"
13841   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13842         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13843   "TARGET_HARD_FLOAT && TARGET_FPRS"
13844   "mffs %0")
13846 (define_insn "rs6000_mtfsf"
13847   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13848                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13849                     UNSPECV_MTFSF)]
13850   "TARGET_HARD_FLOAT && TARGET_FPRS"
13851   "mtfsf %0,%1")
13854 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13855 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13856 ;; register that is being loaded.  The fused ops must be physically adjacent.
13858 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13859 ;; before register allocation, and is meant to reduce the lifetime for the
13860 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13861 ;; to use the register that is being load.  The peephole2 then gathers any
13862 ;; other fused possibilities that it can find after register allocation.  If
13863 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13865 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13866 ;; before register allocation, so that we can avoid allocating a temporary base
13867 ;; register that won't be used, and that we try to load into base registers,
13868 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13869 ;; (addis followed by load) even on power8.
13871 (define_split
13872   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13873         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13874   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13875   [(parallel [(set (match_dup 0) (match_dup 2))
13876               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13877               (use (match_dup 3))
13878               (clobber (scratch:DI))])]
13880   operands[2] = fusion_wrap_memory_address (operands[1]);
13881   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13884 (define_insn "*toc_fusionload_<mode>"
13885   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13886         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13887    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13888    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13889    (clobber (match_scratch:DI 3 "=X,&b"))]
13890   "TARGET_TOC_FUSION_INT"
13892   if (base_reg_operand (operands[0], <MODE>mode))
13893     return emit_fusion_gpr_load (operands[0], operands[1]);
13895   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13897   [(set_attr "type" "load")
13898    (set_attr "length" "8")])
13900 (define_insn "*toc_fusionload_di"
13901   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13902         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13903    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13904    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13905    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13906   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13907    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13909   if (base_reg_operand (operands[0], DImode))
13910     return emit_fusion_gpr_load (operands[0], operands[1]);
13912   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13914   [(set_attr "type" "load")
13915    (set_attr "length" "8")])
13918 ;; Find cases where the addis that feeds into a load instruction is either used
13919 ;; once or is the same as the target register, and replace it with the fusion
13920 ;; insn
13922 (define_peephole2
13923   [(set (match_operand:P 0 "base_reg_operand" "")
13924         (match_operand:P 1 "fusion_gpr_addis" ""))
13925    (set (match_operand:INT1 2 "base_reg_operand" "")
13926         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13927   "TARGET_P8_FUSION
13928    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13929                          operands[3])"
13930   [(const_int 0)]
13932   expand_fusion_gpr_load (operands);
13933   DONE;
13936 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13937 ;; reload)
13939 (define_insn "fusion_gpr_load_<mode>"
13940   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13941         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13942                      UNSPEC_FUSION_GPR))]
13943   "TARGET_P8_FUSION"
13945   return emit_fusion_gpr_load (operands[0], operands[1]);
13947   [(set_attr "type" "load")
13948    (set_attr "length" "8")])
13951 ;; ISA 3.0 (power9) fusion support
13952 ;; Merge addis with floating load/store to FPRs (or GPRs).
13953 (define_peephole2
13954   [(set (match_operand:P 0 "base_reg_operand" "")
13955         (match_operand:P 1 "fusion_gpr_addis" ""))
13956    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13957         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13958   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13959    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13960   [(const_int 0)]
13962   expand_fusion_p9_load (operands);
13963   DONE;
13966 (define_peephole2
13967   [(set (match_operand:P 0 "base_reg_operand" "")
13968         (match_operand:P 1 "fusion_gpr_addis" ""))
13969    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13970         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13971   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13972    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13973    && !rtx_equal_p (operands[0], operands[3])"
13974   [(const_int 0)]
13976   expand_fusion_p9_store (operands);
13977   DONE;
13980 (define_peephole2
13981   [(set (match_operand:SDI 0 "int_reg_operand" "")
13982         (match_operand:SDI 1 "upper16_cint_operand" ""))
13983    (set (match_dup 0)
13984         (ior:SDI (match_dup 0)
13985                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
13986   "TARGET_P9_FUSION"
13987   [(set (match_dup 0)
13988         (unspec:SDI [(match_dup 1)
13989                      (match_dup 2)] UNSPEC_FUSION_P9))])
13991 (define_peephole2
13992   [(set (match_operand:SDI 0 "int_reg_operand" "")
13993         (match_operand:SDI 1 "upper16_cint_operand" ""))
13994    (set (match_operand:SDI 2 "int_reg_operand" "")
13995         (ior:SDI (match_dup 0)
13996                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
13997   "TARGET_P9_FUSION
13998    && !rtx_equal_p (operands[0], operands[2])
13999    && peep2_reg_dead_p (2, operands[0])"
14000   [(set (match_dup 2)
14001         (unspec:SDI [(match_dup 1)
14002                      (match_dup 3)] UNSPEC_FUSION_P9))])
14004 ;; Fusion insns, created by the define_peephole2 above (and eventually by
14005 ;; reload).  Because we want to eventually have secondary_reload generate
14006 ;; these, they have to have a single alternative that gives the register
14007 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
14008 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
14009   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
14010         (unspec:GPR_FUSION
14011          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14012          UNSPEC_FUSION_P9))
14013    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14014   "TARGET_P9_FUSION"
14016   /* This insn is a secondary reload insn, which cannot have alternatives.
14017      If we are not loading up register 0, use the power8 fusion instead.  */
14018   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
14019     return emit_fusion_gpr_load (operands[0], operands[1]);
14021   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14023   [(set_attr "type" "load")
14024    (set_attr "length" "8")])
14026 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
14027   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14028         (unspec:GPR_FUSION
14029          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
14030          UNSPEC_FUSION_P9))
14031    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14032   "TARGET_P9_FUSION"
14034   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14036   [(set_attr "type" "store")
14037    (set_attr "length" "8")])
14039 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
14040   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
14041         (unspec:FPR_FUSION
14042          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14043          UNSPEC_FUSION_P9))
14044    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14045   "TARGET_P9_FUSION"
14047   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14049   [(set_attr "type" "fpload")
14050    (set_attr "length" "8")])
14052 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
14053   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14054         (unspec:FPR_FUSION
14055          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
14056          UNSPEC_FUSION_P9))
14057    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14058   "TARGET_P9_FUSION"
14060   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14062   [(set_attr "type" "fpstore")
14063    (set_attr "length" "8")])
14065 (define_insn "*fusion_p9_<mode>_constant"
14066   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
14067         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
14068                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
14069                     UNSPEC_FUSION_P9))] 
14070   "TARGET_P9_FUSION"
14072   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
14073   return "ori %0,%0,%2";
14075   [(set_attr "type" "two")
14076    (set_attr "length" "8")])
14079 ;; Miscellaneous ISA 2.06 (power7) instructions
14080 (define_insn "addg6s"
14081   [(set (match_operand:SI 0 "register_operand" "=r")
14082         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14083                     (match_operand:SI 2 "register_operand" "r")]
14084                    UNSPEC_ADDG6S))]
14085   "TARGET_POPCNTD"
14086   "addg6s %0,%1,%2"
14087   [(set_attr "type" "integer")
14088    (set_attr "length" "4")])
14090 (define_insn "cdtbcd"
14091   [(set (match_operand:SI 0 "register_operand" "=r")
14092         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14093                    UNSPEC_CDTBCD))]
14094   "TARGET_POPCNTD"
14095   "cdtbcd %0,%1"
14096   [(set_attr "type" "integer")
14097    (set_attr "length" "4")])
14099 (define_insn "cbcdtd"
14100   [(set (match_operand:SI 0 "register_operand" "=r")
14101         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14102                    UNSPEC_CBCDTD))]
14103   "TARGET_POPCNTD"
14104   "cbcdtd %0,%1"
14105   [(set_attr "type" "integer")
14106    (set_attr "length" "4")])
14108 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14109                                         UNSPEC_DIVEO
14110                                         UNSPEC_DIVEU
14111                                         UNSPEC_DIVEUO])
14113 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
14114                              (UNSPEC_DIVEO      "eo")
14115                              (UNSPEC_DIVEU      "eu")
14116                              (UNSPEC_DIVEUO     "euo")])
14118 (define_insn "div<div_extend>_<mode>"
14119   [(set (match_operand:GPR 0 "register_operand" "=r")
14120         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14121                      (match_operand:GPR 2 "register_operand" "r")]
14122                     UNSPEC_DIV_EXTEND))]
14123   "TARGET_POPCNTD"
14124   "div<wd><div_extend> %0,%1,%2"
14125   [(set_attr "type" "div")
14126    (set_attr "size" "<bits>")])
14129 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14131 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14132 (define_mode_attr FP128_64 [(TF "DF")
14133                             (IF "DF")
14134                             (TD "DI")
14135                             (KF "DI")])
14137 (define_expand "unpack<mode>"
14138   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14139         (unspec:<FP128_64>
14140          [(match_operand:FMOVE128 1 "register_operand" "")
14141           (match_operand:QI 2 "const_0_to_1_operand" "")]
14142          UNSPEC_UNPACK_128BIT))]
14143   "FLOAT128_2REG_P (<MODE>mode)"
14144   "")
14146 (define_insn_and_split "unpack<mode>_dm"
14147   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14148         (unspec:<FP128_64>
14149          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14150           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14151          UNSPEC_UNPACK_128BIT))]
14152   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14153   "#"
14154   "&& reload_completed"
14155   [(set (match_dup 0) (match_dup 3))]
14157   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14159   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14160     {
14161       emit_note (NOTE_INSN_DELETED);
14162       DONE;
14163     }
14165   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14167   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14168    (set_attr "length" "4")])
14170 (define_insn_and_split "unpack<mode>_nodm"
14171   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14172         (unspec:<FP128_64>
14173          [(match_operand:FMOVE128 1 "register_operand" "d,d")
14174           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14175          UNSPEC_UNPACK_128BIT))]
14176   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14177   "#"
14178   "&& reload_completed"
14179   [(set (match_dup 0) (match_dup 3))]
14181   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14183   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14184     {
14185       emit_note (NOTE_INSN_DELETED);
14186       DONE;
14187     }
14189   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14191   [(set_attr "type" "fp,fpstore")
14192    (set_attr "length" "4")])
14194 (define_insn_and_split "pack<mode>"
14195   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14196         (unspec:FMOVE128
14197          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14198           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14199          UNSPEC_PACK_128BIT))]
14200   "FLOAT128_2REG_P (<MODE>mode)"
14201   "@
14202    fmr %L0,%2
14203    #"
14204   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14205   [(set (match_dup 3) (match_dup 1))
14206    (set (match_dup 4) (match_dup 2))]
14208   unsigned dest_hi = REGNO (operands[0]);
14209   unsigned dest_lo = dest_hi + 1;
14211   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14212   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14214   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14215   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14217   [(set_attr "type" "fpsimple,fp")
14218    (set_attr "length" "4,8")])
14220 (define_insn "unpack<mode>"
14221   [(set (match_operand:DI 0 "register_operand" "=d,d")
14222         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14223                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14224          UNSPEC_UNPACK_128BIT))]
14225   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14227   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14228     return ASM_COMMENT_START " xxpermdi to same register";
14230   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14231   return "xxpermdi %x0,%x1,%x1,%3";
14233   [(set_attr "type" "vecperm")])
14235 (define_insn "pack<mode>"
14236   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14237         (unspec:FMOVE128_VSX
14238          [(match_operand:DI 1 "register_operand" "d")
14239           (match_operand:DI 2 "register_operand" "d")]
14240          UNSPEC_PACK_128BIT))]
14241   "TARGET_VSX"
14242   "xxpermdi %x0,%x1,%x2,0"
14243   [(set_attr "type" "vecperm")])
14247 ;; ISA 2.08 IEEE 128-bit floating point support.
14249 (define_insn "add<mode>3"
14250   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14251         (plus:IEEE128
14252          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14253          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14254   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14255   "xsaddqp %0,%1,%2"
14256   [(set_attr "type" "vecfloat")
14257    (set_attr "size" "128")])
14259 (define_insn "sub<mode>3"
14260   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14261         (minus:IEEE128
14262          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14263          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14264   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14265   "xssubqp %0,%1,%2"
14266   [(set_attr "type" "vecfloat")
14267    (set_attr "size" "128")])
14269 (define_insn "mul<mode>3"
14270   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14271         (mult:IEEE128
14272          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14273          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14274   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14275   "xsmulqp %0,%1,%2"
14276   [(set_attr "type" "vecfloat")
14277    (set_attr "size" "128")])
14279 (define_insn "div<mode>3"
14280   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14281         (div:IEEE128
14282          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14283          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14284   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14285   "xsdivqp %0,%1,%2"
14286   [(set_attr "type" "vecdiv")
14287    (set_attr "size" "128")])
14289 (define_insn "sqrt<mode>2"
14290   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14291         (sqrt:IEEE128
14292          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14293   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14294    "xssqrtqp %0,%1"
14295   [(set_attr "type" "vecdiv")
14296    (set_attr "size" "128")])
14298 (define_expand "copysign<mode>3"
14299   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14300    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14301    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14302   "FLOAT128_IEEE_P (<MODE>mode)"
14304   if (TARGET_FLOAT128_HW)
14305     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14306                                          operands[2]));
14307   else
14308     {
14309       rtx tmp = gen_reg_rtx (<MODE>mode);
14310       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14311                                            operands[2], tmp));
14312     }
14313   DONE;
14316 (define_insn "copysign<mode>3_hard"
14317   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14318         (unspec:IEEE128
14319          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14320           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14321          UNSPEC_COPYSIGN))]
14322   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14323    "xscpsgnqp %0,%2,%1"
14324   [(set_attr "type" "vecmove")
14325    (set_attr "size" "128")])
14327 (define_insn "copysign<mode>3_soft"
14328   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14329         (unspec:IEEE128
14330          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14331           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14332           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14333          UNSPEC_COPYSIGN))]
14334   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14335    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14336   [(set_attr "type" "veccomplex")
14337    (set_attr "length" "8")])
14339 (define_insn "neg<mode>2_hw"
14340   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14341         (neg:IEEE128
14342          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14343   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14344   "xsnegqp %0,%1"
14345   [(set_attr "type" "vecmove")
14346    (set_attr "size" "128")])
14349 (define_insn "abs<mode>2_hw"
14350   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14351         (abs:IEEE128
14352          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14353   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14354   "xsabsqp %0,%1"
14355   [(set_attr "type" "vecmove")
14356    (set_attr "size" "128")])
14359 (define_insn "*nabs<mode>2_hw"
14360   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14361         (neg:IEEE128
14362          (abs:IEEE128
14363           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14364   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14365   "xsnabsqp %0,%1"
14366   [(set_attr "type" "vecmove")
14367    (set_attr "size" "128")])
14369 ;; Initially don't worry about doing fusion
14370 (define_insn "*fma<mode>4_hw"
14371   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14372         (fma:IEEE128
14373          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14374          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14375          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14376   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14377   "xsmaddqp %0,%1,%2"
14378   [(set_attr "type" "vecfloat")
14379    (set_attr "size" "128")])
14381 (define_insn "*fms<mode>4_hw"
14382   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14383         (fma:IEEE128
14384          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14385          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14386          (neg:IEEE128
14387           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14388   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14389   "xsmsubqp %0,%1,%2"
14390   [(set_attr "type" "vecfloat")
14391    (set_attr "size" "128")])
14393 (define_insn "*nfma<mode>4_hw"
14394   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14395         (neg:IEEE128
14396          (fma:IEEE128
14397           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14398           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14399           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14400   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14401   "xsnmaddqp %0,%1,%2"
14402   [(set_attr "type" "vecfloat")
14403    (set_attr "size" "128")])
14405 (define_insn "*nfms<mode>4_hw"
14406   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14407         (neg:IEEE128
14408          (fma:IEEE128
14409           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14410           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14411           (neg:IEEE128
14412            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14413   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14414   "xsnmsubqp %0,%1,%2"
14415   [(set_attr "type" "vecfloat")
14416    (set_attr "size" "128")])
14418 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14419   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14420         (float_extend:IEEE128
14421          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14422   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14423   "xscvdpqp %0,%1"
14424   [(set_attr "type" "vecfloat")
14425    (set_attr "size" "128")])
14427 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14428 ;; point is a simple copy.
14429 (define_insn_and_split "extendkftf2"
14430   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14431         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14432   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14433   "@
14434    #
14435    xxlor %x0,%x1,%x1"
14436   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14437   [(const_int 0)]
14439   emit_note (NOTE_INSN_DELETED);
14440   DONE;
14442   [(set_attr "type" "*,veclogical")
14443    (set_attr "length" "0,4")])
14445 (define_insn_and_split "trunctfkf2"
14446   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14447         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14448   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14449   "@
14450    #
14451    xxlor %x0,%x1,%x1"
14452   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14453   [(const_int 0)]
14455   emit_note (NOTE_INSN_DELETED);
14456   DONE;
14458   [(set_attr "type" "*,veclogical")
14459    (set_attr "length" "0,4")])
14461 (define_insn "trunc<mode>df2_hw"
14462   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14463         (float_truncate:DF
14464          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14465   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14466   "xscvqpdp %0,%1"
14467   [(set_attr "type" "vecfloat")
14468    (set_attr "size" "128")])
14470 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14471 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14472 ;; conversion
14473 (define_insn_and_split "trunc<mode>sf2_hw"
14474   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14475         (float_truncate:SF
14476          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14477    (clobber (match_scratch:DF 2 "=v"))]
14478   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14479   "#"
14480   "&& 1"
14481   [(set (match_dup 2)
14482         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14483    (set (match_dup 0)
14484         (float_truncate:SF (match_dup 2)))]
14486   if (GET_CODE (operands[2]) == SCRATCH)
14487     operands[2] = gen_reg_rtx (DFmode);
14489   [(set_attr "type" "vecfloat")
14490    (set_attr "length" "8")])
14492 ;; Conversion between IEEE 128-bit and integer types
14493 (define_insn "fix_<mode>di2_hw"
14494   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14495         (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14496   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14497   "xscvqpsdz %0,%1"
14498   [(set_attr "type" "vecfloat")
14499    (set_attr "size" "128")])
14501 (define_insn "fixuns_<mode>di2_hw"
14502   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14503         (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14504   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14505   "xscvqpudz %0,%1"
14506   [(set_attr "type" "vecfloat")
14507    (set_attr "size" "128")])
14509 (define_insn "fix_<mode>si2_hw"
14510   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14511         (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14512   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14513   "xscvqpswz %0,%1"
14514   [(set_attr "type" "vecfloat")
14515    (set_attr "size" "128")])
14517 (define_insn "fixuns_<mode>si2_hw"
14518   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14519         (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14520   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14521   "xscvqpuwz %0,%1"
14522   [(set_attr "type" "vecfloat")
14523    (set_attr "size" "128")])
14525 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14526 ;; floating point value to 32-bit integer to GPR in order to save it.
14527 (define_insn_and_split "*fix<uns>_<mode>_mem"
14528   [(set (match_operand:SI 0 "memory_operand" "=Z")
14529         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14530    (clobber (match_scratch:SI 2 "=v"))]
14531   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14532   "#"
14533   "&& reload_completed"
14534   [(set (match_dup 2)
14535         (any_fix:SI (match_dup 1)))
14536    (set (match_dup 0)
14537         (match_dup 2))])
14539 (define_insn "float_<mode>di2_hw"
14540   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14541         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14542   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14543   "xscvsdqp %0,%1"
14544   [(set_attr "type" "vecfloat")
14545    (set_attr "size" "128")])
14547 (define_insn_and_split "float_<mode>si2_hw"
14548   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14549         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14550    (clobber (match_scratch:DI 2 "=v"))]
14551   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14552   "#"
14553   "&& 1"
14554   [(set (match_dup 2)
14555         (sign_extend:DI (match_dup 1)))
14556    (set (match_dup 0)
14557         (float:IEEE128 (match_dup 2)))]
14559   if (GET_CODE (operands[2]) == SCRATCH)
14560     operands[2] = gen_reg_rtx (DImode);
14563 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14564   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14565         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14566    (clobber (match_scratch:DI 2 "=X,r,X"))]
14567   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14568   "#"
14569   "&& reload_completed"
14570   [(const_int 0)]
14572   rtx dest = operands[0];
14573   rtx src = operands[1];
14574   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14576   if (altivec_register_operand (src, <QHI:MODE>mode))
14577     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14578   else if (int_reg_operand (src, <QHI:MODE>mode))
14579     {
14580       rtx ext_di = operands[2];
14581       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14582       emit_move_insn (dest_di, ext_di);
14583     }
14584   else if (MEM_P (src))
14585     {
14586       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14587       emit_move_insn (dest_qhi, src);
14588       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14589     }
14590   else
14591     gcc_unreachable ();
14593   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14594   DONE;
14596   [(set_attr "length" "8,12,12")
14597    (set_attr "type" "vecfloat")
14598    (set_attr "size" "128")])
14600 (define_insn "floatuns_<mode>di2_hw"
14601   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14602         (unsigned_float:IEEE128
14603          (match_operand:DI 1 "altivec_register_operand" "v")))]
14604   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14605   "xscvudqp %0,%1"
14606   [(set_attr "type" "vecfloat")
14607    (set_attr "size" "128")])
14609 (define_insn_and_split "floatuns_<mode>si2_hw"
14610   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14611         (unsigned_float:IEEE128
14612          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14613    (clobber (match_scratch:DI 2 "=v"))]
14614   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14615   "#"
14616   "&& 1"
14617   [(set (match_dup 2)
14618         (zero_extend:DI (match_dup 1)))
14619    (set (match_dup 0)
14620         (float:IEEE128 (match_dup 2)))]
14622   if (GET_CODE (operands[2]) == SCRATCH)
14623     operands[2] = gen_reg_rtx (DImode);
14626 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14627   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14628         (unsigned_float:IEEE128
14629          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14630    (clobber (match_scratch:DI 2 "=X,r,X"))]
14631   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14632   "#"
14633   "&& reload_completed"
14634   [(const_int 0)]
14636   rtx dest = operands[0];
14637   rtx src = operands[1];
14638   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14640   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14641     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14642   else if (int_reg_operand (src, <QHI:MODE>mode))
14643     {
14644       rtx ext_di = operands[2];
14645       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14646       emit_move_insn (dest_di, ext_di);
14647     }
14648   else
14649     gcc_unreachable ();
14651   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14652   DONE;
14654   [(set_attr "length" "8,12,8")
14655    (set_attr "type" "vecfloat")
14656    (set_attr "size" "128")])
14658 ;; IEEE 128-bit instructions with round to odd semantics
14659 (define_insn "*trunc<mode>df2_odd"
14660   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14661         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14662                    UNSPEC_ROUND_TO_ODD))]
14663   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14664   "xscvqpdpo %0,%1"
14665   [(set_attr "type" "vecfloat")
14666    (set_attr "size" "128")])
14668 ;; IEEE 128-bit comparisons
14669 (define_insn "*cmp<mode>_hw"
14670   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14671         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14672                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14673   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14674    "xscmpuqp %0,%1,%2"
14675   [(set_attr "type" "veccmp")
14676    (set_attr "size" "128")])
14680 (include "sync.md")
14681 (include "vector.md")
14682 (include "vsx.md")
14683 (include "altivec.md")
14684 (include "spe.md")
14685 (include "dfp.md")
14686 (include "paired.md")
14687 (include "crypto.md")
14688 (include "htm.md")