[rs6000] Use gen_int_mode in ieee_128bit_negative_zero
[official-gcc.git] / gcc / config / powerpcspe / powerpcspe.md
blobdf93f6d343fbd1428a9dae822886d6302888ef49
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")])
704 ;; Iterator to optimize the following cases:
705 ;;      D-form load to FPR register & move to Altivec register
706 ;;      Move Altivec register to FPR register and store
707 (define_mode_iterator ALTIVEC_DFORM [DI DF SF])
710 ;; Start with fixed-point load and store insns.  Here we put only the more
711 ;; complex forms.  Basic data transfer is done later.
713 (define_insn "zero_extendqi<mode>2"
714   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
715         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
716   ""
717   "@
718    lbz%U1%X1 %0,%1
719    rlwinm %0,%1,0,0xff
720    lxsibzx %x0,%y1
721    vextractub %0,%1,7"
722   [(set_attr "type" "load,shift,fpload,vecperm")])
724 (define_insn_and_split "*zero_extendqi<mode>2_dot"
725   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
726         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
727                     (const_int 0)))
728    (clobber (match_scratch:EXTQI 0 "=r,r"))]
729   "rs6000_gen_cell_microcode"
730   "@
731    andi. %0,%1,0xff
732    #"
733   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
734   [(set (match_dup 0)
735         (zero_extend:EXTQI (match_dup 1)))
736    (set (match_dup 2)
737         (compare:CC (match_dup 0)
738                     (const_int 0)))]
739   ""
740   [(set_attr "type" "logical")
741    (set_attr "dot" "yes")
742    (set_attr "length" "4,8")])
744 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
745   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
746         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
747                     (const_int 0)))
748    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
749         (zero_extend:EXTQI (match_dup 1)))]
750   "rs6000_gen_cell_microcode"
751   "@
752    andi. %0,%1,0xff
753    #"
754   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
755   [(set (match_dup 0)
756         (zero_extend:EXTQI (match_dup 1)))
757    (set (match_dup 2)
758         (compare:CC (match_dup 0)
759                     (const_int 0)))]
760   ""
761   [(set_attr "type" "logical")
762    (set_attr "dot" "yes")
763    (set_attr "length" "4,8")])
766 (define_insn "zero_extendhi<mode>2"
767   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
768         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
769   ""
770   "@
771    lhz%U1%X1 %0,%1
772    rlwinm %0,%1,0,0xffff
773    lxsihzx %x0,%y1
774    vextractuh %0,%1,6"
775   [(set_attr "type" "load,shift,fpload,vecperm")])
777 (define_insn_and_split "*zero_extendhi<mode>2_dot"
778   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
779         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
780                     (const_int 0)))
781    (clobber (match_scratch:EXTHI 0 "=r,r"))]
782   "rs6000_gen_cell_microcode"
783   "@
784    andi. %0,%1,0xffff
785    #"
786   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
787   [(set (match_dup 0)
788         (zero_extend:EXTHI (match_dup 1)))
789    (set (match_dup 2)
790         (compare:CC (match_dup 0)
791                     (const_int 0)))]
792   ""
793   [(set_attr "type" "logical")
794    (set_attr "dot" "yes")
795    (set_attr "length" "4,8")])
797 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
798   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
799         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
800                     (const_int 0)))
801    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
802         (zero_extend:EXTHI (match_dup 1)))]
803   "rs6000_gen_cell_microcode"
804   "@
805    andi. %0,%1,0xffff
806    #"
807   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
808   [(set (match_dup 0)
809         (zero_extend:EXTHI (match_dup 1)))
810    (set (match_dup 2)
811         (compare:CC (match_dup 0)
812                     (const_int 0)))]
813   ""
814   [(set_attr "type" "logical")
815    (set_attr "dot" "yes")
816    (set_attr "length" "4,8")])
819 (define_insn "zero_extendsi<mode>2"
820   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
821         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
822   ""
823   "@
824    lwz%U1%X1 %0,%1
825    rldicl %0,%1,0,32
826    lfiwzx %0,%y1
827    lxsiwzx %x0,%y1
828    mtvsrwz %x0,%1
829    mfvsrwz %0,%x1
830    xxextractuw %x0,%x1,4"
831   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
833 (define_insn_and_split "*zero_extendsi<mode>2_dot"
834   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
835         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
836                     (const_int 0)))
837    (clobber (match_scratch:EXTSI 0 "=r,r"))]
838   "rs6000_gen_cell_microcode"
839   "@
840    rldicl. %0,%1,0,32
841    #"
842   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
843   [(set (match_dup 0)
844         (zero_extend:DI (match_dup 1)))
845    (set (match_dup 2)
846         (compare:CC (match_dup 0)
847                     (const_int 0)))]
848   ""
849   [(set_attr "type" "shift")
850    (set_attr "dot" "yes")
851    (set_attr "length" "4,8")])
853 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
854   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
855         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
856                     (const_int 0)))
857    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
858         (zero_extend:EXTSI (match_dup 1)))]
859   "rs6000_gen_cell_microcode"
860   "@
861    rldicl. %0,%1,0,32
862    #"
863   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
864   [(set (match_dup 0)
865         (zero_extend:EXTSI (match_dup 1)))
866    (set (match_dup 2)
867         (compare:CC (match_dup 0)
868                     (const_int 0)))]
869   ""
870   [(set_attr "type" "shift")
871    (set_attr "dot" "yes")
872    (set_attr "length" "4,8")])
875 (define_insn "extendqi<mode>2"
876   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
877         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
878   ""
879   "@
880    extsb %0,%1
881    vextsb2d %0,%1"
882   [(set_attr "type" "exts,vecperm")])
884 (define_insn_and_split "*extendqi<mode>2_dot"
885   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
886         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
887                     (const_int 0)))
888    (clobber (match_scratch:EXTQI 0 "=r,r"))]
889   "rs6000_gen_cell_microcode"
890   "@
891    extsb. %0,%1
892    #"
893   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
894   [(set (match_dup 0)
895         (sign_extend:EXTQI (match_dup 1)))
896    (set (match_dup 2)
897         (compare:CC (match_dup 0)
898                     (const_int 0)))]
899   ""
900   [(set_attr "type" "exts")
901    (set_attr "dot" "yes")
902    (set_attr "length" "4,8")])
904 (define_insn_and_split "*extendqi<mode>2_dot2"
905   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
906         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
907                     (const_int 0)))
908    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
909         (sign_extend:EXTQI (match_dup 1)))]
910   "rs6000_gen_cell_microcode"
911   "@
912    extsb. %0,%1
913    #"
914   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
915   [(set (match_dup 0)
916         (sign_extend:EXTQI (match_dup 1)))
917    (set (match_dup 2)
918         (compare:CC (match_dup 0)
919                     (const_int 0)))]
920   ""
921   [(set_attr "type" "exts")
922    (set_attr "dot" "yes")
923    (set_attr "length" "4,8")])
926 (define_expand "extendhi<mode>2"
927   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
928         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
929   ""
930   "")
932 (define_insn "*extendhi<mode>2"
933   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
934         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
935   "rs6000_gen_cell_microcode || TARGET_VSX_SMALL_INTEGER"
936   "@
937    lha%U1%X1 %0,%1
938    extsh %0,%1
939    #
940    vextsh2d %0,%1"
941   [(set_attr "type" "load,exts,fpload,vecperm")
942    (set_attr "sign_extend" "yes")
943    (set_attr "length" "4,4,8,4")])
945 (define_split
946   [(set (match_operand:EXTHI 0 "altivec_register_operand")
947         (sign_extend:EXTHI
948          (match_operand:HI 1 "indexed_or_indirect_operand")))]
949   "TARGET_P9_VECTOR && reload_completed"
950   [(set (match_dup 2)
951         (match_dup 1))
952    (set (match_dup 0)
953         (sign_extend:EXTHI (match_dup 2)))]
955   operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));
958 (define_insn "*extendhi<mode>2_noload"
959   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
960         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
961   "!rs6000_gen_cell_microcode"
962   "extsh %0,%1"
963   [(set_attr "type" "exts")])
965 (define_insn_and_split "*extendhi<mode>2_dot"
966   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
967         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
968                     (const_int 0)))
969    (clobber (match_scratch:EXTHI 0 "=r,r"))]
970   "rs6000_gen_cell_microcode"
971   "@
972    extsh. %0,%1
973    #"
974   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
975   [(set (match_dup 0)
976         (sign_extend:EXTHI (match_dup 1)))
977    (set (match_dup 2)
978         (compare:CC (match_dup 0)
979                     (const_int 0)))]
980   ""
981   [(set_attr "type" "exts")
982    (set_attr "dot" "yes")
983    (set_attr "length" "4,8")])
985 (define_insn_and_split "*extendhi<mode>2_dot2"
986   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
987         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
988                     (const_int 0)))
989    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
990         (sign_extend:EXTHI (match_dup 1)))]
991   "rs6000_gen_cell_microcode"
992   "@
993    extsh. %0,%1
994    #"
995   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
996   [(set (match_dup 0)
997         (sign_extend:EXTHI (match_dup 1)))
998    (set (match_dup 2)
999         (compare:CC (match_dup 0)
1000                     (const_int 0)))]
1001   ""
1002   [(set_attr "type" "exts")
1003    (set_attr "dot" "yes")
1004    (set_attr "length" "4,8")])
1007 (define_insn "extendsi<mode>2"
1008   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK,wH")
1009         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK,wH")))]
1010   ""
1011   "@
1012    lwa%U1%X1 %0,%1
1013    extsw %0,%1
1014    lfiwax %0,%y1
1015    lxsiwax %x0,%y1
1016    mtvsrwa %x0,%1
1017    vextsw2d %0,%1
1018    #"
1019   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm")
1020    (set_attr "sign_extend" "yes")
1021    (set_attr "length" "4,4,4,4,4,4,8")])
1023 (define_split
1024   [(set (match_operand:DI 0 "altivec_register_operand")
1025         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1026   "TARGET_VSX_SMALL_INTEGER && TARGET_P8_VECTOR && !TARGET_P9_VECTOR
1027    && reload_completed"
1028   [(const_int 0)]
1030   rtx dest = operands[0];
1031   rtx src = operands[1];
1032   int dest_regno = REGNO (dest);
1033   int src_regno = REGNO (src);
1034   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1035   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1037   if (VECTOR_ELT_ORDER_BIG)
1038     {
1039       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1040       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1041     }
1042   else
1043     {
1044       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1045       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1046     }
1047   DONE;
1050 (define_insn_and_split "*extendsi<mode>2_dot"
1051   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1052         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1053                     (const_int 0)))
1054    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1055   "rs6000_gen_cell_microcode"
1056   "@
1057    extsw. %0,%1
1058    #"
1059   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1060   [(set (match_dup 0)
1061         (sign_extend:EXTSI (match_dup 1)))
1062    (set (match_dup 2)
1063         (compare:CC (match_dup 0)
1064                     (const_int 0)))]
1065   ""
1066   [(set_attr "type" "exts")
1067    (set_attr "dot" "yes")
1068    (set_attr "length" "4,8")])
1070 (define_insn_and_split "*extendsi<mode>2_dot2"
1071   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1072         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1073                     (const_int 0)))
1074    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1075         (sign_extend:EXTSI (match_dup 1)))]
1076   "rs6000_gen_cell_microcode"
1077   "@
1078    extsw. %0,%1
1079    #"
1080   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1081   [(set (match_dup 0)
1082         (sign_extend:EXTSI (match_dup 1)))
1083    (set (match_dup 2)
1084         (compare:CC (match_dup 0)
1085                     (const_int 0)))]
1086   ""
1087   [(set_attr "type" "exts")
1088    (set_attr "dot" "yes")
1089    (set_attr "length" "4,8")])
1091 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1093 (define_insn "*macchwc"
1094   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1095         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1096                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1097                                        (const_int 16))
1098                                       (sign_extend:SI
1099                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1100                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1101                     (const_int 0)))
1102    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1103         (plus:SI (mult:SI (ashiftrt:SI
1104                            (match_dup 2)
1105                            (const_int 16))
1106                           (sign_extend:SI
1107                            (match_dup 1)))
1108                  (match_dup 4)))]
1109   "TARGET_MULHW"
1110   "macchw. %0,%1,%2"
1111   [(set_attr "type" "halfmul")])
1113 (define_insn "*macchw"
1114   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1115         (plus:SI (mult:SI (ashiftrt:SI
1116                            (match_operand:SI 2 "gpc_reg_operand" "r")
1117                            (const_int 16))
1118                           (sign_extend:SI
1119                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1120                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1121   "TARGET_MULHW"
1122   "macchw %0,%1,%2"
1123   [(set_attr "type" "halfmul")])
1125 (define_insn "*macchwuc"
1126   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1127         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1128                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1129                                        (const_int 16))
1130                                       (zero_extend:SI
1131                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1132                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1133                     (const_int 0)))
1134    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1135         (plus:SI (mult:SI (lshiftrt:SI
1136                            (match_dup 2)
1137                            (const_int 16))
1138                           (zero_extend:SI
1139                            (match_dup 1)))
1140                  (match_dup 4)))]
1141   "TARGET_MULHW"
1142   "macchwu. %0,%1,%2"
1143   [(set_attr "type" "halfmul")])
1145 (define_insn "*macchwu"
1146   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1147         (plus:SI (mult:SI (lshiftrt:SI
1148                            (match_operand:SI 2 "gpc_reg_operand" "r")
1149                            (const_int 16))
1150                           (zero_extend:SI
1151                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1152                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1153   "TARGET_MULHW"
1154   "macchwu %0,%1,%2"
1155   [(set_attr "type" "halfmul")])
1157 (define_insn "*machhwc"
1158   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1159         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1160                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1161                                        (const_int 16))
1162                                       (ashiftrt:SI
1163                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1164                                        (const_int 16)))
1165                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1166                     (const_int 0)))
1167    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1168         (plus:SI (mult:SI (ashiftrt:SI
1169                            (match_dup 1)
1170                            (const_int 16))
1171                           (ashiftrt:SI
1172                            (match_dup 2)
1173                            (const_int 16)))
1174                  (match_dup 4)))]
1175   "TARGET_MULHW"
1176   "machhw. %0,%1,%2"
1177   [(set_attr "type" "halfmul")])
1179 (define_insn "*machhw"
1180   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1181         (plus:SI (mult:SI (ashiftrt:SI
1182                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1183                            (const_int 16))
1184                           (ashiftrt:SI
1185                            (match_operand:SI 2 "gpc_reg_operand" "r")
1186                            (const_int 16)))
1187                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1188   "TARGET_MULHW"
1189   "machhw %0,%1,%2"
1190   [(set_attr "type" "halfmul")])
1192 (define_insn "*machhwuc"
1193   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1194         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1195                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1196                                        (const_int 16))
1197                                       (lshiftrt:SI
1198                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1199                                        (const_int 16)))
1200                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1201                     (const_int 0)))
1202    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1203         (plus:SI (mult:SI (lshiftrt:SI
1204                            (match_dup 1)
1205                            (const_int 16))
1206                           (lshiftrt:SI
1207                            (match_dup 2)
1208                            (const_int 16)))
1209                  (match_dup 4)))]
1210   "TARGET_MULHW"
1211   "machhwu. %0,%1,%2"
1212   [(set_attr "type" "halfmul")])
1214 (define_insn "*machhwu"
1215   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1216         (plus:SI (mult:SI (lshiftrt:SI
1217                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1218                            (const_int 16))
1219                           (lshiftrt:SI
1220                            (match_operand:SI 2 "gpc_reg_operand" "r")
1221                            (const_int 16)))
1222                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1223   "TARGET_MULHW"
1224   "machhwu %0,%1,%2"
1225   [(set_attr "type" "halfmul")])
1227 (define_insn "*maclhwc"
1228   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1229         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1230                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1231                                       (sign_extend:SI
1232                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1233                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1234                     (const_int 0)))
1235    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1236         (plus:SI (mult:SI (sign_extend:SI
1237                            (match_dup 1))
1238                           (sign_extend:SI
1239                            (match_dup 2)))
1240                  (match_dup 4)))]
1241   "TARGET_MULHW"
1242   "maclhw. %0,%1,%2"
1243   [(set_attr "type" "halfmul")])
1245 (define_insn "*maclhw"
1246   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1247         (plus:SI (mult:SI (sign_extend:SI
1248                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1249                           (sign_extend:SI
1250                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1251                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1252   "TARGET_MULHW"
1253   "maclhw %0,%1,%2"
1254   [(set_attr "type" "halfmul")])
1256 (define_insn "*maclhwuc"
1257   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1258         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1259                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1260                                       (zero_extend:SI
1261                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1262                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1263                     (const_int 0)))
1264    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1265         (plus:SI (mult:SI (zero_extend:SI
1266                            (match_dup 1))
1267                           (zero_extend:SI
1268                            (match_dup 2)))
1269                  (match_dup 4)))]
1270   "TARGET_MULHW"
1271   "maclhwu. %0,%1,%2"
1272   [(set_attr "type" "halfmul")])
1274 (define_insn "*maclhwu"
1275   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1276         (plus:SI (mult:SI (zero_extend:SI
1277                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1278                           (zero_extend:SI
1279                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1280                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1281   "TARGET_MULHW"
1282   "maclhwu %0,%1,%2"
1283   [(set_attr "type" "halfmul")])
1285 (define_insn "*nmacchwc"
1286   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1287         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1288                               (mult:SI (ashiftrt:SI
1289                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1290                                         (const_int 16))
1291                                        (sign_extend:SI
1292                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1293                     (const_int 0)))
1294    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1295         (minus:SI (match_dup 4)
1296                   (mult:SI (ashiftrt:SI
1297                             (match_dup 2)
1298                             (const_int 16))
1299                            (sign_extend:SI
1300                             (match_dup 1)))))]
1301   "TARGET_MULHW"
1302   "nmacchw. %0,%1,%2"
1303   [(set_attr "type" "halfmul")])
1305 (define_insn "*nmacchw"
1306   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1307         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1308                   (mult:SI (ashiftrt:SI
1309                             (match_operand:SI 2 "gpc_reg_operand" "r")
1310                             (const_int 16))
1311                            (sign_extend:SI
1312                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1313   "TARGET_MULHW"
1314   "nmacchw %0,%1,%2"
1315   [(set_attr "type" "halfmul")])
1317 (define_insn "*nmachhwc"
1318   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1319         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1320                               (mult:SI (ashiftrt:SI
1321                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1322                                         (const_int 16))
1323                                        (ashiftrt:SI
1324                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1325                                         (const_int 16))))
1326                     (const_int 0)))
1327    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1328         (minus:SI (match_dup 4)
1329                   (mult:SI (ashiftrt:SI
1330                             (match_dup 1)
1331                             (const_int 16))
1332                            (ashiftrt:SI
1333                             (match_dup 2)
1334                             (const_int 16)))))]
1335   "TARGET_MULHW"
1336   "nmachhw. %0,%1,%2"
1337   [(set_attr "type" "halfmul")])
1339 (define_insn "*nmachhw"
1340   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1342                   (mult:SI (ashiftrt:SI
1343                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1344                             (const_int 16))
1345                            (ashiftrt:SI
1346                             (match_operand:SI 2 "gpc_reg_operand" "r")
1347                             (const_int 16)))))]
1348   "TARGET_MULHW"
1349   "nmachhw %0,%1,%2"
1350   [(set_attr "type" "halfmul")])
1352 (define_insn "*nmaclhwc"
1353   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1354         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1355                               (mult:SI (sign_extend:SI
1356                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1357                                        (sign_extend:SI
1358                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1359                     (const_int 0)))
1360    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1361         (minus:SI (match_dup 4)
1362                   (mult:SI (sign_extend:SI
1363                             (match_dup 1))
1364                            (sign_extend:SI
1365                             (match_dup 2)))))]
1366   "TARGET_MULHW"
1367   "nmaclhw. %0,%1,%2"
1368   [(set_attr "type" "halfmul")])
1370 (define_insn "*nmaclhw"
1371   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1372         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1373                   (mult:SI (sign_extend:SI
1374                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1375                            (sign_extend:SI
1376                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1377   "TARGET_MULHW"
1378   "nmaclhw %0,%1,%2"
1379   [(set_attr "type" "halfmul")])
1381 (define_insn "*mulchwc"
1382   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1383         (compare:CC (mult:SI (ashiftrt:SI
1384                               (match_operand:SI 2 "gpc_reg_operand" "r")
1385                               (const_int 16))
1386                              (sign_extend:SI
1387                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1388                     (const_int 0)))
1389    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390         (mult:SI (ashiftrt:SI
1391                   (match_dup 2)
1392                   (const_int 16))
1393                  (sign_extend:SI
1394                   (match_dup 1))))]
1395   "TARGET_MULHW"
1396   "mulchw. %0,%1,%2"
1397   [(set_attr "type" "halfmul")])
1399 (define_insn "*mulchw"
1400   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1401         (mult:SI (ashiftrt:SI
1402                   (match_operand:SI 2 "gpc_reg_operand" "r")
1403                   (const_int 16))
1404                  (sign_extend:SI
1405                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1406   "TARGET_MULHW"
1407   "mulchw %0,%1,%2"
1408   [(set_attr "type" "halfmul")])
1410 (define_insn "*mulchwuc"
1411   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1412         (compare:CC (mult:SI (lshiftrt:SI
1413                               (match_operand:SI 2 "gpc_reg_operand" "r")
1414                               (const_int 16))
1415                              (zero_extend:SI
1416                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1417                     (const_int 0)))
1418    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1419         (mult:SI (lshiftrt:SI
1420                   (match_dup 2)
1421                   (const_int 16))
1422                  (zero_extend:SI
1423                   (match_dup 1))))]
1424   "TARGET_MULHW"
1425   "mulchwu. %0,%1,%2"
1426   [(set_attr "type" "halfmul")])
1428 (define_insn "*mulchwu"
1429   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1430         (mult:SI (lshiftrt:SI
1431                   (match_operand:SI 2 "gpc_reg_operand" "r")
1432                   (const_int 16))
1433                  (zero_extend:SI
1434                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1435   "TARGET_MULHW"
1436   "mulchwu %0,%1,%2"
1437   [(set_attr "type" "halfmul")])
1439 (define_insn "*mulhhwc"
1440   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1441         (compare:CC (mult:SI (ashiftrt:SI
1442                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1443                               (const_int 16))
1444                              (ashiftrt:SI
1445                               (match_operand:SI 2 "gpc_reg_operand" "r")
1446                               (const_int 16)))
1447                     (const_int 0)))
1448    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1449         (mult:SI (ashiftrt:SI
1450                   (match_dup 1)
1451                   (const_int 16))
1452                  (ashiftrt:SI
1453                   (match_dup 2)
1454                   (const_int 16))))]
1455   "TARGET_MULHW"
1456   "mulhhw. %0,%1,%2"
1457   [(set_attr "type" "halfmul")])
1459 (define_insn "*mulhhw"
1460   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1461         (mult:SI (ashiftrt:SI
1462                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1463                   (const_int 16))
1464                  (ashiftrt:SI
1465                   (match_operand:SI 2 "gpc_reg_operand" "r")
1466                   (const_int 16))))]
1467   "TARGET_MULHW"
1468   "mulhhw %0,%1,%2"
1469   [(set_attr "type" "halfmul")])
1471 (define_insn "*mulhhwuc"
1472   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1473         (compare:CC (mult:SI (lshiftrt:SI
1474                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1475                               (const_int 16))
1476                              (lshiftrt:SI
1477                               (match_operand:SI 2 "gpc_reg_operand" "r")
1478                               (const_int 16)))
1479                     (const_int 0)))
1480    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1481         (mult:SI (lshiftrt:SI
1482                   (match_dup 1)
1483                   (const_int 16))
1484                  (lshiftrt:SI
1485                   (match_dup 2)
1486                   (const_int 16))))]
1487   "TARGET_MULHW"
1488   "mulhhwu. %0,%1,%2"
1489   [(set_attr "type" "halfmul")])
1491 (define_insn "*mulhhwu"
1492   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1493         (mult:SI (lshiftrt:SI
1494                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1495                   (const_int 16))
1496                  (lshiftrt:SI
1497                   (match_operand:SI 2 "gpc_reg_operand" "r")
1498                   (const_int 16))))]
1499   "TARGET_MULHW"
1500   "mulhhwu %0,%1,%2"
1501   [(set_attr "type" "halfmul")])
1503 (define_insn "*mullhwc"
1504   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1505         (compare:CC (mult:SI (sign_extend:SI
1506                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1507                              (sign_extend:SI
1508                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1509                     (const_int 0)))
1510    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1511         (mult:SI (sign_extend:SI
1512                   (match_dup 1))
1513                  (sign_extend:SI
1514                   (match_dup 2))))]
1515   "TARGET_MULHW"
1516   "mullhw. %0,%1,%2"
1517   [(set_attr "type" "halfmul")])
1519 (define_insn "*mullhw"
1520   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1521         (mult:SI (sign_extend:SI
1522                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1523                  (sign_extend:SI
1524                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1525   "TARGET_MULHW"
1526   "mullhw %0,%1,%2"
1527   [(set_attr "type" "halfmul")])
1529 (define_insn "*mullhwuc"
1530   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1531         (compare:CC (mult:SI (zero_extend:SI
1532                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1533                              (zero_extend:SI
1534                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1535                     (const_int 0)))
1536    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1537         (mult:SI (zero_extend:SI
1538                   (match_dup 1))
1539                  (zero_extend:SI
1540                   (match_dup 2))))]
1541   "TARGET_MULHW"
1542   "mullhwu. %0,%1,%2"
1543   [(set_attr "type" "halfmul")])
1545 (define_insn "*mullhwu"
1546   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1547         (mult:SI (zero_extend:SI
1548                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1549                  (zero_extend:SI
1550                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1551   "TARGET_MULHW"
1552   "mullhwu %0,%1,%2"
1553   [(set_attr "type" "halfmul")])
1555 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1556 (define_insn "dlmzb"
1557   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1558         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1559                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1560                    UNSPEC_DLMZB_CR))
1561    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1562         (unspec:SI [(match_dup 1)
1563                     (match_dup 2)]
1564                    UNSPEC_DLMZB))]
1565   "TARGET_DLMZB"
1566   "dlmzb. %0,%1,%2")
1568 (define_expand "strlensi"
1569   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1570         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1571                     (match_operand:QI 2 "const_int_operand" "")
1572                     (match_operand 3 "const_int_operand" "")]
1573                    UNSPEC_DLMZB_STRLEN))
1574    (clobber (match_scratch:CC 4 "=x"))]
1575   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1577   rtx result = operands[0];
1578   rtx src = operands[1];
1579   rtx search_char = operands[2];
1580   rtx align = operands[3];
1581   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1582   rtx loop_label, end_label, mem, cr0, cond;
1583   if (search_char != const0_rtx
1584       || GET_CODE (align) != CONST_INT
1585       || INTVAL (align) < 8)
1586         FAIL;
1587   word1 = gen_reg_rtx (SImode);
1588   word2 = gen_reg_rtx (SImode);
1589   scratch_dlmzb = gen_reg_rtx (SImode);
1590   scratch_string = gen_reg_rtx (Pmode);
1591   loop_label = gen_label_rtx ();
1592   end_label = gen_label_rtx ();
1593   addr = force_reg (Pmode, XEXP (src, 0));
1594   emit_move_insn (scratch_string, addr);
1595   emit_label (loop_label);
1596   mem = change_address (src, SImode, scratch_string);
1597   emit_move_insn (word1, mem);
1598   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1599   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1600   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1601   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1602   emit_jump_insn (gen_rtx_SET (pc_rtx,
1603                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1604                                                      cond,
1605                                                      gen_rtx_LABEL_REF
1606                                                        (VOIDmode,
1607                                                         end_label),
1608                                                      pc_rtx)));
1609   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1610   emit_jump_insn (gen_rtx_SET (pc_rtx,
1611                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1612   emit_barrier ();
1613   emit_label (end_label);
1614   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1615   emit_insn (gen_subsi3 (result, scratch_string, addr));
1616   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1617   DONE;
1620 ;; Fixed-point arithmetic insns.
1622 (define_expand "add<mode>3"
1623   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1624         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1625                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1626   ""
1628   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1629     {
1630       rtx lo0 = gen_lowpart (SImode, operands[0]);
1631       rtx lo1 = gen_lowpart (SImode, operands[1]);
1632       rtx lo2 = gen_lowpart (SImode, operands[2]);
1633       rtx hi0 = gen_highpart (SImode, operands[0]);
1634       rtx hi1 = gen_highpart (SImode, operands[1]);
1635       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1637       if (!reg_or_short_operand (lo2, SImode))
1638         lo2 = force_reg (SImode, lo2);
1639       if (!adde_operand (hi2, SImode))
1640         hi2 = force_reg (SImode, hi2);
1642       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1643       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1644       DONE;
1645     }
1647   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1648     {
1649       rtx tmp = ((!can_create_pseudo_p ()
1650                   || rtx_equal_p (operands[0], operands[1]))
1651                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1653       HOST_WIDE_INT val = INTVAL (operands[2]);
1654       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1655       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1657       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1658         FAIL;
1660       /* The ordering here is important for the prolog expander.
1661          When space is allocated from the stack, adding 'low' first may
1662          produce a temporary deallocation (which would be bad).  */
1663       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1664       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1665       DONE;
1666     }
1669 (define_insn "*add<mode>3"
1670   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1671         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1672                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1673   ""
1674   "@
1675    add %0,%1,%2
1676    addi %0,%1,%2
1677    addis %0,%1,%v2"
1678   [(set_attr "type" "add")])
1680 (define_insn "addsi3_high"
1681   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1682         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1683                  (high:SI (match_operand 2 "" ""))))]
1684   "TARGET_MACHO && !TARGET_64BIT"
1685   "addis %0,%1,ha16(%2)"
1686   [(set_attr "type" "add")])
1688 (define_insn_and_split "*add<mode>3_dot"
1689   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1690         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1691                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1692                     (const_int 0)))
1693    (clobber (match_scratch:GPR 0 "=r,r"))]
1694   "<MODE>mode == Pmode"
1695   "@
1696    add. %0,%1,%2
1697    #"
1698   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1699   [(set (match_dup 0)
1700         (plus:GPR (match_dup 1)
1701                  (match_dup 2)))
1702    (set (match_dup 3)
1703         (compare:CC (match_dup 0)
1704                     (const_int 0)))]
1705   ""
1706   [(set_attr "type" "add")
1707    (set_attr "dot" "yes")
1708    (set_attr "length" "4,8")])
1710 (define_insn_and_split "*add<mode>3_dot2"
1711   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1712         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1713                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1714                     (const_int 0)))
1715    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1716         (plus:GPR (match_dup 1)
1717                   (match_dup 2)))]
1718   "<MODE>mode == Pmode"
1719   "@
1720    add. %0,%1,%2
1721    #"
1722   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1723   [(set (match_dup 0)
1724         (plus:GPR (match_dup 1)
1725                   (match_dup 2)))
1726    (set (match_dup 3)
1727         (compare:CC (match_dup 0)
1728                     (const_int 0)))]
1729   ""
1730   [(set_attr "type" "add")
1731    (set_attr "dot" "yes")
1732    (set_attr "length" "4,8")])
1734 (define_insn_and_split "*add<mode>3_imm_dot"
1735   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1736         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1737                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1738                     (const_int 0)))
1739    (clobber (match_scratch:GPR 0 "=r,r"))
1740    (clobber (reg:GPR CA_REGNO))]
1741   "<MODE>mode == Pmode"
1742   "@
1743    addic. %0,%1,%2
1744    #"
1745   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1746   [(set (match_dup 0)
1747         (plus:GPR (match_dup 1)
1748                   (match_dup 2)))
1749    (set (match_dup 3)
1750         (compare:CC (match_dup 0)
1751                     (const_int 0)))]
1752   ""
1753   [(set_attr "type" "add")
1754    (set_attr "dot" "yes")
1755    (set_attr "length" "4,8")])
1757 (define_insn_and_split "*add<mode>3_imm_dot2"
1758   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1759         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1760                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1761                     (const_int 0)))
1762    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1763         (plus:GPR (match_dup 1)
1764                   (match_dup 2)))
1765    (clobber (reg:GPR CA_REGNO))]
1766   "<MODE>mode == Pmode"
1767   "@
1768    addic. %0,%1,%2
1769    #"
1770   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1771   [(set (match_dup 0)
1772         (plus:GPR (match_dup 1)
1773                   (match_dup 2)))
1774    (set (match_dup 3)
1775         (compare:CC (match_dup 0)
1776                     (const_int 0)))]
1777   ""
1778   [(set_attr "type" "add")
1779    (set_attr "dot" "yes")
1780    (set_attr "length" "4,8")])
1782 ;; Split an add that we can't do in one insn into two insns, each of which
1783 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1784 ;; add should be last in case the result gets used in an address.
1786 (define_split
1787   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1788         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1789                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1790   ""
1791   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1792    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1794   HOST_WIDE_INT val = INTVAL (operands[2]);
1795   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1796   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1798   operands[4] = GEN_INT (low);
1799   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1800     operands[3] = GEN_INT (rest);
1801   else if (can_create_pseudo_p ())
1802     {
1803       operands[3] = gen_reg_rtx (DImode);
1804       emit_move_insn (operands[3], operands[2]);
1805       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1806       DONE;
1807     }
1808   else
1809     FAIL;
1813 (define_insn "add<mode>3_carry"
1814   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1815         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1816                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1817    (set (reg:P CA_REGNO)
1818         (ltu:P (plus:P (match_dup 1)
1819                        (match_dup 2))
1820                (match_dup 1)))]
1821   ""
1822   "add%I2c %0,%1,%2"
1823   [(set_attr "type" "add")])
1825 (define_insn "*add<mode>3_imm_carry_pos"
1826   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1827         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1828                 (match_operand:P 2 "short_cint_operand" "n")))
1829    (set (reg:P CA_REGNO)
1830         (geu:P (match_dup 1)
1831                (match_operand:P 3 "const_int_operand" "n")))]
1832   "INTVAL (operands[2]) > 0
1833    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1834   "addic %0,%1,%2"
1835   [(set_attr "type" "add")])
1837 (define_insn "*add<mode>3_imm_carry_0"
1838   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1839         (match_operand:P 1 "gpc_reg_operand" "r"))
1840    (set (reg:P CA_REGNO)
1841         (const_int 0))]
1842   ""
1843   "addic %0,%1,0"
1844   [(set_attr "type" "add")])
1846 (define_insn "*add<mode>3_imm_carry_m1"
1847   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1848         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1849                 (const_int -1)))
1850    (set (reg:P CA_REGNO)
1851         (ne:P (match_dup 1)
1852               (const_int 0)))]
1853   ""
1854   "addic %0,%1,-1"
1855   [(set_attr "type" "add")])
1857 (define_insn "*add<mode>3_imm_carry_neg"
1858   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1859         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1860                 (match_operand:P 2 "short_cint_operand" "n")))
1861    (set (reg:P CA_REGNO)
1862         (gtu:P (match_dup 1)
1863                (match_operand:P 3 "const_int_operand" "n")))]
1864   "INTVAL (operands[2]) < 0
1865    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1866   "addic %0,%1,%2"
1867   [(set_attr "type" "add")])
1870 (define_expand "add<mode>3_carry_in"
1871   [(parallel [
1872      (set (match_operand:GPR 0 "gpc_reg_operand")
1873           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1874                               (match_operand:GPR 2 "adde_operand"))
1875                     (reg:GPR CA_REGNO)))
1876      (clobber (reg:GPR CA_REGNO))])]
1877   ""
1879   if (operands[2] == const0_rtx)
1880     {
1881       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1882       DONE;
1883     }
1884   if (operands[2] == constm1_rtx)
1885     {
1886       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1887       DONE;
1888     }
1891 (define_insn "*add<mode>3_carry_in_internal"
1892   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1893         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1894                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1895                   (reg:GPR CA_REGNO)))
1896    (clobber (reg:GPR CA_REGNO))]
1897   ""
1898   "adde %0,%1,%2"
1899   [(set_attr "type" "add")])
1901 (define_insn "add<mode>3_carry_in_0"
1902   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1903         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1904                   (reg:GPR CA_REGNO)))
1905    (clobber (reg:GPR CA_REGNO))]
1906   ""
1907   "addze %0,%1"
1908   [(set_attr "type" "add")])
1910 (define_insn "add<mode>3_carry_in_m1"
1911   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1912         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1913                             (reg:GPR CA_REGNO))
1914                   (const_int -1)))
1915    (clobber (reg:GPR CA_REGNO))]
1916   ""
1917   "addme %0,%1"
1918   [(set_attr "type" "add")])
1921 (define_expand "one_cmpl<mode>2"
1922   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1923         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1924   ""
1926   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1927     {
1928       rs6000_split_logical (operands, NOT, false, false, false);
1929       DONE;
1930     }
1933 (define_insn "*one_cmpl<mode>2"
1934   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1935         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1936   ""
1937   "not %0,%1")
1939 (define_insn_and_split "*one_cmpl<mode>2_dot"
1940   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1941         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1942                     (const_int 0)))
1943    (clobber (match_scratch:GPR 0 "=r,r"))]
1944   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1945   "@
1946    not. %0,%1
1947    #"
1948   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1949   [(set (match_dup 0)
1950         (not:GPR (match_dup 1)))
1951    (set (match_dup 2)
1952         (compare:CC (match_dup 0)
1953                     (const_int 0)))]
1954   ""
1955   [(set_attr "type" "logical")
1956    (set_attr "dot" "yes")
1957    (set_attr "length" "4,8")])
1959 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1960   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1961         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1962                     (const_int 0)))
1963    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1964         (not:GPR (match_dup 1)))]
1965   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1966   "@
1967    not. %0,%1
1968    #"
1969   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1970   [(set (match_dup 0)
1971         (not:GPR (match_dup 1)))
1972    (set (match_dup 2)
1973         (compare:CC (match_dup 0)
1974                     (const_int 0)))]
1975   ""
1976   [(set_attr "type" "logical")
1977    (set_attr "dot" "yes")
1978    (set_attr "length" "4,8")])
1981 (define_expand "sub<mode>3"
1982   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1983         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1984                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1985   ""
1987   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1988     {
1989       rtx lo0 = gen_lowpart (SImode, operands[0]);
1990       rtx lo1 = gen_lowpart (SImode, operands[1]);
1991       rtx lo2 = gen_lowpart (SImode, operands[2]);
1992       rtx hi0 = gen_highpart (SImode, operands[0]);
1993       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1994       rtx hi2 = gen_highpart (SImode, operands[2]);
1996       if (!reg_or_short_operand (lo1, SImode))
1997         lo1 = force_reg (SImode, lo1);
1998       if (!adde_operand (hi1, SImode))
1999         hi1 = force_reg (SImode, hi1);
2001       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2002       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2003       DONE;
2004     }
2006   if (short_cint_operand (operands[1], <MODE>mode))
2007     {
2008       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2009       DONE;
2010     }
2013 (define_insn "*subf<mode>3"
2014   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2015         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2016                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2017   ""
2018   "subf %0,%1,%2"
2019   [(set_attr "type" "add")])
2021 (define_insn_and_split "*subf<mode>3_dot"
2022   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2023         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2024                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2025                     (const_int 0)))
2026    (clobber (match_scratch:GPR 0 "=r,r"))]
2027   "<MODE>mode == Pmode"
2028   "@
2029    subf. %0,%1,%2
2030    #"
2031   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2032   [(set (match_dup 0)
2033         (minus:GPR (match_dup 2)
2034                    (match_dup 1)))
2035    (set (match_dup 3)
2036         (compare:CC (match_dup 0)
2037                     (const_int 0)))]
2038   ""
2039   [(set_attr "type" "add")
2040    (set_attr "dot" "yes")
2041    (set_attr "length" "4,8")])
2043 (define_insn_and_split "*subf<mode>3_dot2"
2044   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2045         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2046                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2047                     (const_int 0)))
2048    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2049         (minus:GPR (match_dup 2)
2050                    (match_dup 1)))]
2051   "<MODE>mode == Pmode"
2052   "@
2053    subf. %0,%1,%2
2054    #"
2055   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2056   [(set (match_dup 0)
2057         (minus:GPR (match_dup 2)
2058                    (match_dup 1)))
2059    (set (match_dup 3)
2060         (compare:CC (match_dup 0)
2061                     (const_int 0)))]
2062   ""
2063   [(set_attr "type" "add")
2064    (set_attr "dot" "yes")
2065    (set_attr "length" "4,8")])
2067 (define_insn "subf<mode>3_imm"
2068   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2069         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2070                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2071    (clobber (reg:GPR CA_REGNO))]
2072   ""
2073   "subfic %0,%1,%2"
2074   [(set_attr "type" "add")])
2076 (define_insn_and_split "subf<mode>3_carry_dot2"
2077   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2078         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2079                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2080                     (const_int 0)))
2081    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2082         (minus:P (match_dup 2)
2083                    (match_dup 1)))
2084    (set (reg:P CA_REGNO)
2085         (leu:P (match_dup 1)
2086                (match_dup 2)))]
2087   "<MODE>mode == Pmode"
2088   "@
2089    subfc. %0,%1,%2
2090    #"
2091   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2092   [(parallel [(set (match_dup 0)
2093                    (minus:P (match_dup 2)
2094                             (match_dup 1)))
2095               (set (reg:P CA_REGNO)
2096                    (leu:P (match_dup 1)
2097                           (match_dup 2)))])
2098    (set (match_dup 3)
2099         (compare:CC (match_dup 0)
2100                     (const_int 0)))]
2101   ""
2102   [(set_attr "type" "add")
2103    (set_attr "dot" "yes")
2104    (set_attr "length" "4,8")])
2106 (define_insn "subf<mode>3_carry"
2107   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2108         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2109                  (match_operand:P 1 "gpc_reg_operand" "r")))
2110    (set (reg:P CA_REGNO)
2111         (leu:P (match_dup 1)
2112                (match_dup 2)))]
2113   ""
2114   "subf%I2c %0,%1,%2"
2115   [(set_attr "type" "add")])
2117 (define_insn "*subf<mode>3_imm_carry_0"
2118   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2119         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2120    (set (reg:P CA_REGNO)
2121         (eq:P (match_dup 1)
2122               (const_int 0)))]
2123   ""
2124   "subfic %0,%1,0"
2125   [(set_attr "type" "add")])
2127 (define_insn "*subf<mode>3_imm_carry_m1"
2128   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2129         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2130    (set (reg:P CA_REGNO)
2131         (const_int 1))]
2132   ""
2133   "subfic %0,%1,-1"
2134   [(set_attr "type" "add")])
2137 (define_expand "subf<mode>3_carry_in"
2138   [(parallel [
2139      (set (match_operand:GPR 0 "gpc_reg_operand")
2140           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2141                               (reg:GPR CA_REGNO))
2142                     (match_operand:GPR 2 "adde_operand")))
2143      (clobber (reg:GPR CA_REGNO))])]
2144   ""
2146   if (operands[2] == const0_rtx)
2147     {
2148       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2149       DONE;
2150     }
2151   if (operands[2] == constm1_rtx)
2152     {
2153       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2154       DONE;
2155     }
2158 (define_insn "*subf<mode>3_carry_in_internal"
2159   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2160         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2161                             (reg:GPR CA_REGNO))
2162                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2163    (clobber (reg:GPR CA_REGNO))]
2164   ""
2165   "subfe %0,%1,%2"
2166   [(set_attr "type" "add")])
2168 (define_insn "subf<mode>3_carry_in_0"
2169   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2170         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2171                   (reg:GPR CA_REGNO)))
2172    (clobber (reg:GPR CA_REGNO))]
2173   ""
2174   "subfze %0,%1"
2175   [(set_attr "type" "add")])
2177 (define_insn "subf<mode>3_carry_in_m1"
2178   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2179         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2180                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2181                   (const_int -2)))
2182    (clobber (reg:GPR CA_REGNO))]
2183   ""
2184   "subfme %0,%1"
2185   [(set_attr "type" "add")])
2187 (define_insn "subf<mode>3_carry_in_xx"
2188   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2189         (plus:GPR (reg:GPR CA_REGNO)
2190                   (const_int -1)))
2191    (clobber (reg:GPR CA_REGNO))]
2192   ""
2193   "subfe %0,%0,%0"
2194   [(set_attr "type" "add")])
2197 (define_insn "neg<mode>2"
2198   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2199         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2200   ""
2201   "neg %0,%1"
2202   [(set_attr "type" "add")])
2204 (define_insn_and_split "*neg<mode>2_dot"
2205   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2206         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2207                     (const_int 0)))
2208    (clobber (match_scratch:GPR 0 "=r,r"))]
2209   "<MODE>mode == Pmode"
2210   "@
2211    neg. %0,%1
2212    #"
2213   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2214   [(set (match_dup 0)
2215         (neg:GPR (match_dup 1)))
2216    (set (match_dup 2)
2217         (compare:CC (match_dup 0)
2218                     (const_int 0)))]
2219   ""
2220   [(set_attr "type" "add")
2221    (set_attr "dot" "yes")
2222    (set_attr "length" "4,8")])
2224 (define_insn_and_split "*neg<mode>2_dot2"
2225   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2226         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2227                     (const_int 0)))
2228    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2229         (neg:GPR (match_dup 1)))]
2230   "<MODE>mode == Pmode"
2231   "@
2232    neg. %0,%1
2233    #"
2234   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2235   [(set (match_dup 0)
2236         (neg:GPR (match_dup 1)))
2237    (set (match_dup 2)
2238         (compare:CC (match_dup 0)
2239                     (const_int 0)))]
2240   ""
2241   [(set_attr "type" "add")
2242    (set_attr "dot" "yes")
2243    (set_attr "length" "4,8")])
2246 (define_insn "clz<mode>2"
2247   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2248         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2249   ""
2250   "cntlz<wd> %0,%1"
2251   [(set_attr "type" "cntlz")])
2253 (define_expand "ctz<mode>2"
2254    [(set (match_operand:GPR 0 "gpc_reg_operand")
2255          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2256   ""
2258   if (TARGET_CTZ)
2259     {
2260       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2261       DONE;
2262     }
2264   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2265   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2266   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2268   if (TARGET_POPCNTD)
2269     {
2270       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2271       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2272       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2273       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2274     }
2275   else
2276     {
2277       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2278       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2279       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2280       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2281     }
2283   DONE;
2286 (define_insn "ctz<mode>2_hw"
2287   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2288         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2289   "TARGET_CTZ"
2290   "cnttz<wd> %0,%1"
2291   [(set_attr "type" "cntlz")])
2293 (define_expand "ffs<mode>2"
2294   [(set (match_operand:GPR 0 "gpc_reg_operand")
2295         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2296   ""
2298   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2299   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2300   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2301   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2302   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2303   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2304   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2305   DONE;
2309 (define_expand "popcount<mode>2"
2310   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2311         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2312   "TARGET_POPCNTB || TARGET_POPCNTD"
2314   rs6000_emit_popcount (operands[0], operands[1]);
2315   DONE;
2318 (define_insn "popcntb<mode>2"
2319   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2320         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2321                     UNSPEC_POPCNTB))]
2322   "TARGET_POPCNTB"
2323   "popcntb %0,%1"
2324   [(set_attr "type" "popcnt")])
2326 (define_insn "popcntd<mode>2"
2327   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2328         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2329   "TARGET_POPCNTD"
2330   "popcnt<wd> %0,%1"
2331   [(set_attr "type" "popcnt")])
2334 (define_expand "parity<mode>2"
2335   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2336         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2337   "TARGET_POPCNTB"
2339   rs6000_emit_parity (operands[0], operands[1]);
2340   DONE;
2343 (define_insn "parity<mode>2_cmpb"
2344   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2345         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2346   "TARGET_CMPB && TARGET_POPCNTB"
2347   "prty<wd> %0,%1"
2348   [(set_attr "type" "popcnt")])
2350 (define_insn "cmpb<mode>3"
2351   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2352         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2353                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2354   "TARGET_CMPB"
2355   "cmpb %0,%1,%2"
2356   [(set_attr "type" "cmp")])
2358 ;; Since the hardware zeros the upper part of the register, save generating the
2359 ;; AND immediate if we are converting to unsigned
2360 (define_insn "*bswap<mode>2_extenddi"
2361   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2362         (zero_extend:DI
2363          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2364   "TARGET_POWERPC64"
2365   "l<wd>brx %0,%y1"
2366   [(set_attr "length" "4")
2367    (set_attr "type" "load")])
2369 (define_insn "*bswaphi2_extendsi"
2370   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2371         (zero_extend:SI
2372          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2373   ""
2374   "lhbrx %0,%y1"
2375   [(set_attr "length" "4")
2376    (set_attr "type" "load")])
2378 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2379 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2380 ;; load with byte swap, which can be slower than doing it in the registers.  It
2381 ;; also prevents certain failures with the RELOAD register allocator.
2383 (define_expand "bswap<mode>2"
2384   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2385    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2386   ""
2388   rtx dest = operands[0];
2389   rtx src = operands[1];
2391   if (!REG_P (dest) && !REG_P (src))
2392     src = force_reg (<MODE>mode, src);
2394   if (MEM_P (src))
2395     emit_insn (gen_bswap<mode>2_load (dest, src));
2396   else if (MEM_P (dest))
2397     emit_insn (gen_bswap<mode>2_store (dest, src));
2398   else
2399     emit_insn (gen_bswap<mode>2_reg (dest, src));
2400   DONE;
2403 (define_insn "bswap<mode>2_load"
2404   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2405         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2406   ""
2407   "l<wd>brx %0,%y1"
2408   [(set_attr "type" "load")])
2410 (define_insn "bswap<mode>2_store"
2411   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2412         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2413   ""
2414   "st<wd>brx %1,%y0"
2415   [(set_attr "type" "store")])
2417 (define_insn_and_split "bswaphi2_reg"
2418   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
2419         (bswap:HI
2420          (match_operand:HI 1 "gpc_reg_operand" "r")))
2421    (clobber (match_scratch:SI 2 "=&r"))]
2422   ""
2423   "#"
2424   "reload_completed"
2425   [(set (match_dup 3)
2426         (and:SI (lshiftrt:SI (match_dup 4)
2427                              (const_int 8))
2428                 (const_int 255)))
2429    (set (match_dup 2)
2430         (and:SI (ashift:SI (match_dup 4)
2431                            (const_int 8))
2432                 (const_int 65280)))             ;; 0xff00
2433    (set (match_dup 3)
2434         (ior:SI (match_dup 3)
2435                 (match_dup 2)))]
2437   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2438   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2440   [(set_attr "length" "12")
2441    (set_attr "type" "*")])
2443 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2444 ;; zero_extract insns do not change for -mlittle.
2445 (define_insn_and_split "bswapsi2_reg"
2446   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
2447         (bswap:SI
2448          (match_operand:SI 1 "gpc_reg_operand" "r")))]
2449   ""
2450   "#"
2451   "reload_completed"
2452   [(set (match_dup 0)                                   ; DABC
2453         (rotate:SI (match_dup 1)
2454                    (const_int 24)))
2455    (set (match_dup 0)                                   ; DCBC
2456         (ior:SI (and:SI (ashift:SI (match_dup 1)
2457                                    (const_int 8))
2458                         (const_int 16711680))
2459                 (and:SI (match_dup 0)
2460                         (const_int -16711681))))
2461    (set (match_dup 0)                                   ; DCBA
2462         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2463                                      (const_int 24))
2464                         (const_int 255))
2465                 (and:SI (match_dup 0)
2466                         (const_int -256))))]
2467   "")
2469 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2470 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2471 ;; complex code.
2473 (define_expand "bswapdi2"
2474   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2475                    (bswap:DI
2476                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2477               (clobber (match_scratch:DI 2 ""))
2478               (clobber (match_scratch:DI 3 ""))])]
2479   ""
2481   rtx dest = operands[0];
2482   rtx src = operands[1];
2484   if (!REG_P (dest) && !REG_P (src))
2485     operands[1] = src = force_reg (DImode, src);
2487   if (TARGET_POWERPC64 && TARGET_LDBRX)
2488     {
2489       if (MEM_P (src))
2490         emit_insn (gen_bswapdi2_load (dest, src));
2491       else if (MEM_P (dest))
2492         emit_insn (gen_bswapdi2_store (dest, src));
2493       else
2494         emit_insn (gen_bswapdi2_reg (dest, src));
2495       DONE;
2496     }
2498   if (!TARGET_POWERPC64)
2499     {
2500       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2501          that uses 64-bit registers needs the same scratch registers as 64-bit
2502          mode.  */
2503       emit_insn (gen_bswapdi2_32bit (dest, src));
2504       DONE;
2505     }
2508 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2509 (define_insn "bswapdi2_load"
2510   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2511         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2512   "TARGET_POWERPC64 && TARGET_LDBRX"
2513   "ldbrx %0,%y1"
2514   [(set_attr "type" "load")])
2516 (define_insn "bswapdi2_store"
2517   [(set (match_operand:DI 0 "memory_operand" "=Z")
2518         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2519   "TARGET_POWERPC64 && TARGET_LDBRX"
2520   "stdbrx %1,%y0"
2521   [(set_attr "type" "store")])
2523 (define_insn "bswapdi2_reg"
2524   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2525         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2526    (clobber (match_scratch:DI 2 "=&r"))
2527    (clobber (match_scratch:DI 3 "=&r"))]
2528   "TARGET_POWERPC64 && TARGET_LDBRX"
2529   "#"
2530   [(set_attr "length" "36")])
2532 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2533 (define_insn "*bswapdi2_64bit"
2534   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2535         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2536    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2537    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2538   "TARGET_POWERPC64 && !TARGET_LDBRX
2539    && (REG_P (operands[0]) || REG_P (operands[1]))
2540    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2541    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2542   "#"
2543   [(set_attr "length" "16,12,36")])
2545 (define_split
2546   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2547         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2548    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2549    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2550   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2551   [(const_int 0)]
2552   "
2554   rtx dest   = operands[0];
2555   rtx src    = operands[1];
2556   rtx op2    = operands[2];
2557   rtx op3    = operands[3];
2558   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2559                                     BYTES_BIG_ENDIAN ? 4 : 0);
2560   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2561                                      BYTES_BIG_ENDIAN ? 4 : 0);
2562   rtx addr1;
2563   rtx addr2;
2564   rtx word1;
2565   rtx word2;
2567   addr1 = XEXP (src, 0);
2568   if (GET_CODE (addr1) == PLUS)
2569     {
2570       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2571       if (TARGET_AVOID_XFORM)
2572         {
2573           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2574           addr2 = op2;
2575         }
2576       else
2577         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2578     }
2579   else if (TARGET_AVOID_XFORM)
2580     {
2581       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2582       addr2 = op2;
2583     }
2584   else
2585     {
2586       emit_move_insn (op2, GEN_INT (4));
2587       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2588     }
2590   word1 = change_address (src, SImode, addr1);
2591   word2 = change_address (src, SImode, addr2);
2593   if (BYTES_BIG_ENDIAN)
2594     {
2595       emit_insn (gen_bswapsi2 (op3_32, word2));
2596       emit_insn (gen_bswapsi2 (dest_32, word1));
2597     }
2598   else
2599     {
2600       emit_insn (gen_bswapsi2 (op3_32, word1));
2601       emit_insn (gen_bswapsi2 (dest_32, word2));
2602     }
2604   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2605   emit_insn (gen_iordi3 (dest, dest, op3));
2606   DONE;
2609 (define_split
2610   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2611         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2612    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2613    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2614   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2615   [(const_int 0)]
2616   "
2618   rtx dest   = operands[0];
2619   rtx src    = operands[1];
2620   rtx op2    = operands[2];
2621   rtx op3    = operands[3];
2622   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2623                                     BYTES_BIG_ENDIAN ? 4 : 0);
2624   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2625                                     BYTES_BIG_ENDIAN ? 4 : 0);
2626   rtx addr1;
2627   rtx addr2;
2628   rtx word1;
2629   rtx word2;
2631   addr1 = XEXP (dest, 0);
2632   if (GET_CODE (addr1) == PLUS)
2633     {
2634       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2635       if (TARGET_AVOID_XFORM)
2636         {
2637           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2638           addr2 = op2;
2639         }
2640       else
2641         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2642     }
2643   else if (TARGET_AVOID_XFORM)
2644     {
2645       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2646       addr2 = op2;
2647     }
2648   else
2649     {
2650       emit_move_insn (op2, GEN_INT (4));
2651       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2652     }
2654   word1 = change_address (dest, SImode, addr1);
2655   word2 = change_address (dest, SImode, addr2);
2657   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2659   if (BYTES_BIG_ENDIAN)
2660     {
2661       emit_insn (gen_bswapsi2 (word1, src_si));
2662       emit_insn (gen_bswapsi2 (word2, op3_si));
2663     }
2664   else
2665     {
2666       emit_insn (gen_bswapsi2 (word2, src_si));
2667       emit_insn (gen_bswapsi2 (word1, op3_si));
2668     }
2669   DONE;
2672 (define_split
2673   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2674         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2675    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2676    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2677   "TARGET_POWERPC64 && reload_completed"
2678   [(const_int 0)]
2679   "
2681   rtx dest    = operands[0];
2682   rtx src     = operands[1];
2683   rtx op2     = operands[2];
2684   rtx op3     = operands[3];
2685   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2686   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2687   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2688   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2689   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2691   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2692   emit_insn (gen_bswapsi2 (dest_si, src_si));
2693   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2694   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2695   emit_insn (gen_iordi3 (dest, dest, op3));
2696   DONE;
2699 (define_insn "bswapdi2_32bit"
2700   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2701         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2702    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2703   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2704   "#"
2705   [(set_attr "length" "16,12,36")])
2707 (define_split
2708   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2709         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2710    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2711   "!TARGET_POWERPC64 && reload_completed"
2712   [(const_int 0)]
2713   "
2715   rtx dest  = operands[0];
2716   rtx src   = operands[1];
2717   rtx op2   = operands[2];
2718   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2719   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2720   rtx addr1;
2721   rtx addr2;
2722   rtx word1;
2723   rtx word2;
2725   addr1 = XEXP (src, 0);
2726   if (GET_CODE (addr1) == PLUS)
2727     {
2728       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2729       if (TARGET_AVOID_XFORM
2730           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2731         {
2732           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2733           addr2 = op2;
2734         }
2735       else
2736         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2737     }
2738   else if (TARGET_AVOID_XFORM
2739            || REGNO (addr1) == REGNO (dest2))
2740     {
2741       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2742       addr2 = op2;
2743     }
2744   else
2745     {
2746       emit_move_insn (op2, GEN_INT (4));
2747       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2748     }
2750   word1 = change_address (src, SImode, addr1);
2751   word2 = change_address (src, SImode, addr2);
2753   emit_insn (gen_bswapsi2 (dest2, word1));
2754   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2755      thus allowing us to omit an early clobber on the output.  */
2756   emit_insn (gen_bswapsi2 (dest1, word2));
2757   DONE;
2760 (define_split
2761   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2762         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2763    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2764   "!TARGET_POWERPC64 && reload_completed"
2765   [(const_int 0)]
2766   "
2768   rtx dest = operands[0];
2769   rtx src  = operands[1];
2770   rtx op2  = operands[2];
2771   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2772   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2773   rtx addr1;
2774   rtx addr2;
2775   rtx word1;
2776   rtx word2;
2778   addr1 = XEXP (dest, 0);
2779   if (GET_CODE (addr1) == PLUS)
2780     {
2781       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2782       if (TARGET_AVOID_XFORM)
2783         {
2784           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2785           addr2 = op2;
2786         }
2787       else
2788         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2789     }
2790   else if (TARGET_AVOID_XFORM)
2791     {
2792       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2793       addr2 = op2;
2794     }
2795   else
2796     {
2797       emit_move_insn (op2, GEN_INT (4));
2798       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2799     }
2801   word1 = change_address (dest, SImode, addr1);
2802   word2 = change_address (dest, SImode, addr2);
2804   emit_insn (gen_bswapsi2 (word2, src1));
2805   emit_insn (gen_bswapsi2 (word1, src2));
2806   DONE;
2809 (define_split
2810   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2811         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2812    (clobber (match_operand:SI 2 "" ""))]
2813   "!TARGET_POWERPC64 && reload_completed"
2814   [(const_int 0)]
2815   "
2817   rtx dest  = operands[0];
2818   rtx src   = operands[1];
2819   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2820   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2821   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2822   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2824   emit_insn (gen_bswapsi2 (dest1, src2));
2825   emit_insn (gen_bswapsi2 (dest2, src1));
2826   DONE;
2830 (define_insn "mul<mode>3"
2831   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2832         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2833                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2834   ""
2835   "@
2836    mull<wd> %0,%1,%2
2837    mulli %0,%1,%2"
2838    [(set_attr "type" "mul")
2839     (set (attr "size")
2840       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2841                 (const_string "8")
2842              (match_operand:GPR 2 "short_cint_operand" "")
2843                 (const_string "16")]
2844         (const_string "<bits>")))])
2846 (define_insn_and_split "*mul<mode>3_dot"
2847   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2848         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2849                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2850                     (const_int 0)))
2851    (clobber (match_scratch:GPR 0 "=r,r"))]
2852   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2853   "@
2854    mull<wd>. %0,%1,%2
2855    #"
2856   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2857   [(set (match_dup 0)
2858         (mult:GPR (match_dup 1)
2859                   (match_dup 2)))
2860    (set (match_dup 3)
2861         (compare:CC (match_dup 0)
2862                     (const_int 0)))]
2863   ""
2864   [(set_attr "type" "mul")
2865    (set_attr "size" "<bits>")
2866    (set_attr "dot" "yes")
2867    (set_attr "length" "4,8")])
2869 (define_insn_and_split "*mul<mode>3_dot2"
2870   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2871         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2872                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2873                     (const_int 0)))
2874    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2875         (mult:GPR (match_dup 1)
2876                   (match_dup 2)))]
2877   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2878   "@
2879    mull<wd>. %0,%1,%2
2880    #"
2881   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2882   [(set (match_dup 0)
2883         (mult:GPR (match_dup 1)
2884                   (match_dup 2)))
2885    (set (match_dup 3)
2886         (compare:CC (match_dup 0)
2887                     (const_int 0)))]
2888   ""
2889   [(set_attr "type" "mul")
2890    (set_attr "size" "<bits>")
2891    (set_attr "dot" "yes")
2892    (set_attr "length" "4,8")])
2895 (define_expand "<su>mul<mode>3_highpart"
2896   [(set (match_operand:GPR 0 "gpc_reg_operand")
2897         (subreg:GPR
2898           (mult:<DMODE> (any_extend:<DMODE>
2899                           (match_operand:GPR 1 "gpc_reg_operand"))
2900                         (any_extend:<DMODE>
2901                           (match_operand:GPR 2 "gpc_reg_operand")))
2902          0))]
2903   ""
2905   if (<MODE>mode == SImode && TARGET_POWERPC64)
2906     {
2907       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2908                                              operands[2]));
2909       DONE;
2910     }
2912   if (!WORDS_BIG_ENDIAN)
2913     {
2914       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2915                                                  operands[2]));
2916       DONE;
2917     }
2920 (define_insn "*<su>mul<mode>3_highpart"
2921   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2922         (subreg:GPR
2923           (mult:<DMODE> (any_extend:<DMODE>
2924                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2925                         (any_extend:<DMODE>
2926                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2927          0))]
2928   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2929   "mulh<wd><u> %0,%1,%2"
2930   [(set_attr "type" "mul")
2931    (set_attr "size" "<bits>")])
2933 (define_insn "<su>mulsi3_highpart_le"
2934   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2935         (subreg:SI
2936           (mult:DI (any_extend:DI
2937                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2938                    (any_extend:DI
2939                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2940          4))]
2941   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2942   "mulhw<u> %0,%1,%2"
2943   [(set_attr "type" "mul")])
2945 (define_insn "<su>muldi3_highpart_le"
2946   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2947         (subreg:DI
2948           (mult:TI (any_extend:TI
2949                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2950                    (any_extend:TI
2951                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2952          8))]
2953   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2954   "mulhd<u> %0,%1,%2"
2955   [(set_attr "type" "mul")
2956    (set_attr "size" "64")])
2958 (define_insn "<su>mulsi3_highpart_64"
2959   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2960         (truncate:SI
2961           (lshiftrt:DI
2962             (mult:DI (any_extend:DI
2963                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2964                      (any_extend:DI
2965                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2966             (const_int 32))))]
2967   "TARGET_POWERPC64"
2968   "mulhw<u> %0,%1,%2"
2969   [(set_attr "type" "mul")])
2971 (define_expand "<u>mul<mode><dmode>3"
2972   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2973         (mult:<DMODE> (any_extend:<DMODE>
2974                         (match_operand:GPR 1 "gpc_reg_operand"))
2975                       (any_extend:<DMODE>
2976                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2977   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2979   rtx l = gen_reg_rtx (<MODE>mode);
2980   rtx h = gen_reg_rtx (<MODE>mode);
2981   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2982   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2983   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2984   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2985   DONE;
2988 (define_insn "*maddld4"
2989   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2990         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2991                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2992                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2993   "TARGET_MADDLD"
2994   "maddld %0,%1,%2,%3"
2995   [(set_attr "type" "mul")])
2997 (define_insn "udiv<mode>3"
2998   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2999         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3000                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3001   ""
3002   "div<wd>u %0,%1,%2"
3003   [(set_attr "type" "div")
3004    (set_attr "size" "<bits>")])
3007 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3008 ;; modulus.  If it isn't a power of two, force operands into register and do
3009 ;; a normal divide.
3010 (define_expand "div<mode>3"
3011   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3012         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3013                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3014   ""
3016   if (CONST_INT_P (operands[2])
3017       && INTVAL (operands[2]) > 0
3018       && exact_log2 (INTVAL (operands[2])) >= 0)
3019     {
3020       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3021       DONE;
3022     }
3024   operands[2] = force_reg (<MODE>mode, operands[2]);
3027 (define_insn "*div<mode>3"
3028   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3029         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3030                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3031   ""
3032   "div<wd> %0,%1,%2"
3033   [(set_attr "type" "div")
3034    (set_attr "size" "<bits>")])
3036 (define_insn "div<mode>3_sra"
3037   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3038         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3039                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3040    (clobber (reg:GPR CA_REGNO))]
3041   ""
3042   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3043   [(set_attr "type" "two")
3044    (set_attr "length" "8")])
3046 (define_insn_and_split "*div<mode>3_sra_dot"
3047   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3048         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3049                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3050                     (const_int 0)))
3051    (clobber (match_scratch:GPR 0 "=r,r"))
3052    (clobber (reg:GPR CA_REGNO))]
3053   "<MODE>mode == Pmode"
3054   "@
3055    sra<wd>i %0,%1,%p2\;addze. %0,%0
3056    #"
3057   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3058   [(parallel [(set (match_dup 0)
3059                    (div:GPR (match_dup 1)
3060                             (match_dup 2)))
3061               (clobber (reg:GPR CA_REGNO))])
3062    (set (match_dup 3)
3063         (compare:CC (match_dup 0)
3064                     (const_int 0)))]
3065   ""
3066   [(set_attr "type" "two")
3067    (set_attr "length" "8,12")
3068    (set_attr "cell_micro" "not")])
3070 (define_insn_and_split "*div<mode>3_sra_dot2"
3071   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3072         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3073                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3074                     (const_int 0)))
3075    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3076         (div:GPR (match_dup 1)
3077                  (match_dup 2)))
3078    (clobber (reg:GPR CA_REGNO))]
3079   "<MODE>mode == Pmode"
3080   "@
3081    sra<wd>i %0,%1,%p2\;addze. %0,%0
3082    #"
3083   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3084   [(parallel [(set (match_dup 0)
3085                    (div:GPR (match_dup 1)
3086                             (match_dup 2)))
3087               (clobber (reg:GPR CA_REGNO))])
3088    (set (match_dup 3)
3089         (compare:CC (match_dup 0)
3090                     (const_int 0)))]
3091   ""
3092   [(set_attr "type" "two")
3093    (set_attr "length" "8,12")
3094    (set_attr "cell_micro" "not")])
3096 (define_expand "mod<mode>3"
3097   [(set (match_operand:GPR 0 "gpc_reg_operand")
3098         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3099                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3100   ""
3102   int i;
3103   rtx temp1;
3104   rtx temp2;
3106   if (GET_CODE (operands[2]) != CONST_INT
3107       || INTVAL (operands[2]) <= 0
3108       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3109     {
3110       if (!TARGET_MODULO)
3111         FAIL;
3113       operands[2] = force_reg (<MODE>mode, operands[2]);
3114     }
3115   else
3116     {
3117       temp1 = gen_reg_rtx (<MODE>mode);
3118       temp2 = gen_reg_rtx (<MODE>mode);
3120       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3121       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3122       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3123       DONE;
3124     }
3127 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3128 ;; mod, prefer putting the result of mod into a different register
3129 (define_insn "*mod<mode>3"
3130   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3131         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3132                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3133   "TARGET_MODULO"
3134   "mods<wd> %0,%1,%2"
3135   [(set_attr "type" "div")
3136    (set_attr "size" "<bits>")])
3139 (define_insn "umod<mode>3"
3140   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3141         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3142                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3143   "TARGET_MODULO"
3144   "modu<wd> %0,%1,%2"
3145   [(set_attr "type" "div")
3146    (set_attr "size" "<bits>")])
3148 ;; On machines with modulo support, do a combined div/mod the old fashioned
3149 ;; method, since the multiply/subtract is faster than doing the mod instruction
3150 ;; after a divide.
3152 (define_peephole2
3153   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3154         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3155                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3156    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3157         (mod:GPR (match_dup 1)
3158                  (match_dup 2)))]
3159   "TARGET_MODULO
3160    && ! reg_mentioned_p (operands[0], operands[1])
3161    && ! reg_mentioned_p (operands[0], operands[2])
3162    && ! reg_mentioned_p (operands[3], operands[1])
3163    && ! reg_mentioned_p (operands[3], operands[2])"
3164   [(set (match_dup 0)
3165         (div:GPR (match_dup 1)
3166                  (match_dup 2)))
3167    (set (match_dup 3)
3168         (mult:GPR (match_dup 0)
3169                   (match_dup 2)))
3170    (set (match_dup 3)
3171         (minus:GPR (match_dup 1)
3172                    (match_dup 3)))])
3174 (define_peephole2
3175   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3176         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3177                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3178    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3179         (umod:GPR (match_dup 1)
3180                   (match_dup 2)))]
3181   "TARGET_MODULO
3182    && ! reg_mentioned_p (operands[0], operands[1])
3183    && ! reg_mentioned_p (operands[0], operands[2])
3184    && ! reg_mentioned_p (operands[3], operands[1])
3185    && ! reg_mentioned_p (operands[3], operands[2])"
3186   [(set (match_dup 0)
3187         (udiv:GPR (match_dup 1)
3188                   (match_dup 2)))
3189    (set (match_dup 3)
3190         (mult:GPR (match_dup 0)
3191                   (match_dup 2)))
3192    (set (match_dup 3)
3193         (minus:GPR (match_dup 1)
3194                    (match_dup 3)))])
3197 ;; Logical instructions
3198 ;; The logical instructions are mostly combined by using match_operator,
3199 ;; but the plain AND insns are somewhat different because there is no
3200 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3201 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3203 (define_expand "and<mode>3"
3204   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3205         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3206                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3207   ""
3209   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3210     {
3211       rs6000_split_logical (operands, AND, false, false, false);
3212       DONE;
3213     }
3215   if (CONST_INT_P (operands[2]))
3216     {
3217       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3218         {
3219           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3220           DONE;
3221         }
3223       if (logical_const_operand (operands[2], <MODE>mode)
3224           && rs6000_gen_cell_microcode)
3225         {
3226           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3227           DONE;
3228         }
3230       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3231         {
3232           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3233           DONE;
3234         }
3236       operands[2] = force_reg (<MODE>mode, operands[2]);
3237     }
3241 (define_insn "and<mode>3_imm"
3242   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3243         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3244                  (match_operand:GPR 2 "logical_const_operand" "n")))
3245    (clobber (match_scratch:CC 3 "=x"))]
3246   "rs6000_gen_cell_microcode
3247    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3248   "andi%e2. %0,%1,%u2"
3249   [(set_attr "type" "logical")
3250    (set_attr "dot" "yes")])
3252 (define_insn_and_split "*and<mode>3_imm_dot"
3253   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3254         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3255                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3256                     (const_int 0)))
3257    (clobber (match_scratch:GPR 0 "=r,r"))
3258    (clobber (match_scratch:CC 4 "=X,x"))]
3259   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3260    && rs6000_gen_cell_microcode
3261    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3262   "@
3263    andi%e2. %0,%1,%u2
3264    #"
3265   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3266   [(parallel [(set (match_dup 0)
3267                    (and:GPR (match_dup 1)
3268                             (match_dup 2)))
3269               (clobber (match_dup 4))])
3270    (set (match_dup 3)
3271         (compare:CC (match_dup 0)
3272                     (const_int 0)))]
3273   ""
3274   [(set_attr "type" "logical")
3275    (set_attr "dot" "yes")
3276    (set_attr "length" "4,8")])
3278 (define_insn_and_split "*and<mode>3_imm_dot2"
3279   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3280         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3281                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3282                     (const_int 0)))
3283    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3284         (and:GPR (match_dup 1)
3285                  (match_dup 2)))
3286    (clobber (match_scratch:CC 4 "=X,x"))]
3287   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3288    && rs6000_gen_cell_microcode
3289    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3290   "@
3291    andi%e2. %0,%1,%u2
3292    #"
3293   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3294   [(parallel [(set (match_dup 0)
3295                    (and:GPR (match_dup 1)
3296                             (match_dup 2)))
3297               (clobber (match_dup 4))])
3298    (set (match_dup 3)
3299         (compare:CC (match_dup 0)
3300                     (const_int 0)))]
3301   ""
3302   [(set_attr "type" "logical")
3303    (set_attr "dot" "yes")
3304    (set_attr "length" "4,8")])
3306 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3307   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3308         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3309                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3310                     (const_int 0)))
3311    (clobber (match_scratch:GPR 0 "=r,r"))]
3312   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3313    && rs6000_gen_cell_microcode
3314    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3315   "@
3316    andi%e2. %0,%1,%u2
3317    #"
3318   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3319   [(set (match_dup 0)
3320         (and:GPR (match_dup 1)
3321                  (match_dup 2)))
3322    (set (match_dup 3)
3323         (compare:CC (match_dup 0)
3324                     (const_int 0)))]
3325   ""
3326   [(set_attr "type" "logical")
3327    (set_attr "dot" "yes")
3328    (set_attr "length" "4,8")])
3330 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3331   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3332         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3333                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3334                     (const_int 0)))
3335    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3336         (and:GPR (match_dup 1)
3337                  (match_dup 2)))]
3338   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3339    && rs6000_gen_cell_microcode
3340    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3341   "@
3342    andi%e2. %0,%1,%u2
3343    #"
3344   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3345   [(set (match_dup 0)
3346         (and:GPR (match_dup 1)
3347                  (match_dup 2)))
3348    (set (match_dup 3)
3349         (compare:CC (match_dup 0)
3350                     (const_int 0)))]
3351   ""
3352   [(set_attr "type" "logical")
3353    (set_attr "dot" "yes")
3354    (set_attr "length" "4,8")])
3356 (define_insn "*and<mode>3_imm_dot_shifted"
3357   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3358         (compare:CC
3359           (and:GPR
3360             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3361                           (match_operand:SI 4 "const_int_operand" "n"))
3362             (match_operand:GPR 2 "const_int_operand" "n"))
3363           (const_int 0)))
3364    (clobber (match_scratch:GPR 0 "=r"))]
3365   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3366                                    << INTVAL (operands[4])),
3367                           DImode)
3368    && (<MODE>mode == Pmode
3369        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3370    && rs6000_gen_cell_microcode"
3372   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3373   return "andi%e2. %0,%1,%u2";
3375   [(set_attr "type" "logical")
3376    (set_attr "dot" "yes")])
3379 (define_insn "and<mode>3_mask"
3380   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3381         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3382                  (match_operand:GPR 2 "const_int_operand" "n")))]
3383   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3385   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3387   [(set_attr "type" "shift")])
3389 (define_insn_and_split "*and<mode>3_mask_dot"
3390   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3391         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3392                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3393                     (const_int 0)))
3394    (clobber (match_scratch:GPR 0 "=r,r"))]
3395   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3396    && rs6000_gen_cell_microcode
3397    && !logical_const_operand (operands[2], <MODE>mode)
3398    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3400   if (which_alternative == 0)
3401     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3402   else
3403     return "#";
3405   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3406   [(set (match_dup 0)
3407         (and:GPR (match_dup 1)
3408                  (match_dup 2)))
3409    (set (match_dup 3)
3410         (compare:CC (match_dup 0)
3411                     (const_int 0)))]
3412   ""
3413   [(set_attr "type" "shift")
3414    (set_attr "dot" "yes")
3415    (set_attr "length" "4,8")])
3417 (define_insn_and_split "*and<mode>3_mask_dot2"
3418   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3419         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3420                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3421                     (const_int 0)))
3422    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3423         (and:GPR (match_dup 1)
3424                  (match_dup 2)))]
3425   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3426    && rs6000_gen_cell_microcode
3427    && !logical_const_operand (operands[2], <MODE>mode)
3428    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3430   if (which_alternative == 0)
3431     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3432   else
3433     return "#";
3435   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3436   [(set (match_dup 0)
3437         (and:GPR (match_dup 1)
3438                  (match_dup 2)))
3439    (set (match_dup 3)
3440         (compare:CC (match_dup 0)
3441                     (const_int 0)))]
3442   ""
3443   [(set_attr "type" "shift")
3444    (set_attr "dot" "yes")
3445    (set_attr "length" "4,8")])
3448 (define_insn_and_split "*and<mode>3_2insn"
3449   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3450         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3451                  (match_operand:GPR 2 "const_int_operand" "n")))]
3452   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3453    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3454         || (logical_const_operand (operands[2], <MODE>mode)
3455             && rs6000_gen_cell_microcode))"
3456   "#"
3457   "&& 1"
3458   [(pc)]
3460   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3461   DONE;
3463   [(set_attr "type" "shift")
3464    (set_attr "length" "8")])
3466 (define_insn_and_split "*and<mode>3_2insn_dot"
3467   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3468         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3469                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3470                     (const_int 0)))
3471    (clobber (match_scratch:GPR 0 "=r,r"))]
3472   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3473    && rs6000_gen_cell_microcode
3474    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3475    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3476         || (logical_const_operand (operands[2], <MODE>mode)
3477             && rs6000_gen_cell_microcode))"
3478   "#"
3479   "&& reload_completed"
3480   [(pc)]
3482   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3483   DONE;
3485   [(set_attr "type" "shift")
3486    (set_attr "dot" "yes")
3487    (set_attr "length" "8,12")])
3489 (define_insn_and_split "*and<mode>3_2insn_dot2"
3490   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3491         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3492                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3493                     (const_int 0)))
3494    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3495         (and:GPR (match_dup 1)
3496                  (match_dup 2)))]
3497   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3498    && rs6000_gen_cell_microcode
3499    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3500    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3501         || (logical_const_operand (operands[2], <MODE>mode)
3502             && rs6000_gen_cell_microcode))"
3503   "#"
3504   "&& reload_completed"
3505   [(pc)]
3507   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3508   DONE;
3510   [(set_attr "type" "shift")
3511    (set_attr "dot" "yes")
3512    (set_attr "length" "8,12")])
3515 (define_expand "<code><mode>3"
3516   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3517         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3518                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3519   ""
3521   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3522     {
3523       rs6000_split_logical (operands, <CODE>, false, false, false);
3524       DONE;
3525     }
3527   if (non_logical_cint_operand (operands[2], <MODE>mode))
3528     {
3529       rtx tmp = ((!can_create_pseudo_p ()
3530                   || rtx_equal_p (operands[0], operands[1]))
3531                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3533       HOST_WIDE_INT value = INTVAL (operands[2]);
3534       HOST_WIDE_INT lo = value & 0xffff;
3535       HOST_WIDE_INT hi = value - lo;
3537       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3538       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3539       DONE;
3540     }
3542   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3543     operands[2] = force_reg (<MODE>mode, operands[2]);
3546 (define_split
3547   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3548         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3549                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3550   ""
3551   [(set (match_dup 3)
3552         (iorxor:GPR (match_dup 1)
3553                     (match_dup 4)))
3554    (set (match_dup 0)
3555         (iorxor:GPR (match_dup 3)
3556                     (match_dup 5)))]
3558   operands[3] = ((!can_create_pseudo_p ()
3559                   || rtx_equal_p (operands[0], operands[1]))
3560                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3562   HOST_WIDE_INT value = INTVAL (operands[2]);
3563   HOST_WIDE_INT lo = value & 0xffff;
3564   HOST_WIDE_INT hi = value - lo;
3566   operands[4] = GEN_INT (hi);
3567   operands[5] = GEN_INT (lo);
3570 (define_insn "*bool<mode>3_imm"
3571   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3572         (match_operator:GPR 3 "boolean_or_operator"
3573          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3574           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3575   ""
3576   "%q3i%e2 %0,%1,%u2"
3577   [(set_attr "type" "logical")])
3579 (define_insn "*bool<mode>3"
3580   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3581         (match_operator:GPR 3 "boolean_operator"
3582          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3583           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3584   ""
3585   "%q3 %0,%1,%2"
3586   [(set_attr "type" "logical")])
3588 (define_insn_and_split "*bool<mode>3_dot"
3589   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3590         (compare:CC (match_operator:GPR 3 "boolean_operator"
3591          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3592           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3593          (const_int 0)))
3594    (clobber (match_scratch:GPR 0 "=r,r"))]
3595   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3596   "@
3597    %q3. %0,%1,%2
3598    #"
3599   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3600   [(set (match_dup 0)
3601         (match_dup 3))
3602    (set (match_dup 4)
3603         (compare:CC (match_dup 0)
3604                     (const_int 0)))]
3605   ""
3606   [(set_attr "type" "logical")
3607    (set_attr "dot" "yes")
3608    (set_attr "length" "4,8")])
3610 (define_insn_and_split "*bool<mode>3_dot2"
3611   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3612         (compare:CC (match_operator:GPR 3 "boolean_operator"
3613          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3614           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3615          (const_int 0)))
3616    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3617         (match_dup 3))]
3618   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3619   "@
3620    %q3. %0,%1,%2
3621    #"
3622   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3623   [(set (match_dup 0)
3624         (match_dup 3))
3625    (set (match_dup 4)
3626         (compare:CC (match_dup 0)
3627                     (const_int 0)))]
3628   ""
3629   [(set_attr "type" "logical")
3630    (set_attr "dot" "yes")
3631    (set_attr "length" "4,8")])
3634 (define_insn "*boolc<mode>3"
3635   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3636         (match_operator:GPR 3 "boolean_operator"
3637          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3638           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3639   ""
3640   "%q3 %0,%1,%2"
3641   [(set_attr "type" "logical")])
3643 (define_insn_and_split "*boolc<mode>3_dot"
3644   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3645         (compare:CC (match_operator:GPR 3 "boolean_operator"
3646          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3647           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3648          (const_int 0)))
3649    (clobber (match_scratch:GPR 0 "=r,r"))]
3650   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3651   "@
3652    %q3. %0,%1,%2
3653    #"
3654   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3655   [(set (match_dup 0)
3656         (match_dup 3))
3657    (set (match_dup 4)
3658         (compare:CC (match_dup 0)
3659                     (const_int 0)))]
3660   ""
3661   [(set_attr "type" "logical")
3662    (set_attr "dot" "yes")
3663    (set_attr "length" "4,8")])
3665 (define_insn_and_split "*boolc<mode>3_dot2"
3666   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3667         (compare:CC (match_operator:GPR 3 "boolean_operator"
3668          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3669           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3670          (const_int 0)))
3671    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3672         (match_dup 3))]
3673   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3674   "@
3675    %q3. %0,%1,%2
3676    #"
3677   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3678   [(set (match_dup 0)
3679         (match_dup 3))
3680    (set (match_dup 4)
3681         (compare:CC (match_dup 0)
3682                     (const_int 0)))]
3683   ""
3684   [(set_attr "type" "logical")
3685    (set_attr "dot" "yes")
3686    (set_attr "length" "4,8")])
3689 (define_insn "*boolcc<mode>3"
3690   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3691         (match_operator:GPR 3 "boolean_operator"
3692          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3693           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3694   ""
3695   "%q3 %0,%1,%2"
3696   [(set_attr "type" "logical")])
3698 (define_insn_and_split "*boolcc<mode>3_dot"
3699   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3700         (compare:CC (match_operator:GPR 3 "boolean_operator"
3701          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3702           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3703          (const_int 0)))
3704    (clobber (match_scratch:GPR 0 "=r,r"))]
3705   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3706   "@
3707    %q3. %0,%1,%2
3708    #"
3709   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3710   [(set (match_dup 0)
3711         (match_dup 3))
3712    (set (match_dup 4)
3713         (compare:CC (match_dup 0)
3714                     (const_int 0)))]
3715   ""
3716   [(set_attr "type" "logical")
3717    (set_attr "dot" "yes")
3718    (set_attr "length" "4,8")])
3720 (define_insn_and_split "*boolcc<mode>3_dot2"
3721   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3722         (compare:CC (match_operator:GPR 3 "boolean_operator"
3723          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3724           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3725          (const_int 0)))
3726    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3727         (match_dup 3))]
3728   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3729   "@
3730    %q3. %0,%1,%2
3731    #"
3732   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3733   [(set (match_dup 0)
3734         (match_dup 3))
3735    (set (match_dup 4)
3736         (compare:CC (match_dup 0)
3737                     (const_int 0)))]
3738   ""
3739   [(set_attr "type" "logical")
3740    (set_attr "dot" "yes")
3741    (set_attr "length" "4,8")])
3744 ;; TODO: Should have dots of this as well.
3745 (define_insn "*eqv<mode>3"
3746   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3747         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3748                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3749   ""
3750   "eqv %0,%1,%2"
3751   [(set_attr "type" "logical")])
3753 ;; Rotate-and-mask and insert.
3755 (define_insn "*rotl<mode>3_mask"
3756   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3757         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3758                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3759                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3760                  (match_operand:GPR 3 "const_int_operand" "n")))]
3761   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3763   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3765   [(set_attr "type" "shift")
3766    (set_attr "maybe_var_shift" "yes")])
3768 (define_insn_and_split "*rotl<mode>3_mask_dot"
3769   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3770         (compare:CC
3771           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3772                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3773                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3774                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3775           (const_int 0)))
3776    (clobber (match_scratch:GPR 0 "=r,r"))]
3777   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3778    && rs6000_gen_cell_microcode
3779    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3781   if (which_alternative == 0)
3782     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3783   else
3784     return "#";
3786   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3787   [(set (match_dup 0)
3788         (and:GPR (match_dup 4)
3789                  (match_dup 3)))
3790    (set (match_dup 5)
3791         (compare:CC (match_dup 0)
3792                     (const_int 0)))]
3793   ""
3794   [(set_attr "type" "shift")
3795    (set_attr "maybe_var_shift" "yes")
3796    (set_attr "dot" "yes")
3797    (set_attr "length" "4,8")])
3799 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3800   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3801         (compare:CC
3802           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3803                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3804                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3805                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3806           (const_int 0)))
3807    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3808         (and:GPR (match_dup 4)
3809                  (match_dup 3)))]
3810   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3811    && rs6000_gen_cell_microcode
3812    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3814   if (which_alternative == 0)
3815     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3816   else
3817     return "#";
3819   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3820   [(set (match_dup 0)
3821         (and:GPR (match_dup 4)
3822                  (match_dup 3)))
3823    (set (match_dup 5)
3824         (compare:CC (match_dup 0)
3825                     (const_int 0)))]
3826   ""
3827   [(set_attr "type" "shift")
3828    (set_attr "maybe_var_shift" "yes")
3829    (set_attr "dot" "yes")
3830    (set_attr "length" "4,8")])
3832 ; Special case for less-than-0.  We can do it with just one machine
3833 ; instruction, but the generic optimizers do not realise it is cheap.
3834 (define_insn "*lt0_disi"
3835   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3836         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3837                (const_int 0)))]
3838   "TARGET_POWERPC64"
3839   "rlwinm %0,%1,1,31,31"
3840   [(set_attr "type" "shift")])
3844 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3845 ; both are an AND so are the same precedence).
3846 (define_insn "*rotl<mode>3_insert"
3847   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3848         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3849                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3850                             (match_operand:SI 2 "const_int_operand" "n")])
3851                           (match_operand:GPR 3 "const_int_operand" "n"))
3852                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3853                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3854   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3855    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3857   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3859   [(set_attr "type" "insert")])
3860 ; FIXME: this needs an attr "size", so that the scheduler can see the
3861 ; difference between rlwimi and rldimi.  We also might want dot forms,
3862 ; but not for rlwimi on POWER4 and similar processors.
3864 (define_insn "*rotl<mode>3_insert_2"
3865   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3866         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3867                           (match_operand:GPR 6 "const_int_operand" "n"))
3868                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3869                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3870                             (match_operand:SI 2 "const_int_operand" "n")])
3871                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3872   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3873    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3875   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3877   [(set_attr "type" "insert")])
3879 ; There are also some forms without one of the ANDs.
3880 (define_insn "*rotl<mode>3_insert_3"
3881   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3882         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3883                           (match_operand:GPR 4 "const_int_operand" "n"))
3884                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3885                              (match_operand:SI 2 "const_int_operand" "n"))))]
3886   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3888   if (<MODE>mode == SImode)
3889     return "rlwimi %0,%1,%h2,0,31-%h2";
3890   else
3891     return "rldimi %0,%1,%H2,0";
3893   [(set_attr "type" "insert")])
3895 (define_insn "*rotl<mode>3_insert_4"
3896   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3897         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3898                           (match_operand:GPR 4 "const_int_operand" "n"))
3899                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3900                                (match_operand:SI 2 "const_int_operand" "n"))))]
3901   "<MODE>mode == SImode &&
3902    GET_MODE_PRECISION (<MODE>mode)
3903    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3905   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3906                          - INTVAL (operands[2]));
3907   if (<MODE>mode == SImode)
3908     return "rlwimi %0,%1,%h2,32-%h2,31";
3909   else
3910     return "rldimi %0,%1,%H2,64-%H2";
3912   [(set_attr "type" "insert")])
3914 (define_insn "*rotlsi3_insert_5"
3915   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3916         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3917                         (match_operand:SI 2 "const_int_operand" "n,n"))
3918                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3919                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3920   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3921    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3922    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3923   "@
3924    rlwimi %0,%3,0,%4
3925    rlwimi %0,%1,0,%2"
3926   [(set_attr "type" "insert")])
3928 (define_insn "*rotldi3_insert_6"
3929   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3930         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3931                         (match_operand:DI 2 "const_int_operand" "n"))
3932                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3933                         (match_operand:DI 4 "const_int_operand" "n"))))]
3934   "exact_log2 (-UINTVAL (operands[2])) > 0
3935    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3937   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3938   return "rldimi %0,%3,0,%5";
3940   [(set_attr "type" "insert")
3941    (set_attr "size" "64")])
3943 (define_insn "*rotldi3_insert_7"
3944   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3945         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3946                         (match_operand:DI 4 "const_int_operand" "n"))
3947                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3948                         (match_operand:DI 2 "const_int_operand" "n"))))]
3949   "exact_log2 (-UINTVAL (operands[2])) > 0
3950    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3952   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3953   return "rldimi %0,%3,0,%5";
3955   [(set_attr "type" "insert")
3956    (set_attr "size" "64")])
3959 ; This handles the important case of multiple-precision shifts.  There is
3960 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3961 (define_split
3962   [(set (match_operand:GPR 0 "gpc_reg_operand")
3963         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3964                              (match_operand:SI 3 "const_int_operand"))
3965                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3966                                (match_operand:SI 4 "const_int_operand"))))]
3967   "can_create_pseudo_p ()
3968    && INTVAL (operands[3]) + INTVAL (operands[4])
3969       >= GET_MODE_PRECISION (<MODE>mode)"
3970   [(set (match_dup 5)
3971         (lshiftrt:GPR (match_dup 2)
3972                       (match_dup 4)))
3973    (set (match_dup 0)
3974         (ior:GPR (and:GPR (match_dup 5)
3975                           (match_dup 6))
3976                  (ashift:GPR (match_dup 1)
3977                              (match_dup 3))))]
3979   unsigned HOST_WIDE_INT mask = 1;
3980   mask = (mask << INTVAL (operands[3])) - 1;
3981   operands[5] = gen_reg_rtx (<MODE>mode);
3982   operands[6] = GEN_INT (mask);
3985 (define_split
3986   [(set (match_operand:GPR 0 "gpc_reg_operand")
3987         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3988                                (match_operand:SI 4 "const_int_operand"))
3989                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3990                              (match_operand:SI 3 "const_int_operand"))))]
3991   "can_create_pseudo_p ()
3992    && INTVAL (operands[3]) + INTVAL (operands[4])
3993       >= GET_MODE_PRECISION (<MODE>mode)"
3994   [(set (match_dup 5)
3995         (lshiftrt:GPR (match_dup 2)
3996                       (match_dup 4)))
3997    (set (match_dup 0)
3998         (ior:GPR (and:GPR (match_dup 5)
3999                           (match_dup 6))
4000                  (ashift:GPR (match_dup 1)
4001                              (match_dup 3))))]
4003   unsigned HOST_WIDE_INT mask = 1;
4004   mask = (mask << INTVAL (operands[3])) - 1;
4005   operands[5] = gen_reg_rtx (<MODE>mode);
4006   operands[6] = GEN_INT (mask);
4010 ; Another important case is setting some bits to 1; we can do that with
4011 ; an insert instruction, in many cases.
4012 (define_insn_and_split "*ior<mode>_mask"
4013   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4014         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4015                  (match_operand:GPR 2 "const_int_operand" "n")))
4016    (clobber (match_scratch:GPR 3 "=r"))]
4017   "!logical_const_operand (operands[2], <MODE>mode)
4018    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4019   "#"
4020   "&& 1"
4021   [(set (match_dup 3)
4022         (const_int -1))
4023    (set (match_dup 0)
4024         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4025                                       (match_dup 4))
4026                           (match_dup 2))
4027                  (and:GPR (match_dup 1)
4028                           (match_dup 5))))]
4030   int nb, ne;
4031   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4032   if (GET_CODE (operands[3]) == SCRATCH)
4033     operands[3] = gen_reg_rtx (<MODE>mode);
4034   operands[4] = GEN_INT (ne);
4035   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4037   [(set_attr "type" "two")
4038    (set_attr "length" "8")])
4041 ;; Now the simple shifts.
4043 (define_insn "rotl<mode>3"
4044   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4045         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4046                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4047   ""
4048   "rotl<wd>%I2 %0,%1,%<hH>2"
4049   [(set_attr "type" "shift")
4050    (set_attr "maybe_var_shift" "yes")])
4052 (define_insn "*rotlsi3_64"
4053   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4054         (zero_extend:DI
4055             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4056                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4057   "TARGET_POWERPC64"
4058   "rotlw%I2 %0,%1,%h2"
4059   [(set_attr "type" "shift")
4060    (set_attr "maybe_var_shift" "yes")])
4062 (define_insn_and_split "*rotl<mode>3_dot"
4063   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4064         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4065                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4066                     (const_int 0)))
4067    (clobber (match_scratch:GPR 0 "=r,r"))]
4068   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4069   "@
4070    rotl<wd>%I2. %0,%1,%<hH>2
4071    #"
4072   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4073   [(set (match_dup 0)
4074         (rotate:GPR (match_dup 1)
4075                     (match_dup 2)))
4076    (set (match_dup 3)
4077         (compare:CC (match_dup 0)
4078                     (const_int 0)))]
4079   ""
4080   [(set_attr "type" "shift")
4081    (set_attr "maybe_var_shift" "yes")
4082    (set_attr "dot" "yes")
4083    (set_attr "length" "4,8")])
4085 (define_insn_and_split "*rotl<mode>3_dot2"
4086   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4087         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4088                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4089                     (const_int 0)))
4090    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4091         (rotate:GPR (match_dup 1)
4092                     (match_dup 2)))]
4093   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4094   "@
4095    rotl<wd>%I2. %0,%1,%<hH>2
4096    #"
4097   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4098   [(set (match_dup 0)
4099         (rotate:GPR (match_dup 1)
4100                     (match_dup 2)))
4101    (set (match_dup 3)
4102         (compare:CC (match_dup 0)
4103                     (const_int 0)))]
4104   ""
4105   [(set_attr "type" "shift")
4106    (set_attr "maybe_var_shift" "yes")
4107    (set_attr "dot" "yes")
4108    (set_attr "length" "4,8")])
4111 (define_insn "ashl<mode>3"
4112   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4113         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4114                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4115   ""
4116   "sl<wd>%I2 %0,%1,%<hH>2"
4117   [(set_attr "type" "shift")
4118    (set_attr "maybe_var_shift" "yes")])
4120 (define_insn "*ashlsi3_64"
4121   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4122         (zero_extend:DI
4123             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4124                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4125   "TARGET_POWERPC64"
4126   "slw%I2 %0,%1,%h2"
4127   [(set_attr "type" "shift")
4128    (set_attr "maybe_var_shift" "yes")])
4130 (define_insn_and_split "*ashl<mode>3_dot"
4131   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4132         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4133                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4134                     (const_int 0)))
4135    (clobber (match_scratch:GPR 0 "=r,r"))]
4136   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4137   "@
4138    sl<wd>%I2. %0,%1,%<hH>2
4139    #"
4140   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4141   [(set (match_dup 0)
4142         (ashift:GPR (match_dup 1)
4143                     (match_dup 2)))
4144    (set (match_dup 3)
4145         (compare:CC (match_dup 0)
4146                     (const_int 0)))]
4147   ""
4148   [(set_attr "type" "shift")
4149    (set_attr "maybe_var_shift" "yes")
4150    (set_attr "dot" "yes")
4151    (set_attr "length" "4,8")])
4153 (define_insn_and_split "*ashl<mode>3_dot2"
4154   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4155         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4156                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4157                     (const_int 0)))
4158    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4159         (ashift:GPR (match_dup 1)
4160                     (match_dup 2)))]
4161   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4162   "@
4163    sl<wd>%I2. %0,%1,%<hH>2
4164    #"
4165   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4166   [(set (match_dup 0)
4167         (ashift:GPR (match_dup 1)
4168                     (match_dup 2)))
4169    (set (match_dup 3)
4170         (compare:CC (match_dup 0)
4171                     (const_int 0)))]
4172   ""
4173   [(set_attr "type" "shift")
4174    (set_attr "maybe_var_shift" "yes")
4175    (set_attr "dot" "yes")
4176    (set_attr "length" "4,8")])
4178 ;; Pretend we have a memory form of extswsli until register allocation is done
4179 ;; so that we use LWZ to load the value from memory, instead of LWA.
4180 (define_insn_and_split "ashdi3_extswsli"
4181   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4182         (ashift:DI
4183          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4184          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4185   "TARGET_EXTSWSLI"
4186   "@
4187    extswsli %0,%1,%2
4188    #"
4189   "&& reload_completed && MEM_P (operands[1])"
4190   [(set (match_dup 3)
4191         (match_dup 1))
4192    (set (match_dup 0)
4193         (ashift:DI (sign_extend:DI (match_dup 3))
4194                    (match_dup 2)))]
4196   operands[3] = gen_lowpart (SImode, operands[0]);
4198   [(set_attr "type" "shift")
4199    (set_attr "maybe_var_shift" "no")])
4202 (define_insn_and_split "ashdi3_extswsli_dot"
4203   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4204         (compare:CC
4205          (ashift:DI
4206           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4207           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4208          (const_int 0)))
4209    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4210   "TARGET_EXTSWSLI"
4211   "@
4212    extswsli. %0,%1,%2
4213    #
4214    #
4215    #"
4216   "&& reload_completed
4217    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4218        || memory_operand (operands[1], SImode))"
4219   [(pc)]
4221   rtx dest = operands[0];
4222   rtx src = operands[1];
4223   rtx shift = operands[2];
4224   rtx cr = operands[3];
4225   rtx src2;
4227   if (!MEM_P (src))
4228     src2 = src;
4229   else
4230     {
4231       src2 = gen_lowpart (SImode, dest);
4232       emit_move_insn (src2, src);
4233     }
4235   if (REGNO (cr) == CR0_REGNO)
4236     {
4237       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4238       DONE;
4239     }
4241   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4242   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4243   DONE;
4245   [(set_attr "type" "shift")
4246    (set_attr "maybe_var_shift" "no")
4247    (set_attr "dot" "yes")
4248    (set_attr "length" "4,8,8,12")])
4250 (define_insn_and_split "ashdi3_extswsli_dot2"
4251   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4252         (compare:CC
4253          (ashift:DI
4254           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4255           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4256          (const_int 0)))
4257    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4258         (ashift:DI (sign_extend:DI (match_dup 1))
4259                    (match_dup 2)))]
4260   "TARGET_EXTSWSLI"
4261   "@
4262    extswsli. %0,%1,%2
4263    #
4264    #
4265    #"
4266   "&& reload_completed
4267    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4268        || memory_operand (operands[1], SImode))"
4269   [(pc)]
4271   rtx dest = operands[0];
4272   rtx src = operands[1];
4273   rtx shift = operands[2];
4274   rtx cr = operands[3];
4275   rtx src2;
4277   if (!MEM_P (src))
4278     src2 = src;
4279   else
4280     {
4281       src2 = gen_lowpart (SImode, dest);
4282       emit_move_insn (src2, src);
4283     }
4285   if (REGNO (cr) == CR0_REGNO)
4286     {
4287       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4288       DONE;
4289     }
4291   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4292   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4293   DONE;
4295   [(set_attr "type" "shift")
4296    (set_attr "maybe_var_shift" "no")
4297    (set_attr "dot" "yes")
4298    (set_attr "length" "4,8,8,12")])
4300 (define_insn "lshr<mode>3"
4301   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4302         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4303                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4304   ""
4305   "sr<wd>%I2 %0,%1,%<hH>2"
4306   [(set_attr "type" "shift")
4307    (set_attr "maybe_var_shift" "yes")])
4309 (define_insn "*lshrsi3_64"
4310   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4311         (zero_extend:DI
4312             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4313                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4314   "TARGET_POWERPC64"
4315   "srw%I2 %0,%1,%h2"
4316   [(set_attr "type" "shift")
4317    (set_attr "maybe_var_shift" "yes")])
4319 (define_insn_and_split "*lshr<mode>3_dot"
4320   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4321         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4322                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4323                     (const_int 0)))
4324    (clobber (match_scratch:GPR 0 "=r,r"))]
4325   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4326   "@
4327    sr<wd>%I2. %0,%1,%<hH>2
4328    #"
4329   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4330   [(set (match_dup 0)
4331         (lshiftrt:GPR (match_dup 1)
4332                       (match_dup 2)))
4333    (set (match_dup 3)
4334         (compare:CC (match_dup 0)
4335                     (const_int 0)))]
4336   ""
4337   [(set_attr "type" "shift")
4338    (set_attr "maybe_var_shift" "yes")
4339    (set_attr "dot" "yes")
4340    (set_attr "length" "4,8")])
4342 (define_insn_and_split "*lshr<mode>3_dot2"
4343   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4344         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4345                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4346                     (const_int 0)))
4347    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4348         (lshiftrt:GPR (match_dup 1)
4349                       (match_dup 2)))]
4350   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4351   "@
4352    sr<wd>%I2. %0,%1,%<hH>2
4353    #"
4354   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4355   [(set (match_dup 0)
4356         (lshiftrt:GPR (match_dup 1)
4357                       (match_dup 2)))
4358    (set (match_dup 3)
4359         (compare:CC (match_dup 0)
4360                     (const_int 0)))]
4361   ""
4362   [(set_attr "type" "shift")
4363    (set_attr "maybe_var_shift" "yes")
4364    (set_attr "dot" "yes")
4365    (set_attr "length" "4,8")])
4368 (define_insn "ashr<mode>3"
4369   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4370         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4371                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4372    (clobber (reg:GPR CA_REGNO))]
4373   ""
4374   "sra<wd>%I2 %0,%1,%<hH>2"
4375   [(set_attr "type" "shift")
4376    (set_attr "maybe_var_shift" "yes")])
4378 (define_insn "*ashrsi3_64"
4379   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4380         (sign_extend:DI
4381             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4382                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4383    (clobber (reg:SI CA_REGNO))]
4384   "TARGET_POWERPC64"
4385   "sraw%I2 %0,%1,%h2"
4386   [(set_attr "type" "shift")
4387    (set_attr "maybe_var_shift" "yes")])
4389 (define_insn_and_split "*ashr<mode>3_dot"
4390   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4391         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4392                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4393                     (const_int 0)))
4394    (clobber (match_scratch:GPR 0 "=r,r"))
4395    (clobber (reg:GPR CA_REGNO))]
4396   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4397   "@
4398    sra<wd>%I2. %0,%1,%<hH>2
4399    #"
4400   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4401   [(parallel [(set (match_dup 0)
4402                    (ashiftrt:GPR (match_dup 1)
4403                                  (match_dup 2)))
4404               (clobber (reg:GPR CA_REGNO))])
4405    (set (match_dup 3)
4406         (compare:CC (match_dup 0)
4407                     (const_int 0)))]
4408   ""
4409   [(set_attr "type" "shift")
4410    (set_attr "maybe_var_shift" "yes")
4411    (set_attr "dot" "yes")
4412    (set_attr "length" "4,8")])
4414 (define_insn_and_split "*ashr<mode>3_dot2"
4415   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4416         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4417                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4418                     (const_int 0)))
4419    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4420         (ashiftrt:GPR (match_dup 1)
4421                       (match_dup 2)))
4422    (clobber (reg:GPR CA_REGNO))]
4423   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4424   "@
4425    sra<wd>%I2. %0,%1,%<hH>2
4426    #"
4427   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4428   [(parallel [(set (match_dup 0)
4429                    (ashiftrt:GPR (match_dup 1)
4430                                  (match_dup 2)))
4431               (clobber (reg:GPR CA_REGNO))])
4432    (set (match_dup 3)
4433         (compare:CC (match_dup 0)
4434                     (const_int 0)))]
4435   ""
4436   [(set_attr "type" "shift")
4437    (set_attr "maybe_var_shift" "yes")
4438    (set_attr "dot" "yes")
4439    (set_attr "length" "4,8")])
4441 ;; Builtins to replace a division to generate FRE reciprocal estimate
4442 ;; instructions and the necessary fixup instructions
4443 (define_expand "recip<mode>3"
4444   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4445    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4446    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4447   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4449    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4450    DONE;
4453 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4454 ;; hardware division.  This is only done before register allocation and with
4455 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4456 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4457 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4458 (define_split
4459   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4460         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4461                     (match_operand 2 "gpc_reg_operand" "")))]
4462   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4463    && can_create_pseudo_p () && flag_finite_math_only
4464    && !flag_trapping_math && flag_reciprocal_math"
4465   [(const_int 0)]
4467   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4468   DONE;
4471 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4472 ;; appropriate fixup.
4473 (define_expand "rsqrt<mode>2"
4474   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4475    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4476   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4478   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4479   DONE;
4482 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4483 ;; modes here, and also add in conditional vsx/power8-vector support to access
4484 ;; values in the traditional Altivec registers if the appropriate
4485 ;; -mupper-regs-{df,sf} option is enabled.
4487 (define_expand "abs<mode>2"
4488   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4489         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4490   "TARGET_<MODE>_INSN"
4491   "")
4493 (define_insn "*abs<mode>2_fpr"
4494   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4495         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4496   "TARGET_<MODE>_FPR"
4497   "@
4498    fabs %0,%1
4499    xsabsdp %x0,%x1"
4500   [(set_attr "type" "fpsimple")
4501    (set_attr "fp_type" "fp_addsub_<Fs>")])
4503 (define_insn "*nabs<mode>2_fpr"
4504   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4505         (neg:SFDF
4506          (abs:SFDF
4507           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4508   "TARGET_<MODE>_FPR"
4509   "@
4510    fnabs %0,%1
4511    xsnabsdp %x0,%x1"
4512   [(set_attr "type" "fpsimple")
4513    (set_attr "fp_type" "fp_addsub_<Fs>")])
4515 (define_expand "neg<mode>2"
4516   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4517         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4518   "TARGET_<MODE>_INSN"
4519   "")
4521 (define_insn "*neg<mode>2_fpr"
4522   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4523         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4524   "TARGET_<MODE>_FPR"
4525   "@
4526    fneg %0,%1
4527    xsnegdp %x0,%x1"
4528   [(set_attr "type" "fpsimple")
4529    (set_attr "fp_type" "fp_addsub_<Fs>")])
4531 (define_expand "add<mode>3"
4532   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4533         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4534                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4535   "TARGET_<MODE>_INSN"
4536   "")
4538 (define_insn "*add<mode>3_fpr"
4539   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4540         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4541                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4542   "TARGET_<MODE>_FPR"
4543   "@
4544    fadd<Ftrad> %0,%1,%2
4545    xsadd<Fvsx> %x0,%x1,%x2"
4546   [(set_attr "type" "fp")
4547    (set_attr "fp_type" "fp_addsub_<Fs>")])
4549 (define_expand "sub<mode>3"
4550   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4551         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4552                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4553   "TARGET_<MODE>_INSN"
4554   "")
4556 (define_insn "*sub<mode>3_fpr"
4557   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4558         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4559                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4560   "TARGET_<MODE>_FPR"
4561   "@
4562    fsub<Ftrad> %0,%1,%2
4563    xssub<Fvsx> %x0,%x1,%x2"
4564   [(set_attr "type" "fp")
4565    (set_attr "fp_type" "fp_addsub_<Fs>")])
4567 (define_expand "mul<mode>3"
4568   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4569         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4570                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4571   "TARGET_<MODE>_INSN"
4572   "")
4574 (define_insn "*mul<mode>3_fpr"
4575   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4576         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4577                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4578   "TARGET_<MODE>_FPR"
4579   "@
4580    fmul<Ftrad> %0,%1,%2
4581    xsmul<Fvsx> %x0,%x1,%x2"
4582   [(set_attr "type" "dmul")
4583    (set_attr "fp_type" "fp_mul_<Fs>")])
4585 (define_expand "div<mode>3"
4586   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4587         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4588                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4589   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4591   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4592       && can_create_pseudo_p () && flag_finite_math_only
4593       && !flag_trapping_math && flag_reciprocal_math)
4594     {
4595       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4596       DONE;
4597     }
4600 (define_insn "*div<mode>3_fpr"
4601   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4602         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4603                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4604   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4605   "@
4606    fdiv<Ftrad> %0,%1,%2
4607    xsdiv<Fvsx> %x0,%x1,%x2"
4608   [(set_attr "type" "<Fs>div")
4609    (set_attr "fp_type" "fp_div_<Fs>")])
4611 (define_insn "*sqrt<mode>2_internal"
4612   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4613         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4614   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4615    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4616   "@
4617    fsqrt<Ftrad> %0,%1
4618    xssqrt<Fvsx> %x0,%x1"
4619   [(set_attr "type" "<Fs>sqrt")
4620    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4622 (define_expand "sqrt<mode>2"
4623   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4624         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4625   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4626    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4628   if (<MODE>mode == SFmode
4629       && TARGET_RECIP_PRECISION
4630       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4631       && !optimize_function_for_size_p (cfun)
4632       && flag_finite_math_only && !flag_trapping_math
4633       && flag_unsafe_math_optimizations)
4634     {
4635       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4636       DONE;
4637     }
4640 ;; Floating point reciprocal approximation
4641 (define_insn "fre<Fs>"
4642   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4643         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4644                      UNSPEC_FRES))]
4645   "TARGET_<FFRE>"
4646   "@
4647    fre<Ftrad> %0,%1
4648    xsre<Fvsx> %x0,%x1"
4649   [(set_attr "type" "fp")])
4651 (define_insn "*rsqrt<mode>2"
4652   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4653         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4654                      UNSPEC_RSQRT))]
4655   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4656   "@
4657    frsqrte<Ftrad> %0,%1
4658    xsrsqrte<Fvsx> %x0,%x1"
4659   [(set_attr "type" "fp")])
4661 ;; Floating point comparisons
4662 (define_insn "*cmp<mode>_fpr"
4663   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4664         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4665                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4666   "TARGET_<MODE>_FPR"
4667   "@
4668    fcmpu %0,%1,%2
4669    xscmpudp %0,%x1,%x2"
4670   [(set_attr "type" "fpcompare")])
4672 ;; Floating point conversions
4673 (define_expand "extendsfdf2"
4674   [(set (match_operand:DF 0 "gpc_reg_operand")
4675         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand")))]
4676   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4678   if (HONOR_SNANS (SFmode))
4679     operands[1] = force_reg (SFmode, operands[1]);
4682 (define_insn_and_split "*extendsfdf2_fpr"
4683   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4684         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4685   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4686    && !HONOR_SNANS (SFmode)"
4687   "@
4688    #
4689    fmr %0,%1
4690    lfs%U1%X1 %0,%1
4691    #
4692    xscpsgndp %x0,%x1,%x1
4693    lxsspx %x0,%y1
4694    lxssp %0,%1"
4695   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4696   [(const_int 0)]
4698   emit_note (NOTE_INSN_DELETED);
4699   DONE;
4701   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4703 (define_insn "*extendsfdf2_snan"
4704   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4705         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4706   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4707    && HONOR_SNANS (SFmode)"
4708   "@
4709    frsp %0,%1
4710    xsrsp %x0,%x1"
4711   [(set_attr "type" "fp")])
4713 (define_expand "truncdfsf2"
4714   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4715         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4716   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4717   "")
4719 (define_insn "*truncdfsf2_fpr"
4720   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4721         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4722   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4723   "@
4724    frsp %0,%1
4725    xsrsp %x0,%x1"
4726   [(set_attr "type" "fp")])
4728 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4729 ;; builtins.c and optabs.c that are not correct for IBM long double
4730 ;; when little-endian.
4731 (define_expand "signbit<mode>2"
4732   [(set (match_dup 2)
4733         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4734    (set (match_dup 3)
4735         (subreg:DI (match_dup 2) 0))
4736    (set (match_dup 4)
4737         (match_dup 5))
4738    (set (match_operand:SI 0 "gpc_reg_operand" "")
4739         (match_dup 6))]
4740   "TARGET_HARD_FLOAT
4741    && (TARGET_FPRS || TARGET_E500_DOUBLE)
4742    && (!FLOAT128_IEEE_P (<MODE>mode)
4743        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4745   if (FLOAT128_IEEE_P (<MODE>mode))
4746     {
4747       if (<MODE>mode == KFmode)
4748         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4749       else if (<MODE>mode == TFmode)
4750         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4751       else
4752         gcc_unreachable ();
4753       DONE;
4754     }
4755   operands[2] = gen_reg_rtx (DFmode);
4756   operands[3] = gen_reg_rtx (DImode);
4757   if (TARGET_POWERPC64)
4758     {
4759       operands[4] = gen_reg_rtx (DImode);
4760       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4761       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4762                                     WORDS_BIG_ENDIAN ? 4 : 0);
4763     }
4764   else
4765     {
4766       operands[4] = gen_reg_rtx (SImode);
4767       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4768                                     WORDS_BIG_ENDIAN ? 0 : 4);
4769       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4770     }
4773 (define_expand "copysign<mode>3"
4774   [(set (match_dup 3)
4775         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4776    (set (match_dup 4)
4777         (neg:SFDF (abs:SFDF (match_dup 1))))
4778    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4779         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4780                                (match_dup 5))
4781                          (match_dup 3)
4782                          (match_dup 4)))]
4783   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4784    && ((TARGET_PPC_GFXOPT
4785         && !HONOR_NANS (<MODE>mode)
4786         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4787        || TARGET_CMPB
4788        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4790   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4791     {
4792       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4793                                              operands[2]));
4794       DONE;
4795     }
4797    operands[3] = gen_reg_rtx (<MODE>mode);
4798    operands[4] = gen_reg_rtx (<MODE>mode);
4799    operands[5] = CONST0_RTX (<MODE>mode);
4800   })
4802 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4803 ;; and load.
4804 (define_insn_and_split "signbit<mode>2_dm"
4805   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4806         (unspec:SI
4807          [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4808          UNSPEC_SIGNBIT))]
4809   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4810   "#"
4811   "&& reload_completed"
4812   [(const_int 0)]
4814   rs6000_split_signbit (operands[0], operands[1]);
4815   DONE;
4817  [(set_attr "length" "8,8,4")
4818   (set_attr "type" "mftgpr,load,integer")])
4820 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4821   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4822         (any_extend:DI
4823          (unspec:SI
4824           [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4825           UNSPEC_SIGNBIT)))]
4826   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4827   "#"
4828   "&& reload_completed"
4829   [(const_int 0)]
4831   rs6000_split_signbit (operands[0], operands[1]);
4832   DONE;
4834  [(set_attr "length" "8,8,4")
4835   (set_attr "type" "mftgpr,load,integer")])
4837 ;; TARGET_MODES_TIEABLE_P doesn't allow DImode to be tied with the various
4838 ;; floating point types, which makes normal SUBREG's problematical.  Instead
4839 ;; use a special pattern to avoid using a normal movdi.
4840 (define_insn "signbit<mode>2_dm2"
4841   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4842         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4843                     (const_int 0)]
4844                    UNSPEC_SIGNBIT))]
4845   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4846   "mfvsrd %0,%x1"
4847  [(set_attr "type" "mftgpr")])
4850 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4851 ;; compiler from optimizing -0.0
4852 (define_insn "copysign<mode>3_fcpsgn"
4853   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4854         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4855                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4856                      UNSPEC_COPYSIGN))]
4857   "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4858   "@
4859    fcpsgn %0,%2,%1
4860    xscpsgndp %x0,%x2,%x1"
4861   [(set_attr "type" "fpsimple")])
4863 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4864 ;; fsel instruction and some auxiliary computations.  Then we just have a
4865 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4866 ;; combine.
4867 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4868 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4869 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4870 ;; define_splits to make them if made by combine.  On VSX machines we have the
4871 ;; min/max instructions.
4873 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4874 ;; to allow either DF/SF to use only traditional registers.
4876 (define_expand "s<minmax><mode>3"
4877   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4878         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4879                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4880   "TARGET_MINMAX_<MODE>"
4882   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4883   DONE;
4886 (define_insn "*s<minmax><mode>3_vsx"
4887   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4888         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4889                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4890   "TARGET_VSX && TARGET_<MODE>_FPR"
4892   return (TARGET_P9_MINMAX
4893           ? "xs<minmax>cdp %x0,%x1,%x2"
4894           : "xs<minmax>dp %x0,%x1,%x2");
4896   [(set_attr "type" "fp")])
4898 ;; The conditional move instructions allow us to perform max and min operations
4899 ;; even when we don't have the appropriate max/min instruction using the FSEL
4900 ;; instruction.
4902 (define_insn_and_split "*s<minmax><mode>3_fpr"
4903   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4904         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4905                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4906   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4907   "#"
4908   "&& 1"
4909   [(const_int 0)]
4911   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4912   DONE;
4915 (define_expand "mov<mode>cc"
4916    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4917          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4918                            (match_operand:GPR 2 "gpc_reg_operand" "")
4919                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4920   "TARGET_ISEL<sel>"
4921   "
4923   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4924     DONE;
4925   else
4926     FAIL;
4929 ;; We use the BASE_REGS for the isel input operands because, if rA is
4930 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4931 ;; because we may switch the operands and rB may end up being rA.
4933 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4934 ;; leave out the mode in operand 4 and use one pattern, but reload can
4935 ;; change the mode underneath our feet and then gets confused trying
4936 ;; to reload the value.
4937 (define_insn "isel_signed_<mode>"
4938   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4939         (if_then_else:GPR
4940          (match_operator 1 "scc_comparison_operator"
4941                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4942                           (const_int 0)])
4943          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4944          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4945   "TARGET_ISEL<sel>"
4946   "*
4947 { return output_isel (operands); }"
4948   [(set_attr "type" "isel")
4949    (set_attr "length" "4")])
4951 (define_insn "isel_unsigned_<mode>"
4952   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4953         (if_then_else:GPR
4954          (match_operator 1 "scc_comparison_operator"
4955                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4956                           (const_int 0)])
4957          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4958          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4959   "TARGET_ISEL<sel>"
4960   "*
4961 { return output_isel (operands); }"
4962   [(set_attr "type" "isel")
4963    (set_attr "length" "4")])
4965 ;; These patterns can be useful for combine; they let combine know that
4966 ;; isel can handle reversed comparisons so long as the operands are
4967 ;; registers.
4969 (define_insn "*isel_reversed_signed_<mode>"
4970   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4971         (if_then_else:GPR
4972          (match_operator 1 "scc_rev_comparison_operator"
4973                          [(match_operand:CC 4 "cc_reg_operand" "y")
4974                           (const_int 0)])
4975          (match_operand:GPR 2 "gpc_reg_operand" "b")
4976          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4977   "TARGET_ISEL<sel>"
4978   "*
4979 { return output_isel (operands); }"
4980   [(set_attr "type" "isel")
4981    (set_attr "length" "4")])
4983 (define_insn "*isel_reversed_unsigned_<mode>"
4984   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4985         (if_then_else:GPR
4986          (match_operator 1 "scc_rev_comparison_operator"
4987                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4988                           (const_int 0)])
4989          (match_operand:GPR 2 "gpc_reg_operand" "b")
4990          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4991   "TARGET_ISEL<sel>"
4992   "*
4993 { return output_isel (operands); }"
4994   [(set_attr "type" "isel")
4995    (set_attr "length" "4")])
4997 ;; Floating point conditional move
4998 (define_expand "mov<mode>cc"
4999    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5000          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
5001                             (match_operand:SFDF 2 "gpc_reg_operand" "")
5002                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
5003   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5004   "
5006   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5007     DONE;
5008   else
5009     FAIL;
5012 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5013   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5014         (if_then_else:SFDF
5015          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5016              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5017          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5018          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5019   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5020   "fsel %0,%1,%2,%3"
5021   [(set_attr "type" "fp")])
5023 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5024   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5025         (if_then_else:SFDF
5026          (match_operator:CCFP 1 "fpmask_comparison_operator"
5027                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5028                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5029          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5030          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5031    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5032   "TARGET_P9_MINMAX"
5033   "#"
5034   ""
5035   [(set (match_dup 6)
5036         (if_then_else:V2DI (match_dup 1)
5037                            (match_dup 7)
5038                            (match_dup 8)))
5039    (set (match_dup 0)
5040         (if_then_else:SFDF (ne (match_dup 6)
5041                                (match_dup 8))
5042                            (match_dup 4)
5043                            (match_dup 5)))]
5045   if (GET_CODE (operands[6]) == SCRATCH)
5046     operands[6] = gen_reg_rtx (V2DImode);
5048   operands[7] = CONSTM1_RTX (V2DImode);
5049   operands[8] = CONST0_RTX (V2DImode);
5051  [(set_attr "length" "8")
5052   (set_attr "type" "vecperm")])
5054 ;; Handle inverting the fpmask comparisons.
5055 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5056   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5057         (if_then_else:SFDF
5058          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5059                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5060                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5061          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5062          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5063    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5064   "TARGET_P9_MINMAX"
5065   "#"
5066   "&& 1"
5067   [(set (match_dup 6)
5068         (if_then_else:V2DI (match_dup 9)
5069                            (match_dup 7)
5070                            (match_dup 8)))
5071    (set (match_dup 0)
5072         (if_then_else:SFDF (ne (match_dup 6)
5073                                (match_dup 8))
5074                            (match_dup 5)
5075                            (match_dup 4)))]
5077   rtx op1 = operands[1];
5078   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5080   if (GET_CODE (operands[6]) == SCRATCH)
5081     operands[6] = gen_reg_rtx (V2DImode);
5083   operands[7] = CONSTM1_RTX (V2DImode);
5084   operands[8] = CONST0_RTX (V2DImode);
5086   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5088  [(set_attr "length" "8")
5089   (set_attr "type" "vecperm")])
5091 (define_insn "*fpmask<mode>"
5092   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5093         (if_then_else:V2DI
5094          (match_operator:CCFP 1 "fpmask_comparison_operator"
5095                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5096                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5097          (match_operand:V2DI 4 "all_ones_constant" "")
5098          (match_operand:V2DI 5 "zero_constant" "")))]
5099   "TARGET_P9_MINMAX"
5100   "xscmp%V1dp %x0,%x2,%x3"
5101   [(set_attr "type" "fpcompare")])
5103 (define_insn "*xxsel<mode>"
5104   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5105         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5106                                (match_operand:V2DI 2 "zero_constant" ""))
5107                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5108                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5109   "TARGET_P9_MINMAX"
5110   "xxsel %x0,%x4,%x3,%x1"
5111   [(set_attr "type" "vecmove")])
5114 ;; Conversions to and from floating-point.
5116 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5117 ; don't want to support putting SImode in FPR registers.
5118 (define_insn "lfiwax"
5119   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5120         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5121                    UNSPEC_LFIWAX))]
5122   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5123   "@
5124    lfiwax %0,%y1
5125    lxsiwax %x0,%y1
5126    mtvsrwa %x0,%1
5127    vextsw2d %0,%1"
5128   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5130 ; This split must be run before register allocation because it allocates the
5131 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5132 ; it earlier to allow for the combiner to merge insns together where it might
5133 ; not be needed and also in case the insns are deleted as dead code.
5135 (define_insn_and_split "floatsi<mode>2_lfiwax"
5136   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5137         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5138    (clobber (match_scratch:DI 2 "=wi"))]
5139   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5140    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5141   "#"
5142   ""
5143   [(pc)]
5144   "
5146   rtx dest = operands[0];
5147   rtx src = operands[1];
5148   rtx tmp;
5150   if (!MEM_P (src) && TARGET_POWERPC64
5151       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5152     tmp = convert_to_mode (DImode, src, false);
5153   else
5154     {
5155       tmp = operands[2];
5156       if (GET_CODE (tmp) == SCRATCH)
5157         tmp = gen_reg_rtx (DImode);
5158       if (MEM_P (src))
5159         {
5160           src = rs6000_address_for_fpconvert (src);
5161           emit_insn (gen_lfiwax (tmp, src));
5162         }
5163       else
5164         {
5165           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5166           emit_move_insn (stack, src);
5167           emit_insn (gen_lfiwax (tmp, stack));
5168         }
5169     }
5170   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5171   DONE;
5173   [(set_attr "length" "12")
5174    (set_attr "type" "fpload")])
5176 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5177   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5178         (float:SFDF
5179          (sign_extend:DI
5180           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5181    (clobber (match_scratch:DI 2 "=wi"))]
5182   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5183    && <SI_CONVERT_FP>"
5184   "#"
5185   ""
5186   [(pc)]
5187   "
5189   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5190   if (GET_CODE (operands[2]) == SCRATCH)
5191     operands[2] = gen_reg_rtx (DImode);
5192   if (TARGET_VSX_SMALL_INTEGER)
5193     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5194   else
5195     emit_insn (gen_lfiwax (operands[2], operands[1]));
5196   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5197   DONE;
5199   [(set_attr "length" "8")
5200    (set_attr "type" "fpload")])
5202 (define_insn "lfiwzx"
5203   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5204         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5205                    UNSPEC_LFIWZX))]
5206   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5207   "@
5208    lfiwzx %0,%y1
5209    lxsiwzx %x0,%y1
5210    mtvsrwz %x0,%1
5211    xxextractuw %x0,%x1,4"
5212   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5214 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5215   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5216         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5217    (clobber (match_scratch:DI 2 "=wi"))]
5218   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5219    && <SI_CONVERT_FP>"
5220   "#"
5221   ""
5222   [(pc)]
5223   "
5225   rtx dest = operands[0];
5226   rtx src = operands[1];
5227   rtx tmp;
5229   if (!MEM_P (src) && TARGET_POWERPC64
5230       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5231     tmp = convert_to_mode (DImode, src, true);
5232   else
5233     {
5234       tmp = operands[2];
5235       if (GET_CODE (tmp) == SCRATCH)
5236         tmp = gen_reg_rtx (DImode);
5237       if (MEM_P (src))
5238         {
5239           src = rs6000_address_for_fpconvert (src);
5240           emit_insn (gen_lfiwzx (tmp, src));
5241         }
5242       else
5243         {
5244           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5245           emit_move_insn (stack, src);
5246           emit_insn (gen_lfiwzx (tmp, stack));
5247         }
5248     }
5249   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5250   DONE;
5252   [(set_attr "length" "12")
5253    (set_attr "type" "fpload")])
5255 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5256   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5257         (unsigned_float:SFDF
5258          (zero_extend:DI
5259           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5260    (clobber (match_scratch:DI 2 "=wi"))]
5261   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5262    && <SI_CONVERT_FP>"
5263   "#"
5264   ""
5265   [(pc)]
5266   "
5268   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5269   if (GET_CODE (operands[2]) == SCRATCH)
5270     operands[2] = gen_reg_rtx (DImode);
5271   if (TARGET_VSX_SMALL_INTEGER)
5272     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5273   else
5274     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5275   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5276   DONE;
5278   [(set_attr "length" "8")
5279    (set_attr "type" "fpload")])
5281 ; For each of these conversions, there is a define_expand, a define_insn
5282 ; with a '#' template, and a define_split (with C code).  The idea is
5283 ; to allow constant folding with the template of the define_insn,
5284 ; then to have the insns split later (between sched1 and final).
5286 (define_expand "floatsidf2"
5287   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5288                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5289               (use (match_dup 2))
5290               (use (match_dup 3))
5291               (clobber (match_dup 4))
5292               (clobber (match_dup 5))
5293               (clobber (match_dup 6))])]
5294   "TARGET_HARD_FLOAT 
5295    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5296   "
5298   if (TARGET_E500_DOUBLE)
5299     {
5300       if (!REG_P (operands[1]))
5301         operands[1] = force_reg (SImode, operands[1]);
5302       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5303       DONE;
5304     }
5305   else if (TARGET_LFIWAX && TARGET_FCFID)
5306     {
5307       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5308       DONE;
5309     }
5310   else if (TARGET_FCFID)
5311     {
5312       rtx dreg = operands[1];
5313       if (!REG_P (dreg))
5314         dreg = force_reg (SImode, dreg);
5315       dreg = convert_to_mode (DImode, dreg, false);
5316       emit_insn (gen_floatdidf2 (operands[0], dreg));
5317       DONE;
5318     }
5320   if (!REG_P (operands[1]))
5321     operands[1] = force_reg (SImode, operands[1]);
5322   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5323   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5324   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5325   operands[5] = gen_reg_rtx (DFmode);
5326   operands[6] = gen_reg_rtx (SImode);
5329 (define_insn_and_split "*floatsidf2_internal"
5330   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5331         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5332    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5333    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5334    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5335    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5336    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5337   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5338   "#"
5339   ""
5340   [(pc)]
5341   "
5343   rtx lowword, highword;
5344   gcc_assert (MEM_P (operands[4]));
5345   highword = adjust_address (operands[4], SImode, 0);
5346   lowword = adjust_address (operands[4], SImode, 4);
5347   if (! WORDS_BIG_ENDIAN)
5348     std::swap (lowword, highword);
5350   emit_insn (gen_xorsi3 (operands[6], operands[1],
5351                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5352   emit_move_insn (lowword, operands[6]);
5353   emit_move_insn (highword, operands[2]);
5354   emit_move_insn (operands[5], operands[4]);
5355   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5356   DONE;
5358   [(set_attr "length" "24")
5359    (set_attr "type" "fp")])
5361 ;; If we don't have a direct conversion to single precision, don't enable this
5362 ;; conversion for 32-bit without fast math, because we don't have the insn to
5363 ;; generate the fixup swizzle to avoid double rounding problems.
5364 (define_expand "floatunssisf2"
5365   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5366         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5367   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5368    && (!TARGET_FPRS
5369        || (TARGET_FPRS
5370            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5371                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5372                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5373   "
5375   if (!TARGET_FPRS)
5376     {
5377       if (!REG_P (operands[1]))
5378         operands[1] = force_reg (SImode, operands[1]);
5379     }
5380   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5381     {
5382       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5383       DONE;
5384     }
5385   else
5386     {
5387       rtx dreg = operands[1];
5388       if (!REG_P (dreg))
5389         dreg = force_reg (SImode, dreg);
5390       dreg = convert_to_mode (DImode, dreg, true);
5391       emit_insn (gen_floatdisf2 (operands[0], dreg));
5392       DONE;
5393     }
5396 (define_expand "floatunssidf2"
5397   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5398                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5399               (use (match_dup 2))
5400               (use (match_dup 3))
5401               (clobber (match_dup 4))
5402               (clobber (match_dup 5))])]
5403   "TARGET_HARD_FLOAT
5404    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5405   "
5407   if (TARGET_E500_DOUBLE)
5408     {
5409       if (!REG_P (operands[1]))
5410         operands[1] = force_reg (SImode, operands[1]);
5411       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5412       DONE;
5413     }
5414   else if (TARGET_LFIWZX && TARGET_FCFID)
5415     {
5416       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5417       DONE;
5418     }
5419   else if (TARGET_FCFID)
5420     {
5421       rtx dreg = operands[1];
5422       if (!REG_P (dreg))
5423         dreg = force_reg (SImode, dreg);
5424       dreg = convert_to_mode (DImode, dreg, true);
5425       emit_insn (gen_floatdidf2 (operands[0], dreg));
5426       DONE;
5427     }
5429   if (!REG_P (operands[1]))
5430     operands[1] = force_reg (SImode, operands[1]);
5431   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5432   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5433   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5434   operands[5] = gen_reg_rtx (DFmode);
5437 (define_insn_and_split "*floatunssidf2_internal"
5438   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5439         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5440    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5441    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5442    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5443    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5444   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5445    && !(TARGET_FCFID && TARGET_POWERPC64)"
5446   "#"
5447   ""
5448   [(pc)]
5449   "
5451   rtx lowword, highword;
5452   gcc_assert (MEM_P (operands[4]));
5453   highword = adjust_address (operands[4], SImode, 0);
5454   lowword = adjust_address (operands[4], SImode, 4);
5455   if (! WORDS_BIG_ENDIAN)
5456     std::swap (lowword, highword);
5458   emit_move_insn (lowword, operands[1]);
5459   emit_move_insn (highword, operands[2]);
5460   emit_move_insn (operands[5], operands[4]);
5461   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5462   DONE;
5464   [(set_attr "length" "20")
5465    (set_attr "type" "fp")])
5467 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5468 ;; vector registers.  These insns favor doing the sign/zero extension in
5469 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5470 ;; extension and then a direct move.
5472 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5473   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5474                    (float:FP_ISA3
5475                     (match_operand:QHI 1 "input_operand")))
5476               (clobber (match_scratch:DI 2))
5477               (clobber (match_scratch:DI 3))
5478               (clobber (match_scratch:<QHI:MODE> 4))])]
5479   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5480    && TARGET_VSX_SMALL_INTEGER"
5482   if (MEM_P (operands[1]))
5483     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5486 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5487   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5488         (float:FP_ISA3
5489          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5490    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5491    (clobber (match_scratch:DI 3 "=X,r,X"))
5492    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5493   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5494    && TARGET_UPPER_REGS_DI && TARGET_VSX_SMALL_INTEGER"
5495   "#"
5496   "&& reload_completed"
5497   [(const_int 0)]
5499   rtx result = operands[0];
5500   rtx input = operands[1];
5501   rtx di = operands[2];
5503   if (!MEM_P (input))
5504     {
5505       rtx tmp = operands[3];
5506       if (altivec_register_operand (input, <QHI:MODE>mode))
5507         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5508       else if (GET_CODE (tmp) == SCRATCH)
5509         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5510       else
5511         {
5512           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5513           emit_move_insn (di, tmp);
5514         }
5515     }
5516   else
5517     {
5518       rtx tmp = operands[4];
5519       emit_move_insn (tmp, input);
5520       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5521     }
5523   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5524   DONE;
5527 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5528   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5529                    (unsigned_float:FP_ISA3
5530                     (match_operand:QHI 1 "input_operand" "")))
5531               (clobber (match_scratch:DI 2 ""))
5532               (clobber (match_scratch:DI 3 ""))])]
5533   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5534    && TARGET_VSX_SMALL_INTEGER"
5536   if (MEM_P (operands[1]))
5537     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5540 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5541   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5542         (unsigned_float:FP_ISA3
5543          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5544    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5545    (clobber (match_scratch:DI 3 "=X,r,X"))]
5546   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5547    && TARGET_VSX_SMALL_INTEGER"
5548   "#"
5549   "&& reload_completed"
5550   [(const_int 0)]
5552   rtx result = operands[0];
5553   rtx input = operands[1];
5554   rtx di = operands[2];
5556   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5557     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5558   else
5559     {
5560       rtx tmp = operands[3];
5561       if (GET_CODE (tmp) == SCRATCH)
5562         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5563       else
5564         {
5565           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5566           emit_move_insn (di, tmp);
5567         }
5568     }
5570   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5571   DONE;
5574 (define_expand "fix_trunc<mode>si2"
5575   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5576         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5577   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5578   "
5580   if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER)
5581     {
5582       rtx src = force_reg (<MODE>mode, operands[1]);
5584       if (TARGET_STFIWX)
5585         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5586       else
5587         {
5588           rtx tmp = gen_reg_rtx (DImode);
5589           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5590           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5591                                                       tmp, stack));
5592         }
5593       DONE;
5594     }
5597 ; Like the convert to float patterns, this insn must be split before
5598 ; register allocation so that it can allocate the memory slot if it
5599 ; needed
5600 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5601   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5602         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5603    (clobber (match_scratch:DI 2 "=d"))]
5604   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5605    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5606    && TARGET_STFIWX && can_create_pseudo_p ()
5607    && !TARGET_VSX_SMALL_INTEGER"
5608   "#"
5609   ""
5610   [(pc)]
5612   rtx dest = operands[0];
5613   rtx src = operands[1];
5614   rtx tmp = operands[2];
5616   if (GET_CODE (tmp) == SCRATCH)
5617     tmp = gen_reg_rtx (DImode);
5619   emit_insn (gen_fctiwz_<mode> (tmp, src));
5620   if (MEM_P (dest))
5621     {
5622       dest = rs6000_address_for_fpconvert (dest);
5623       emit_insn (gen_stfiwx (dest, tmp));
5624       DONE;
5625     }
5626   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5627     {
5628       dest = gen_lowpart (DImode, dest);
5629       emit_move_insn (dest, tmp);
5630       DONE;
5631     }
5632   else
5633     {
5634       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5635       emit_insn (gen_stfiwx (stack, tmp));
5636       emit_move_insn (dest, stack);
5637       DONE;
5638     }
5640   [(set_attr "length" "12")
5641    (set_attr "type" "fp")])
5643 (define_insn_and_split "fix_trunc<mode>si2_internal"
5644   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5645         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5646    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5647    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5648   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5649    && !TARGET_VSX_SMALL_INTEGER"
5650   "#"
5651   ""
5652   [(pc)]
5653   "
5655   rtx lowword;
5656   gcc_assert (MEM_P (operands[3]));
5657   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5659   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5660   emit_move_insn (operands[3], operands[2]);
5661   emit_move_insn (operands[0], lowword);
5662   DONE;
5664   [(set_attr "length" "16")
5665    (set_attr "type" "fp")])
5667 (define_expand "fix_trunc<mode>di2"
5668   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5669         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5670   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5671    && TARGET_FCFID"
5672   "")
5674 (define_insn "*fix_trunc<mode>di2_fctidz"
5675   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5676         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5677   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5678     && TARGET_FCFID"
5679   "@
5680    fctidz %0,%1
5681    xscvdpsxds %x0,%x1"
5682   [(set_attr "type" "fp")])
5684 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5685   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5686                    (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5687               (clobber (match_scratch:DI 2))])]
5688   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5689    && TARGET_VSX_SMALL_INTEGER"
5691   if (MEM_P (operands[0]))
5692     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5695 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5696   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5697         (fix:QHI
5698          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5699    (clobber (match_scratch:DI 2 "=X,wi"))]
5700   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5701    && TARGET_VSX_SMALL_INTEGER"
5702   "#"
5703   "&& reload_completed"
5704   [(const_int 0)]
5706   rtx dest = operands[0];
5707   rtx src = operands[1];
5709   if (vsx_register_operand (dest, <QHI:MODE>mode))
5710     {
5711       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5712       emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5713     }
5714   else
5715     {
5716       rtx tmp = operands[2];
5717       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5719       emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5720       emit_move_insn (dest, tmp2);
5721     }
5722   DONE;
5725 (define_expand "fixuns_trunc<mode>si2"
5726   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5727         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5728   "TARGET_HARD_FLOAT
5729    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5730        || <E500_CONVERT>)"
5731   "
5733   if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER)
5734     {
5735       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5736       DONE;
5737     }
5740 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5741   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5742         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5743    (clobber (match_scratch:DI 2 "=d"))]
5744   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5745    && TARGET_STFIWX && can_create_pseudo_p ()
5746    && !TARGET_VSX_SMALL_INTEGER"
5747   "#"
5748   ""
5749   [(pc)]
5751   rtx dest = operands[0];
5752   rtx src = operands[1];
5753   rtx tmp = operands[2];
5755   if (GET_CODE (tmp) == SCRATCH)
5756     tmp = gen_reg_rtx (DImode);
5758   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5759   if (MEM_P (dest))
5760     {
5761       dest = rs6000_address_for_fpconvert (dest);
5762       emit_insn (gen_stfiwx (dest, tmp));
5763       DONE;
5764     }
5765   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5766     {
5767       dest = gen_lowpart (DImode, dest);
5768       emit_move_insn (dest, tmp);
5769       DONE;
5770     }
5771   else
5772     {
5773       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5774       emit_insn (gen_stfiwx (stack, tmp));
5775       emit_move_insn (dest, stack);
5776       DONE;
5777     }
5779   [(set_attr "length" "12")
5780    (set_attr "type" "fp")])
5782 (define_insn "fixuns_trunc<mode>di2"
5783   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5784         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5785   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ"
5786   "@
5787    fctiduz %0,%1
5788    xscvdpuxds %x0,%x1"
5789   [(set_attr "type" "fp")])
5791 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5792   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5793                    (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5794               (clobber (match_scratch:DI 2))])]
5795   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5796    && TARGET_VSX_SMALL_INTEGER"
5798   if (MEM_P (operands[0]))
5799     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5802 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5803   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5804         (unsigned_fix:QHI
5805          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5806    (clobber (match_scratch:DI 2 "=X,wi"))]
5807   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5808    && TARGET_VSX_SMALL_INTEGER"
5809   "#"
5810   "&& reload_completed"
5811   [(const_int 0)]
5813   rtx dest = operands[0];
5814   rtx src = operands[1];
5816   if (vsx_register_operand (dest, <QHI:MODE>mode))
5817     {
5818       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5819       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5820     }
5821   else
5822     {
5823       rtx tmp = operands[2];
5824       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5826       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5827       emit_move_insn (dest, tmp2);
5828     }
5829   DONE;
5832 ;; If -mvsx-small-integer, we can represent the FIX operation directly.  On
5833 ;; older machines, we have to use an UNSPEC to produce a SImode and move it
5834 ;; to another location, since SImode is not allowed in vector registers.
5835 (define_insn "*fctiw<u>z_<mode>_smallint"
5836   [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5837         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5838   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5839    && TARGET_VSX_SMALL_INTEGER"
5840   "@
5841    fctiw<u>z %0,%1
5842    xscvdp<su>xws %x0,%x1"
5843   [(set_attr "type" "fp")])
5845 ;; Combiner pattern to prevent moving the result of converting a floating point
5846 ;; value to 32-bit integer to GPR in order to save it.
5847 (define_insn_and_split "*fctiw<u>z_<mode>_mem"
5848   [(set (match_operand:SI 0 "memory_operand" "=Z")
5849         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5850    (clobber (match_scratch:SI 2 "=wa"))]
5851   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5852    && TARGET_VSX_SMALL_INTEGER"
5853   "#"
5854   "&& reload_completed"
5855   [(set (match_dup 2)
5856         (any_fix:SI (match_dup 1)))
5857    (set (match_dup 0)
5858         (match_dup 2))])
5860 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5861 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5862 ;; because the first makes it clear that operand 0 is not live
5863 ;; before the instruction.
5864 (define_insn "fctiwz_<mode>"
5865   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5866         (unspec:DI [(fix:SI
5867                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5868                    UNSPEC_FCTIWZ))]
5869   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5870   "@
5871    fctiwz %0,%1
5872    xscvdpsxws %x0,%x1"
5873   [(set_attr "type" "fp")])
5875 (define_insn "fctiwuz_<mode>"
5876   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5877         (unspec:DI [(unsigned_fix:SI
5878                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5879                    UNSPEC_FCTIWUZ))]
5880   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5881   "@
5882    fctiwuz %0,%1
5883    xscvdpuxws %x0,%x1"
5884   [(set_attr "type" "fp")])
5886 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5887 ;; since the friz instruction does not truncate the value if the floating
5888 ;; point value is < LONG_MIN or > LONG_MAX.
5889 (define_insn "*friz"
5890   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5891         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5892   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5893    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5894   "@
5895    friz %0,%1
5896    xsrdpiz %x0,%x1"
5897   [(set_attr "type" "fp")])
5899 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5900 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5901 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5902 ;; extend it, store it back on the stack from the GPR, load it back into the
5903 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5904 ;; disable using store and load to sign/zero extend the value.
5905 (define_insn_and_split "*round32<mode>2_fprs"
5906   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5907         (float:SFDF
5908          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5909    (clobber (match_scratch:DI 2 "=d"))
5910    (clobber (match_scratch:DI 3 "=d"))]
5911   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5912    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5913    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5914   "#"
5915   ""
5916   [(pc)]
5918   rtx dest = operands[0];
5919   rtx src = operands[1];
5920   rtx tmp1 = operands[2];
5921   rtx tmp2 = operands[3];
5922   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5924   if (GET_CODE (tmp1) == SCRATCH)
5925     tmp1 = gen_reg_rtx (DImode);
5926   if (GET_CODE (tmp2) == SCRATCH)
5927     tmp2 = gen_reg_rtx (DImode);
5929   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5930   emit_insn (gen_stfiwx (stack, tmp1));
5931   emit_insn (gen_lfiwax (tmp2, stack));
5932   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5933   DONE;
5935   [(set_attr "type" "fpload")
5936    (set_attr "length" "16")])
5938 (define_insn_and_split "*roundu32<mode>2_fprs"
5939   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5940         (unsigned_float:SFDF
5941          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5942    (clobber (match_scratch:DI 2 "=d"))
5943    (clobber (match_scratch:DI 3 "=d"))]
5944   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5945    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5946    && can_create_pseudo_p ()"
5947   "#"
5948   ""
5949   [(pc)]
5951   rtx dest = operands[0];
5952   rtx src = operands[1];
5953   rtx tmp1 = operands[2];
5954   rtx tmp2 = operands[3];
5955   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5957   if (GET_CODE (tmp1) == SCRATCH)
5958     tmp1 = gen_reg_rtx (DImode);
5959   if (GET_CODE (tmp2) == SCRATCH)
5960     tmp2 = gen_reg_rtx (DImode);
5962   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5963   emit_insn (gen_stfiwx (stack, tmp1));
5964   emit_insn (gen_lfiwzx (tmp2, stack));
5965   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5966   DONE;
5968   [(set_attr "type" "fpload")
5969    (set_attr "length" "16")])
5971 ;; No VSX equivalent to fctid
5972 (define_insn "lrint<mode>di2"
5973   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5974         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5975                    UNSPEC_FCTID))]
5976   "TARGET_<MODE>_FPR && TARGET_FPRND"
5977   "fctid %0,%1"
5978   [(set_attr "type" "fp")])
5980 (define_insn "btrunc<mode>2"
5981   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5982         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5983                      UNSPEC_FRIZ))]
5984   "TARGET_<MODE>_FPR && TARGET_FPRND"
5985   "@
5986    friz %0,%1
5987    xsrdpiz %x0,%x1"
5988   [(set_attr "type" "fp")
5989    (set_attr "fp_type" "fp_addsub_<Fs>")])
5991 (define_insn "ceil<mode>2"
5992   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5993         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5994                      UNSPEC_FRIP))]
5995   "TARGET_<MODE>_FPR && TARGET_FPRND"
5996   "@
5997    frip %0,%1
5998    xsrdpip %x0,%x1"
5999   [(set_attr "type" "fp")
6000    (set_attr "fp_type" "fp_addsub_<Fs>")])
6002 (define_insn "floor<mode>2"
6003   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6004         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6005                      UNSPEC_FRIM))]
6006   "TARGET_<MODE>_FPR && TARGET_FPRND"
6007   "@
6008    frim %0,%1
6009    xsrdpim %x0,%x1"
6010   [(set_attr "type" "fp")
6011    (set_attr "fp_type" "fp_addsub_<Fs>")])
6013 ;; No VSX equivalent to frin
6014 (define_insn "round<mode>2"
6015   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6016         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6017                      UNSPEC_FRIN))]
6018   "TARGET_<MODE>_FPR && TARGET_FPRND"
6019   "frin %0,%1"
6020   [(set_attr "type" "fp")
6021    (set_attr "fp_type" "fp_addsub_<Fs>")])
6023 (define_insn "*xsrdpi<mode>2"
6024   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6025         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6026                      UNSPEC_XSRDPI))]
6027   "TARGET_<MODE>_FPR && TARGET_VSX"
6028   "xsrdpi %x0,%x1"
6029   [(set_attr "type" "fp")
6030    (set_attr "fp_type" "fp_addsub_<Fs>")])
6032 (define_expand "lround<mode>di2"
6033   [(set (match_dup 2)
6034         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
6035                      UNSPEC_XSRDPI))
6036    (set (match_operand:DI 0 "gpc_reg_operand" "")
6037         (unspec:DI [(match_dup 2)]
6038                    UNSPEC_FCTID))]
6039   "TARGET_<MODE>_FPR && TARGET_VSX"
6041   operands[2] = gen_reg_rtx (<MODE>mode);
6044 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6045 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6046 ; is only generated for Power8 or later.
6047 (define_insn "stfiwx"
6048   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6049         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6050                    UNSPEC_STFIWX))]
6051   "TARGET_PPC_GFXOPT"
6052   "@
6053    stfiwx %1,%y0
6054    stxsiwx %x1,%y0"
6055   [(set_attr "type" "fpstore")])
6057 ;; If we don't have a direct conversion to single precision, don't enable this
6058 ;; conversion for 32-bit without fast math, because we don't have the insn to
6059 ;; generate the fixup swizzle to avoid double rounding problems.
6060 (define_expand "floatsisf2"
6061   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6062         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6063   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6064    && (!TARGET_FPRS
6065        || (TARGET_FPRS
6066            && ((TARGET_FCFIDS && TARGET_LFIWAX)
6067                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6068                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
6069   "
6071   if (!TARGET_FPRS)
6072     {
6073       if (!REG_P (operands[1]))
6074         operands[1] = force_reg (SImode, operands[1]);
6075     }
6076   else if (TARGET_FCFIDS && TARGET_LFIWAX)
6077     {
6078       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6079       DONE;
6080     }
6081   else if (TARGET_FCFID && TARGET_LFIWAX)
6082     {
6083       rtx dfreg = gen_reg_rtx (DFmode);
6084       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6085       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6086       DONE;
6087     }
6088   else
6089     {
6090       rtx dreg = operands[1];
6091       if (!REG_P (dreg))
6092         dreg = force_reg (SImode, dreg);
6093       dreg = convert_to_mode (DImode, dreg, false);
6094       emit_insn (gen_floatdisf2 (operands[0], dreg));
6095       DONE;
6096     }
6099 (define_expand "floatdidf2"
6100   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6101         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6102   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6103   "")
6105 (define_insn "*floatdidf2_fpr"
6106   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6107         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6108   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6109   "@
6110    fcfid %0,%1
6111    xscvsxddp %x0,%x1"
6112   [(set_attr "type" "fp")])
6114 ; Allow the combiner to merge source memory operands to the conversion so that
6115 ; the optimizer/register allocator doesn't try to load the value too early in a
6116 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6117 ; hit.  We will split after reload to avoid the trip through the GPRs
6119 (define_insn_and_split "*floatdidf2_mem"
6120   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6121         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6122    (clobber (match_scratch:DI 2 "=d,wi"))]
6123   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6124   "#"
6125   "&& reload_completed"
6126   [(set (match_dup 2) (match_dup 1))
6127    (set (match_dup 0) (float:DF (match_dup 2)))]
6128   ""
6129   [(set_attr "length" "8")
6130    (set_attr "type" "fpload")])
6132 (define_expand "floatunsdidf2"
6133   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6134         (unsigned_float:DF
6135          (match_operand:DI 1 "gpc_reg_operand" "")))]
6136   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6137   "")
6139 (define_insn "*floatunsdidf2_fcfidu"
6140   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6141         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6142   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6143   "@
6144    fcfidu %0,%1
6145    xscvuxddp %x0,%x1"
6146   [(set_attr "type" "fp")
6147    (set_attr "length" "4")])
6149 (define_insn_and_split "*floatunsdidf2_mem"
6150   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6151         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6152    (clobber (match_scratch:DI 2 "=d,wi"))]
6153   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6154   "#"
6155   "&& reload_completed"
6156   [(set (match_dup 2) (match_dup 1))
6157    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6158   ""
6159   [(set_attr "length" "8")
6160    (set_attr "type" "fpload")])
6162 (define_expand "floatdisf2"
6163   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6164         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6165   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6166    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6167   "
6169   if (!TARGET_FCFIDS)
6170     {
6171       rtx val = operands[1];
6172       if (!flag_unsafe_math_optimizations)
6173         {
6174           rtx label = gen_label_rtx ();
6175           val = gen_reg_rtx (DImode);
6176           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6177           emit_label (label);
6178         }
6179       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6180       DONE;
6181     }
6184 (define_insn "floatdisf2_fcfids"
6185   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6186         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6187   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6188    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6189   "@
6190    fcfids %0,%1
6191    xscvsxdsp %x0,%x1"
6192   [(set_attr "type" "fp")])
6194 (define_insn_and_split "*floatdisf2_mem"
6195   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6196         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6197    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6198   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6199    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6200   "#"
6201   "&& reload_completed"
6202   [(pc)]
6203   "
6205   emit_move_insn (operands[2], operands[1]);
6206   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6207   DONE;
6209   [(set_attr "length" "8")])
6211 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6212 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6213 ;; from double rounding.
6214 ;; Instead of creating a new cpu type for two FP operations, just use fp
6215 (define_insn_and_split "floatdisf2_internal1"
6216   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6217         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6218    (clobber (match_scratch:DF 2 "=d"))]
6219   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6220    && !TARGET_FCFIDS"
6221   "#"
6222   "&& reload_completed"
6223   [(set (match_dup 2)
6224         (float:DF (match_dup 1)))
6225    (set (match_dup 0)
6226         (float_truncate:SF (match_dup 2)))]
6227   ""
6228   [(set_attr "length" "8")
6229    (set_attr "type" "fp")])
6231 ;; Twiddles bits to avoid double rounding.
6232 ;; Bits that might be truncated when converting to DFmode are replaced
6233 ;; by a bit that won't be lost at that stage, but is below the SFmode
6234 ;; rounding position.
6235 (define_expand "floatdisf2_internal2"
6236   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6237                                               (const_int 53)))
6238               (clobber (reg:DI CA_REGNO))])
6239    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6240                                            (const_int 2047)))
6241    (set (match_dup 3) (plus:DI (match_dup 3)
6242                                (const_int 1)))
6243    (set (match_dup 0) (plus:DI (match_dup 0)
6244                                (const_int 2047)))
6245    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6246                                      (const_int 2)))
6247    (set (match_dup 0) (ior:DI (match_dup 0)
6248                               (match_dup 1)))
6249    (set (match_dup 0) (and:DI (match_dup 0)
6250                               (const_int -2048)))
6251    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6252                            (label_ref (match_operand:DI 2 "" ""))
6253                            (pc)))
6254    (set (match_dup 0) (match_dup 1))]
6255   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6256    && !TARGET_FCFIDS"
6257   "
6259   operands[3] = gen_reg_rtx (DImode);
6260   operands[4] = gen_reg_rtx (CCUNSmode);
6263 (define_expand "floatunsdisf2"
6264   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6265         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6266   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6267    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6268   "")
6270 (define_insn "floatunsdisf2_fcfidus"
6271   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6272         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6273   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6274    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6275   "@
6276    fcfidus %0,%1
6277    xscvuxdsp %x0,%x1"
6278   [(set_attr "type" "fp")])
6280 (define_insn_and_split "*floatunsdisf2_mem"
6281   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6282         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6283    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6284   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6285    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6286   "#"
6287   "&& reload_completed"
6288   [(pc)]
6289   "
6291   emit_move_insn (operands[2], operands[1]);
6292   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6293   DONE;
6295   [(set_attr "length" "8")
6296    (set_attr "type" "fpload")])
6298 ;; Define the TImode operations that can be done in a small number
6299 ;; of instructions.  The & constraints are to prevent the register
6300 ;; allocator from allocating registers that overlap with the inputs
6301 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6302 ;; also allow for the output being the same as one of the inputs.
6304 (define_expand "addti3"
6305   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6306         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6307                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6308   "TARGET_64BIT"
6310   rtx lo0 = gen_lowpart (DImode, operands[0]);
6311   rtx lo1 = gen_lowpart (DImode, operands[1]);
6312   rtx lo2 = gen_lowpart (DImode, operands[2]);
6313   rtx hi0 = gen_highpart (DImode, operands[0]);
6314   rtx hi1 = gen_highpart (DImode, operands[1]);
6315   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6317   if (!reg_or_short_operand (lo2, DImode))
6318     lo2 = force_reg (DImode, lo2);
6319   if (!adde_operand (hi2, DImode))
6320     hi2 = force_reg (DImode, hi2);
6322   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6323   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6324   DONE;
6327 (define_expand "subti3"
6328   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6329         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6330                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6331   "TARGET_64BIT"
6333   rtx lo0 = gen_lowpart (DImode, operands[0]);
6334   rtx lo1 = gen_lowpart (DImode, operands[1]);
6335   rtx lo2 = gen_lowpart (DImode, operands[2]);
6336   rtx hi0 = gen_highpart (DImode, operands[0]);
6337   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6338   rtx hi2 = gen_highpart (DImode, operands[2]);
6340   if (!reg_or_short_operand (lo1, DImode))
6341     lo1 = force_reg (DImode, lo1);
6342   if (!adde_operand (hi1, DImode))
6343     hi1 = force_reg (DImode, hi1);
6345   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6346   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6347   DONE;
6350 ;; 128-bit logical operations expanders
6352 (define_expand "and<mode>3"
6353   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6354         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6355                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6356   ""
6357   "")
6359 (define_expand "ior<mode>3"
6360   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6361         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6362                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6363   ""
6364   "")
6366 (define_expand "xor<mode>3"
6367   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6368         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6369                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6370   ""
6371   "")
6373 (define_expand "one_cmpl<mode>2"
6374   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6375         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6376   ""
6377   "")
6379 (define_expand "nor<mode>3"
6380   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6381         (and:BOOL_128
6382          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6383          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6384   ""
6385   "")
6387 (define_expand "andc<mode>3"
6388   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6389         (and:BOOL_128
6390          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6391          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6392   ""
6393   "")
6395 ;; Power8 vector logical instructions.
6396 (define_expand "eqv<mode>3"
6397   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6398         (not:BOOL_128
6399          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6400                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6401   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6402   "")
6404 ;; Rewrite nand into canonical form
6405 (define_expand "nand<mode>3"
6406   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6407         (ior:BOOL_128
6408          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6409          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6410   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6411   "")
6413 ;; The canonical form is to have the negated element first, so we need to
6414 ;; reverse arguments.
6415 (define_expand "orc<mode>3"
6416   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6417         (ior:BOOL_128
6418          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6419          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6420   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6421   "")
6423 ;; 128-bit logical operations insns and split operations
6424 (define_insn_and_split "*and<mode>3_internal"
6425   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6426         (and:BOOL_128
6427          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6428          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6429   ""
6431   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6432     return "xxland %x0,%x1,%x2";
6434   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6435     return "vand %0,%1,%2";
6437   return "#";
6439   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6440   [(const_int 0)]
6442   rs6000_split_logical (operands, AND, false, false, false);
6443   DONE;
6445   [(set (attr "type")
6446       (if_then_else
6447         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6448         (const_string "veclogical")
6449         (const_string "integer")))
6450    (set (attr "length")
6451       (if_then_else
6452         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6453         (const_string "4")
6454         (if_then_else
6455          (match_test "TARGET_POWERPC64")
6456          (const_string "8")
6457          (const_string "16"))))])
6459 ;; 128-bit IOR/XOR
6460 (define_insn_and_split "*bool<mode>3_internal"
6461   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6462         (match_operator:BOOL_128 3 "boolean_or_operator"
6463          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6464           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6465   ""
6467   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6468     return "xxl%q3 %x0,%x1,%x2";
6470   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6471     return "v%q3 %0,%1,%2";
6473   return "#";
6475   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6476   [(const_int 0)]
6478   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6479   DONE;
6481   [(set (attr "type")
6482       (if_then_else
6483         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6484         (const_string "veclogical")
6485         (const_string "integer")))
6486    (set (attr "length")
6487       (if_then_else
6488         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6489         (const_string "4")
6490         (if_then_else
6491          (match_test "TARGET_POWERPC64")
6492          (const_string "8")
6493          (const_string "16"))))])
6495 ;; 128-bit ANDC/ORC
6496 (define_insn_and_split "*boolc<mode>3_internal1"
6497   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6498         (match_operator:BOOL_128 3 "boolean_operator"
6499          [(not:BOOL_128
6500            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6501           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6502   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6504   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6505     return "xxl%q3 %x0,%x1,%x2";
6507   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6508     return "v%q3 %0,%1,%2";
6510   return "#";
6512   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6513    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6514   [(const_int 0)]
6516   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6517   DONE;
6519   [(set (attr "type")
6520       (if_then_else
6521         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6522         (const_string "veclogical")
6523         (const_string "integer")))
6524    (set (attr "length")
6525       (if_then_else
6526         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6527         (const_string "4")
6528         (if_then_else
6529          (match_test "TARGET_POWERPC64")
6530          (const_string "8")
6531          (const_string "16"))))])
6533 (define_insn_and_split "*boolc<mode>3_internal2"
6534   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6535         (match_operator:TI2 3 "boolean_operator"
6536          [(not:TI2
6537            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6538           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6539   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6540   "#"
6541   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6542   [(const_int 0)]
6544   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6545   DONE;
6547   [(set_attr "type" "integer")
6548    (set (attr "length")
6549         (if_then_else
6550          (match_test "TARGET_POWERPC64")
6551          (const_string "8")
6552          (const_string "16")))])
6554 ;; 128-bit NAND/NOR
6555 (define_insn_and_split "*boolcc<mode>3_internal1"
6556   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6557         (match_operator:BOOL_128 3 "boolean_operator"
6558          [(not:BOOL_128
6559            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6560           (not:BOOL_128
6561            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6562   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6564   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6565     return "xxl%q3 %x0,%x1,%x2";
6567   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6568     return "v%q3 %0,%1,%2";
6570   return "#";
6572   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6573    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6574   [(const_int 0)]
6576   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6577   DONE;
6579   [(set (attr "type")
6580       (if_then_else
6581         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6582         (const_string "veclogical")
6583         (const_string "integer")))
6584    (set (attr "length")
6585       (if_then_else
6586         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6587         (const_string "4")
6588         (if_then_else
6589          (match_test "TARGET_POWERPC64")
6590          (const_string "8")
6591          (const_string "16"))))])
6593 (define_insn_and_split "*boolcc<mode>3_internal2"
6594   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6595         (match_operator:TI2 3 "boolean_operator"
6596          [(not:TI2
6597            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6598           (not:TI2
6599            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6600   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6601   "#"
6602   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6603   [(const_int 0)]
6605   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6606   DONE;
6608   [(set_attr "type" "integer")
6609    (set (attr "length")
6610         (if_then_else
6611          (match_test "TARGET_POWERPC64")
6612          (const_string "8")
6613          (const_string "16")))])
6616 ;; 128-bit EQV
6617 (define_insn_and_split "*eqv<mode>3_internal1"
6618   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6619         (not:BOOL_128
6620          (xor:BOOL_128
6621           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6622           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6623   "TARGET_P8_VECTOR"
6625   if (vsx_register_operand (operands[0], <MODE>mode))
6626     return "xxleqv %x0,%x1,%x2";
6628   return "#";
6630   "TARGET_P8_VECTOR && reload_completed
6631    && int_reg_operand (operands[0], <MODE>mode)"
6632   [(const_int 0)]
6634   rs6000_split_logical (operands, XOR, true, false, false);
6635   DONE;
6637   [(set (attr "type")
6638       (if_then_else
6639         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6640         (const_string "veclogical")
6641         (const_string "integer")))
6642    (set (attr "length")
6643       (if_then_else
6644         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6645         (const_string "4")
6646         (if_then_else
6647          (match_test "TARGET_POWERPC64")
6648          (const_string "8")
6649          (const_string "16"))))])
6651 (define_insn_and_split "*eqv<mode>3_internal2"
6652   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6653         (not:TI2
6654          (xor:TI2
6655           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6656           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6657   "!TARGET_P8_VECTOR"
6658   "#"
6659   "reload_completed && !TARGET_P8_VECTOR"
6660   [(const_int 0)]
6662   rs6000_split_logical (operands, XOR, true, false, false);
6663   DONE;
6665   [(set_attr "type" "integer")
6666    (set (attr "length")
6667         (if_then_else
6668          (match_test "TARGET_POWERPC64")
6669          (const_string "8")
6670          (const_string "16")))])
6672 ;; 128-bit one's complement
6673 (define_insn_and_split "*one_cmpl<mode>3_internal"
6674   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6675         (not:BOOL_128
6676           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6677   ""
6679   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6680     return "xxlnor %x0,%x1,%x1";
6682   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6683     return "vnor %0,%1,%1";
6685   return "#";
6687   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6688   [(const_int 0)]
6690   rs6000_split_logical (operands, NOT, false, false, false);
6691   DONE;
6693   [(set (attr "type")
6694       (if_then_else
6695         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6696         (const_string "veclogical")
6697         (const_string "integer")))
6698    (set (attr "length")
6699       (if_then_else
6700         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6701         (const_string "4")
6702         (if_then_else
6703          (match_test "TARGET_POWERPC64")
6704          (const_string "8")
6705          (const_string "16"))))])
6708 ;; Now define ways of moving data around.
6710 ;; Set up a register with a value from the GOT table
6712 (define_expand "movsi_got"
6713   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6714         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6715                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6716   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6717   "
6719   if (GET_CODE (operands[1]) == CONST)
6720     {
6721       rtx offset = const0_rtx;
6722       HOST_WIDE_INT value;
6724       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6725       value = INTVAL (offset);
6726       if (value != 0)
6727         {
6728           rtx tmp = (!can_create_pseudo_p ()
6729                      ? operands[0]
6730                      : gen_reg_rtx (Pmode));
6731           emit_insn (gen_movsi_got (tmp, operands[1]));
6732           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6733           DONE;
6734         }
6735     }
6737   operands[2] = rs6000_got_register (operands[1]);
6740 (define_insn "*movsi_got_internal"
6741   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6742         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6743                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6744                    UNSPEC_MOVSI_GOT))]
6745   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6746   "lwz %0,%a1@got(%2)"
6747   [(set_attr "type" "load")])
6749 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6750 ;; didn't get allocated to a hard register.
6751 (define_split
6752   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6753         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6754                     (match_operand:SI 2 "memory_operand" "")]
6755                    UNSPEC_MOVSI_GOT))]
6756   "DEFAULT_ABI == ABI_V4
6757     && flag_pic == 1
6758     && (reload_in_progress || reload_completed)"
6759   [(set (match_dup 0) (match_dup 2))
6760    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6761                                  UNSPEC_MOVSI_GOT))]
6762   "")
6764 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6765 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6766 ;; and this is even supposed to be faster, but it is simpler not to get
6767 ;; integers in the TOC.
6768 (define_insn "movsi_low"
6769   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6770         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6771                            (match_operand 2 "" ""))))]
6772   "TARGET_MACHO && ! TARGET_64BIT"
6773   "lwz %0,lo16(%2)(%1)"
6774   [(set_attr "type" "load")
6775    (set_attr "length" "4")])
6777 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6778 ;;              STW          STFIWX       STXSIWX      LI           LIS
6779 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6780 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6781 ;;              MF%1         MT%0         MT%0         NOP
6782 (define_insn "*movsi_internal1"
6783   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6784                 "=r,         r,           r,           ?*wI,        ?*wH,
6785                  m,          ?Z,          ?Z,          r,           r,
6786                  r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6787                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6788                  r,          *c*l,        *h,          *h")
6790         (match_operand:SI 1 "input_operand"
6791                 "r,          U,           m,           Z,           Z,
6792                  r,          wI,          wH,          I,           L,
6793                  n,          wIwH,        O,           wM,          wB,
6794                  O,          wM,          wS,          r,           wIwH,
6795                  *h,         r,           r,           0"))]
6797   "!TARGET_SINGLE_FPU &&
6798    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6799   "@
6800    mr %0,%1
6801    la %0,%a1
6802    lwz%U1%X1 %0,%1
6803    lfiwzx %0,%y1
6804    lxsiwzx %x0,%y1
6805    stw%U0%X0 %1,%0
6806    stfiwx %1,%y0
6807    stxsiwx %x1,%y0
6808    li %0,%1
6809    lis %0,%v1
6810    #
6811    xxlor %x0,%x1,%x1
6812    xxspltib %x0,0
6813    xxspltib %x0,255
6814    vspltisw %0,%1
6815    xxlxor %x0,%x0,%x0
6816    xxlorc %x0,%x0,%x0
6817    #
6818    mtvsrwz %x0,%1
6819    mfvsrwz %0,%x1
6820    mf%1 %0
6821    mt%0 %1
6822    mt%0 %1
6823    nop"
6824   [(set_attr "type"
6825                 "*,          *,           load,        fpload,      fpload,
6826                  store,      fpstore,     fpstore,     *,           *,
6827                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6828                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6829                  *,           *,           *,           *")
6831    (set_attr "length"
6832                 "4,          4,           4,           4,           4,
6833                  4,          4,           4,           4,           4,
6834                  8,          4,           4,           4,           4,
6835                  4,          4,           8,           4,           4,
6836                  4,          4,           4,           4")])
6838 (define_insn "*movsi_internal1_single"
6839   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6840         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6841   "TARGET_SINGLE_FPU &&
6842    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6843   "@
6844    mr %0,%1
6845    la %0,%a1
6846    lwz%U1%X1 %0,%1
6847    stw%U0%X0 %1,%0
6848    li %0,%1
6849    lis %0,%v1
6850    #
6851    mf%1 %0
6852    mt%0 %1
6853    mt%0 %1
6854    nop
6855    stfs%U0%X0 %1,%0
6856    lfs%U1%X1 %0,%1"
6857   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6858    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6860 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6861 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6863 ;; Because SF values are actually stored as DF values within the vector
6864 ;; registers, we need to convert the value to the vector SF format when
6865 ;; we need to use the bits in a union or similar cases.  We only need
6866 ;; to do this transformation when the value is a vector register.  Loads,
6867 ;; stores, and transfers within GPRs are assumed to be safe.
6869 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6870 ;; no alternatives, because the call is created as part of secondary_reload,
6871 ;; and operand #2's register class is used to allocate the temporary register.
6872 ;; This function is called before reload, and it creates the temporary as
6873 ;; needed.
6875 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6876 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  MTVSRWZ
6877 ;;              VSX->VSX
6879 (define_insn_and_split "movsi_from_sf"
6880   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6881                 "=r,         r,           ?*wI,        ?*wH,     m,
6882                  m,          wY,          Z,           r,        wIwH,
6883                  ?wK")
6885         (unspec:SI [(match_operand:SF 1 "input_operand"
6886                 "r,          m,           Z,           Z,        r,
6887                  f,          wb,          wu,          wIwH,     r,
6888                  wK")]
6889                     UNSPEC_SI_FROM_SF))
6891    (clobber (match_scratch:V4SF 2
6892                 "=X,         X,           X,           X,        X,
6893                  X,          X,           X,           wa,       X,
6894                  wa"))]
6896   "TARGET_NO_SF_SUBREG
6897    && (register_operand (operands[0], SImode)
6898        || register_operand (operands[1], SFmode))"
6899   "@
6900    mr %0,%1
6901    lwz%U1%X1 %0,%1
6902    lfiwzx %0,%y1
6903    lxsiwzx %x0,%y1
6904    stw%U0%X0 %1,%0
6905    stfs%U0%X0 %1,%0
6906    stxssp %1,%0
6907    stxsspx %x1,%y0
6908    #
6909    mtvsrwz %x0,%1
6910    #"
6911   "&& reload_completed
6912    && register_operand (operands[0], SImode)
6913    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6914   [(const_int 0)]
6916   rtx op0 = operands[0];
6917   rtx op1 = operands[1];
6918   rtx op2 = operands[2];
6919   rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
6921   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6923   if (int_reg_operand (op0, SImode))
6924     {
6925       emit_insn (gen_p8_mfvsrd_4_disf (op0_di, op2));
6926       emit_insn (gen_lshrdi3 (op0_di, op0_di, GEN_INT (32)));
6927     }
6928   else
6929     {
6930       rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6931       rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6932       emit_insn (gen_vextract4b (op0_di, op1_v16qi, byte_off));
6933     }
6935   DONE;
6937   [(set_attr "type"
6938                 "*,          load,        fpload,      fpload,   store,
6939                  fpstore,    fpstore,     fpstore,     mftgpr,   mffgpr,
6940                  veclogical")
6942    (set_attr "length"
6943                 "4,          4,           4,           4,        4,
6944                  4,          4,           4,           12,       4,
6945                  8")])
6947 ;; movsi_from_sf with zero extension
6949 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6950 ;;              MTVSRWZ      VSX->VSX
6952 (define_insn_and_split "*movdi_from_sf_zero_ext"
6953   [(set (match_operand:DI 0 "gpc_reg_operand"
6954                 "=r,         r,           ?*wI,        ?*wH,     r,
6955                 wIwH,        ?wK")
6957         (zero_extend:DI
6958          (unspec:SI [(match_operand:SF 1 "input_operand"
6959                 "r,          m,           Z,           Z,        wIwH,
6960                  r,          wK")]
6961                     UNSPEC_SI_FROM_SF)))
6963    (clobber (match_scratch:V4SF 2
6964                 "=X,         X,           X,           X,        wa,
6965                  X,          wa"))]
6967   "TARGET_DIRECT_MOVE_64BIT
6968    && (register_operand (operands[0], DImode)
6969        || register_operand (operands[1], SImode))"
6970   "@
6971    rldicl %0,%1,0,32
6972    lwz%U1%X1 %0,%1
6973    lfiwzx %0,%y1
6974    lxsiwzx %x0,%y1
6975    #
6976    mtvsrwz %x0,%1
6977    #"
6978   "&& reload_completed
6979    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6980   [(const_int 0)]
6982   rtx op0 = operands[0];
6983   rtx op1 = operands[1];
6984   rtx op2 = operands[2];
6986   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6988   if (int_reg_operand (op0, DImode))
6989     {
6990       emit_insn (gen_p8_mfvsrd_4_disf (op0, op2));
6991       emit_insn (gen_lshrdi3 (op0, op0, GEN_INT (32)));
6992     }
6993   else
6994     {
6995       rtx op0_si = gen_rtx_REG (SImode, REGNO (op0));
6996       rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6997       rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6998       emit_insn (gen_vextract4b (op0_si, op1_v16qi, byte_off));
6999     }
7001   DONE;
7003   [(set_attr "type"
7004                 "*,          load,        fpload,      fpload,  mftgpr,
7005                  mffgpr,     veclogical")
7007    (set_attr "length"
7008                 "4,          4,           4,           4,        12,
7009                  4,          8")])
7011 ;; Split a load of a large constant into the appropriate two-insn
7012 ;; sequence.
7014 (define_split
7015   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7016         (match_operand:SI 1 "const_int_operand" ""))]
7017   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7018    && (INTVAL (operands[1]) & 0xffff) != 0"
7019   [(set (match_dup 0)
7020         (match_dup 2))
7021    (set (match_dup 0)
7022         (ior:SI (match_dup 0)
7023                 (match_dup 3)))]
7024   "
7026   if (rs6000_emit_set_const (operands[0], operands[1]))
7027     DONE;
7028   else
7029     FAIL;
7032 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7033 (define_split
7034   [(set (match_operand:DI 0 "altivec_register_operand")
7035         (match_operand:DI 1 "xxspltib_constant_split"))]
7036   "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
7037   [(const_int 0)]
7039   rtx op0 = operands[0];
7040   rtx op1 = operands[1];
7041   int r = REGNO (op0);
7042   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7044   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7045   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7046   DONE;
7049 (define_insn "*mov<mode>_internal2"
7050   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7051         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7052                     (const_int 0)))
7053    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7054   ""
7055   "@
7056    cmp<wd>i %2,%0,0
7057    mr. %0,%1
7058    #"
7059   [(set_attr "type" "cmp,logical,cmp")
7060    (set_attr "dot" "yes")
7061    (set_attr "length" "4,4,8")])
7063 (define_split
7064   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
7065         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
7066                     (const_int 0)))
7067    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
7068   "reload_completed"
7069   [(set (match_dup 0) (match_dup 1))
7070    (set (match_dup 2)
7071         (compare:CC (match_dup 0)
7072                     (const_int 0)))]
7073   "")
7075 (define_expand "mov<mode>"
7076   [(set (match_operand:INT 0 "general_operand" "")
7077         (match_operand:INT 1 "any_operand" ""))]
7078   ""
7079   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7081 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7082 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7083 ;;              MTVSRWZ     MF%1       MT%1       NOP
7084 (define_insn "*mov<mode>_internal"
7085   [(set (match_operand:QHI 0 "nonimmediate_operand"
7086                 "=r,        r,         ?*wJwK,    m,         Z,         r,
7087                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7088                  ?*wJwK,    r,         *c*l,      *h")
7090         (match_operand:QHI 1 "input_operand"
7091                 "r,         m,         Z,         r,         wJwK,      i,
7092                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7093                  r,         *h,        r,         0"))]
7095   "gpc_reg_operand (operands[0], <MODE>mode)
7096    || gpc_reg_operand (operands[1], <MODE>mode)"
7097   "@
7098    mr %0,%1
7099    l<wd>z%U1%X1 %0,%1
7100    lxsi<wd>zx %x0,%y1
7101    st<wd>%U0%X0 %1,%0
7102    stxsi<wd>x %x1,%y0
7103    li %0,%1
7104    xxlor %x0,%x1,%x1
7105    xxspltib %x0,0
7106    xxspltib %x0,255
7107    vspltis<wd> %0,%1
7108    #
7109    mfvsrwz %0,%x1
7110    mtvsrwz %x0,%1
7111    mf%1 %0
7112    mt%0 %1
7113    nop"
7114   [(set_attr "type"
7115                 "*,         load,      fpload,    store,     fpstore,   *,
7116                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7117                  mffgpr,    mfjmpr,    mtjmpr,    *")
7119    (set_attr "length"
7120                 "4,         4,         4,         4,         4,         4,
7121                  4,         4,         4,         4,         8,         4,
7122                  4,         4,         4,         4")])
7125 ;; Here is how to move condition codes around.  When we store CC data in
7126 ;; an integer register or memory, we store just the high-order 4 bits.
7127 ;; This lets us not shift in the most common case of CR0.
7128 (define_expand "movcc"
7129   [(set (match_operand:CC 0 "nonimmediate_operand" "")
7130         (match_operand:CC 1 "nonimmediate_operand" ""))]
7131   ""
7132   "")
7134 (define_insn "*movcc_internal1"
7135   [(set (match_operand:CC 0 "nonimmediate_operand"
7136                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7137         (match_operand:CC 1 "general_operand"
7138                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7139   "register_operand (operands[0], CCmode)
7140    || register_operand (operands[1], CCmode)"
7141   "@
7142    mcrf %0,%1
7143    mtcrf 128,%1
7144    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7145    crxor %0,%0,%0
7146    mfcr %0%Q1
7147    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7148    mr %0,%1
7149    li %0,%1
7150    mf%1 %0
7151    mt%0 %1
7152    lwz%U1%X1 %0,%1
7153    stw%U0%X0 %1,%0"
7154   [(set (attr "type")
7155      (cond [(eq_attr "alternative" "0,3")
7156                 (const_string "cr_logical")
7157             (eq_attr "alternative" "1,2")
7158                 (const_string "mtcr")
7159             (eq_attr "alternative" "6,7")
7160                 (const_string "integer")
7161             (eq_attr "alternative" "8")
7162                 (const_string "mfjmpr")
7163             (eq_attr "alternative" "9")
7164                 (const_string "mtjmpr")
7165             (eq_attr "alternative" "10")
7166                 (const_string "load")
7167             (eq_attr "alternative" "11")
7168                 (const_string "store")
7169             (match_test "TARGET_MFCRF")
7170                 (const_string "mfcrf")
7171            ]
7172         (const_string "mfcr")))
7173    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7175 ;; For floating-point, we normally deal with the floating-point registers
7176 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7177 ;; can produce floating-point values in fixed-point registers.  Unless the
7178 ;; value is a simple constant or already in memory, we deal with this by
7179 ;; allocating memory and copying the value explicitly via that memory location.
7181 ;; Move 32-bit binary/decimal floating point
7182 (define_expand "mov<mode>"
7183   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7184         (match_operand:FMOVE32 1 "any_operand" ""))]
7185   "<fmove_ok>"
7186   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7188 (define_split
7189   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7190         (match_operand:FMOVE32 1 "const_double_operand" ""))]
7191   "reload_completed
7192    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7193        || (GET_CODE (operands[0]) == SUBREG
7194            && GET_CODE (SUBREG_REG (operands[0])) == REG
7195            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7196   [(set (match_dup 2) (match_dup 3))]
7197   "
7199   long l;
7201   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7203   if (! TARGET_POWERPC64)
7204     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7205   else
7206     operands[2] = gen_lowpart (SImode, operands[0]);
7208   operands[3] = gen_int_mode (l, SImode);
7211 ;; Originally, we tried to keep movsf and movsd common, but the differences
7212 ;; addressing was making it rather difficult to hide with mode attributes.  In
7213 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7214 ;; before the VSX stores meant that the register allocator would tend to do a
7215 ;; direct move to the GPR (which involves conversion from scalar to
7216 ;; vector/memory formats) to save values in the traditional Altivec registers,
7217 ;; while SDmode had problems on power6 if the GPR store was not first due to
7218 ;; the power6 not having an integer store operation.
7220 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7221 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7222 ;;      MR           MT<x>      MF<x>       NOP
7224 (define_insn "movsf_hardfloat"
7225   [(set (match_operand:SF 0 "nonimmediate_operand"
7226          "=!r,       f,         wb,         wu,        m,         wY,
7227           Z,         m,         ww,         !r,        f,         ww,
7228           !r,        *c*l,      !r,         *h")
7229         (match_operand:SF 1 "input_operand"
7230          "m,         m,         wY,         Z,         f,         wb,
7231           wu,        r,         j,          j,         f,         ww,
7232           r,         r,         *h,         0"))]
7233   "(register_operand (operands[0], SFmode)
7234    || register_operand (operands[1], SFmode))
7235    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7236    && (TARGET_ALLOW_SF_SUBREG
7237        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7238   "@
7239    lwz%U1%X1 %0,%1
7240    lfs%U1%X1 %0,%1
7241    lxssp %0,%1
7242    lxsspx %x0,%y1
7243    stfs%U0%X0 %1,%0
7244    stxssp %1,%0
7245    stxsspx %x1,%y0
7246    stw%U0%X0 %1,%0
7247    xxlxor %x0,%x0,%x0
7248    li %0,0
7249    fmr %0,%1
7250    xscpsgndp %x0,%x1,%x1
7251    mr %0,%1
7252    mt%0 %1
7253    mf%1 %0
7254    nop"
7255   [(set_attr "type"
7256         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7257          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7258          *,          mtjmpr,    mfjmpr,     *")])
7260 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7261 ;;      FMR          MR         MT%0       MF%1       NOP
7262 (define_insn "movsd_hardfloat"
7263   [(set (match_operand:SD 0 "nonimmediate_operand"
7264          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7265           f,         !r,        *c*l,      !r,        *h")
7266         (match_operand:SD 1 "input_operand"
7267          "m,         Z,         r,         wx,        r,         wh,
7268           f,         r,         r,         *h,        0"))]
7269   "(register_operand (operands[0], SDmode)
7270    || register_operand (operands[1], SDmode))
7271    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
7272   "@
7273    lwz%U1%X1 %0,%1
7274    lfiwzx %0,%y1
7275    stw%U0%X0 %1,%0
7276    stfiwx %1,%y0
7277    mtvsrwz %x0,%1
7278    mfvsrwz %0,%x1
7279    fmr %0,%1
7280    mr %0,%1
7281    mt%0 %1
7282    mf%1 %0
7283    nop"
7284   [(set_attr "type"
7285         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7286          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7288 (define_insn "*mov<mode>_softfloat"
7289   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7290         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7291   "(gpc_reg_operand (operands[0], <MODE>mode)
7292    || gpc_reg_operand (operands[1], <MODE>mode))
7293    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
7294   "@
7295    mr %0,%1
7296    mt%0 %1
7297    mf%1 %0
7298    lwz%U1%X1 %0,%1
7299    stw%U0%X0 %1,%0
7300    li %0,%1
7301    lis %0,%v1
7302    #
7303    #
7304    nop"
7305   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7306    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7308 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7309 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7311 ;; Because SF values are actually stored as DF values within the vector
7312 ;; registers, we need to convert the value to the vector SF format when
7313 ;; we need to use the bits in a union or similar cases.  We only need
7314 ;; to do this transformation when the value is a vector register.  Loads,
7315 ;; stores, and transfers within GPRs are assumed to be safe.
7317 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7318 ;; no alternatives, because the call is created as part of secondary_reload,
7319 ;; and operand #2's register class is used to allocate the temporary register.
7320 ;; This function is called before reload, and it creates the temporary as
7321 ;; needed.
7323 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7324 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7325 (define_insn_and_split "movsf_from_si"
7326   [(set (match_operand:SF 0 "rs6000_nonimmediate_operand"
7327             "=!r,       f,         wb,        wu,        m,         Z,
7328              Z,         wy,        ?r,        !r")
7330         (unspec:SF [(match_operand:SI 1 "input_operand" 
7331             "m,         m,         wY,        Z,         r,         f,
7332              wu,        r,         wy,        r")]
7333                    UNSPEC_SF_FROM_SI))
7335    (clobber (match_scratch:DI 2
7336             "=X,        X,         X,         X,         X,         X,
7337              X,         r,         X,         X"))]
7339   "TARGET_NO_SF_SUBREG
7340    && (register_operand (operands[0], SFmode)
7341        || register_operand (operands[1], SImode))"
7342   "@
7343    lwz%U1%X1 %0,%1
7344    lfs%U1%X1 %0,%1
7345    lxssp %0,%1
7346    lxsspx %x0,%y1
7347    stw%U0%X0 %1,%0
7348    stfiwx %1,%y0
7349    stxsiwx %x1,%y0
7350    #
7351    mfvsrwz %0,%x1
7352    mr %0,%1"
7354   "&& reload_completed
7355    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7356    && int_reg_operand_not_pseudo (operands[1], SImode)"
7357   [(const_int 0)]
7359   rtx op0 = operands[0];
7360   rtx op1 = operands[1];
7361   rtx op2 = operands[2];
7362   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7364   /* Move SF value to upper 32-bits for xscvspdpn.  */
7365   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7366   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7367   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7368   DONE;
7370   [(set_attr "length"
7371             "4,          4,         4,         4,         4,         4,
7372              4,          12,        4,         4")
7373    (set_attr "type"
7374             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7375              fpstore,    vecfloat,  mffgpr,    *")])
7378 ;; Move 64-bit binary/decimal floating point
7379 (define_expand "mov<mode>"
7380   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7381         (match_operand:FMOVE64 1 "any_operand" ""))]
7382   ""
7383   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7385 (define_split
7386   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7387         (match_operand:FMOVE64 1 "const_int_operand" ""))]
7388   "! TARGET_POWERPC64 && reload_completed
7389    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7390        || (GET_CODE (operands[0]) == SUBREG
7391            && GET_CODE (SUBREG_REG (operands[0])) == REG
7392            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7393   [(set (match_dup 2) (match_dup 4))
7394    (set (match_dup 3) (match_dup 1))]
7395   "
7397   int endian = (WORDS_BIG_ENDIAN == 0);
7398   HOST_WIDE_INT value = INTVAL (operands[1]);
7400   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7401   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7402   operands[4] = GEN_INT (value >> 32);
7403   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7406 (define_split
7407   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7408         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7409   "! TARGET_POWERPC64 && reload_completed
7410    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7411        || (GET_CODE (operands[0]) == SUBREG
7412            && GET_CODE (SUBREG_REG (operands[0])) == REG
7413            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7414   [(set (match_dup 2) (match_dup 4))
7415    (set (match_dup 3) (match_dup 5))]
7416   "
7418   int endian = (WORDS_BIG_ENDIAN == 0);
7419   long l[2];
7421   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7423   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7424   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7425   operands[4] = gen_int_mode (l[endian], SImode);
7426   operands[5] = gen_int_mode (l[1 - endian], SImode);
7429 (define_split
7430   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7431         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7432   "TARGET_POWERPC64 && reload_completed
7433    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7434        || (GET_CODE (operands[0]) == SUBREG
7435            && GET_CODE (SUBREG_REG (operands[0])) == REG
7436            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7437   [(set (match_dup 2) (match_dup 3))]
7438   "
7440   int endian = (WORDS_BIG_ENDIAN == 0);
7441   long l[2];
7442   HOST_WIDE_INT val;
7444   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7446   operands[2] = gen_lowpart (DImode, operands[0]);
7447   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7448   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7449          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7451   operands[3] = gen_int_mode (val, DImode);
7454 ;; Don't have reload use general registers to load a constant.  It is
7455 ;; less efficient than loading the constant into an FP register, since
7456 ;; it will probably be used there.
7458 ;; The move constraints are ordered to prefer floating point registers before
7459 ;; general purpose registers to avoid doing a store and a load to get the value
7460 ;; into a floating point register when it is needed for a floating point
7461 ;; operation.  Prefer traditional floating point registers over VSX registers,
7462 ;; since the D-form version of the memory instructions does not need a GPR for
7463 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7464 ;; registers.
7466 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7467 ;; except for 0.0 which can be created on VSX with an xor instruction.
7469 (define_insn "*mov<mode>_hardfloat32"
7470   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7471         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7472   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7473    && (gpc_reg_operand (operands[0], <MODE>mode)
7474        || gpc_reg_operand (operands[1], <MODE>mode))"
7475   "@
7476    stfd%U0%X0 %1,%0
7477    lfd%U1%X1 %0,%1
7478    fmr %0,%1
7479    lxsd%U1x %x0,%y1
7480    stxsd%U0x %x1,%y0
7481    lxsd %0,%1
7482    stxsd %1,%0
7483    xxlor %x0,%x1,%x1
7484    xxlxor %x0,%x0,%x0
7485    #
7486    #
7487    #
7488    #"
7489   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7490    (set_attr "size" "64")
7491    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7493 (define_insn "*mov<mode>_softfloat32"
7494   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7495         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7496   "! TARGET_POWERPC64 
7497    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
7498        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
7499        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
7500    && (gpc_reg_operand (operands[0], <MODE>mode)
7501        || gpc_reg_operand (operands[1], <MODE>mode))"
7502   "#"
7503   [(set_attr "type" "store,load,two,*,*,*")
7504    (set_attr "length" "8,8,8,8,12,16")])
7506 ; ld/std require word-aligned displacements -> 'Y' constraint.
7507 ; List Y->r and r->Y before r->r for reload.
7508 (define_insn "*mov<mode>_hardfloat64"
7509   [(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>")
7510         (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"))]
7511   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7512    && (gpc_reg_operand (operands[0], <MODE>mode)
7513        || gpc_reg_operand (operands[1], <MODE>mode))"
7514   "@
7515    stfd%U0%X0 %1,%0
7516    lfd%U1%X1 %0,%1
7517    fmr %0,%1
7518    lxsd %0,%1
7519    stxsd %1,%0
7520    lxsd%U1x %x0,%y1
7521    stxsd%U0x %x1,%y0
7522    xxlor %x0,%x1,%x1
7523    xxlxor %x0,%x0,%x0
7524    li %0,0
7525    std%U0%X0 %1,%0
7526    ld%U1%X1 %0,%1
7527    mr %0,%1
7528    mt%0 %1
7529    mf%1 %0
7530    nop
7531    mftgpr %0,%1
7532    mffgpr %0,%1
7533    mfvsrd %0,%x1
7534    mtvsrd %x0,%1"
7535   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7536    (set_attr "size" "64")
7537    (set_attr "length" "4")])
7539 (define_insn "*mov<mode>_softfloat64"
7540   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7541         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7542   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7543    && (gpc_reg_operand (operands[0], <MODE>mode)
7544        || gpc_reg_operand (operands[1], <MODE>mode))"
7545   "@
7546    std%U0%X0 %1,%0
7547    ld%U1%X1 %0,%1
7548    mr %0,%1
7549    mt%0 %1
7550    mf%1 %0
7551    #
7552    #
7553    #
7554    nop"
7555   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7556    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7558 (define_expand "mov<mode>"
7559   [(set (match_operand:FMOVE128 0 "general_operand" "")
7560         (match_operand:FMOVE128 1 "any_operand" ""))]
7561   ""
7562   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7564 ;; It's important to list Y->r and r->Y before r->r because otherwise
7565 ;; reload, given m->r, will try to pick r->r and reload it, which
7566 ;; doesn't make progress.
7568 ;; We can't split little endian direct moves of TDmode, because the words are
7569 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7570 ;; problematical.  Don't allow direct move for this case.
7572 (define_insn_and_split "*mov<mode>_64bit_dm"
7573   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7574         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7575   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7576    && FLOAT128_2REG_P (<MODE>mode)
7577    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7578    && (gpc_reg_operand (operands[0], <MODE>mode)
7579        || gpc_reg_operand (operands[1], <MODE>mode))"
7580   "#"
7581   "&& reload_completed"
7582   [(pc)]
7583 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7584   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7586 (define_insn_and_split "*movtd_64bit_nodm"
7587   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7588         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7589   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7590    && (gpc_reg_operand (operands[0], TDmode)
7591        || gpc_reg_operand (operands[1], TDmode))"
7592   "#"
7593   "&& reload_completed"
7594   [(pc)]
7595 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7596   [(set_attr "length" "8,8,8,12,12,8")])
7598 (define_insn_and_split "*mov<mode>_32bit"
7599   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7600         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7601   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7602    && (FLOAT128_2REG_P (<MODE>mode)
7603        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7604        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7605    && (gpc_reg_operand (operands[0], <MODE>mode)
7606        || gpc_reg_operand (operands[1], <MODE>mode))"
7607   "#"
7608   "&& reload_completed"
7609   [(pc)]
7610 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7611   [(set_attr "length" "8,8,8,8,20,20,16")])
7613 (define_insn_and_split "*mov<mode>_softfloat"
7614   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7615         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7616   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7617    && (gpc_reg_operand (operands[0], <MODE>mode)
7618        || gpc_reg_operand (operands[1], <MODE>mode))"
7619   "#"
7620   "&& reload_completed"
7621   [(pc)]
7622 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7623   [(set_attr "length" "20,20,16")])
7625 (define_expand "extenddf<mode>2"
7626   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7627         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7628   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7629    && TARGET_LONG_DOUBLE_128"
7631   if (FLOAT128_IEEE_P (<MODE>mode))
7632     rs6000_expand_float128_convert (operands[0], operands[1], false);
7633   else if (TARGET_E500_DOUBLE)
7634     {
7635       gcc_assert (<MODE>mode == TFmode);
7636       emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7637     }
7638   else if (TARGET_VSX)
7639     {
7640       if (<MODE>mode == TFmode)
7641         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7642       else if (<MODE>mode == IFmode)
7643         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7644       else
7645         gcc_unreachable ();
7646     }
7647    else
7648     {
7649       rtx zero = gen_reg_rtx (DFmode);
7650       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7652       if (<MODE>mode == TFmode)
7653         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7654       else if (<MODE>mode == IFmode)
7655         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7656       else
7657         gcc_unreachable ();
7658     }
7659   DONE;
7662 ;; Allow memory operands for the source to be created by the combiner.
7663 (define_insn_and_split "extenddf<mode>2_fprs"
7664   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7665         (float_extend:IBM128
7666          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7667    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7668   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7669    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7670   "#"
7671   "&& reload_completed"
7672   [(set (match_dup 3) (match_dup 1))
7673    (set (match_dup 4) (match_dup 2))]
7675   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7676   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7678   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7679   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7682 (define_insn_and_split "extenddf<mode>2_vsx"
7683   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7684         (float_extend:IBM128
7685          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7686   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7687   "#"
7688   "&& reload_completed"
7689   [(set (match_dup 2) (match_dup 1))
7690    (set (match_dup 3) (match_dup 4))]
7692   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7693   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7695   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7696   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7697   operands[4] = CONST0_RTX (DFmode);
7700 (define_expand "extendsf<mode>2"
7701   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7702         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7703   "TARGET_HARD_FLOAT
7704    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7705    && TARGET_LONG_DOUBLE_128"
7707   if (FLOAT128_IEEE_P (<MODE>mode))
7708     rs6000_expand_float128_convert (operands[0], operands[1], false);
7709   else
7710     {
7711       rtx tmp = gen_reg_rtx (DFmode);
7712       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7713       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7714     }
7715   DONE;
7718 (define_expand "trunc<mode>df2"
7719   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7720         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7721   "TARGET_HARD_FLOAT
7722    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7723    && TARGET_LONG_DOUBLE_128"
7725   if (FLOAT128_IEEE_P (<MODE>mode))
7726     {
7727       rs6000_expand_float128_convert (operands[0], operands[1], false);
7728       DONE;
7729     }
7732 (define_insn_and_split "trunc<mode>df2_internal1"
7733   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7734         (float_truncate:DF
7735          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7736   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7737    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7738   "@
7739    #
7740    fmr %0,%1"
7741   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7742   [(const_int 0)]
7744   emit_note (NOTE_INSN_DELETED);
7745   DONE;
7747   [(set_attr "type" "fpsimple")])
7749 (define_insn "trunc<mode>df2_internal2"
7750   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7751         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7752   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7753    && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7754   "fadd %0,%1,%L1"
7755   [(set_attr "type" "fp")
7756    (set_attr "fp_type" "fp_addsub_d")])
7758 (define_expand "trunc<mode>sf2"
7759   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7760         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7761   "TARGET_HARD_FLOAT
7762    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7763    && TARGET_LONG_DOUBLE_128"
7765   if (FLOAT128_IEEE_P (<MODE>mode))
7766     rs6000_expand_float128_convert (operands[0], operands[1], false);
7767   else if (TARGET_E500_DOUBLE)
7768     {
7769       gcc_assert (<MODE>mode == TFmode);
7770       emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7771     }
7772   else if (<MODE>mode == TFmode)
7773     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7774   else if (<MODE>mode == IFmode)
7775     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7776   else
7777     gcc_unreachable ();
7778   DONE;
7781 (define_insn_and_split "trunc<mode>sf2_fprs"
7782   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7783         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7784    (clobber (match_scratch:DF 2 "=d"))]
7785   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
7786    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7787   "#"
7788   "&& reload_completed"
7789   [(set (match_dup 2)
7790         (float_truncate:DF (match_dup 1)))
7791    (set (match_dup 0)
7792         (float_truncate:SF (match_dup 2)))]
7793   "")
7795 (define_expand "floatsi<mode>2"
7796   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7797                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7798               (clobber (match_scratch:DI 2))])]
7799   "TARGET_HARD_FLOAT
7800    && (TARGET_FPRS || TARGET_E500_DOUBLE)
7801    && TARGET_LONG_DOUBLE_128"
7803   rtx op0 = operands[0];
7804   rtx op1 = operands[1];
7806   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7807     ;
7808   else if (FLOAT128_IEEE_P (<MODE>mode))
7809     {
7810       rs6000_expand_float128_convert (op0, op1, false);
7811       DONE;
7812     }
7813   else
7814     {
7815       rtx tmp = gen_reg_rtx (DFmode);
7816       expand_float (tmp, op1, false);
7817       if (<MODE>mode == TFmode)
7818         emit_insn (gen_extenddftf2 (op0, tmp));
7819       else if (<MODE>mode == IFmode)
7820         emit_insn (gen_extenddfif2 (op0, tmp));
7821       else
7822         gcc_unreachable ();
7823       DONE;
7824     }
7827 ; fadd, but rounding towards zero.
7828 ; This is probably not the optimal code sequence.
7829 (define_insn "fix_trunc_helper<mode>"
7830   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7831         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7832                    UNSPEC_FIX_TRUNC_TF))
7833    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7834   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7835    && FLOAT128_IBM_P (<MODE>mode)"
7836   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7837   [(set_attr "type" "fp")
7838    (set_attr "length" "20")])
7840 (define_expand "fix_trunc<mode>si2"
7841   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7842         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7843   "TARGET_HARD_FLOAT
7844    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7846   rtx op0 = operands[0];
7847   rtx op1 = operands[1];
7849   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7850     ;
7851   else
7852     {
7853       if (FLOAT128_IEEE_P (<MODE>mode))
7854         rs6000_expand_float128_convert (op0, op1, false);
7855       else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7856         emit_insn (gen_spe_fix_trunctfsi2 (op0, op1));
7857       else if (<MODE>mode == TFmode)
7858         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7859       else if (<MODE>mode == IFmode)
7860         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7861       else
7862         gcc_unreachable ();
7863       DONE;
7864     }
7867 (define_expand "fix_trunc<mode>si2_fprs"
7868   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7869                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7870               (clobber (match_dup 2))
7871               (clobber (match_dup 3))
7872               (clobber (match_dup 4))
7873               (clobber (match_dup 5))])]
7874   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7876   operands[2] = gen_reg_rtx (DFmode);
7877   operands[3] = gen_reg_rtx (DFmode);
7878   operands[4] = gen_reg_rtx (DImode);
7879   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7882 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7883   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7884         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7885    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7886    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7887    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7888    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7889   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7890   "#"
7891   ""
7892   [(pc)]
7894   rtx lowword;
7895   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7896                                          operands[3]));
7898   gcc_assert (MEM_P (operands[5]));
7899   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7901   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7902   emit_move_insn (operands[5], operands[4]);
7903   emit_move_insn (operands[0], lowword);
7904   DONE;
7907 (define_expand "fix_trunc<mode>di2"
7908   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7909         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7910   "TARGET_FLOAT128_TYPE"
7912   if (!TARGET_FLOAT128_HW)
7913     {
7914       rs6000_expand_float128_convert (operands[0], operands[1], false);
7915       DONE;
7916     }
7919 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7920   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7921         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7922   "TARGET_FLOAT128_TYPE"
7924   rs6000_expand_float128_convert (operands[0], operands[1], true);
7925   DONE;
7928 (define_expand "floatdi<mode>2"
7929   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7930         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7931   "TARGET_FLOAT128_TYPE"
7933   if (!TARGET_FLOAT128_HW)
7934     {
7935       rs6000_expand_float128_convert (operands[0], operands[1], false);
7936       DONE;
7937     }
7940 (define_expand "floatunsdi<IEEE128:mode>2"
7941   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7942         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7943   "TARGET_FLOAT128_TYPE"
7945   if (!TARGET_FLOAT128_HW)
7946     {
7947       rs6000_expand_float128_convert (operands[0], operands[1], true);
7948       DONE;
7949     }
7952 (define_expand "floatuns<IEEE128:mode>2"
7953   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7954         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7955   "TARGET_FLOAT128_TYPE"
7957   rtx op0 = operands[0];
7958   rtx op1 = operands[1];
7960   if (TARGET_FLOAT128_HW)
7961     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7962   else
7963     rs6000_expand_float128_convert (op0, op1, true);
7964   DONE;
7967 (define_expand "neg<mode>2"
7968   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7969         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7970   "FLOAT128_IEEE_P (<MODE>mode)
7971    || (FLOAT128_IBM_P (<MODE>mode)
7972        && TARGET_HARD_FLOAT
7973        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7974   "
7976   if (FLOAT128_IEEE_P (<MODE>mode))
7977     {
7978       if (TARGET_FLOAT128_HW)
7979         {
7980           if (<MODE>mode == TFmode)
7981             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7982           else if (<MODE>mode == KFmode)
7983             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7984           else
7985             gcc_unreachable ();
7986         }
7987       else if (TARGET_FLOAT128_TYPE)
7988         {
7989           if (<MODE>mode == TFmode)
7990             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7991           else if (<MODE>mode == KFmode)
7992             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7993           else
7994             gcc_unreachable ();
7995         }
7996       else
7997         {
7998           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7999           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8000                                                 <MODE>mode,
8001                                                 operands[1], <MODE>mode);
8003           if (target && !rtx_equal_p (target, operands[0]))
8004             emit_move_insn (operands[0], target);
8005         }
8006       DONE;
8007     }
8010 (define_insn "neg<mode>2_internal"
8011   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8012         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8013   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
8014   "*
8016   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8017     return \"fneg %L0,%L1\;fneg %0,%1\";
8018   else
8019     return \"fneg %0,%1\;fneg %L0,%L1\";
8021   [(set_attr "type" "fpsimple")
8022    (set_attr "length" "8")])
8024 (define_expand "abs<mode>2"
8025   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
8026         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
8027   "FLOAT128_IEEE_P (<MODE>mode)
8028    || (FLOAT128_IBM_P (<MODE>mode)
8029        && TARGET_HARD_FLOAT
8030        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
8031   "
8033   rtx label;
8035   if (FLOAT128_IEEE_P (<MODE>mode))
8036     {
8037       if (TARGET_FLOAT128_HW)
8038         {
8039           if (<MODE>mode == TFmode)
8040             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
8041           else if (<MODE>mode == KFmode)
8042             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
8043           else
8044             FAIL;
8045           DONE;
8046         }
8047       else if (TARGET_FLOAT128_TYPE)
8048         {
8049           if (<MODE>mode == TFmode)
8050             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8051           else if (<MODE>mode == KFmode)
8052             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8053           else
8054             FAIL;
8055           DONE;
8056         }
8057       else
8058         FAIL;
8059     }
8061   label = gen_label_rtx ();
8062   if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
8063     {
8064       if (flag_finite_math_only && !flag_trapping_math)
8065         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
8066       else
8067         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
8068     }
8069   else if (<MODE>mode == TFmode)
8070     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8071   else if (<MODE>mode == TFmode)
8072     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8073   else
8074     FAIL;
8075   emit_label (label);
8076   DONE;
8079 (define_expand "abs<mode>2_internal"
8080   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
8081         (match_operand:IBM128 1 "gpc_reg_operand" ""))
8082    (set (match_dup 3) (match_dup 5))
8083    (set (match_dup 5) (abs:DF (match_dup 5)))
8084    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8085    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8086                            (label_ref (match_operand 2 "" ""))
8087                            (pc)))
8088    (set (match_dup 6) (neg:DF (match_dup 6)))]
8089   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
8090    && TARGET_LONG_DOUBLE_128"
8091   "
8093   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8094   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8095   operands[3] = gen_reg_rtx (DFmode);
8096   operands[4] = gen_reg_rtx (CCFPmode);
8097   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8098   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8102 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8103 ;; register
8105 (define_expand "ieee_128bit_negative_zero"
8106   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
8107   "TARGET_FLOAT128_TYPE"
8109   rtvec v = rtvec_alloc (16);
8110   int i, high;
8112   for (i = 0; i < 16; i++)
8113     RTVEC_ELT (v, i) = const0_rtx;
8115   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8116   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8118   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8119   DONE;
8122 ;; IEEE 128-bit negate
8124 ;; We have 2 insns here for negate and absolute value.  The first uses
8125 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8126 ;; insns, and second insn after the first split pass loads up the bit to
8127 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8128 ;; neg/abs to create the constant just once.
8130 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8131   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8132         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8133    (clobber (match_scratch:V16QI 2 "=v"))]
8134   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8135   "#"
8136   "&& 1"
8137   [(parallel [(set (match_dup 0)
8138                    (neg:IEEE128 (match_dup 1)))
8139               (use (match_dup 2))])]
8141   if (GET_CODE (operands[2]) == SCRATCH)
8142     operands[2] = gen_reg_rtx (V16QImode);
8144   operands[3] = gen_reg_rtx (V16QImode);
8145   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8147   [(set_attr "length" "8")
8148    (set_attr "type" "vecsimple")])
8150 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8151   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8152         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8153    (use (match_operand:V16QI 2 "register_operand" "v"))]
8154   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8155   "xxlxor %x0,%x1,%x2"
8156   [(set_attr "type" "veclogical")])
8158 ;; IEEE 128-bit absolute value
8159 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8160   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8161         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8162    (clobber (match_scratch:V16QI 2 "=v"))]
8163   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8164   "#"
8165   "&& 1"
8166   [(parallel [(set (match_dup 0)
8167                    (abs:IEEE128 (match_dup 1)))
8168               (use (match_dup 2))])]
8170   if (GET_CODE (operands[2]) == SCRATCH)
8171     operands[2] = gen_reg_rtx (V16QImode);
8173   operands[3] = gen_reg_rtx (V16QImode);
8174   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8176   [(set_attr "length" "8")
8177    (set_attr "type" "vecsimple")])
8179 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8180   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8181         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8182    (use (match_operand:V16QI 2 "register_operand" "v"))]
8183   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8184   "xxlandc %x0,%x1,%x2"
8185   [(set_attr "type" "veclogical")])
8187 ;; IEEE 128-bit negative absolute value
8188 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8189   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8190         (neg:IEEE128
8191          (abs:IEEE128
8192           (match_operand:IEEE128 1 "register_operand" "wa"))))
8193    (clobber (match_scratch:V16QI 2 "=v"))]
8194   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8195    && FLOAT128_IEEE_P (<MODE>mode)"
8196   "#"
8197   "&& 1"
8198   [(parallel [(set (match_dup 0)
8199                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8200               (use (match_dup 2))])]
8202   if (GET_CODE (operands[2]) == SCRATCH)
8203     operands[2] = gen_reg_rtx (V16QImode);
8205   operands[3] = gen_reg_rtx (V16QImode);
8206   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8208   [(set_attr "length" "8")
8209    (set_attr "type" "vecsimple")])
8211 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8212   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8213         (neg:IEEE128
8214          (abs:IEEE128
8215           (match_operand:IEEE128 1 "register_operand" "wa"))))
8216    (use (match_operand:V16QI 2 "register_operand" "v"))]
8217   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8218   "xxlor %x0,%x1,%x2"
8219   [(set_attr "type" "veclogical")])
8221 ;; Float128 conversion functions.  These expand to library function calls.
8222 ;; We use expand to convert from IBM double double to IEEE 128-bit
8223 ;; and trunc for the opposite.
8224 (define_expand "extendiftf2"
8225   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8226         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8227   "TARGET_FLOAT128_TYPE"
8229   rs6000_expand_float128_convert (operands[0], operands[1], false);
8230   DONE;
8233 (define_expand "extendifkf2"
8234   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8235         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8236   "TARGET_FLOAT128_TYPE"
8238   rs6000_expand_float128_convert (operands[0], operands[1], false);
8239   DONE;
8242 (define_expand "extendtfkf2"
8243   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8244         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8245   "TARGET_FLOAT128_TYPE"
8247   rs6000_expand_float128_convert (operands[0], operands[1], false);
8248   DONE;
8251 (define_expand "trunciftf2"
8252   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8253         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8254   "TARGET_FLOAT128_TYPE"
8256   rs6000_expand_float128_convert (operands[0], operands[1], false);
8257   DONE;
8260 (define_expand "truncifkf2"
8261   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8262         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8263   "TARGET_FLOAT128_TYPE"
8265   rs6000_expand_float128_convert (operands[0], operands[1], false);
8266   DONE;
8269 (define_expand "trunckftf2"
8270   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8271         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8272   "TARGET_FLOAT128_TYPE"
8274   rs6000_expand_float128_convert (operands[0], operands[1], false);
8275   DONE;
8278 (define_expand "trunctfif2"
8279   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8280         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8281   "TARGET_FLOAT128_TYPE"
8283   rs6000_expand_float128_convert (operands[0], operands[1], false);
8284   DONE;
8288 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8289 ;; must have 3 arguments, and scratch register constraint must be a single
8290 ;; constraint.
8292 ;; Reload patterns to support gpr load/store with misaligned mem.
8293 ;; and multiple gpr load/store at offset >= 0xfffc
8294 (define_expand "reload_<mode>_store"
8295   [(parallel [(match_operand 0 "memory_operand" "=m")
8296               (match_operand 1 "gpc_reg_operand" "r")
8297               (match_operand:GPR 2 "register_operand" "=&b")])]
8298   ""
8300   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8301   DONE;
8304 (define_expand "reload_<mode>_load"
8305   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8306               (match_operand 1 "memory_operand" "m")
8307               (match_operand:GPR 2 "register_operand" "=b")])]
8308   ""
8310   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8311   DONE;
8315 ;; Reload patterns for various types using the vector registers.  We may need
8316 ;; an additional base register to convert the reg+offset addressing to reg+reg
8317 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8318 ;; index register for gpr registers.
8319 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8320   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8321               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8322               (match_operand:P 2 "register_operand" "=b")])]
8323   "<P:tptrsize>"
8325   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8326   DONE;
8329 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8330   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8331               (match_operand:RELOAD 1 "memory_operand" "m")
8332               (match_operand:P 2 "register_operand" "=b")])]
8333   "<P:tptrsize>"
8335   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8336   DONE;
8340 ;; Reload sometimes tries to move the address to a GPR, and can generate
8341 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8342 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8344 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8345   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8346         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8347                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8348                (const_int -16)))]
8349   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
8350   "#"
8351   "&& reload_completed"
8352   [(set (match_dup 0)
8353         (plus:P (match_dup 1)
8354                 (match_dup 2)))
8355    (set (match_dup 0)
8356         (and:P (match_dup 0)
8357                (const_int -16)))])
8359 ;; Power8 merge instructions to allow direct move to/from floating point
8360 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8361 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8362 ;; value, since it is allocated in reload and not all of the flow information
8363 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8364 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8365 ;; schedule other instructions between the two instructions.
8367 (define_insn "p8_fmrgow_<mode>"
8368   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8369         (unspec:FMOVE64X [
8370                 (match_operand:DF 1 "register_operand" "d")
8371                 (match_operand:DF 2 "register_operand" "d")]
8372                          UNSPEC_P8V_FMRGOW))]
8373   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8374   "fmrgow %0,%1,%2"
8375   [(set_attr "type" "fpsimple")])
8377 (define_insn "p8_mtvsrwz"
8378   [(set (match_operand:DF 0 "register_operand" "=d")
8379         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8380                    UNSPEC_P8V_MTVSRWZ))]
8381   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8382   "mtvsrwz %x0,%1"
8383   [(set_attr "type" "mftgpr")])
8385 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8386   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8387         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8388                          UNSPEC_P8V_RELOAD_FROM_GPR))
8389    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8390   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8391   "#"
8392   "&& reload_completed"
8393   [(const_int 0)]
8395   rtx dest = operands[0];
8396   rtx src = operands[1];
8397   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8398   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8399   rtx gpr_hi_reg = gen_highpart (SImode, src);
8400   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8402   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8403   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8404   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8405   DONE;
8407   [(set_attr "length" "12")
8408    (set_attr "type" "three")])
8410 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8411 (define_insn "p8_mtvsrd_df"
8412   [(set (match_operand:DF 0 "register_operand" "=wa")
8413         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8414                    UNSPEC_P8V_MTVSRD))]
8415   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8416   "mtvsrd %x0,%1"
8417   [(set_attr "type" "mftgpr")])
8419 (define_insn "p8_xxpermdi_<mode>"
8420   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8421         (unspec:FMOVE128_GPR [
8422                 (match_operand:DF 1 "register_operand" "wa")
8423                 (match_operand:DF 2 "register_operand" "wa")]
8424                 UNSPEC_P8V_XXPERMDI))]
8425   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8426   "xxpermdi %x0,%x1,%x2,0"
8427   [(set_attr "type" "vecperm")])
8429 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8430   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8431         (unspec:FMOVE128_GPR
8432          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8433          UNSPEC_P8V_RELOAD_FROM_GPR))
8434    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8435   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8436   "#"
8437   "&& reload_completed"
8438   [(const_int 0)]
8440   rtx dest = operands[0];
8441   rtx src = operands[1];
8442   /* You might think that we could use op0 as one temp and a DF clobber
8443      as op2, but you'd be wrong.  Secondary reload move patterns don't
8444      check for overlap of the clobber and the destination.  */
8445   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8446   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8447   rtx gpr_hi_reg = gen_highpart (DImode, src);
8448   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8450   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8451   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8452   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8453   DONE;
8455   [(set_attr "length" "12")
8456    (set_attr "type" "three")])
8458 (define_split
8459   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8460         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8461   "reload_completed
8462    && (int_reg_operand (operands[0], <MODE>mode)
8463        || int_reg_operand (operands[1], <MODE>mode))
8464    && (!TARGET_DIRECT_MOVE_128
8465        || (!vsx_register_operand (operands[0], <MODE>mode)
8466            && !vsx_register_operand (operands[1], <MODE>mode)))"
8467   [(pc)]
8468 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8470 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8471 ;; type is stored internally as double precision in the VSX registers, we have
8472 ;; to convert it from the vector format.
8473 (define_insn "p8_mtvsrd_sf"
8474   [(set (match_operand:SF 0 "register_operand" "=wa")
8475         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8476                    UNSPEC_P8V_MTVSRD))]
8477   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8478   "mtvsrd %x0,%1"
8479   [(set_attr "type" "mftgpr")])
8481 (define_insn_and_split "reload_vsx_from_gprsf"
8482   [(set (match_operand:SF 0 "register_operand" "=wa")
8483         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8484                    UNSPEC_P8V_RELOAD_FROM_GPR))
8485    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8486   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8487   "#"
8488   "&& reload_completed"
8489   [(const_int 0)]
8491   rtx op0 = operands[0];
8492   rtx op1 = operands[1];
8493   rtx op2 = operands[2];
8494   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8496   /* Move SF value to upper 32-bits for xscvspdpn.  */
8497   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8498   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8499   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8500   DONE;
8502   [(set_attr "length" "8")
8503    (set_attr "type" "two")])
8505 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8506 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8507 ;; and then doing a move of that.
8508 (define_insn "p8_mfvsrd_3_<mode>"
8509   [(set (match_operand:DF 0 "register_operand" "=r")
8510         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8511                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8512   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8513   "mfvsrd %0,%x1"
8514   [(set_attr "type" "mftgpr")])
8516 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8517   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8518         (unspec:FMOVE128_GPR
8519          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8520          UNSPEC_P8V_RELOAD_FROM_VSX))
8521    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8522   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8523   "#"
8524   "&& reload_completed"
8525   [(const_int 0)]
8527   rtx dest = operands[0];
8528   rtx src = operands[1];
8529   rtx tmp = operands[2];
8530   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8531   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8533   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8534   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8535   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8536   DONE;
8538   [(set_attr "length" "12")
8539    (set_attr "type" "three")])
8541 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8542 ;; type is stored internally as double precision, we have to convert it to the
8543 ;; vector format.
8545 (define_insn_and_split "reload_gpr_from_vsxsf"
8546   [(set (match_operand:SF 0 "register_operand" "=r")
8547         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8548                    UNSPEC_P8V_RELOAD_FROM_VSX))
8549    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8550   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8551   "#"
8552   "&& reload_completed"
8553   [(const_int 0)]
8555   rtx op0 = operands[0];
8556   rtx op1 = operands[1];
8557   rtx op2 = operands[2];
8558   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8560   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8561   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8562   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8563   DONE;
8565   [(set_attr "length" "12")
8566    (set_attr "type" "three")])
8568 (define_insn "p8_mfvsrd_4_disf"
8569   [(set (match_operand:DI 0 "register_operand" "=r")
8570         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8571                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8572   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8573   "mfvsrd %0,%x1"
8574   [(set_attr "type" "mftgpr")])
8577 ;; Next come the multi-word integer load and store and the load and store
8578 ;; multiple insns.
8580 ;; List r->r after r->Y, otherwise reload will try to reload a
8581 ;; non-offsettable address by using r->r which won't make progress.
8582 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8583 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8585 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8586 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8587 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8588 ;;        AVX const  
8590 (define_insn "*movdi_internal32"
8591   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8592          "=Y,        r,         r,         ^m,        ^d,         ^d,
8593           r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8594           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8595           *wv")
8597         (match_operand:DI 1 "input_operand"
8598           "r,        Y,         r,         d,         m,          d,
8599            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8600            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8601            wB"))]
8603   "! TARGET_POWERPC64
8604    && (gpc_reg_operand (operands[0], DImode)
8605        || gpc_reg_operand (operands[1], DImode))"
8606   "@
8607    #
8608    #
8609    #
8610    stfd%U0%X0 %1,%0
8611    lfd%U1%X1 %0,%1
8612    fmr %0,%1
8613    #
8614    stxsd %1,%0
8615    stxsdx %x1,%y0
8616    lxsd %0,%1
8617    lxsdx %x0,%y1
8618    xxlor %x0,%x1,%x1
8619    xxspltib %x0,0
8620    xxspltib %x0,255
8621    vspltisw %0,%1
8622    xxlxor %x0,%x0,%x0
8623    xxlorc %x0,%x0,%x0
8624    #
8625    #"
8626   [(set_attr "type"
8627                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8628                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8629                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8630                 vecsimple")
8631    (set_attr "size" "64")])
8633 (define_split
8634   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8635         (match_operand:DI 1 "const_int_operand" ""))]
8636   "! TARGET_POWERPC64 && reload_completed
8637    && gpr_or_gpr_p (operands[0], operands[1])
8638    && !direct_move_p (operands[0], operands[1])"
8639   [(set (match_dup 2) (match_dup 4))
8640    (set (match_dup 3) (match_dup 1))]
8641   "
8643   HOST_WIDE_INT value = INTVAL (operands[1]);
8644   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8645                                        DImode);
8646   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8647                                        DImode);
8648   operands[4] = GEN_INT (value >> 32);
8649   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8652 (define_split
8653   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8654         (match_operand:DIFD 1 "input_operand" ""))]
8655   "reload_completed && !TARGET_POWERPC64
8656    && gpr_or_gpr_p (operands[0], operands[1])
8657    && !direct_move_p (operands[0], operands[1])"
8658   [(pc)]
8659 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8661 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8662 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8663 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8664 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8665 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8666 (define_insn "*movdi_internal64"
8667   [(set (match_operand:DI 0 "nonimmediate_operand"
8668                "=Y,        r,         r,         r,         r,          r,
8669                 ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
8670                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8671                 *wi,       *wv,       *wv,       r,         *h,         *h,
8672                 ?*r,       ?*wg,      ?*r,       ?*wj")
8674         (match_operand:DI 1 "input_operand"
8675                 "r,        Y,         r,         I,         L,          nF,
8676                  d,        m,         d,         wb,        wv,         wY,
8677                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8678                  wM,       wS,        wB,        *h,        r,          0,
8679                  wg,       r,         wj,        r"))]
8681   "TARGET_POWERPC64
8682    && (gpc_reg_operand (operands[0], DImode)
8683        || gpc_reg_operand (operands[1], DImode))"
8684   "@
8685    std%U0%X0 %1,%0
8686    ld%U1%X1 %0,%1
8687    mr %0,%1
8688    li %0,%1
8689    lis %0,%v1
8690    #
8691    stfd%U0%X0 %1,%0
8692    lfd%U1%X1 %0,%1
8693    fmr %0,%1
8694    stxsd %1,%0
8695    stxsdx %x1,%y0
8696    lxsd %0,%1
8697    lxsdx %x0,%y1
8698    xxlor %x0,%x1,%x1
8699    xxspltib %x0,0
8700    xxspltib %x0,255
8701    #
8702    xxlxor %x0,%x0,%x0
8703    xxlorc %x0,%x0,%x0
8704    #
8705    #
8706    mf%1 %0
8707    mt%0 %1
8708    nop
8709    mftgpr %0,%1
8710    mffgpr %0,%1
8711    mfvsrd %0,%x1
8712    mtvsrd %x0,%1"
8713   [(set_attr "type"
8714                "store,      load,       *,         *,         *,         *,
8715                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8716                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8717                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8718                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8720    (set_attr "size" "64")
8721    (set_attr "length"
8722                "4,         4,         4,         4,         4,          20,
8723                 4,         4,         4,         4,         4,          4,
8724                 4,         4,         4,         4,         4,          8,
8725                 8,         4,         4,         4,         4,          4,
8726                 4,         4,         4,         4")])
8728 ; Some DImode loads are best done as a load of -1 followed by a mask
8729 ; instruction.
8730 (define_split
8731   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8732         (match_operand:DI 1 "const_int_operand"))]
8733   "TARGET_POWERPC64
8734    && num_insns_constant (operands[1], DImode) > 1
8735    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8736    && rs6000_is_valid_and_mask (operands[1], DImode)"
8737   [(set (match_dup 0)
8738         (const_int -1))
8739    (set (match_dup 0)
8740         (and:DI (match_dup 0)
8741                 (match_dup 1)))]
8742   "")
8744 ;; Split a load of a large constant into the appropriate five-instruction
8745 ;; sequence.  Handle anything in a constant number of insns.
8746 ;; When non-easy constants can go in the TOC, this should use
8747 ;; easy_fp_constant predicate.
8748 (define_split
8749   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8750         (match_operand:DI 1 "const_int_operand" ""))]
8751   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8752   [(set (match_dup 0) (match_dup 2))
8753    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8754   "
8756   if (rs6000_emit_set_const (operands[0], operands[1]))
8757     DONE;
8758   else
8759     FAIL;
8762 (define_split
8763   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8764         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8765   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8766   [(set (match_dup 0) (match_dup 2))
8767    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8768   "
8770   if (rs6000_emit_set_const (operands[0], operands[1]))
8771     DONE;
8772   else
8773     FAIL;
8776 (define_split
8777   [(set (match_operand:DI 0 "altivec_register_operand" "")
8778         (match_operand:DI 1 "s5bit_cint_operand" ""))]
8779   "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8780   [(const_int 0)]
8782   rtx op0 = operands[0];
8783   rtx op1 = operands[1];
8784   int r = REGNO (op0);
8785   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8787   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8788   if (op1 != const0_rtx && op1 != constm1_rtx)
8789     {
8790       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8791       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8792     }
8793   DONE;
8796 ;; Split integer constants that can be loaded with XXSPLTIB and a
8797 ;; sign extend operation.
8798 (define_split
8799   [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8800         (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8801   "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8802   [(const_int 0)]
8804   rtx op0 = operands[0];
8805   rtx op1 = operands[1];
8806   int r = REGNO (op0);
8807   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8809   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8810   if (<MODE>mode == DImode)
8811     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8812   else if (<MODE>mode == SImode)
8813     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8814   else if (<MODE>mode == HImode)
8815     {
8816       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8817       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8818     }
8819   DONE;
8823 ;; TImode/PTImode is similar, except that we usually want to compute the
8824 ;; address into a register and use lsi/stsi (the exception is during reload).
8826 (define_insn "*mov<mode>_string"
8827   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8828         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8829   "! TARGET_POWERPC64
8830    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8831    && (gpc_reg_operand (operands[0], <MODE>mode)
8832        || gpc_reg_operand (operands[1], <MODE>mode))"
8833   "*
8835   switch (which_alternative)
8836     {
8837     default:
8838       gcc_unreachable ();
8839     case 0:
8840       if (TARGET_STRING)
8841         return \"stswi %1,%P0,16\";
8842       /* FALLTHRU */
8843     case 1:
8844       return \"#\";
8845     case 2:
8846       /* If the address is not used in the output, we can use lsi.  Otherwise,
8847          fall through to generating four loads.  */
8848       if (TARGET_STRING
8849           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8850         return \"lswi %0,%P1,16\";
8851       /* fall through */
8852     case 3:
8853     case 4:
8854     case 5:
8855       return \"#\";
8856     }
8858   [(set_attr "type" "store,store,load,load,*,*")
8859    (set_attr "update" "yes")
8860    (set_attr "indexed" "yes")
8861    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8862                                           (const_string "always")
8863                                           (const_string "conditional")))])
8865 (define_insn "*mov<mode>_ppc64"
8866   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8867         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8868   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8869    && (gpc_reg_operand (operands[0], <MODE>mode)
8870        || gpc_reg_operand (operands[1], <MODE>mode)))"
8872   return rs6000_output_move_128bit (operands);
8874   [(set_attr "type" "store,store,load,load,*,*")
8875    (set_attr "length" "8")])
8877 (define_split
8878   [(set (match_operand:TI2 0 "int_reg_operand" "")
8879         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8880   "TARGET_POWERPC64
8881    && (VECTOR_MEM_NONE_P (<MODE>mode)
8882        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8883   [(set (match_dup 2) (match_dup 4))
8884    (set (match_dup 3) (match_dup 5))]
8885   "
8887   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8888                                        <MODE>mode);
8889   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8890                                        <MODE>mode);
8891   if (CONST_WIDE_INT_P (operands[1]))
8892     {
8893       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8894       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8895     }
8896   else if (CONST_INT_P (operands[1]))
8897     {
8898       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8899       operands[5] = operands[1];
8900     }
8901   else
8902     FAIL;
8905 (define_split
8906   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8907         (match_operand:TI2 1 "input_operand" ""))]
8908   "reload_completed
8909    && gpr_or_gpr_p (operands[0], operands[1])
8910    && !direct_move_p (operands[0], operands[1])
8911    && !quad_load_store_p (operands[0], operands[1])"
8912   [(pc)]
8913 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8915 (define_expand "load_multiple"
8916   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8917                           (match_operand:SI 1 "" ""))
8918                      (use (match_operand:SI 2 "" ""))])]
8919   "TARGET_STRING && !TARGET_POWERPC64"
8920   "
8922   int regno;
8923   int count;
8924   rtx op1;
8925   int i;
8927   /* Support only loading a constant number of fixed-point registers from
8928      memory and only bother with this if more than two; the machine
8929      doesn't support more than eight.  */
8930   if (GET_CODE (operands[2]) != CONST_INT
8931       || INTVAL (operands[2]) <= 2
8932       || INTVAL (operands[2]) > 8
8933       || GET_CODE (operands[1]) != MEM
8934       || GET_CODE (operands[0]) != REG
8935       || REGNO (operands[0]) >= 32)
8936     FAIL;
8938   count = INTVAL (operands[2]);
8939   regno = REGNO (operands[0]);
8941   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8942   op1 = replace_equiv_address (operands[1],
8943                                force_reg (SImode, XEXP (operands[1], 0)));
8945   for (i = 0; i < count; i++)
8946     XVECEXP (operands[3], 0, i)
8947       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8948                      adjust_address_nv (op1, SImode, i * 4));
8951 (define_insn "*ldmsi8"
8952   [(match_parallel 0 "load_multiple_operation"
8953     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8954           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8955      (set (match_operand:SI 3 "gpc_reg_operand" "")
8956           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8957      (set (match_operand:SI 4 "gpc_reg_operand" "")
8958           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8959      (set (match_operand:SI 5 "gpc_reg_operand" "")
8960           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8961      (set (match_operand:SI 6 "gpc_reg_operand" "")
8962           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8963      (set (match_operand:SI 7 "gpc_reg_operand" "")
8964           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8965      (set (match_operand:SI 8 "gpc_reg_operand" "")
8966           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8967      (set (match_operand:SI 9 "gpc_reg_operand" "")
8968           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8969   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8970   "*
8971 { return rs6000_output_load_multiple (operands); }"
8972   [(set_attr "type" "load")
8973    (set_attr "update" "yes")
8974    (set_attr "indexed" "yes")
8975    (set_attr "length" "32")])
8977 (define_insn "*ldmsi7"
8978   [(match_parallel 0 "load_multiple_operation"
8979     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8980           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8981      (set (match_operand:SI 3 "gpc_reg_operand" "")
8982           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8983      (set (match_operand:SI 4 "gpc_reg_operand" "")
8984           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8985      (set (match_operand:SI 5 "gpc_reg_operand" "")
8986           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8987      (set (match_operand:SI 6 "gpc_reg_operand" "")
8988           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8989      (set (match_operand:SI 7 "gpc_reg_operand" "")
8990           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8991      (set (match_operand:SI 8 "gpc_reg_operand" "")
8992           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8993   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8994   "*
8995 { return rs6000_output_load_multiple (operands); }"
8996   [(set_attr "type" "load")
8997    (set_attr "update" "yes")
8998    (set_attr "indexed" "yes")
8999    (set_attr "length" "32")])
9001 (define_insn "*ldmsi6"
9002   [(match_parallel 0 "load_multiple_operation"
9003     [(set (match_operand:SI 2 "gpc_reg_operand" "")
9004           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9005      (set (match_operand:SI 3 "gpc_reg_operand" "")
9006           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9007      (set (match_operand:SI 4 "gpc_reg_operand" "")
9008           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9009      (set (match_operand:SI 5 "gpc_reg_operand" "")
9010           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9011      (set (match_operand:SI 6 "gpc_reg_operand" "")
9012           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
9013      (set (match_operand:SI 7 "gpc_reg_operand" "")
9014           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
9015   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9016   "*
9017 { return rs6000_output_load_multiple (operands); }"
9018   [(set_attr "type" "load")
9019    (set_attr "update" "yes")
9020    (set_attr "indexed" "yes")
9021    (set_attr "length" "32")])
9023 (define_insn "*ldmsi5"
9024   [(match_parallel 0 "load_multiple_operation"
9025     [(set (match_operand:SI 2 "gpc_reg_operand" "")
9026           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9027      (set (match_operand:SI 3 "gpc_reg_operand" "")
9028           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9029      (set (match_operand:SI 4 "gpc_reg_operand" "")
9030           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9031      (set (match_operand:SI 5 "gpc_reg_operand" "")
9032           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9033      (set (match_operand:SI 6 "gpc_reg_operand" "")
9034           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
9035   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9036   "*
9037 { return rs6000_output_load_multiple (operands); }"
9038   [(set_attr "type" "load")
9039    (set_attr "update" "yes")
9040    (set_attr "indexed" "yes")
9041    (set_attr "length" "32")])
9043 (define_insn "*ldmsi4"
9044   [(match_parallel 0 "load_multiple_operation"
9045     [(set (match_operand:SI 2 "gpc_reg_operand" "")
9046           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9047      (set (match_operand:SI 3 "gpc_reg_operand" "")
9048           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9049      (set (match_operand:SI 4 "gpc_reg_operand" "")
9050           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9051      (set (match_operand:SI 5 "gpc_reg_operand" "")
9052           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
9053   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9054   "*
9055 { return rs6000_output_load_multiple (operands); }"
9056   [(set_attr "type" "load")
9057    (set_attr "update" "yes")
9058    (set_attr "indexed" "yes")
9059    (set_attr "length" "32")])
9061 (define_insn "*ldmsi3"
9062   [(match_parallel 0 "load_multiple_operation"
9063     [(set (match_operand:SI 2 "gpc_reg_operand" "")
9064           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9065      (set (match_operand:SI 3 "gpc_reg_operand" "")
9066           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9067      (set (match_operand:SI 4 "gpc_reg_operand" "")
9068           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
9069   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
9070   "*
9071 { return rs6000_output_load_multiple (operands); }"
9072   [(set_attr "type" "load")
9073    (set_attr "update" "yes")
9074    (set_attr "indexed" "yes")
9075    (set_attr "length" "32")])
9077 (define_expand "store_multiple"
9078   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
9079                           (match_operand:SI 1 "" ""))
9080                      (clobber (scratch:SI))
9081                      (use (match_operand:SI 2 "" ""))])]
9082   "TARGET_STRING && !TARGET_POWERPC64"
9083   "
9085   int regno;
9086   int count;
9087   rtx to;
9088   rtx op0;
9089   int i;
9091   /* Support only storing a constant number of fixed-point registers to
9092      memory and only bother with this if more than two; the machine
9093      doesn't support more than eight.  */
9094   if (GET_CODE (operands[2]) != CONST_INT
9095       || INTVAL (operands[2]) <= 2
9096       || INTVAL (operands[2]) > 8
9097       || GET_CODE (operands[0]) != MEM
9098       || GET_CODE (operands[1]) != REG
9099       || REGNO (operands[1]) >= 32)
9100     FAIL;
9102   count = INTVAL (operands[2]);
9103   regno = REGNO (operands[1]);
9105   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
9106   to = force_reg (SImode, XEXP (operands[0], 0));
9107   op0 = replace_equiv_address (operands[0], to);
9109   XVECEXP (operands[3], 0, 0)
9110     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
9111   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
9112                                                  gen_rtx_SCRATCH (SImode));
9114   for (i = 1; i < count; i++)
9115     XVECEXP (operands[3], 0, i + 1)
9116       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
9117                      gen_rtx_REG (SImode, regno + i));
9120 (define_insn "*stmsi8"
9121   [(match_parallel 0 "store_multiple_operation"
9122     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9123           (match_operand:SI 2 "gpc_reg_operand" "r"))
9124      (clobber (match_scratch:SI 3 "=X"))
9125      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9126           (match_operand:SI 4 "gpc_reg_operand" "r"))
9127      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9128           (match_operand:SI 5 "gpc_reg_operand" "r"))
9129      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9130           (match_operand:SI 6 "gpc_reg_operand" "r"))
9131      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9132           (match_operand:SI 7 "gpc_reg_operand" "r"))
9133      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9134           (match_operand:SI 8 "gpc_reg_operand" "r"))
9135      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9136           (match_operand:SI 9 "gpc_reg_operand" "r"))
9137      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9138           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9139   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9140   "stswi %2,%1,%O0"
9141   [(set_attr "type" "store")
9142    (set_attr "update" "yes")
9143    (set_attr "indexed" "yes")
9144    (set_attr "cell_micro" "always")])
9146 (define_insn "*stmsi7"
9147   [(match_parallel 0 "store_multiple_operation"
9148     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9149           (match_operand:SI 2 "gpc_reg_operand" "r"))
9150      (clobber (match_scratch:SI 3 "=X"))
9151      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9152           (match_operand:SI 4 "gpc_reg_operand" "r"))
9153      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9154           (match_operand:SI 5 "gpc_reg_operand" "r"))
9155      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9156           (match_operand:SI 6 "gpc_reg_operand" "r"))
9157      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9158           (match_operand:SI 7 "gpc_reg_operand" "r"))
9159      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9160           (match_operand:SI 8 "gpc_reg_operand" "r"))
9161      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9162           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9163   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9164   "stswi %2,%1,%O0"
9165   [(set_attr "type" "store")
9166    (set_attr "update" "yes")
9167    (set_attr "indexed" "yes")
9168    (set_attr "cell_micro" "always")])
9170 (define_insn "*stmsi6"
9171   [(match_parallel 0 "store_multiple_operation"
9172     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9173           (match_operand:SI 2 "gpc_reg_operand" "r"))
9174      (clobber (match_scratch:SI 3 "=X"))
9175      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9176           (match_operand:SI 4 "gpc_reg_operand" "r"))
9177      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9178           (match_operand:SI 5 "gpc_reg_operand" "r"))
9179      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9180           (match_operand:SI 6 "gpc_reg_operand" "r"))
9181      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9182           (match_operand:SI 7 "gpc_reg_operand" "r"))
9183      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9184           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9185   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9186   "stswi %2,%1,%O0"
9187   [(set_attr "type" "store")
9188    (set_attr "update" "yes")
9189    (set_attr "indexed" "yes")
9190    (set_attr "cell_micro" "always")])
9192 (define_insn "*stmsi5"
9193   [(match_parallel 0 "store_multiple_operation"
9194     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9195           (match_operand:SI 2 "gpc_reg_operand" "r"))
9196      (clobber (match_scratch:SI 3 "=X"))
9197      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9198           (match_operand:SI 4 "gpc_reg_operand" "r"))
9199      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9200           (match_operand:SI 5 "gpc_reg_operand" "r"))
9201      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9202           (match_operand:SI 6 "gpc_reg_operand" "r"))
9203      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9204           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9205   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9206   "stswi %2,%1,%O0"
9207   [(set_attr "type" "store")
9208    (set_attr "update" "yes")
9209    (set_attr "indexed" "yes")
9210    (set_attr "cell_micro" "always")])
9212 (define_insn "*stmsi4"
9213   [(match_parallel 0 "store_multiple_operation"
9214     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9215           (match_operand:SI 2 "gpc_reg_operand" "r"))
9216      (clobber (match_scratch:SI 3 "=X"))
9217      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9218           (match_operand:SI 4 "gpc_reg_operand" "r"))
9219      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9220           (match_operand:SI 5 "gpc_reg_operand" "r"))
9221      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9222           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9223   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9224   "stswi %2,%1,%O0"
9225   [(set_attr "type" "store")
9226    (set_attr "update" "yes")
9227    (set_attr "indexed" "yes")
9228    (set_attr "cell_micro" "always")])
9230 (define_insn "*stmsi3"
9231   [(match_parallel 0 "store_multiple_operation"
9232     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9233           (match_operand:SI 2 "gpc_reg_operand" "r"))
9234      (clobber (match_scratch:SI 3 "=X"))
9235      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9236           (match_operand:SI 4 "gpc_reg_operand" "r"))
9237      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9238           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9239   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9240   "stswi %2,%1,%O0"
9241   [(set_attr "type" "store")
9242    (set_attr "update" "yes")
9243    (set_attr "indexed" "yes")
9244    (set_attr "cell_micro" "always")])
9246 (define_expand "setmemsi"
9247   [(parallel [(set (match_operand:BLK 0 "" "")
9248                    (match_operand 2 "const_int_operand" ""))
9249               (use (match_operand:SI 1 "" ""))
9250               (use (match_operand:SI 3 "" ""))])]
9251   ""
9252   "
9254   /* If value to set is not zero, use the library routine.  */
9255   if (operands[2] != const0_rtx)
9256     FAIL;
9258   if (expand_block_clear (operands))
9259     DONE;
9260   else
9261     FAIL;
9264 ;; String compare N insn.
9265 ;; Argument 0 is the target (result)
9266 ;; Argument 1 is the destination
9267 ;; Argument 2 is the source
9268 ;; Argument 3 is the length
9269 ;; Argument 4 is the alignment
9271 (define_expand "cmpstrnsi"
9272   [(parallel [(set (match_operand:SI 0)
9273                (compare:SI (match_operand:BLK 1)
9274                            (match_operand:BLK 2)))
9275               (use (match_operand:SI 3))
9276               (use (match_operand:SI 4))])]
9277   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9279   if (optimize_insn_for_size_p ())
9280     FAIL;
9282   if (expand_strn_compare (operands, 0))
9283     DONE;
9284   else  
9285     FAIL;
9288 ;; String compare insn.
9289 ;; Argument 0 is the target (result)
9290 ;; Argument 1 is the destination
9291 ;; Argument 2 is the source
9292 ;; Argument 3 is the alignment
9294 (define_expand "cmpstrsi"
9295   [(parallel [(set (match_operand:SI 0)
9296                (compare:SI (match_operand:BLK 1)
9297                            (match_operand:BLK 2)))
9298               (use (match_operand:SI 3))])]
9299   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9301   if (optimize_insn_for_size_p ())
9302     FAIL;
9304   if (expand_strn_compare (operands, 1))
9305     DONE;
9306   else  
9307     FAIL;
9310 ;; Block compare insn.
9311 ;; Argument 0 is the target (result)
9312 ;; Argument 1 is the destination
9313 ;; Argument 2 is the source
9314 ;; Argument 3 is the length
9315 ;; Argument 4 is the alignment
9317 (define_expand "cmpmemsi"
9318   [(parallel [(set (match_operand:SI 0)
9319                (compare:SI (match_operand:BLK 1)
9320                            (match_operand:BLK 2)))
9321               (use (match_operand:SI 3))
9322               (use (match_operand:SI 4))])]
9323   "TARGET_POPCNTD"
9325   if (expand_block_compare (operands))
9326     DONE;
9327   else
9328     FAIL;
9331 ;; String/block move insn.
9332 ;; Argument 0 is the destination
9333 ;; Argument 1 is the source
9334 ;; Argument 2 is the length
9335 ;; Argument 3 is the alignment
9337 (define_expand "movmemsi"
9338   [(parallel [(set (match_operand:BLK 0 "" "")
9339                    (match_operand:BLK 1 "" ""))
9340               (use (match_operand:SI 2 "" ""))
9341               (use (match_operand:SI 3 "" ""))])]
9342   ""
9343   "
9345   if (expand_block_move (operands))
9346     DONE;
9347   else
9348     FAIL;
9351 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
9352 ;; register allocator doesn't have a clue about allocating 8 word registers.
9353 ;; rD/rS = r5 is preferred, efficient form.
9354 (define_expand "movmemsi_8reg"
9355   [(parallel [(set (match_operand 0 "" "")
9356                    (match_operand 1 "" ""))
9357               (use (match_operand 2 "" ""))
9358               (use (match_operand 3 "" ""))
9359               (clobber (reg:SI  5))
9360               (clobber (reg:SI  6))
9361               (clobber (reg:SI  7))
9362               (clobber (reg:SI  8))
9363               (clobber (reg:SI  9))
9364               (clobber (reg:SI 10))
9365               (clobber (reg:SI 11))
9366               (clobber (reg:SI 12))
9367               (clobber (match_scratch:SI 4 ""))])]
9368   "TARGET_STRING"
9369   "")
9371 (define_insn ""
9372   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9373         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9374    (use (match_operand:SI 2 "immediate_operand" "i"))
9375    (use (match_operand:SI 3 "immediate_operand" "i"))
9376    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9377    (clobber (reg:SI  6))
9378    (clobber (reg:SI  7))
9379    (clobber (reg:SI  8))
9380    (clobber (reg:SI  9))
9381    (clobber (reg:SI 10))
9382    (clobber (reg:SI 11))
9383    (clobber (reg:SI 12))
9384    (clobber (match_scratch:SI 5 "=X"))]
9385   "TARGET_STRING
9386    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9387        || INTVAL (operands[2]) == 0)
9388    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9389    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9390    && REGNO (operands[4]) == 5"
9391   "lswi %4,%1,%2\;stswi %4,%0,%2"
9392   [(set_attr "type" "store")
9393    (set_attr "update" "yes")
9394    (set_attr "indexed" "yes")
9395    (set_attr "cell_micro" "always")
9396    (set_attr "length" "8")])
9398 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
9399 ;; register allocator doesn't have a clue about allocating 6 word registers.
9400 ;; rD/rS = r5 is preferred, efficient form.
9401 (define_expand "movmemsi_6reg"
9402   [(parallel [(set (match_operand 0 "" "")
9403                    (match_operand 1 "" ""))
9404               (use (match_operand 2 "" ""))
9405               (use (match_operand 3 "" ""))
9406               (clobber (reg:SI  5))
9407               (clobber (reg:SI  6))
9408               (clobber (reg:SI  7))
9409               (clobber (reg:SI  8))
9410               (clobber (reg:SI  9))
9411               (clobber (reg:SI 10))
9412               (clobber (match_scratch:SI 4 ""))])]
9413   "TARGET_STRING"
9414   "")
9416 (define_insn ""
9417   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9418         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9419    (use (match_operand:SI 2 "immediate_operand" "i"))
9420    (use (match_operand:SI 3 "immediate_operand" "i"))
9421    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9422    (clobber (reg:SI  6))
9423    (clobber (reg:SI  7))
9424    (clobber (reg:SI  8))
9425    (clobber (reg:SI  9))
9426    (clobber (reg:SI 10))
9427    (clobber (match_scratch:SI 5 "=X"))]
9428   "TARGET_STRING
9429    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9430    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9431    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9432    && REGNO (operands[4]) == 5"
9433   "lswi %4,%1,%2\;stswi %4,%0,%2"
9434   [(set_attr "type" "store")
9435    (set_attr "update" "yes")
9436    (set_attr "indexed" "yes")
9437    (set_attr "cell_micro" "always")
9438    (set_attr "length" "8")])
9440 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9441 ;; problems with TImode.
9442 ;; rD/rS = r5 is preferred, efficient form.
9443 (define_expand "movmemsi_4reg"
9444   [(parallel [(set (match_operand 0 "" "")
9445                    (match_operand 1 "" ""))
9446               (use (match_operand 2 "" ""))
9447               (use (match_operand 3 "" ""))
9448               (clobber (reg:SI 5))
9449               (clobber (reg:SI 6))
9450               (clobber (reg:SI 7))
9451               (clobber (reg:SI 8))
9452               (clobber (match_scratch:SI 4 ""))])]
9453   "TARGET_STRING"
9454   "")
9456 (define_insn ""
9457   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9458         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9459    (use (match_operand:SI 2 "immediate_operand" "i"))
9460    (use (match_operand:SI 3 "immediate_operand" "i"))
9461    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9462    (clobber (reg:SI 6))
9463    (clobber (reg:SI 7))
9464    (clobber (reg:SI 8))
9465    (clobber (match_scratch:SI 5 "=X"))]
9466   "TARGET_STRING
9467    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9468    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9469    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9470    && REGNO (operands[4]) == 5"
9471   "lswi %4,%1,%2\;stswi %4,%0,%2"
9472   [(set_attr "type" "store")
9473    (set_attr "update" "yes")
9474    (set_attr "indexed" "yes")
9475    (set_attr "cell_micro" "always")
9476    (set_attr "length" "8")])
9478 ;; Move up to 8 bytes at a time.
9479 (define_expand "movmemsi_2reg"
9480   [(parallel [(set (match_operand 0 "" "")
9481                    (match_operand 1 "" ""))
9482               (use (match_operand 2 "" ""))
9483               (use (match_operand 3 "" ""))
9484               (clobber (match_scratch:DI 4 ""))
9485               (clobber (match_scratch:SI 5 ""))])]
9486   "TARGET_STRING && ! TARGET_POWERPC64"
9487   "")
9489 (define_insn ""
9490   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9491         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9492    (use (match_operand:SI 2 "immediate_operand" "i"))
9493    (use (match_operand:SI 3 "immediate_operand" "i"))
9494    (clobber (match_scratch:DI 4 "=&r"))
9495    (clobber (match_scratch:SI 5 "=X"))]
9496   "TARGET_STRING && ! TARGET_POWERPC64
9497    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9498   "lswi %4,%1,%2\;stswi %4,%0,%2"
9499   [(set_attr "type" "store")
9500    (set_attr "update" "yes")
9501    (set_attr "indexed" "yes")
9502    (set_attr "cell_micro" "always")
9503    (set_attr "length" "8")])
9505 ;; Move up to 4 bytes at a time.
9506 (define_expand "movmemsi_1reg"
9507   [(parallel [(set (match_operand 0 "" "")
9508                    (match_operand 1 "" ""))
9509               (use (match_operand 2 "" ""))
9510               (use (match_operand 3 "" ""))
9511               (clobber (match_scratch:SI 4 ""))
9512               (clobber (match_scratch:SI 5 ""))])]
9513   "TARGET_STRING"
9514   "")
9516 (define_insn ""
9517   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9518         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9519    (use (match_operand:SI 2 "immediate_operand" "i"))
9520    (use (match_operand:SI 3 "immediate_operand" "i"))
9521    (clobber (match_scratch:SI 4 "=&r"))
9522    (clobber (match_scratch:SI 5 "=X"))]
9523   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9524   "lswi %4,%1,%2\;stswi %4,%0,%2"
9525   [(set_attr "type" "store")
9526    (set_attr "update" "yes")
9527    (set_attr "indexed" "yes")
9528    (set_attr "cell_micro" "always")
9529    (set_attr "length" "8")])
9531 ;; Define insns that do load or store with update.  Some of these we can
9532 ;; get by using pre-decrement or pre-increment, but the hardware can also
9533 ;; do cases where the increment is not the size of the object.
9535 ;; In all these cases, we use operands 0 and 1 for the register being
9536 ;; incremented because those are the operands that local-alloc will
9537 ;; tie and these are the pair most likely to be tieable (and the ones
9538 ;; that will benefit the most).
9540 (define_insn "*movdi_update1"
9541   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9542         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9543                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9544    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9545         (plus:DI (match_dup 1) (match_dup 2)))]
9546   "TARGET_POWERPC64 && TARGET_UPDATE
9547    && (!avoiding_indexed_address_p (DImode)
9548        || !gpc_reg_operand (operands[2], DImode))"
9549   "@
9550    ldux %3,%0,%2
9551    ldu %3,%2(%0)"
9552   [(set_attr "type" "load")
9553    (set_attr "update" "yes")
9554    (set_attr "indexed" "yes,no")])
9556 (define_insn "movdi_<mode>_update"
9557   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9558                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9559         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9560    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9561         (plus:P (match_dup 1) (match_dup 2)))]
9562   "TARGET_POWERPC64 && TARGET_UPDATE
9563    && (!avoiding_indexed_address_p (Pmode)
9564        || !gpc_reg_operand (operands[2], Pmode)
9565        || (REG_P (operands[0])
9566            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9567   "@
9568    stdux %3,%0,%2
9569    stdu %3,%2(%0)"
9570   [(set_attr "type" "store")
9571    (set_attr "update" "yes")
9572    (set_attr "indexed" "yes,no")])
9574 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9575 ;; needed for stack allocation, even if the user passes -mno-update.
9576 (define_insn "movdi_<mode>_update_stack"
9577   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9578                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9579         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9580    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9581         (plus:P (match_dup 1) (match_dup 2)))]
9582   "TARGET_POWERPC64"
9583   "@
9584    stdux %3,%0,%2
9585    stdu %3,%2(%0)"
9586   [(set_attr "type" "store")
9587    (set_attr "update" "yes")
9588    (set_attr "indexed" "yes,no")])
9590 (define_insn "*movsi_update1"
9591   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9592         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9593                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9594    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9595         (plus:SI (match_dup 1) (match_dup 2)))]
9596   "TARGET_UPDATE
9597    && (!avoiding_indexed_address_p (SImode)
9598        || !gpc_reg_operand (operands[2], SImode))"
9599   "@
9600    lwzux %3,%0,%2
9601    lwzu %3,%2(%0)"
9602   [(set_attr "type" "load")
9603    (set_attr "update" "yes")
9604    (set_attr "indexed" "yes,no")])
9606 (define_insn "*movsi_update2"
9607   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9608         (sign_extend:DI
9609          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9610                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9611    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9612         (plus:DI (match_dup 1) (match_dup 2)))]
9613   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9614    && !avoiding_indexed_address_p (DImode)"
9615   "lwaux %3,%0,%2"
9616   [(set_attr "type" "load")
9617    (set_attr "sign_extend" "yes")
9618    (set_attr "update" "yes")
9619    (set_attr "indexed" "yes")])
9621 (define_insn "movsi_update"
9622   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9623                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9624         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9625    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9626         (plus:SI (match_dup 1) (match_dup 2)))]
9627   "TARGET_UPDATE
9628    && (!avoiding_indexed_address_p (SImode)
9629        || !gpc_reg_operand (operands[2], SImode)
9630        || (REG_P (operands[0])
9631            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9632   "@
9633    stwux %3,%0,%2
9634    stwu %3,%2(%0)"
9635   [(set_attr "type" "store")
9636    (set_attr "update" "yes")
9637    (set_attr "indexed" "yes,no")])
9639 ;; This is an unconditional pattern; needed for stack allocation, even
9640 ;; if the user passes -mno-update.
9641 (define_insn "movsi_update_stack"
9642   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9643                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9644         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9645    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9646         (plus:SI (match_dup 1) (match_dup 2)))]
9647   ""
9648   "@
9649    stwux %3,%0,%2
9650    stwu %3,%2(%0)"
9651   [(set_attr "type" "store")
9652    (set_attr "update" "yes")
9653    (set_attr "indexed" "yes,no")])
9655 (define_insn "*movhi_update1"
9656   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9657         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9658                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9659    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9660         (plus:SI (match_dup 1) (match_dup 2)))]
9661   "TARGET_UPDATE
9662    && (!avoiding_indexed_address_p (SImode)
9663        || !gpc_reg_operand (operands[2], SImode))"
9664   "@
9665    lhzux %3,%0,%2
9666    lhzu %3,%2(%0)"
9667   [(set_attr "type" "load")
9668    (set_attr "update" "yes")
9669    (set_attr "indexed" "yes,no")])
9671 (define_insn "*movhi_update2"
9672   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9673         (zero_extend:SI
9674          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9675                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9676    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9677         (plus:SI (match_dup 1) (match_dup 2)))]
9678   "TARGET_UPDATE
9679    && (!avoiding_indexed_address_p (SImode)
9680        || !gpc_reg_operand (operands[2], SImode))"
9681   "@
9682    lhzux %3,%0,%2
9683    lhzu %3,%2(%0)"
9684   [(set_attr "type" "load")
9685    (set_attr "update" "yes")
9686    (set_attr "indexed" "yes,no")])
9688 (define_insn "*movhi_update3"
9689   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9690         (sign_extend:SI
9691          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9692                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9693    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9694         (plus:SI (match_dup 1) (match_dup 2)))]
9695   "TARGET_UPDATE && rs6000_gen_cell_microcode
9696    && (!avoiding_indexed_address_p (SImode)
9697        || !gpc_reg_operand (operands[2], SImode))"
9698   "@
9699    lhaux %3,%0,%2
9700    lhau %3,%2(%0)"
9701   [(set_attr "type" "load")
9702    (set_attr "sign_extend" "yes")
9703    (set_attr "update" "yes")
9704    (set_attr "indexed" "yes,no")])
9706 (define_insn "*movhi_update4"
9707   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9708                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9709         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9710    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9711         (plus:SI (match_dup 1) (match_dup 2)))]
9712   "TARGET_UPDATE
9713    && (!avoiding_indexed_address_p (SImode)
9714        || !gpc_reg_operand (operands[2], SImode))"
9715   "@
9716    sthux %3,%0,%2
9717    sthu %3,%2(%0)"
9718   [(set_attr "type" "store")
9719    (set_attr "update" "yes")
9720    (set_attr "indexed" "yes,no")])
9722 (define_insn "*movqi_update1"
9723   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9724         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9725                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9726    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9727         (plus:SI (match_dup 1) (match_dup 2)))]
9728   "TARGET_UPDATE
9729    && (!avoiding_indexed_address_p (SImode)
9730        || !gpc_reg_operand (operands[2], SImode))"
9731   "@
9732    lbzux %3,%0,%2
9733    lbzu %3,%2(%0)"
9734   [(set_attr "type" "load")
9735    (set_attr "update" "yes")
9736    (set_attr "indexed" "yes,no")])
9738 (define_insn "*movqi_update2"
9739   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9740         (zero_extend:SI
9741          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9742                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9743    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9744         (plus:SI (match_dup 1) (match_dup 2)))]
9745   "TARGET_UPDATE
9746    && (!avoiding_indexed_address_p (SImode)
9747        || !gpc_reg_operand (operands[2], SImode))"
9748   "@
9749    lbzux %3,%0,%2
9750    lbzu %3,%2(%0)"
9751   [(set_attr "type" "load")
9752    (set_attr "update" "yes")
9753    (set_attr "indexed" "yes,no")])
9755 (define_insn "*movqi_update3"
9756   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9757                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9758         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9759    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9760         (plus:SI (match_dup 1) (match_dup 2)))]
9761   "TARGET_UPDATE
9762    && (!avoiding_indexed_address_p (SImode)
9763        || !gpc_reg_operand (operands[2], SImode))"
9764   "@
9765    stbux %3,%0,%2
9766    stbu %3,%2(%0)"
9767   [(set_attr "type" "store")
9768    (set_attr "update" "yes")
9769    (set_attr "indexed" "yes,no")])
9771 (define_insn "*movsf_update1"
9772   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9773         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9774                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9775    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9776         (plus:SI (match_dup 1) (match_dup 2)))]
9777   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9778    && (!avoiding_indexed_address_p (SImode)
9779        || !gpc_reg_operand (operands[2], SImode))"
9780   "@
9781    lfsux %3,%0,%2
9782    lfsu %3,%2(%0)"
9783   [(set_attr "type" "fpload")
9784    (set_attr "update" "yes")
9785    (set_attr "indexed" "yes,no")])
9787 (define_insn "*movsf_update2"
9788   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9789                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9790         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9791    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9792         (plus:SI (match_dup 1) (match_dup 2)))]
9793   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9794    && (!avoiding_indexed_address_p (SImode)
9795        || !gpc_reg_operand (operands[2], SImode))"
9796   "@
9797    stfsux %3,%0,%2
9798    stfsu %3,%2(%0)"
9799   [(set_attr "type" "fpstore")
9800    (set_attr "update" "yes")
9801    (set_attr "indexed" "yes,no")])
9803 (define_insn "*movsf_update3"
9804   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9805         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9806                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9807    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9808         (plus:SI (match_dup 1) (match_dup 2)))]
9809   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9810    && (!avoiding_indexed_address_p (SImode)
9811        || !gpc_reg_operand (operands[2], SImode))"
9812   "@
9813    lwzux %3,%0,%2
9814    lwzu %3,%2(%0)"
9815   [(set_attr "type" "load")
9816    (set_attr "update" "yes")
9817    (set_attr "indexed" "yes,no")])
9819 (define_insn "*movsf_update4"
9820   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9821                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9822         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9823    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9824         (plus:SI (match_dup 1) (match_dup 2)))]
9825   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9826    && (!avoiding_indexed_address_p (SImode)
9827        || !gpc_reg_operand (operands[2], SImode))"
9828   "@
9829    stwux %3,%0,%2
9830    stwu %3,%2(%0)"
9831   [(set_attr "type" "store")
9832    (set_attr "update" "yes")
9833    (set_attr "indexed" "yes,no")])
9835 (define_insn "*movdf_update1"
9836   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9837         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9838                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9839    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9840         (plus:SI (match_dup 1) (match_dup 2)))]
9841   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9842    && (!avoiding_indexed_address_p (SImode)
9843        || !gpc_reg_operand (operands[2], SImode))"
9844   "@
9845    lfdux %3,%0,%2
9846    lfdu %3,%2(%0)"
9847   [(set_attr "type" "fpload")
9848    (set_attr "update" "yes")
9849    (set_attr "indexed" "yes,no")
9850    (set_attr "size" "64")])
9852 (define_insn "*movdf_update2"
9853   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9854                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9855         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9856    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9857         (plus:SI (match_dup 1) (match_dup 2)))]
9858   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9859    && (!avoiding_indexed_address_p (SImode)
9860        || !gpc_reg_operand (operands[2], SImode))"
9861   "@
9862    stfdux %3,%0,%2
9863    stfdu %3,%2(%0)"
9864   [(set_attr "type" "fpstore")
9865    (set_attr "update" "yes")
9866    (set_attr "indexed" "yes,no")])
9869 ;; After inserting conditional returns we can sometimes have
9870 ;; unnecessary register moves.  Unfortunately we cannot have a
9871 ;; modeless peephole here, because some single SImode sets have early
9872 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9873 ;; sequences, using get_attr_length here will smash the operands
9874 ;; array.  Neither is there an early_cobbler_p predicate.
9875 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9876 ;; Also this optimization interferes with scalars going into
9877 ;; altivec registers (the code does reloading through the FPRs).
9878 (define_peephole2
9879   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9880         (match_operand:DF 1 "any_operand" ""))
9881    (set (match_operand:DF 2 "gpc_reg_operand" "")
9882         (match_dup 0))]
9883   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9884    && !TARGET_UPPER_REGS_DF
9885    && peep2_reg_dead_p (2, operands[0])"
9886   [(set (match_dup 2) (match_dup 1))])
9888 (define_peephole2
9889   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9890         (match_operand:SF 1 "any_operand" ""))
9891    (set (match_operand:SF 2 "gpc_reg_operand" "")
9892         (match_dup 0))]
9893   "!TARGET_UPPER_REGS_SF
9894    && peep2_reg_dead_p (2, operands[0])"
9895   [(set (match_dup 2) (match_dup 1))])
9898 ;; TLS support.
9900 ;; Mode attributes for different ABIs.
9901 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9902 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9903 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9904 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9906 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9907   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9908         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9909               (match_operand 4 "" "g")))
9910    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9911                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9912                    UNSPEC_TLSGD)
9913    (clobber (reg:SI LR_REGNO))]
9914   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9916   if (TARGET_CMODEL != CMODEL_SMALL)
9917     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9918            "bl %z3\;nop";
9919   else
9920     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9922   "&& TARGET_TLS_MARKERS"
9923   [(set (match_dup 0)
9924         (unspec:TLSmode [(match_dup 1)
9925                          (match_dup 2)]
9926                         UNSPEC_TLSGD))
9927    (parallel [(set (match_dup 0)
9928                    (call (mem:TLSmode (match_dup 3))
9929                          (match_dup 4)))
9930               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9931               (clobber (reg:SI LR_REGNO))])]
9932   ""
9933   [(set_attr "type" "two")
9934    (set (attr "length")
9935      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9936                    (const_int 16)
9937                    (const_int 12)))])
9939 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9940   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9941         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9942               (match_operand 4 "" "g")))
9943    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9944                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9945                    UNSPEC_TLSGD)
9946    (clobber (reg:SI LR_REGNO))]
9947   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9949   if (flag_pic)
9950     {
9951       if (TARGET_SECURE_PLT && flag_pic == 2)
9952         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9953       else
9954         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9955     }
9956   else
9957     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9959   "&& TARGET_TLS_MARKERS"
9960   [(set (match_dup 0)
9961         (unspec:TLSmode [(match_dup 1)
9962                          (match_dup 2)]
9963                         UNSPEC_TLSGD))
9964    (parallel [(set (match_dup 0)
9965                    (call (mem:TLSmode (match_dup 3))
9966                          (match_dup 4)))
9967               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9968               (clobber (reg:SI LR_REGNO))])]
9969   ""
9970   [(set_attr "type" "two")
9971    (set_attr "length" "8")])
9973 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9974   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9975         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9976                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9977                         UNSPEC_TLSGD))]
9978   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9979   "addi %0,%1,%2@got@tlsgd"
9980   "&& TARGET_CMODEL != CMODEL_SMALL"
9981   [(set (match_dup 3)
9982         (high:TLSmode
9983             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9984    (set (match_dup 0)
9985         (lo_sum:TLSmode (match_dup 3)
9986             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9987   "
9989   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9991   [(set (attr "length")
9992      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9993                    (const_int 8)
9994                    (const_int 4)))])
9996 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9997   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9998      (high:TLSmode
9999        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10000                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10001                        UNSPEC_TLSGD)))]
10002   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10003   "addis %0,%1,%2@got@tlsgd@ha"
10004   [(set_attr "length" "4")])
10006 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
10007   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10008      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10009        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10010                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10011                        UNSPEC_TLSGD)))]
10012   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10013   "addi %0,%1,%2@got@tlsgd@l"
10014   [(set_attr "length" "4")])
10016 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
10017   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10018         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10019               (match_operand 2 "" "g")))
10020    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
10021                    UNSPEC_TLSGD)
10022    (clobber (reg:SI LR_REGNO))]
10023   "HAVE_AS_TLS && TARGET_TLS_MARKERS
10024    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10025   "bl %z1(%3@tlsgd)\;nop"
10026   [(set_attr "type" "branch")
10027    (set_attr "length" "8")])
10029 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
10030   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10031         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10032               (match_operand 2 "" "g")))
10033    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
10034                    UNSPEC_TLSGD)
10035    (clobber (reg:SI LR_REGNO))]
10036   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10038   if (flag_pic)
10039     {
10040       if (TARGET_SECURE_PLT && flag_pic == 2)
10041         return "bl %z1+32768(%3@tlsgd)@plt";
10042       return "bl %z1(%3@tlsgd)@plt";
10043     }
10044   return "bl %z1(%3@tlsgd)";
10046   [(set_attr "type" "branch")
10047    (set_attr "length" "4")])
10049 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
10050   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10051         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10052               (match_operand 3 "" "g")))
10053    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10054                    UNSPEC_TLSLD)
10055    (clobber (reg:SI LR_REGNO))]
10056   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10058   if (TARGET_CMODEL != CMODEL_SMALL)
10059     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
10060            "bl %z2\;nop";
10061   else
10062     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
10064   "&& TARGET_TLS_MARKERS"
10065   [(set (match_dup 0)
10066         (unspec:TLSmode [(match_dup 1)]
10067                         UNSPEC_TLSLD))
10068    (parallel [(set (match_dup 0)
10069                    (call (mem:TLSmode (match_dup 2))
10070                          (match_dup 3)))
10071               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10072               (clobber (reg:SI LR_REGNO))])]
10073   ""
10074   [(set_attr "type" "two")
10075    (set (attr "length")
10076      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10077                    (const_int 16)
10078                    (const_int 12)))])
10080 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
10081   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10082         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10083               (match_operand 3 "" "g")))
10084    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10085                    UNSPEC_TLSLD)
10086    (clobber (reg:SI LR_REGNO))]
10087   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
10089   if (flag_pic)
10090     {
10091       if (TARGET_SECURE_PLT && flag_pic == 2)
10092         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
10093       else
10094         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
10095     }
10096   else
10097     return "addi %0,%1,%&@got@tlsld\;bl %z2";
10099   "&& TARGET_TLS_MARKERS"
10100   [(set (match_dup 0)
10101         (unspec:TLSmode [(match_dup 1)]
10102                         UNSPEC_TLSLD))
10103    (parallel [(set (match_dup 0)
10104                    (call (mem:TLSmode (match_dup 2))
10105                          (match_dup 3)))
10106               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10107               (clobber (reg:SI LR_REGNO))])]
10108   ""
10109   [(set_attr "length" "8")])
10111 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
10112   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10113         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10114                         UNSPEC_TLSLD))]
10115   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10116   "addi %0,%1,%&@got@tlsld"
10117   "&& TARGET_CMODEL != CMODEL_SMALL"
10118   [(set (match_dup 2)
10119         (high:TLSmode
10120             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10121    (set (match_dup 0)
10122         (lo_sum:TLSmode (match_dup 2)
10123             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10124   "
10126   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10128   [(set (attr "length")
10129      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10130                    (const_int 8)
10131                    (const_int 4)))])
10133 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10134   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10135      (high:TLSmode
10136        (unspec:TLSmode [(const_int 0)
10137                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10138                        UNSPEC_TLSLD)))]
10139   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10140   "addis %0,%1,%&@got@tlsld@ha"
10141   [(set_attr "length" "4")])
10143 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10144   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10145      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10146        (unspec:TLSmode [(const_int 0)
10147                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10148                        UNSPEC_TLSLD)))]
10149   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10150   "addi %0,%1,%&@got@tlsld@l"
10151   [(set_attr "length" "4")])
10153 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10154   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10155         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10156               (match_operand 2 "" "g")))
10157    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10158    (clobber (reg:SI LR_REGNO))]
10159   "HAVE_AS_TLS && TARGET_TLS_MARKERS
10160    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10161   "bl %z1(%&@tlsld)\;nop"
10162   [(set_attr "type" "branch")
10163    (set_attr "length" "8")])
10165 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10166   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10167         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10168               (match_operand 2 "" "g")))
10169    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10170    (clobber (reg:SI LR_REGNO))]
10171   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10173   if (flag_pic)
10174     {
10175       if (TARGET_SECURE_PLT && flag_pic == 2)
10176         return "bl %z1+32768(%&@tlsld)@plt";
10177       return "bl %z1(%&@tlsld)@plt";
10178     }
10179   return "bl %z1(%&@tlsld)";
10181   [(set_attr "type" "branch")
10182    (set_attr "length" "4")])
10184 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10185   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10186         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10187                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10188                         UNSPEC_TLSDTPREL))]
10189   "HAVE_AS_TLS"
10190   "addi %0,%1,%2@dtprel")
10192 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10193   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10194         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10195                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10196                         UNSPEC_TLSDTPRELHA))]
10197   "HAVE_AS_TLS"
10198   "addis %0,%1,%2@dtprel@ha")
10200 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10201   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10202         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10203                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10204                         UNSPEC_TLSDTPRELLO))]
10205   "HAVE_AS_TLS"
10206   "addi %0,%1,%2@dtprel@l")
10208 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10209   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10210         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10211                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10212                         UNSPEC_TLSGOTDTPREL))]
10213   "HAVE_AS_TLS"
10214   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10215   "&& TARGET_CMODEL != CMODEL_SMALL"
10216   [(set (match_dup 3)
10217         (high:TLSmode
10218             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10219    (set (match_dup 0)
10220         (lo_sum:TLSmode (match_dup 3)
10221             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10222   "
10224   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10226   [(set (attr "length")
10227      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10228                    (const_int 8)
10229                    (const_int 4)))])
10231 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10232   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10233      (high:TLSmode
10234        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10235                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10236                        UNSPEC_TLSGOTDTPREL)))]
10237   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10238   "addis %0,%1,%2@got@dtprel@ha"
10239   [(set_attr "length" "4")])
10241 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10242   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10243      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10244          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10245                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10246                          UNSPEC_TLSGOTDTPREL)))]
10247   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10248   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10249   [(set_attr "length" "4")])
10251 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10252   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10253         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10254                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10255                         UNSPEC_TLSTPREL))]
10256   "HAVE_AS_TLS"
10257   "addi %0,%1,%2@tprel")
10259 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10260   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10261         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10262                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10263                         UNSPEC_TLSTPRELHA))]
10264   "HAVE_AS_TLS"
10265   "addis %0,%1,%2@tprel@ha")
10267 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10268   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10269         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10270                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10271                         UNSPEC_TLSTPRELLO))]
10272   "HAVE_AS_TLS"
10273   "addi %0,%1,%2@tprel@l")
10275 ;; "b" output constraint here and on tls_tls input to support linker tls
10276 ;; optimization.  The linker may edit the instructions emitted by a
10277 ;; tls_got_tprel/tls_tls pair to addis,addi.
10278 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10279   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10280         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10281                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10282                         UNSPEC_TLSGOTTPREL))]
10283   "HAVE_AS_TLS"
10284   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10285   "&& TARGET_CMODEL != CMODEL_SMALL"
10286   [(set (match_dup 3)
10287         (high:TLSmode
10288             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10289    (set (match_dup 0)
10290         (lo_sum:TLSmode (match_dup 3)
10291             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10292   "
10294   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10296   [(set (attr "length")
10297      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10298                    (const_int 8)
10299                    (const_int 4)))])
10301 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10302   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10303      (high:TLSmode
10304        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10305                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10306                        UNSPEC_TLSGOTTPREL)))]
10307   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10308   "addis %0,%1,%2@got@tprel@ha"
10309   [(set_attr "length" "4")])
10311 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10312   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10313      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10314          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10315                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10316                          UNSPEC_TLSGOTTPREL)))]
10317   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10318   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10319   [(set_attr "length" "4")])
10321 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10322   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10323         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10324                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10325                         UNSPEC_TLSTLS))]
10326   "TARGET_ELF && HAVE_AS_TLS"
10327   "add %0,%1,%2@tls")
10329 (define_expand "tls_get_tpointer"
10330   [(set (match_operand:SI 0 "gpc_reg_operand" "")
10331         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10332   "TARGET_XCOFF && HAVE_AS_TLS"
10333   "
10335   emit_insn (gen_tls_get_tpointer_internal ());
10336   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10337   DONE;
10340 (define_insn "tls_get_tpointer_internal"
10341   [(set (reg:SI 3)
10342         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10343    (clobber (reg:SI LR_REGNO))]
10344   "TARGET_XCOFF && HAVE_AS_TLS"
10345   "bla __get_tpointer")
10347 (define_expand "tls_get_addr<mode>"
10348   [(set (match_operand:P 0 "gpc_reg_operand" "")
10349         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10350                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10351   "TARGET_XCOFF && HAVE_AS_TLS"
10352   "
10354   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10355   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10356   emit_insn (gen_tls_get_addr_internal<mode> ());
10357   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10358   DONE;
10361 (define_insn "tls_get_addr_internal<mode>"
10362   [(set (reg:P 3)
10363         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10364    (clobber (reg:P 0))
10365    (clobber (reg:P 4))
10366    (clobber (reg:P 5))
10367    (clobber (reg:P 11))
10368    (clobber (reg:CC CR0_REGNO))
10369    (clobber (reg:P LR_REGNO))]
10370   "TARGET_XCOFF && HAVE_AS_TLS"
10371   "bla __tls_get_addr")
10373 ;; Next come insns related to the calling sequence.
10375 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10376 ;; We move the back-chain and decrement the stack pointer.
10378 (define_expand "allocate_stack"
10379   [(set (match_operand 0 "gpc_reg_operand" "")
10380         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10381    (set (reg 1)
10382         (minus (reg 1) (match_dup 1)))]
10383   ""
10384   "
10385 { rtx chain = gen_reg_rtx (Pmode);
10386   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10387   rtx neg_op0;
10388   rtx insn, par, set, mem;
10390   emit_move_insn (chain, stack_bot);
10392   /* Check stack bounds if necessary.  */
10393   if (crtl->limit_stack)
10394     {
10395       rtx available;
10396       available = expand_binop (Pmode, sub_optab,
10397                                 stack_pointer_rtx, stack_limit_rtx,
10398                                 NULL_RTX, 1, OPTAB_WIDEN);
10399       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10400     }
10402   if (GET_CODE (operands[1]) != CONST_INT
10403       || INTVAL (operands[1]) < -32767
10404       || INTVAL (operands[1]) > 32768)
10405     {
10406       neg_op0 = gen_reg_rtx (Pmode);
10407       if (TARGET_32BIT)
10408         emit_insn (gen_negsi2 (neg_op0, operands[1]));
10409       else
10410         emit_insn (gen_negdi2 (neg_op0, operands[1]));
10411     }
10412   else
10413     neg_op0 = GEN_INT (- INTVAL (operands[1]));
10415   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10416                                        : gen_movdi_di_update_stack))
10417                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10418                          chain));
10419   /* Since we didn't use gen_frame_mem to generate the MEM, grab
10420      it now and set the alias set/attributes. The above gen_*_update
10421      calls will generate a PARALLEL with the MEM set being the first
10422      operation. */
10423   par = PATTERN (insn);
10424   gcc_assert (GET_CODE (par) == PARALLEL);
10425   set = XVECEXP (par, 0, 0);
10426   gcc_assert (GET_CODE (set) == SET);
10427   mem = SET_DEST (set);
10428   gcc_assert (MEM_P (mem));
10429   MEM_NOTRAP_P (mem) = 1;
10430   set_mem_alias_set (mem, get_frame_alias_set ());
10432   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10433   DONE;
10436 ;; These patterns say how to save and restore the stack pointer.  We need not
10437 ;; save the stack pointer at function level since we are careful to
10438 ;; preserve the backchain.  At block level, we have to restore the backchain
10439 ;; when we restore the stack pointer.
10441 ;; For nonlocal gotos, we must save both the stack pointer and its
10442 ;; backchain and restore both.  Note that in the nonlocal case, the
10443 ;; save area is a memory location.
10445 (define_expand "save_stack_function"
10446   [(match_operand 0 "any_operand" "")
10447    (match_operand 1 "any_operand" "")]
10448   ""
10449   "DONE;")
10451 (define_expand "restore_stack_function"
10452   [(match_operand 0 "any_operand" "")
10453    (match_operand 1 "any_operand" "")]
10454   ""
10455   "DONE;")
10457 ;; Adjust stack pointer (op0) to a new value (op1).
10458 ;; First copy old stack backchain to new location, and ensure that the
10459 ;; scheduler won't reorder the sp assignment before the backchain write.
10460 (define_expand "restore_stack_block"
10461   [(set (match_dup 2) (match_dup 3))
10462    (set (match_dup 4) (match_dup 2))
10463    (match_dup 5)
10464    (set (match_operand 0 "register_operand" "")
10465         (match_operand 1 "register_operand" ""))]
10466   ""
10467   "
10469   rtvec p;
10471   operands[1] = force_reg (Pmode, operands[1]);
10472   operands[2] = gen_reg_rtx (Pmode);
10473   operands[3] = gen_frame_mem (Pmode, operands[0]);
10474   operands[4] = gen_frame_mem (Pmode, operands[1]);
10475   p = rtvec_alloc (1);
10476   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10477                                   const0_rtx);
10478   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10481 (define_expand "save_stack_nonlocal"
10482   [(set (match_dup 3) (match_dup 4))
10483    (set (match_operand 0 "memory_operand" "") (match_dup 3))
10484    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10485   ""
10486   "
10488   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10490   /* Copy the backchain to the first word, sp to the second.  */
10491   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10492   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10493   operands[3] = gen_reg_rtx (Pmode);
10494   operands[4] = gen_frame_mem (Pmode, operands[1]);
10497 (define_expand "restore_stack_nonlocal"
10498   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10499    (set (match_dup 3) (match_dup 4))
10500    (set (match_dup 5) (match_dup 2))
10501    (match_dup 6)
10502    (set (match_operand 0 "register_operand" "") (match_dup 3))]
10503   ""
10504   "
10506   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10507   rtvec p;
10509   /* Restore the backchain from the first word, sp from the second.  */
10510   operands[2] = gen_reg_rtx (Pmode);
10511   operands[3] = gen_reg_rtx (Pmode);
10512   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10513   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10514   operands[5] = gen_frame_mem (Pmode, operands[3]);
10515   p = rtvec_alloc (1);
10516   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10517                                   const0_rtx);
10518   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10521 ;; TOC register handling.
10523 ;; Code to initialize the TOC register...
10525 (define_insn "load_toc_aix_si"
10526   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10527                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10528               (use (reg:SI 2))])]
10529   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10530   "*
10532   char buf[30];
10533   extern int need_toc_init;
10534   need_toc_init = 1;
10535   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10536   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10537   operands[2] = gen_rtx_REG (Pmode, 2);
10538   return \"lwz %0,%1(%2)\";
10540   [(set_attr "type" "load")
10541    (set_attr "update" "no")
10542    (set_attr "indexed" "no")])
10544 (define_insn "load_toc_aix_di"
10545   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10546                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10547               (use (reg:DI 2))])]
10548   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10549   "*
10551   char buf[30];
10552   extern int need_toc_init;
10553   need_toc_init = 1;
10554   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10555                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10556   if (TARGET_ELF)
10557     strcat (buf, \"@toc\");
10558   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10559   operands[2] = gen_rtx_REG (Pmode, 2);
10560   return \"ld %0,%1(%2)\";
10562   [(set_attr "type" "load")
10563    (set_attr "update" "no")
10564    (set_attr "indexed" "no")])
10566 (define_insn "load_toc_v4_pic_si"
10567   [(set (reg:SI LR_REGNO)
10568         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10569   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10570   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10571   [(set_attr "type" "branch")
10572    (set_attr "length" "4")])
10574 (define_expand "load_toc_v4_PIC_1"
10575   [(parallel [(set (reg:SI LR_REGNO)
10576                    (match_operand:SI 0 "immediate_operand" "s"))
10577               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10578   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10579    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10580   "")
10582 (define_insn "load_toc_v4_PIC_1_normal"
10583   [(set (reg:SI LR_REGNO)
10584         (match_operand:SI 0 "immediate_operand" "s"))
10585    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10586   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10587    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10588   "bcl 20,31,%0\\n%0:"
10589   [(set_attr "type" "branch")
10590    (set_attr "length" "4")
10591    (set_attr "cannot_copy" "yes")])
10593 (define_insn "load_toc_v4_PIC_1_476"
10594   [(set (reg:SI LR_REGNO)
10595         (match_operand:SI 0 "immediate_operand" "s"))
10596    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10597   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10598    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10599   "*
10601   char name[32];
10602   static char templ[32];
10604   get_ppc476_thunk_name (name);
10605   sprintf (templ, \"bl %s\\n%%0:\", name);
10606   return templ;
10608   [(set_attr "type" "branch")
10609    (set_attr "length" "4")
10610    (set_attr "cannot_copy" "yes")])
10612 (define_expand "load_toc_v4_PIC_1b"
10613   [(parallel [(set (reg:SI LR_REGNO)
10614                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10615                                (label_ref (match_operand 1 "" ""))]
10616                            UNSPEC_TOCPTR))
10617               (match_dup 1)])]
10618   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10619   "")
10621 (define_insn "load_toc_v4_PIC_1b_normal"
10622   [(set (reg:SI LR_REGNO)
10623         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10624                     (label_ref (match_operand 1 "" ""))]
10625                 UNSPEC_TOCPTR))
10626    (match_dup 1)]
10627   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10628   "bcl 20,31,$+8\;.long %0-$"
10629   [(set_attr "type" "branch")
10630    (set_attr "length" "8")])
10632 (define_insn "load_toc_v4_PIC_1b_476"
10633   [(set (reg:SI LR_REGNO)
10634         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10635                     (label_ref (match_operand 1 "" ""))]
10636                 UNSPEC_TOCPTR))
10637    (match_dup 1)]
10638   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10639   "*
10641   char name[32];
10642   static char templ[32];
10644   get_ppc476_thunk_name (name);
10645   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10646   return templ;
10648   [(set_attr "type" "branch")
10649    (set_attr "length" "16")])
10651 (define_insn "load_toc_v4_PIC_2"
10652   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10653         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10654                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10655                              (match_operand:SI 3 "immediate_operand" "s")))))]
10656   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10657   "lwz %0,%2-%3(%1)"
10658   [(set_attr "type" "load")])
10660 (define_insn "load_toc_v4_PIC_3b"
10661   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10662         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10663                  (high:SI
10664                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10665                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10666   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10667   "addis %0,%1,%2-%3@ha")
10669 (define_insn "load_toc_v4_PIC_3c"
10670   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10671         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10672                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10673                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10674   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10675   "addi %0,%1,%2-%3@l")
10677 ;; If the TOC is shared over a translation unit, as happens with all
10678 ;; the kinds of PIC that we support, we need to restore the TOC
10679 ;; pointer only when jumping over units of translation.
10680 ;; On Darwin, we need to reload the picbase.
10682 (define_expand "builtin_setjmp_receiver"
10683   [(use (label_ref (match_operand 0 "" "")))]
10684   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10685    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10686    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10687   "
10689 #if TARGET_MACHO
10690   if (DEFAULT_ABI == ABI_DARWIN)
10691     {
10692       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10693       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10694       rtx tmplabrtx;
10695       char tmplab[20];
10697       crtl->uses_pic_offset_table = 1;
10698       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10699                                   CODE_LABEL_NUMBER (operands[0]));
10700       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10702       emit_insn (gen_load_macho_picbase (tmplabrtx));
10703       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10704       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10705     }
10706   else
10707 #endif
10708     rs6000_emit_load_toc_table (FALSE);
10709   DONE;
10712 ;; Largetoc support
10713 (define_insn "*largetoc_high"
10714   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10715         (high:DI
10716           (unspec [(match_operand:DI 1 "" "")
10717                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10718                   UNSPEC_TOCREL)))]
10719    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10720    "addis %0,%2,%1@toc@ha")
10722 (define_insn "*largetoc_high_aix<mode>"
10723   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10724         (high:P
10725           (unspec [(match_operand:P 1 "" "")
10726                    (match_operand:P 2 "gpc_reg_operand" "b")]
10727                   UNSPEC_TOCREL)))]
10728    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10729    "addis %0,%1@u(%2)")
10731 (define_insn "*largetoc_high_plus"
10732   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10733         (high:DI
10734           (plus:DI
10735             (unspec [(match_operand:DI 1 "" "")
10736                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10737                     UNSPEC_TOCREL)
10738             (match_operand:DI 3 "add_cint_operand" "n"))))]
10739    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10740    "addis %0,%2,%1+%3@toc@ha")
10742 (define_insn "*largetoc_high_plus_aix<mode>"
10743   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10744         (high:P
10745           (plus:P
10746             (unspec [(match_operand:P 1 "" "")
10747                      (match_operand:P 2 "gpc_reg_operand" "b")]
10748                     UNSPEC_TOCREL)
10749             (match_operand:P 3 "add_cint_operand" "n"))))]
10750    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10751    "addis %0,%1+%3@u(%2)")
10753 (define_insn "*largetoc_low"
10754   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10755         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10756                    (match_operand:DI 2 "" "")))]
10757    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10758    "addi %0,%1,%2@l")
10760 (define_insn "*largetoc_low_aix<mode>"
10761   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10762         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10763                    (match_operand:P 2 "" "")))]
10764    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10765    "la %0,%2@l(%1)")
10767 (define_insn_and_split "*tocref<mode>"
10768   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10769         (match_operand:P 1 "small_toc_ref" "R"))]
10770    "TARGET_TOC"
10771    "la %0,%a1"
10772    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10773   [(set (match_dup 0) (high:P (match_dup 1)))
10774    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10776 ;; Elf specific ways of loading addresses for non-PIC code.
10777 ;; The output of this could be r0, but we make a very strong
10778 ;; preference for a base register because it will usually
10779 ;; be needed there.
10780 (define_insn "elf_high"
10781   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10782         (high:SI (match_operand 1 "" "")))]
10783   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10784   "lis %0,%1@ha")
10786 (define_insn "elf_low"
10787   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10788         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10789                    (match_operand 2 "" "")))]
10790    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10791    "la %0,%2@l(%1)")
10793 ;; Call and call_value insns
10794 (define_expand "call"
10795   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10796                     (match_operand 1 "" ""))
10797               (use (match_operand 2 "" ""))
10798               (clobber (reg:SI LR_REGNO))])]
10799   ""
10800   "
10802 #if TARGET_MACHO
10803   if (MACHOPIC_INDIRECT)
10804     operands[0] = machopic_indirect_call_target (operands[0]);
10805 #endif
10807   gcc_assert (GET_CODE (operands[0]) == MEM);
10808   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10810   operands[0] = XEXP (operands[0], 0);
10812   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10813     {
10814       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10815       DONE;
10816     }
10818   if (GET_CODE (operands[0]) != SYMBOL_REF
10819       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10820     {
10821       if (INTVAL (operands[2]) & CALL_LONG)
10822         operands[0] = rs6000_longcall_ref (operands[0]);
10824       switch (DEFAULT_ABI)
10825         {
10826         case ABI_V4:
10827         case ABI_DARWIN:
10828           operands[0] = force_reg (Pmode, operands[0]);
10829           break;
10831         default:
10832           gcc_unreachable ();
10833         }
10834     }
10837 (define_expand "call_value"
10838   [(parallel [(set (match_operand 0 "" "")
10839                    (call (mem:SI (match_operand 1 "address_operand" ""))
10840                          (match_operand 2 "" "")))
10841               (use (match_operand 3 "" ""))
10842               (clobber (reg:SI LR_REGNO))])]
10843   ""
10844   "
10846 #if TARGET_MACHO
10847   if (MACHOPIC_INDIRECT)
10848     operands[1] = machopic_indirect_call_target (operands[1]);
10849 #endif
10851   gcc_assert (GET_CODE (operands[1]) == MEM);
10852   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10854   operands[1] = XEXP (operands[1], 0);
10856   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10857     {
10858       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10859       DONE;
10860     }
10862   if (GET_CODE (operands[1]) != SYMBOL_REF
10863       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10864     {
10865       if (INTVAL (operands[3]) & CALL_LONG)
10866         operands[1] = rs6000_longcall_ref (operands[1]);
10868       switch (DEFAULT_ABI)
10869         {
10870         case ABI_V4:
10871         case ABI_DARWIN:
10872           operands[1] = force_reg (Pmode, operands[1]);
10873           break;
10875         default:
10876           gcc_unreachable ();
10877         }
10878     }
10881 ;; Call to function in current module.  No TOC pointer reload needed.
10882 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10883 ;; either the function was not prototyped, or it was prototyped as a
10884 ;; variable argument function.  It is > 0 if FP registers were passed
10885 ;; and < 0 if they were not.
10887 (define_insn "*call_local32"
10888   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10889          (match_operand 1 "" "g,g"))
10890    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10891    (clobber (reg:SI LR_REGNO))]
10892   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10893   "*
10895   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10896     output_asm_insn (\"crxor 6,6,6\", operands);
10898   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10899     output_asm_insn (\"creqv 6,6,6\", operands);
10901   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10903   [(set_attr "type" "branch")
10904    (set_attr "length" "4,8")])
10906 (define_insn "*call_local64"
10907   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10908          (match_operand 1 "" "g,g"))
10909    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10910    (clobber (reg:SI LR_REGNO))]
10911   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10912   "*
10914   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10915     output_asm_insn (\"crxor 6,6,6\", operands);
10917   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10918     output_asm_insn (\"creqv 6,6,6\", operands);
10920   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10922   [(set_attr "type" "branch")
10923    (set_attr "length" "4,8")])
10925 (define_insn "*call_value_local32"
10926   [(set (match_operand 0 "" "")
10927         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10928               (match_operand 2 "" "g,g")))
10929    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10930    (clobber (reg:SI LR_REGNO))]
10931   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10932   "*
10934   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10935     output_asm_insn (\"crxor 6,6,6\", operands);
10937   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10938     output_asm_insn (\"creqv 6,6,6\", operands);
10940   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10942   [(set_attr "type" "branch")
10943    (set_attr "length" "4,8")])
10946 (define_insn "*call_value_local64"
10947   [(set (match_operand 0 "" "")
10948         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10949               (match_operand 2 "" "g,g")))
10950    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10951    (clobber (reg:SI LR_REGNO))]
10952   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10953   "*
10955   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10956     output_asm_insn (\"crxor 6,6,6\", operands);
10958   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10959     output_asm_insn (\"creqv 6,6,6\", operands);
10961   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10963   [(set_attr "type" "branch")
10964    (set_attr "length" "4,8")])
10967 ;; A function pointer under System V is just a normal pointer
10968 ;; operands[0] is the function pointer
10969 ;; operands[1] is the stack size to clean up
10970 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10971 ;; which indicates how to set cr1
10973 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10974   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10975          (match_operand 1 "" "g,g,g,g"))
10976    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10977    (clobber (reg:SI LR_REGNO))]
10978   "DEFAULT_ABI == ABI_V4
10979    || DEFAULT_ABI == ABI_DARWIN"
10981   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10982     output_asm_insn ("crxor 6,6,6", operands);
10984   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10985     output_asm_insn ("creqv 6,6,6", operands);
10987   return "b%T0l";
10989   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10990    (set_attr "length" "4,4,8,8")])
10992 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10993   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10994          (match_operand 1 "" "g,g"))
10995    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10996    (clobber (reg:SI LR_REGNO))]
10997   "(DEFAULT_ABI == ABI_DARWIN
10998    || (DEFAULT_ABI == ABI_V4
10999        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
11001   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11002     output_asm_insn ("crxor 6,6,6", operands);
11004   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11005     output_asm_insn ("creqv 6,6,6", operands);
11007 #if TARGET_MACHO
11008   return output_call(insn, operands, 0, 2);
11009 #else
11010   if (DEFAULT_ABI == ABI_V4 && flag_pic)
11011     {
11012       gcc_assert (!TARGET_SECURE_PLT);
11013       return "bl %z0@plt";
11014     }
11015   else
11016     return "bl %z0";
11017 #endif
11019   "DEFAULT_ABI == ABI_V4
11020    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11021    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11022   [(parallel [(call (mem:SI (match_dup 0))
11023                     (match_dup 1))
11024               (use (match_dup 2))
11025               (use (match_dup 3))
11026               (clobber (reg:SI LR_REGNO))])]
11028   operands[3] = pic_offset_table_rtx;
11030   [(set_attr "type" "branch,branch")
11031    (set_attr "length" "4,8")])
11033 (define_insn "*call_nonlocal_sysv_secure<mode>"
11034   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11035          (match_operand 1 "" "g,g"))
11036    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11037    (use (match_operand:SI 3 "register_operand" "r,r"))
11038    (clobber (reg:SI LR_REGNO))]
11039   "(DEFAULT_ABI == ABI_V4
11040     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11041     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11043   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11044     output_asm_insn ("crxor 6,6,6", operands);
11046   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11047     output_asm_insn ("creqv 6,6,6", operands);
11049   if (flag_pic == 2)
11050     /* The magic 32768 offset here and in the other sysv call insns
11051        corresponds to the offset of r30 in .got2, as given by LCTOC1.
11052        See sysv4.h:toc_section.  */
11053     return "bl %z0+32768@plt";
11054   else
11055     return "bl %z0@plt";
11057   [(set_attr "type" "branch,branch")
11058    (set_attr "length" "4,8")])
11060 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11061   [(set (match_operand 0 "" "")
11062         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
11063               (match_operand 2 "" "g,g,g,g")))
11064    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
11065    (clobber (reg:SI LR_REGNO))]
11066   "DEFAULT_ABI == ABI_V4
11067    || DEFAULT_ABI == ABI_DARWIN"
11069   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11070     output_asm_insn ("crxor 6,6,6", operands);
11072   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11073     output_asm_insn ("creqv 6,6,6", operands);
11075   return "b%T1l";
11077   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
11078    (set_attr "length" "4,4,8,8")])
11080 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
11081   [(set (match_operand 0 "" "")
11082         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11083               (match_operand 2 "" "g,g")))
11084    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11085    (clobber (reg:SI LR_REGNO))]
11086   "(DEFAULT_ABI == ABI_DARWIN
11087    || (DEFAULT_ABI == ABI_V4
11088        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11090   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11091     output_asm_insn ("crxor 6,6,6", operands);
11093   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11094     output_asm_insn ("creqv 6,6,6", operands);
11096 #if TARGET_MACHO
11097   return output_call(insn, operands, 1, 3);
11098 #else
11099   if (DEFAULT_ABI == ABI_V4 && flag_pic)
11100     {
11101       gcc_assert (!TARGET_SECURE_PLT);
11102       return "bl %z1@plt";
11103     }
11104   else
11105     return "bl %z1";
11106 #endif
11108   "DEFAULT_ABI == ABI_V4
11109    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11110    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11111   [(parallel [(set (match_dup 0)
11112                    (call (mem:SI (match_dup 1))
11113                          (match_dup 2)))
11114               (use (match_dup 3))
11115               (use (match_dup 4))
11116               (clobber (reg:SI LR_REGNO))])]
11118   operands[4] = pic_offset_table_rtx;
11120   [(set_attr "type" "branch,branch")
11121    (set_attr "length" "4,8")])
11123 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11124   [(set (match_operand 0 "" "")
11125         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11126               (match_operand 2 "" "g,g")))
11127    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11128    (use (match_operand:SI 4 "register_operand" "r,r"))
11129    (clobber (reg:SI LR_REGNO))]
11130   "(DEFAULT_ABI == ABI_V4
11131     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11132     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11134   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11135     output_asm_insn ("crxor 6,6,6", operands);
11137   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11138     output_asm_insn ("creqv 6,6,6", operands);
11140   if (flag_pic == 2)
11141     return "bl %z1+32768@plt";
11142   else
11143     return "bl %z1@plt";
11145   [(set_attr "type" "branch,branch")
11146    (set_attr "length" "4,8")])
11149 ;; Call to AIX abi function in the same module.
11151 (define_insn "*call_local_aix<mode>"
11152   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11153          (match_operand 1 "" "g"))
11154    (clobber (reg:P LR_REGNO))]
11155   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11156   "bl %z0"
11157   [(set_attr "type" "branch")
11158    (set_attr "length" "4")])
11160 (define_insn "*call_value_local_aix<mode>"
11161   [(set (match_operand 0 "" "")
11162         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11163               (match_operand 2 "" "g")))
11164    (clobber (reg:P LR_REGNO))]
11165   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11166   "bl %z1"
11167   [(set_attr "type" "branch")
11168    (set_attr "length" "4")])
11170 ;; Call to AIX abi function which may be in another module.
11171 ;; Restore the TOC pointer (r2) after the call.
11173 (define_insn "*call_nonlocal_aix<mode>"
11174   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11175          (match_operand 1 "" "g"))
11176    (clobber (reg:P LR_REGNO))]
11177   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11178   "bl %z0\;nop"
11179   [(set_attr "type" "branch")
11180    (set_attr "length" "8")])
11182 (define_insn "*call_value_nonlocal_aix<mode>"
11183   [(set (match_operand 0 "" "")
11184         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11185               (match_operand 2 "" "g")))
11186    (clobber (reg:P LR_REGNO))]
11187   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11188   "bl %z1\;nop"
11189   [(set_attr "type" "branch")
11190    (set_attr "length" "8")])
11192 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11193 ;; Operand0 is the addresss of the function to call
11194 ;; Operand2 is the location in the function descriptor to load r2 from
11195 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11197 (define_insn "*call_indirect_aix<mode>"
11198   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11199          (match_operand 1 "" "g,g"))
11200    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11201    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11202    (clobber (reg:P LR_REGNO))]
11203   "DEFAULT_ABI == ABI_AIX"
11204   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11205   [(set_attr "type" "jmpreg")
11206    (set_attr "length" "12")])
11208 (define_insn "*call_value_indirect_aix<mode>"
11209   [(set (match_operand 0 "" "")
11210         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11211               (match_operand 2 "" "g,g")))
11212    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11213    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11214    (clobber (reg:P LR_REGNO))]
11215   "DEFAULT_ABI == ABI_AIX"
11216   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11217   [(set_attr "type" "jmpreg")
11218    (set_attr "length" "12")])
11220 ;; Call to indirect functions with the ELFv2 ABI.
11221 ;; Operand0 is the addresss of the function to call
11222 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11224 (define_insn "*call_indirect_elfv2<mode>"
11225   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11226          (match_operand 1 "" "g,g"))
11227    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11228    (clobber (reg:P LR_REGNO))]
11229   "DEFAULT_ABI == ABI_ELFv2"
11230   "b%T0l\;<ptrload> 2,%2(1)"
11231   [(set_attr "type" "jmpreg")
11232    (set_attr "length" "8")])
11234 (define_insn "*call_value_indirect_elfv2<mode>"
11235   [(set (match_operand 0 "" "")
11236         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11237               (match_operand 2 "" "g,g")))
11238    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11239    (clobber (reg:P LR_REGNO))]
11240   "DEFAULT_ABI == ABI_ELFv2"
11241   "b%T1l\;<ptrload> 2,%3(1)"
11242   [(set_attr "type" "jmpreg")
11243    (set_attr "length" "8")])
11246 ;; Call subroutine returning any type.
11247 (define_expand "untyped_call"
11248   [(parallel [(call (match_operand 0 "" "")
11249                     (const_int 0))
11250               (match_operand 1 "" "")
11251               (match_operand 2 "" "")])]
11252   ""
11253   "
11255   int i;
11257   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11259   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11260     {
11261       rtx set = XVECEXP (operands[2], 0, i);
11262       emit_move_insn (SET_DEST (set), SET_SRC (set));
11263     }
11265   /* The optimizer does not know that the call sets the function value
11266      registers we stored in the result block.  We avoid problems by
11267      claiming that all hard registers are used and clobbered at this
11268      point.  */
11269   emit_insn (gen_blockage ());
11271   DONE;
11274 ;; sibling call patterns
11275 (define_expand "sibcall"
11276   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11277                     (match_operand 1 "" ""))
11278               (use (match_operand 2 "" ""))
11279               (simple_return)])]
11280   ""
11281   "
11283 #if TARGET_MACHO
11284   if (MACHOPIC_INDIRECT)
11285     operands[0] = machopic_indirect_call_target (operands[0]);
11286 #endif
11288   gcc_assert (GET_CODE (operands[0]) == MEM);
11289   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11291   operands[0] = XEXP (operands[0], 0);
11293   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11294     {
11295       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11296       DONE;
11297     }
11300 (define_expand "sibcall_value"
11301   [(parallel [(set (match_operand 0 "register_operand" "")
11302                 (call (mem:SI (match_operand 1 "address_operand" ""))
11303                       (match_operand 2 "" "")))
11304               (use (match_operand 3 "" ""))
11305               (simple_return)])]
11306   ""
11307   "
11309 #if TARGET_MACHO
11310   if (MACHOPIC_INDIRECT)
11311     operands[1] = machopic_indirect_call_target (operands[1]);
11312 #endif
11314   gcc_assert (GET_CODE (operands[1]) == MEM);
11315   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11317   operands[1] = XEXP (operands[1], 0);
11319   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11320     {
11321       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11322       DONE;
11323     }
11326 (define_insn "*sibcall_local32"
11327   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11328          (match_operand 1 "" "g,g"))
11329    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11330    (simple_return)]
11331   "(INTVAL (operands[2]) & CALL_LONG) == 0"
11332   "*
11334   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11335     output_asm_insn (\"crxor 6,6,6\", operands);
11337   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11338     output_asm_insn (\"creqv 6,6,6\", operands);
11340   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11342   [(set_attr "type" "branch")
11343    (set_attr "length" "4,8")])
11345 (define_insn "*sibcall_local64"
11346   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11347          (match_operand 1 "" "g,g"))
11348    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11349    (simple_return)]
11350   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11351   "*
11353   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11354     output_asm_insn (\"crxor 6,6,6\", operands);
11356   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11357     output_asm_insn (\"creqv 6,6,6\", operands);
11359   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11361   [(set_attr "type" "branch")
11362    (set_attr "length" "4,8")])
11364 (define_insn "*sibcall_value_local32"
11365   [(set (match_operand 0 "" "")
11366         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11367               (match_operand 2 "" "g,g")))
11368    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11369    (simple_return)]
11370   "(INTVAL (operands[3]) & CALL_LONG) == 0"
11371   "*
11373   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11374     output_asm_insn (\"crxor 6,6,6\", operands);
11376   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11377     output_asm_insn (\"creqv 6,6,6\", operands);
11379   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11381   [(set_attr "type" "branch")
11382    (set_attr "length" "4,8")])
11384 (define_insn "*sibcall_value_local64"
11385   [(set (match_operand 0 "" "")
11386         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11387               (match_operand 2 "" "g,g")))
11388    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11389    (simple_return)]
11390   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11391   "*
11393   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11394     output_asm_insn (\"crxor 6,6,6\", operands);
11396   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11397     output_asm_insn (\"creqv 6,6,6\", operands);
11399   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11401   [(set_attr "type" "branch")
11402    (set_attr "length" "4,8")])
11404 (define_insn "*sibcall_nonlocal_sysv<mode>"
11405   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11406          (match_operand 1 "" ""))
11407    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11408    (simple_return)]
11409   "(DEFAULT_ABI == ABI_DARWIN
11410     || DEFAULT_ABI == ABI_V4)
11411    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11412   "*
11414   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11415     output_asm_insn (\"crxor 6,6,6\", operands);
11417   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11418     output_asm_insn (\"creqv 6,6,6\", operands);
11420   if (which_alternative >= 2)
11421     return \"b%T0\";
11422   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11423     {
11424       gcc_assert (!TARGET_SECURE_PLT);
11425       return \"b %z0@plt\";
11426     }
11427   else
11428     return \"b %z0\";
11430   [(set_attr "type" "branch")
11431    (set_attr "length" "4,8,4,8")])
11433 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11434   [(set (match_operand 0 "" "")
11435         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11436               (match_operand 2 "" "")))
11437    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11438    (simple_return)]
11439   "(DEFAULT_ABI == ABI_DARWIN
11440     || DEFAULT_ABI == ABI_V4)
11441    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11442   "*
11444   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11445     output_asm_insn (\"crxor 6,6,6\", operands);
11447   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11448     output_asm_insn (\"creqv 6,6,6\", operands);
11450   if (which_alternative >= 2)
11451     return \"b%T1\";
11452   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11453     {
11454       gcc_assert (!TARGET_SECURE_PLT);
11455       return \"b %z1@plt\";
11456     }
11457   else
11458     return \"b %z1\";
11460   [(set_attr "type" "branch")
11461    (set_attr "length" "4,8,4,8")])
11463 ;; AIX ABI sibling call patterns.
11465 (define_insn "*sibcall_aix<mode>"
11466   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11467          (match_operand 1 "" "g,g"))
11468    (simple_return)]
11469   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11470   "@
11471    b %z0
11472    b%T0"
11473   [(set_attr "type" "branch")
11474    (set_attr "length" "4")])
11476 (define_insn "*sibcall_value_aix<mode>"
11477   [(set (match_operand 0 "" "")
11478         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11479               (match_operand 2 "" "g,g")))
11480    (simple_return)]
11481   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11482   "@
11483    b %z1
11484    b%T1"
11485   [(set_attr "type" "branch")
11486    (set_attr "length" "4")])
11488 (define_expand "sibcall_epilogue"
11489   [(use (const_int 0))]
11490   ""
11492   if (!TARGET_SCHED_PROLOG)
11493     emit_insn (gen_blockage ());
11494   rs6000_emit_epilogue (TRUE);
11495   DONE;
11498 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11499 ;; all of memory.  This blocks insns from being moved across this point.
11501 (define_insn "blockage"
11502   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11503   ""
11504   "")
11506 (define_expand "probe_stack_address"
11507   [(use (match_operand 0 "address_operand"))]
11508   ""
11510   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11511   MEM_VOLATILE_P (operands[0]) = 1;
11513   if (TARGET_64BIT)
11514     emit_insn (gen_probe_stack_di (operands[0]));
11515   else
11516     emit_insn (gen_probe_stack_si (operands[0]));
11517   DONE;
11520 (define_insn "probe_stack_<mode>"
11521   [(set (match_operand:P 0 "memory_operand" "=m")
11522         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11523   ""
11525   operands[1] = gen_rtx_REG (Pmode, 0);
11526   return "st<wd>%U0%X0 %1,%0";
11528   [(set_attr "type" "store")
11529    (set (attr "update")
11530         (if_then_else (match_operand 0 "update_address_mem")
11531                       (const_string "yes")
11532                       (const_string "no")))
11533    (set (attr "indexed")
11534         (if_then_else (match_operand 0 "indexed_address_mem")
11535                       (const_string "yes")
11536                       (const_string "no")))
11537    (set_attr "length" "4")])
11539 (define_insn "probe_stack_range<P:mode>"
11540   [(set (match_operand:P 0 "register_operand" "=r")
11541         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11542                             (match_operand:P 2 "register_operand" "r")]
11543                            UNSPECV_PROBE_STACK_RANGE))]
11544   ""
11545   "* return output_probe_stack_range (operands[0], operands[2]);"
11546   [(set_attr "type" "three")])
11548 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11549 ;; signed & unsigned, and one type of branch.
11551 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11552 ;; insns, and branches.
11554 (define_expand "cbranch<mode>4"
11555   [(use (match_operator 0 "rs6000_cbranch_operator"
11556          [(match_operand:GPR 1 "gpc_reg_operand" "")
11557           (match_operand:GPR 2 "reg_or_short_operand" "")]))
11558    (use (match_operand 3 ""))]
11559   ""
11560   "
11562   /* Take care of the possibility that operands[2] might be negative but
11563      this might be a logical operation.  That insn doesn't exist.  */
11564   if (GET_CODE (operands[2]) == CONST_INT
11565       && INTVAL (operands[2]) < 0)
11566     {
11567       operands[2] = force_reg (<MODE>mode, operands[2]);
11568       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11569                                     GET_MODE (operands[0]),
11570                                     operands[1], operands[2]);
11571    }
11573   rs6000_emit_cbranch (<MODE>mode, operands);
11574   DONE;
11577 (define_expand "cbranch<mode>4"
11578   [(use (match_operator 0 "rs6000_cbranch_operator"
11579          [(match_operand:FP 1 "gpc_reg_operand" "")
11580           (match_operand:FP 2 "gpc_reg_operand" "")]))
11581    (use (match_operand 3 ""))]
11582   ""
11583   "
11585   rs6000_emit_cbranch (<MODE>mode, operands);
11586   DONE;
11589 (define_expand "cstore<mode>4_signed"
11590   [(use (match_operator 1 "signed_comparison_operator"
11591          [(match_operand:P 2 "gpc_reg_operand")
11592           (match_operand:P 3 "gpc_reg_operand")]))
11593    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11594   ""
11596   enum rtx_code cond_code = GET_CODE (operands[1]);
11598   rtx op0 = operands[0];
11599   rtx op1 = operands[2];
11600   rtx op2 = operands[3];
11602   if (cond_code == GE || cond_code == LT)
11603     {
11604       cond_code = swap_condition (cond_code);
11605       std::swap (op1, op2);
11606     }
11608   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11609   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11610   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11612   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11613   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11614   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11616   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11618   if (cond_code == LE)
11619     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11620   else
11621     {
11622       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11623       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11624       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11625     }
11627   DONE;
11630 (define_expand "cstore<mode>4_unsigned"
11631   [(use (match_operator 1 "unsigned_comparison_operator"
11632          [(match_operand:P 2 "gpc_reg_operand")
11633           (match_operand:P 3 "reg_or_short_operand")]))
11634    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11635   ""
11637   enum rtx_code cond_code = GET_CODE (operands[1]);
11639   rtx op0 = operands[0];
11640   rtx op1 = operands[2];
11641   rtx op2 = operands[3];
11643   if (cond_code == GEU || cond_code == LTU)
11644     {
11645       cond_code = swap_condition (cond_code);
11646       std::swap (op1, op2);
11647     }
11649   if (!gpc_reg_operand (op1, <MODE>mode))
11650     op1 = force_reg (<MODE>mode, op1);
11651   if (!reg_or_short_operand (op2, <MODE>mode))
11652     op2 = force_reg (<MODE>mode, op2);
11654   rtx tmp = gen_reg_rtx (<MODE>mode);
11655   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11657   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11658   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11660   if (cond_code == LEU)
11661     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11662   else
11663     emit_insn (gen_neg<mode>2 (op0, tmp2));
11665   DONE;
11668 (define_expand "cstore_si_as_di"
11669   [(use (match_operator 1 "unsigned_comparison_operator"
11670          [(match_operand:SI 2 "gpc_reg_operand")
11671           (match_operand:SI 3 "reg_or_short_operand")]))
11672    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11673   ""
11675   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11676   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11678   operands[2] = force_reg (SImode, operands[2]);
11679   operands[3] = force_reg (SImode, operands[3]);
11680   rtx op1 = gen_reg_rtx (DImode);
11681   rtx op2 = gen_reg_rtx (DImode);
11682   convert_move (op1, operands[2], uns_flag);
11683   convert_move (op2, operands[3], uns_flag);
11685   if (cond_code == GT || cond_code == LE)
11686     {
11687       cond_code = swap_condition (cond_code);
11688       std::swap (op1, op2);
11689     }
11691   rtx tmp = gen_reg_rtx (DImode);
11692   rtx tmp2 = gen_reg_rtx (DImode);
11693   emit_insn (gen_subdi3 (tmp, op1, op2));
11694   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11696   rtx tmp3;
11697   switch (cond_code)
11698     {
11699     default:
11700       gcc_unreachable ();
11701     case LT:
11702       tmp3 = tmp2;
11703       break;
11704     case GE:
11705       tmp3 = gen_reg_rtx (DImode);
11706       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11707       break;
11708     }
11710   convert_move (operands[0], tmp3, 1);
11712   DONE;
11715 (define_expand "cstore<mode>4_signed_imm"
11716   [(use (match_operator 1 "signed_comparison_operator"
11717          [(match_operand:GPR 2 "gpc_reg_operand")
11718           (match_operand:GPR 3 "immediate_operand")]))
11719    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11720   ""
11722   bool invert = false;
11724   enum rtx_code cond_code = GET_CODE (operands[1]);
11726   rtx op0 = operands[0];
11727   rtx op1 = operands[2];
11728   HOST_WIDE_INT val = INTVAL (operands[3]);
11730   if (cond_code == GE || cond_code == GT)
11731     {
11732       cond_code = reverse_condition (cond_code);
11733       invert = true;
11734     }
11736   if (cond_code == LE)
11737     val++;
11739   rtx tmp = gen_reg_rtx (<MODE>mode);
11740   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11741   rtx x = gen_reg_rtx (<MODE>mode);
11742   if (val < 0)
11743     emit_insn (gen_and<mode>3 (x, op1, tmp));
11744   else
11745     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11747   if (invert)
11748     {
11749       rtx tmp = gen_reg_rtx (<MODE>mode);
11750       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11751       x = tmp;
11752     }
11754   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11755   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11757   DONE;
11760 (define_expand "cstore<mode>4_unsigned_imm"
11761   [(use (match_operator 1 "unsigned_comparison_operator"
11762          [(match_operand:GPR 2 "gpc_reg_operand")
11763           (match_operand:GPR 3 "immediate_operand")]))
11764    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11765   ""
11767   bool invert = false;
11769   enum rtx_code cond_code = GET_CODE (operands[1]);
11771   rtx op0 = operands[0];
11772   rtx op1 = operands[2];
11773   HOST_WIDE_INT val = INTVAL (operands[3]);
11775   if (cond_code == GEU || cond_code == GTU)
11776     {
11777       cond_code = reverse_condition (cond_code);
11778       invert = true;
11779     }
11781   if (cond_code == LEU)
11782     val++;
11784   rtx tmp = gen_reg_rtx (<MODE>mode);
11785   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11786   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11787   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11788   rtx x = gen_reg_rtx (<MODE>mode);
11789   if (val < 0)
11790     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11791   else
11792     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11794   if (invert)
11795     {
11796       rtx tmp = gen_reg_rtx (<MODE>mode);
11797       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11798       x = tmp;
11799     }
11801   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11802   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11804   DONE;
11807 (define_expand "cstore<mode>4"
11808   [(use (match_operator 1 "rs6000_cbranch_operator"
11809          [(match_operand:GPR 2 "gpc_reg_operand")
11810           (match_operand:GPR 3 "reg_or_short_operand")]))
11811    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11812   ""
11814   /* Use ISEL if the user asked for it.  */
11815   if (TARGET_ISEL)
11816     rs6000_emit_sISEL (<MODE>mode, operands);
11818   /* Expanding EQ and NE directly to some machine instructions does not help
11819      but does hurt combine.  So don't.  */
11820   else if (GET_CODE (operands[1]) == EQ)
11821     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11822   else if (<MODE>mode == Pmode
11823            && GET_CODE (operands[1]) == NE)
11824     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11825   else if (GET_CODE (operands[1]) == NE)
11826     {
11827       rtx tmp = gen_reg_rtx (<MODE>mode);
11828       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11829       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11830     }
11832   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11833      etc. combinations magically work out just right.  */
11834   else if (<MODE>mode == Pmode
11835            && unsigned_comparison_operator (operands[1], VOIDmode))
11836     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11837                                            operands[2], operands[3]));
11839   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11840   else if (<MODE>mode == SImode && Pmode == DImode)
11841     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11842                                     operands[2], operands[3]));
11844   /* For signed comparisons against a constant, we can do some simple
11845      bit-twiddling.  */
11846   else if (signed_comparison_operator (operands[1], VOIDmode)
11847            && CONST_INT_P (operands[3]))
11848     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11849                                              operands[2], operands[3]));
11851   /* And similarly for unsigned comparisons.  */
11852   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11853            && CONST_INT_P (operands[3]))
11854     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11855                                                operands[2], operands[3]));
11857   /* We also do not want to use mfcr for signed comparisons.  */
11858   else if (<MODE>mode == Pmode
11859            && signed_comparison_operator (operands[1], VOIDmode))
11860     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11861                                          operands[2], operands[3]));
11863   /* Everything else, use the mfcr brute force.  */
11864   else
11865     rs6000_emit_sCOND (<MODE>mode, operands);
11867   DONE;
11870 (define_expand "cstore<mode>4"
11871   [(use (match_operator 1 "rs6000_cbranch_operator"
11872          [(match_operand:FP 2 "gpc_reg_operand")
11873           (match_operand:FP 3 "gpc_reg_operand")]))
11874    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11875   ""
11877   rs6000_emit_sCOND (<MODE>mode, operands);
11878   DONE;
11882 (define_expand "stack_protect_set"
11883   [(match_operand 0 "memory_operand")
11884    (match_operand 1 "memory_operand")]
11885   ""
11887   if (rs6000_stack_protector_guard == SSP_TLS)
11888     {
11889       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11890       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11891       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11892       operands[1] = gen_rtx_MEM (Pmode, addr);
11893     }
11895   if (TARGET_64BIT)
11896     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11897   else
11898     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11900   DONE;
11903 (define_insn "stack_protect_setsi"
11904   [(set (match_operand:SI 0 "memory_operand" "=m")
11905         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11906    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11907   "TARGET_32BIT"
11908   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11909   [(set_attr "type" "three")
11910    (set_attr "length" "12")])
11912 (define_insn "stack_protect_setdi"
11913   [(set (match_operand:DI 0 "memory_operand" "=Y")
11914         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11915    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11916   "TARGET_64BIT"
11917   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11918   [(set_attr "type" "three")
11919    (set_attr "length" "12")])
11921 (define_expand "stack_protect_test"
11922   [(match_operand 0 "memory_operand")
11923    (match_operand 1 "memory_operand")
11924    (match_operand 2 "")]
11925   ""
11927   rtx guard = operands[1];
11929   if (rs6000_stack_protector_guard == SSP_TLS)
11930     {
11931       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11932       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11933       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11934       guard = gen_rtx_MEM (Pmode, addr);
11935     }
11937   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11938   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11939   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11940   emit_jump_insn (jump);
11942   DONE;
11945 (define_insn "stack_protect_testsi"
11946   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11947         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11948                       (match_operand:SI 2 "memory_operand" "m,m")]
11949                      UNSPEC_SP_TEST))
11950    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11951    (clobber (match_scratch:SI 3 "=&r,&r"))]
11952   "TARGET_32BIT"
11953   "@
11954    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11955    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11956   [(set_attr "length" "16,20")])
11958 (define_insn "stack_protect_testdi"
11959   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11960         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11961                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11962                      UNSPEC_SP_TEST))
11963    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11964    (clobber (match_scratch:DI 3 "=&r,&r"))]
11965   "TARGET_64BIT"
11966   "@
11967    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11968    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11969   [(set_attr "length" "16,20")])
11972 ;; Here are the actual compare insns.
11973 (define_insn "*cmp<mode>_signed"
11974   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11975         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11976                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11977   ""
11978   "cmp<wd>%I2 %0,%1,%2"
11979   [(set_attr "type" "cmp")])
11981 (define_insn "*cmp<mode>_unsigned"
11982   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11983         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11984                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11985   ""
11986   "cmpl<wd>%I2 %0,%1,%2"
11987   [(set_attr "type" "cmp")])
11989 ;; If we are comparing a register for equality with a large constant,
11990 ;; we can do this with an XOR followed by a compare.  But this is profitable
11991 ;; only if the large constant is only used for the comparison (and in this
11992 ;; case we already have a register to reuse as scratch).
11994 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11995 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11997 (define_peephole2
11998   [(set (match_operand:SI 0 "register_operand")
11999         (match_operand:SI 1 "logical_const_operand" ""))
12000    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
12001                        [(match_dup 0)
12002                         (match_operand:SI 2 "logical_const_operand" "")]))
12003    (set (match_operand:CC 4 "cc_reg_operand" "")
12004         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
12005                     (match_dup 0)))
12006    (set (pc)
12007         (if_then_else (match_operator 6 "equality_operator"
12008                        [(match_dup 4) (const_int 0)])
12009                       (match_operand 7 "" "")
12010                       (match_operand 8 "" "")))]
12011   "peep2_reg_dead_p (3, operands[0])
12012    && peep2_reg_dead_p (4, operands[4])
12013    && REGNO (operands[0]) != REGNO (operands[5])"
12014  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
12015   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
12016   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
12019   /* Get the constant we are comparing against, and see what it looks like
12020      when sign-extended from 16 to 32 bits.  Then see what constant we could
12021      XOR with SEXTC to get the sign-extended value.  */
12022   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
12023                                               SImode,
12024                                               operands[1], operands[2]);
12025   HOST_WIDE_INT c = INTVAL (cnst);
12026   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
12027   HOST_WIDE_INT xorv = c ^ sextc;
12029   operands[9] = GEN_INT (xorv);
12030   operands[10] = GEN_INT (sextc);
12033 ;; The following two insns don't exist as single insns, but if we provide
12034 ;; them, we can swap an add and compare, which will enable us to overlap more
12035 ;; of the required delay between a compare and branch.  We generate code for
12036 ;; them by splitting.
12038 (define_insn ""
12039   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
12040         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
12041                     (match_operand:SI 2 "short_cint_operand" "i")))
12042    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12043         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12044   ""
12045   "#"
12046   [(set_attr "length" "8")])
12048 (define_insn ""
12049   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
12050         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
12051                        (match_operand:SI 2 "u_short_cint_operand" "i")))
12052    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12053         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12054   ""
12055   "#"
12056   [(set_attr "length" "8")])
12058 (define_split
12059   [(set (match_operand:CC 3 "cc_reg_operand" "")
12060         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
12061                     (match_operand:SI 2 "short_cint_operand" "")))
12062    (set (match_operand:SI 0 "gpc_reg_operand" "")
12063         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12064   ""
12065   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
12066    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12068 (define_split
12069   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
12070         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
12071                        (match_operand:SI 2 "u_short_cint_operand" "")))
12072    (set (match_operand:SI 0 "gpc_reg_operand" "")
12073         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12074   ""
12075   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
12076    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12078 ;; Only need to compare second words if first words equal
12079 (define_insn "*cmp<mode>_internal1"
12080   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12081         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12082                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12083   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12084    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12085   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12086   [(set_attr "type" "fpcompare")
12087    (set_attr "length" "12")])
12089 (define_insn_and_split "*cmp<mode>_internal2"
12090   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12091         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12092                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12093     (clobber (match_scratch:DF 3 "=d"))
12094     (clobber (match_scratch:DF 4 "=d"))
12095     (clobber (match_scratch:DF 5 "=d"))
12096     (clobber (match_scratch:DF 6 "=d"))
12097     (clobber (match_scratch:DF 7 "=d"))
12098     (clobber (match_scratch:DF 8 "=d"))
12099     (clobber (match_scratch:DF 9 "=d"))
12100     (clobber (match_scratch:DF 10 "=d"))
12101     (clobber (match_scratch:GPR 11 "=b"))]
12102   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12103    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12104   "#"
12105   "&& reload_completed"
12106   [(set (match_dup 3) (match_dup 14))
12107    (set (match_dup 4) (match_dup 15))
12108    (set (match_dup 9) (abs:DF (match_dup 5)))
12109    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12110    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12111                            (label_ref (match_dup 12))
12112                            (pc)))
12113    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12114    (set (pc) (label_ref (match_dup 13)))
12115    (match_dup 12)
12116    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12117    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12118    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12119    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12120    (match_dup 13)]
12122   REAL_VALUE_TYPE rv;
12123   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12124   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12126   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12127   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12128   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12129   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12130   operands[12] = gen_label_rtx ();
12131   operands[13] = gen_label_rtx ();
12132   real_inf (&rv);
12133   operands[14] = force_const_mem (DFmode,
12134                                   const_double_from_real_value (rv, DFmode));
12135   operands[15] = force_const_mem (DFmode,
12136                                   const_double_from_real_value (dconst0,
12137                                                                 DFmode));
12138   if (TARGET_TOC)
12139     {
12140       rtx tocref;
12141       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12142       operands[14] = gen_const_mem (DFmode, tocref);
12143       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12144       operands[15] = gen_const_mem (DFmode, tocref);
12145       set_mem_alias_set (operands[14], get_TOC_alias_set ());
12146       set_mem_alias_set (operands[15], get_TOC_alias_set ());
12147     }
12150 ;; Now we have the scc insns.  We can do some combinations because of the
12151 ;; way the machine works.
12153 ;; Note that this is probably faster if we can put an insn between the
12154 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
12155 ;; cases the insns below which don't use an intermediate CR field will
12156 ;; be used instead.
12157 (define_insn ""
12158   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12159         (match_operator:SI 1 "scc_comparison_operator"
12160                            [(match_operand 2 "cc_reg_operand" "y")
12161                             (const_int 0)]))]
12162   ""
12163   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12164   [(set (attr "type")
12165      (cond [(match_test "TARGET_MFCRF")
12166                 (const_string "mfcrf")
12167            ]
12168         (const_string "mfcr")))
12169    (set_attr "length" "8")])
12171 ;; Same as above, but get the GT bit.
12172 (define_insn "move_from_CR_gt_bit"
12173   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12174         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
12175   "TARGET_HARD_FLOAT && !TARGET_FPRS"
12176   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
12177   [(set_attr "type" "mfcr")
12178    (set_attr "length" "8")])
12180 ;; Same as above, but get the OV/ORDERED bit.
12181 (define_insn "move_from_CR_ov_bit"
12182   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12183         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12184                    UNSPEC_MV_CR_OV))]
12185   "TARGET_ISEL"
12186   "mfcr %0\;rlwinm %0,%0,%t1,1"
12187   [(set_attr "type" "mfcr")
12188    (set_attr "length" "8")])
12190 (define_insn ""
12191   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12192         (match_operator:DI 1 "scc_comparison_operator"
12193                            [(match_operand 2 "cc_reg_operand" "y")
12194                             (const_int 0)]))]
12195   "TARGET_POWERPC64"
12196   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12197   [(set (attr "type")
12198      (cond [(match_test "TARGET_MFCRF")
12199                 (const_string "mfcrf")
12200            ]
12201         (const_string "mfcr")))
12202    (set_attr "length" "8")])
12204 (define_insn ""
12205   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12206         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12207                                        [(match_operand 2 "cc_reg_operand" "y,y")
12208                                         (const_int 0)])
12209                     (const_int 0)))
12210    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12211         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12212   "TARGET_32BIT"
12213   "@
12214    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12215    #"
12216   [(set_attr "type" "shift")
12217    (set_attr "dot" "yes")
12218    (set_attr "length" "8,16")])
12220 (define_split
12221   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12222         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12223                                        [(match_operand 2 "cc_reg_operand" "")
12224                                         (const_int 0)])
12225                     (const_int 0)))
12226    (set (match_operand:SI 3 "gpc_reg_operand" "")
12227         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12228   "TARGET_32BIT && reload_completed"
12229   [(set (match_dup 3)
12230         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12231    (set (match_dup 0)
12232         (compare:CC (match_dup 3)
12233                     (const_int 0)))]
12234   "")
12236 (define_insn ""
12237   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12238         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12239                                       [(match_operand 2 "cc_reg_operand" "y")
12240                                        (const_int 0)])
12241                    (match_operand:SI 3 "const_int_operand" "n")))]
12242   ""
12243   "*
12245   int is_bit = ccr_bit (operands[1], 1);
12246   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12247   int count;
12249   if (is_bit >= put_bit)
12250     count = is_bit - put_bit;
12251   else
12252     count = 32 - (put_bit - is_bit);
12254   operands[4] = GEN_INT (count);
12255   operands[5] = GEN_INT (put_bit);
12257   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12259   [(set (attr "type")
12260      (cond [(match_test "TARGET_MFCRF")
12261                 (const_string "mfcrf")
12262            ]
12263         (const_string "mfcr")))
12264    (set_attr "length" "8")])
12266 (define_insn ""
12267   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12268         (compare:CC
12269          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12270                                        [(match_operand 2 "cc_reg_operand" "y,y")
12271                                         (const_int 0)])
12272                     (match_operand:SI 3 "const_int_operand" "n,n"))
12273          (const_int 0)))
12274    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12275         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12276                    (match_dup 3)))]
12277   ""
12278   "*
12280   int is_bit = ccr_bit (operands[1], 1);
12281   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12282   int count;
12284   /* Force split for non-cc0 compare.  */
12285   if (which_alternative == 1)
12286      return \"#\";
12288   if (is_bit >= put_bit)
12289     count = is_bit - put_bit;
12290   else
12291     count = 32 - (put_bit - is_bit);
12293   operands[5] = GEN_INT (count);
12294   operands[6] = GEN_INT (put_bit);
12296   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12298   [(set_attr "type" "shift")
12299    (set_attr "dot" "yes")
12300    (set_attr "length" "8,16")])
12302 (define_split
12303   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12304         (compare:CC
12305          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12306                                        [(match_operand 2 "cc_reg_operand" "")
12307                                         (const_int 0)])
12308                     (match_operand:SI 3 "const_int_operand" ""))
12309          (const_int 0)))
12310    (set (match_operand:SI 4 "gpc_reg_operand" "")
12311         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12312                    (match_dup 3)))]
12313   "reload_completed"
12314   [(set (match_dup 4)
12315         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12316                    (match_dup 3)))
12317    (set (match_dup 0)
12318         (compare:CC (match_dup 4)
12319                     (const_int 0)))]
12320   "")
12323 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12324                               (DI "rKJI")])
12326 (define_insn_and_split "eq<mode>3"
12327   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12328         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12329                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12330    (clobber (match_scratch:GPR 3 "=r"))
12331    (clobber (match_scratch:GPR 4 "=r"))]
12332   ""
12333   "#"
12334   ""
12335   [(set (match_dup 4)
12336         (clz:GPR (match_dup 3)))
12337    (set (match_dup 0)
12338         (lshiftrt:GPR (match_dup 4)
12339                       (match_dup 5)))]
12341   operands[3] = rs6000_emit_eqne (<MODE>mode,
12342                                   operands[1], operands[2], operands[3]);
12344   if (GET_CODE (operands[4]) == SCRATCH)
12345     operands[4] = gen_reg_rtx (<MODE>mode);
12347   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12349   [(set (attr "length")
12350         (if_then_else (match_test "operands[2] == const0_rtx")
12351                       (const_string "8")
12352                       (const_string "12")))])
12354 (define_insn_and_split "ne<mode>3"
12355   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12356         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12357               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12358    (clobber (match_scratch:P 3 "=r"))
12359    (clobber (match_scratch:P 4 "=r"))
12360    (clobber (reg:P CA_REGNO))]
12361   "!TARGET_ISEL"
12362   "#"
12363   ""
12364   [(parallel [(set (match_dup 4)
12365                    (plus:P (match_dup 3)
12366                            (const_int -1)))
12367               (set (reg:P CA_REGNO)
12368                    (ne:P (match_dup 3)
12369                          (const_int 0)))])
12370    (parallel [(set (match_dup 0)
12371                    (plus:P (plus:P (not:P (match_dup 4))
12372                                    (reg:P CA_REGNO))
12373                            (match_dup 3)))
12374               (clobber (reg:P CA_REGNO))])]
12376   operands[3] = rs6000_emit_eqne (<MODE>mode,
12377                                   operands[1], operands[2], operands[3]);
12379   if (GET_CODE (operands[4]) == SCRATCH)
12380     operands[4] = gen_reg_rtx (<MODE>mode);
12382   [(set (attr "length")
12383         (if_then_else (match_test "operands[2] == const0_rtx")
12384                       (const_string "8")
12385                       (const_string "12")))])
12387 (define_insn_and_split "*neg_eq_<mode>"
12388   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12389         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12390                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12391    (clobber (match_scratch:P 3 "=r"))
12392    (clobber (match_scratch:P 4 "=r"))
12393    (clobber (reg:P CA_REGNO))]
12394   ""
12395   "#"
12396   ""
12397   [(parallel [(set (match_dup 4)
12398                    (plus:P (match_dup 3)
12399                            (const_int -1)))
12400               (set (reg:P CA_REGNO)
12401                    (ne:P (match_dup 3)
12402                          (const_int 0)))])
12403    (parallel [(set (match_dup 0)
12404                    (plus:P (reg:P CA_REGNO)
12405                            (const_int -1)))
12406               (clobber (reg:P CA_REGNO))])]
12408   operands[3] = rs6000_emit_eqne (<MODE>mode,
12409                                   operands[1], operands[2], operands[3]);
12411   if (GET_CODE (operands[4]) == SCRATCH)
12412     operands[4] = gen_reg_rtx (<MODE>mode);
12414   [(set (attr "length")
12415         (if_then_else (match_test "operands[2] == const0_rtx")
12416                       (const_string "8")
12417                       (const_string "12")))])
12419 (define_insn_and_split "*neg_ne_<mode>"
12420   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12421         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12422                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12423    (clobber (match_scratch:P 3 "=r"))
12424    (clobber (match_scratch:P 4 "=r"))
12425    (clobber (reg:P CA_REGNO))]
12426   ""
12427   "#"
12428   ""
12429   [(parallel [(set (match_dup 4)
12430                    (neg:P (match_dup 3)))
12431               (set (reg:P CA_REGNO)
12432                    (eq:P (match_dup 3)
12433                          (const_int 0)))])
12434    (parallel [(set (match_dup 0)
12435                    (plus:P (reg:P CA_REGNO)
12436                            (const_int -1)))
12437               (clobber (reg:P CA_REGNO))])]
12439   operands[3] = rs6000_emit_eqne (<MODE>mode,
12440                                   operands[1], operands[2], operands[3]);
12442   if (GET_CODE (operands[4]) == SCRATCH)
12443     operands[4] = gen_reg_rtx (<MODE>mode);
12445   [(set (attr "length")
12446         (if_then_else (match_test "operands[2] == const0_rtx")
12447                       (const_string "8")
12448                       (const_string "12")))])
12450 (define_insn_and_split "*plus_eq_<mode>"
12451   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12452         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12453                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12454                 (match_operand:P 3 "gpc_reg_operand" "r")))
12455    (clobber (match_scratch:P 4 "=r"))
12456    (clobber (match_scratch:P 5 "=r"))
12457    (clobber (reg:P CA_REGNO))]
12458   ""
12459   "#"
12460   ""
12461   [(parallel [(set (match_dup 5)
12462                    (neg:P (match_dup 4)))
12463               (set (reg:P CA_REGNO)
12464                    (eq:P (match_dup 4)
12465                          (const_int 0)))])
12466    (parallel [(set (match_dup 0)
12467                    (plus:P (match_dup 3)
12468                            (reg:P CA_REGNO)))
12469               (clobber (reg:P CA_REGNO))])]
12471   operands[4] = rs6000_emit_eqne (<MODE>mode,
12472                                   operands[1], operands[2], operands[4]);
12474   if (GET_CODE (operands[5]) == SCRATCH)
12475     operands[5] = gen_reg_rtx (<MODE>mode);
12477   [(set (attr "length")
12478         (if_then_else (match_test "operands[2] == const0_rtx")
12479                       (const_string "8")
12480                       (const_string "12")))])
12482 (define_insn_and_split "*plus_ne_<mode>"
12483   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12484         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12485                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12486                 (match_operand:P 3 "gpc_reg_operand" "r")))
12487    (clobber (match_scratch:P 4 "=r"))
12488    (clobber (match_scratch:P 5 "=r"))
12489    (clobber (reg:P CA_REGNO))]
12490   ""
12491   "#"
12492   ""
12493   [(parallel [(set (match_dup 5)
12494                    (plus:P (match_dup 4)
12495                            (const_int -1)))
12496               (set (reg:P CA_REGNO)
12497                    (ne:P (match_dup 4)
12498                          (const_int 0)))])
12499    (parallel [(set (match_dup 0)
12500                    (plus:P (match_dup 3)
12501                            (reg:P CA_REGNO)))
12502               (clobber (reg:P CA_REGNO))])]
12504   operands[4] = rs6000_emit_eqne (<MODE>mode,
12505                                   operands[1], operands[2], operands[4]);
12507   if (GET_CODE (operands[5]) == SCRATCH)
12508     operands[5] = gen_reg_rtx (<MODE>mode);
12510   [(set (attr "length")
12511         (if_then_else (match_test "operands[2] == const0_rtx")
12512                       (const_string "8")
12513                       (const_string "12")))])
12515 (define_insn_and_split "*minus_eq_<mode>"
12516   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12517         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12518                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12519                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12520    (clobber (match_scratch:P 4 "=r"))
12521    (clobber (match_scratch:P 5 "=r"))
12522    (clobber (reg:P CA_REGNO))]
12523   ""
12524   "#"
12525   ""
12526   [(parallel [(set (match_dup 5)
12527                    (plus:P (match_dup 4)
12528                            (const_int -1)))
12529               (set (reg:P CA_REGNO)
12530                    (ne:P (match_dup 4)
12531                          (const_int 0)))])
12532    (parallel [(set (match_dup 0)
12533                    (plus:P (plus:P (match_dup 3)
12534                                    (reg:P CA_REGNO))
12535                            (const_int -1)))
12536               (clobber (reg:P CA_REGNO))])]
12538   operands[4] = rs6000_emit_eqne (<MODE>mode,
12539                                   operands[1], operands[2], operands[4]);
12541   if (GET_CODE (operands[5]) == SCRATCH)
12542     operands[5] = gen_reg_rtx (<MODE>mode);
12544   [(set (attr "length")
12545         (if_then_else (match_test "operands[2] == const0_rtx")
12546                       (const_string "8")
12547                       (const_string "12")))])
12549 (define_insn_and_split "*minus_ne_<mode>"
12550   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12551         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12552                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12553                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12554    (clobber (match_scratch:P 4 "=r"))
12555    (clobber (match_scratch:P 5 "=r"))
12556    (clobber (reg:P CA_REGNO))]
12557   ""
12558   "#"
12559   ""
12560   [(parallel [(set (match_dup 5)
12561                    (neg:P (match_dup 4)))
12562               (set (reg:P CA_REGNO)
12563                    (eq:P (match_dup 4)
12564                          (const_int 0)))])
12565    (parallel [(set (match_dup 0)
12566                    (plus:P (plus:P (match_dup 3)
12567                                    (reg:P CA_REGNO))
12568                            (const_int -1)))
12569               (clobber (reg:P CA_REGNO))])]
12571   operands[4] = rs6000_emit_eqne (<MODE>mode,
12572                                   operands[1], operands[2], operands[4]);
12574   if (GET_CODE (operands[5]) == SCRATCH)
12575     operands[5] = gen_reg_rtx (<MODE>mode);
12577   [(set (attr "length")
12578         (if_then_else (match_test "operands[2] == const0_rtx")
12579                       (const_string "8")
12580                       (const_string "12")))])
12582 (define_insn_and_split "*eqsi3_ext<mode>"
12583   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12584         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12585                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12586    (clobber (match_scratch:SI 3 "=r"))
12587    (clobber (match_scratch:SI 4 "=r"))]
12588   ""
12589   "#"
12590   ""
12591   [(set (match_dup 4)
12592         (clz:SI (match_dup 3)))
12593    (set (match_dup 0)
12594         (zero_extend:EXTSI
12595           (lshiftrt:SI (match_dup 4)
12596                        (const_int 5))))]
12598   operands[3] = rs6000_emit_eqne (SImode,
12599                                   operands[1], operands[2], operands[3]);
12601   if (GET_CODE (operands[4]) == SCRATCH)
12602     operands[4] = gen_reg_rtx (SImode);
12604   [(set (attr "length")
12605         (if_then_else (match_test "operands[2] == const0_rtx")
12606                       (const_string "8")
12607                       (const_string "12")))])
12609 (define_insn_and_split "*nesi3_ext<mode>"
12610   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12611         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12612                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12613    (clobber (match_scratch:SI 3 "=r"))
12614    (clobber (match_scratch:SI 4 "=r"))
12615    (clobber (match_scratch:EXTSI 5 "=r"))]
12616   ""
12617   "#"
12618   ""
12619   [(set (match_dup 4)
12620         (clz:SI (match_dup 3)))
12621    (set (match_dup 5)
12622         (zero_extend:EXTSI
12623           (lshiftrt:SI (match_dup 4)
12624                        (const_int 5))))
12625    (set (match_dup 0)
12626         (xor:EXTSI (match_dup 5)
12627                    (const_int 1)))]
12629   operands[3] = rs6000_emit_eqne (SImode,
12630                                   operands[1], operands[2], operands[3]);
12632   if (GET_CODE (operands[4]) == SCRATCH)
12633     operands[4] = gen_reg_rtx (SImode);
12634   if (GET_CODE (operands[5]) == SCRATCH)
12635     operands[5] = gen_reg_rtx (<MODE>mode);
12637   [(set (attr "length")
12638         (if_then_else (match_test "operands[2] == const0_rtx")
12639                       (const_string "12")
12640                       (const_string "16")))])
12642 ;; Define both directions of branch and return.  If we need a reload
12643 ;; register, we'd rather use CR0 since it is much easier to copy a
12644 ;; register CC value to there.
12646 (define_insn ""
12647   [(set (pc)
12648         (if_then_else (match_operator 1 "branch_comparison_operator"
12649                                       [(match_operand 2
12650                                                       "cc_reg_operand" "y")
12651                                        (const_int 0)])
12652                       (label_ref (match_operand 0 "" ""))
12653                       (pc)))]
12654   ""
12655   "*
12657   return output_cbranch (operands[1], \"%l0\", 0, insn);
12659   [(set_attr "type" "branch")])
12661 (define_insn ""
12662   [(set (pc)
12663         (if_then_else (match_operator 0 "branch_comparison_operator"
12664                                       [(match_operand 1
12665                                                       "cc_reg_operand" "y")
12666                                        (const_int 0)])
12667                       (any_return)
12668                       (pc)))]
12669   "<return_pred>"
12670   "*
12672   return output_cbranch (operands[0], NULL, 0, insn);
12674   [(set_attr "type" "jmpreg")
12675    (set_attr "length" "4")])
12677 (define_insn ""
12678   [(set (pc)
12679         (if_then_else (match_operator 1 "branch_comparison_operator"
12680                                       [(match_operand 2
12681                                                       "cc_reg_operand" "y")
12682                                        (const_int 0)])
12683                       (pc)
12684                       (label_ref (match_operand 0 "" ""))))]
12685   ""
12686   "*
12688   return output_cbranch (operands[1], \"%l0\", 1, insn);
12690   [(set_attr "type" "branch")])
12692 (define_insn ""
12693   [(set (pc)
12694         (if_then_else (match_operator 0 "branch_comparison_operator"
12695                                       [(match_operand 1
12696                                                       "cc_reg_operand" "y")
12697                                        (const_int 0)])
12698                       (pc)
12699                       (any_return)))]
12700   "<return_pred>"
12701   "*
12703   return output_cbranch (operands[0], NULL, 1, insn);
12705   [(set_attr "type" "jmpreg")
12706    (set_attr "length" "4")])
12708 ;; Logic on condition register values.
12710 ; This pattern matches things like
12711 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12712 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12713 ;                                  (const_int 1)))
12714 ; which are generated by the branch logic.
12715 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12717 (define_insn "*cceq_ior_compare"
12718   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12719         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12720                         [(match_operator:SI 2
12721                                       "branch_positive_comparison_operator"
12722                                       [(match_operand 3
12723                                                       "cc_reg_operand" "y,y")
12724                                        (const_int 0)])
12725                          (match_operator:SI 4
12726                                       "branch_positive_comparison_operator"
12727                                       [(match_operand 5
12728                                                       "cc_reg_operand" "0,y")
12729                                        (const_int 0)])])
12730                       (const_int 1)))]
12731   ""
12732   "cr%q1 %E0,%j2,%j4"
12733   [(set_attr "type" "cr_logical,delayed_cr")])
12735 ; Why is the constant -1 here, but 1 in the previous pattern?
12736 ; Because ~1 has all but the low bit set.
12737 (define_insn ""
12738   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12739         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12740                         [(not:SI (match_operator:SI 2
12741                                       "branch_positive_comparison_operator"
12742                                       [(match_operand 3
12743                                                       "cc_reg_operand" "y,y")
12744                                        (const_int 0)]))
12745                          (match_operator:SI 4
12746                                 "branch_positive_comparison_operator"
12747                                 [(match_operand 5
12748                                                 "cc_reg_operand" "0,y")
12749                                  (const_int 0)])])
12750                       (const_int -1)))]
12751   ""
12752   "cr%q1 %E0,%j2,%j4"
12753   [(set_attr "type" "cr_logical,delayed_cr")])
12755 (define_insn "*cceq_rev_compare"
12756   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12757         (compare:CCEQ (match_operator:SI 1
12758                                       "branch_positive_comparison_operator"
12759                                       [(match_operand 2
12760                                                       "cc_reg_operand" "0,y")
12761                                        (const_int 0)])
12762                       (const_int 0)))]
12763   ""
12764   "crnot %E0,%j1"
12765   [(set_attr "type" "cr_logical,delayed_cr")])
12767 ;; If we are comparing the result of two comparisons, this can be done
12768 ;; using creqv or crxor.
12770 (define_insn_and_split ""
12771   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12772         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12773                               [(match_operand 2 "cc_reg_operand" "y")
12774                                (const_int 0)])
12775                       (match_operator 3 "branch_comparison_operator"
12776                               [(match_operand 4 "cc_reg_operand" "y")
12777                                (const_int 0)])))]
12778   ""
12779   "#"
12780   ""
12781   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12782                                     (match_dup 5)))]
12783   "
12785   int positive_1, positive_2;
12787   positive_1 = branch_positive_comparison_operator (operands[1],
12788                                                     GET_MODE (operands[1]));
12789   positive_2 = branch_positive_comparison_operator (operands[3],
12790                                                     GET_MODE (operands[3]));
12792   if (! positive_1)
12793     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12794                                                             GET_CODE (operands[1])),
12795                                   SImode,
12796                                   operands[2], const0_rtx);
12797   else if (GET_MODE (operands[1]) != SImode)
12798     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12799                                   operands[2], const0_rtx);
12801   if (! positive_2)
12802     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12803                                                             GET_CODE (operands[3])),
12804                                   SImode,
12805                                   operands[4], const0_rtx);
12806   else if (GET_MODE (operands[3]) != SImode)
12807     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12808                                   operands[4], const0_rtx);
12810   if (positive_1 == positive_2)
12811     {
12812       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12813       operands[5] = constm1_rtx;
12814     }
12815   else
12816     {
12817       operands[5] = const1_rtx;
12818     }
12821 ;; Unconditional branch and return.
12823 (define_insn "jump"
12824   [(set (pc)
12825         (label_ref (match_operand 0 "" "")))]
12826   ""
12827   "b %l0"
12828   [(set_attr "type" "branch")])
12830 (define_insn "<return_str>return"
12831   [(any_return)]
12832   "<return_pred>"
12833   "blr"
12834   [(set_attr "type" "jmpreg")])
12836 (define_expand "indirect_jump"
12837   [(set (pc) (match_operand 0 "register_operand" ""))])
12839 (define_insn "*indirect_jump<mode>"
12840   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12841   ""
12842   "@
12843    bctr
12844    blr"
12845   [(set_attr "type" "jmpreg")])
12847 ;; Table jump for switch statements:
12848 (define_expand "tablejump"
12849   [(use (match_operand 0 "" ""))
12850    (use (label_ref (match_operand 1 "" "")))]
12851   ""
12852   "
12854   if (TARGET_32BIT)
12855     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12856   else
12857     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12858   DONE;
12861 (define_expand "tablejumpsi"
12862   [(set (match_dup 3)
12863         (plus:SI (match_operand:SI 0 "" "")
12864                  (match_dup 2)))
12865    (parallel [(set (pc) (match_dup 3))
12866               (use (label_ref (match_operand 1 "" "")))])]
12867   "TARGET_32BIT"
12868   "
12869 { operands[0] = force_reg (SImode, operands[0]);
12870   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12871   operands[3] = gen_reg_rtx (SImode);
12874 (define_expand "tablejumpdi"
12875   [(set (match_dup 4)
12876         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12877    (set (match_dup 3)
12878         (plus:DI (match_dup 4)
12879                  (match_dup 2)))
12880    (parallel [(set (pc) (match_dup 3))
12881               (use (label_ref (match_operand 1 "" "")))])]
12882   "TARGET_64BIT"
12883   "
12884 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12885   operands[3] = gen_reg_rtx (DImode);
12886   operands[4] = gen_reg_rtx (DImode);
12889 (define_insn "*tablejump<mode>_internal1"
12890   [(set (pc)
12891         (match_operand:P 0 "register_operand" "c,*l"))
12892    (use (label_ref (match_operand 1 "" "")))]
12893   ""
12894   "@
12895    bctr
12896    blr"
12897   [(set_attr "type" "jmpreg")])
12899 (define_insn "nop"
12900   [(unspec [(const_int 0)] UNSPEC_NOP)]
12901   ""
12902   "nop")
12904 (define_insn "group_ending_nop"
12905   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12906   ""
12907   "*
12909   if (rs6000_cpu_attr == CPU_POWER6)
12910     return \"ori 1,1,0\";
12911   return \"ori 2,2,0\";
12914 ;; Define the subtract-one-and-jump insns, starting with the template
12915 ;; so loop.c knows what to generate.
12917 (define_expand "doloop_end"
12918   [(use (match_operand 0 "" ""))        ; loop pseudo
12919    (use (match_operand 1 "" ""))]       ; label
12920   ""
12921   "
12923   if (TARGET_64BIT)
12924     {
12925       if (GET_MODE (operands[0]) != DImode)
12926         FAIL;
12927       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12928     }
12929   else
12930     {
12931       if (GET_MODE (operands[0]) != SImode)
12932         FAIL;
12933       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12934     }
12935   DONE;
12938 (define_expand "ctr<mode>"
12939   [(parallel [(set (pc)
12940                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
12941                                      (const_int 1))
12942                                  (label_ref (match_operand 1 "" ""))
12943                                  (pc)))
12944               (set (match_dup 0)
12945                    (plus:P (match_dup 0)
12946                             (const_int -1)))
12947               (clobber (match_scratch:CC 2 ""))
12948               (clobber (match_scratch:P 3 ""))])]
12949   ""
12950   "")
12952 ;; We need to be able to do this for any operand, including MEM, or we
12953 ;; will cause reload to blow up since we don't allow output reloads on
12954 ;; JUMP_INSNs.
12955 ;; For the length attribute to be calculated correctly, the
12956 ;; label MUST be operand 0.
12957 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12958 ;; the ctr<mode> insns.
12960 (define_insn "ctr<mode>_internal1"
12961   [(set (pc)
12962         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12963                           (const_int 1))
12964                       (label_ref (match_operand 0 "" ""))
12965                       (pc)))
12966    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12967         (plus:P (match_dup 1)
12968                  (const_int -1)))
12969    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12970    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12971   ""
12972   "*
12974   if (which_alternative != 0)
12975     return \"#\";
12976   else if (get_attr_length (insn) == 4)
12977     return \"bdnz %l0\";
12978   else
12979     return \"bdz $+8\;b %l0\";
12981   [(set_attr "type" "branch")
12982    (set_attr "length" "*,16,20,20")])
12984 (define_insn "ctr<mode>_internal2"
12985   [(set (pc)
12986         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12987                           (const_int 1))
12988                       (pc)
12989                       (label_ref (match_operand 0 "" ""))))
12990    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12991         (plus:P (match_dup 1)
12992                  (const_int -1)))
12993    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12994    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12995   ""
12996   "*
12998   if (which_alternative != 0)
12999     return \"#\";
13000   else if (get_attr_length (insn) == 4)
13001     return \"bdz %l0\";
13002   else
13003     return \"bdnz $+8\;b %l0\";
13005   [(set_attr "type" "branch")
13006    (set_attr "length" "*,16,20,20")])
13008 ;; Similar but use EQ
13010 (define_insn "ctr<mode>_internal3"
13011   [(set (pc)
13012         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13013                           (const_int 1))
13014                       (label_ref (match_operand 0 "" ""))
13015                       (pc)))
13016    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13017         (plus:P (match_dup 1)
13018                  (const_int -1)))
13019    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13020    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13021   ""
13022   "*
13024   if (which_alternative != 0)
13025     return \"#\";
13026   else if (get_attr_length (insn) == 4)
13027     return \"bdz %l0\";
13028   else
13029     return \"bdnz $+8\;b %l0\";
13031   [(set_attr "type" "branch")
13032    (set_attr "length" "*,16,20,20")])
13034 (define_insn "ctr<mode>_internal4"
13035   [(set (pc)
13036         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13037                           (const_int 1))
13038                       (pc)
13039                       (label_ref (match_operand 0 "" ""))))
13040    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13041         (plus:P (match_dup 1)
13042                  (const_int -1)))
13043    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13044    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13045   ""
13046   "*
13048   if (which_alternative != 0)
13049     return \"#\";
13050   else if (get_attr_length (insn) == 4)
13051     return \"bdnz %l0\";
13052   else
13053     return \"bdz $+8\;b %l0\";
13055   [(set_attr "type" "branch")
13056    (set_attr "length" "*,16,20,20")])
13058 ;; Now the splitters if we could not allocate the CTR register
13060 (define_split
13061   [(set (pc)
13062         (if_then_else (match_operator 2 "comparison_operator"
13063                                       [(match_operand:P 1 "gpc_reg_operand" "")
13064                                        (const_int 1)])
13065                       (match_operand 5 "" "")
13066                       (match_operand 6 "" "")))
13067    (set (match_operand:P 0 "int_reg_operand" "")
13068         (plus:P (match_dup 1) (const_int -1)))
13069    (clobber (match_scratch:CC 3 ""))
13070    (clobber (match_scratch:P 4 ""))]
13071   "reload_completed"
13072   [(set (match_dup 3)
13073         (compare:CC (match_dup 1)
13074                     (const_int 1)))
13075    (set (match_dup 0)
13076         (plus:P (match_dup 1)
13077                 (const_int -1)))
13078    (set (pc) (if_then_else (match_dup 7)
13079                            (match_dup 5)
13080                            (match_dup 6)))]
13081   "
13082 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13083                                 operands[3], const0_rtx); }")
13085 (define_split
13086   [(set (pc)
13087         (if_then_else (match_operator 2 "comparison_operator"
13088                                       [(match_operand:P 1 "gpc_reg_operand" "")
13089                                        (const_int 1)])
13090                       (match_operand 5 "" "")
13091                       (match_operand 6 "" "")))
13092    (set (match_operand:P 0 "nonimmediate_operand" "")
13093         (plus:P (match_dup 1) (const_int -1)))
13094    (clobber (match_scratch:CC 3 ""))
13095    (clobber (match_scratch:P 4 ""))]
13096   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
13097   [(set (match_dup 3)
13098         (compare:CC (match_dup 1)
13099                     (const_int 1)))
13100    (set (match_dup 4)
13101         (plus:P (match_dup 1)
13102                 (const_int -1)))
13103    (set (match_dup 0)
13104         (match_dup 4))
13105    (set (pc) (if_then_else (match_dup 7)
13106                            (match_dup 5)
13107                            (match_dup 6)))]
13108   "
13109 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13110                                 operands[3], const0_rtx); }")
13112 (define_insn "trap"
13113   [(trap_if (const_int 1) (const_int 0))]
13114   ""
13115   "trap"
13116   [(set_attr "type" "trap")])
13118 (define_expand "ctrap<mode>4"
13119   [(trap_if (match_operator 0 "ordered_comparison_operator"
13120                             [(match_operand:GPR 1 "register_operand")
13121                              (match_operand:GPR 2 "reg_or_short_operand")])
13122             (match_operand 3 "zero_constant" ""))]
13123   ""
13124   "")
13126 (define_insn ""
13127   [(trap_if (match_operator 0 "ordered_comparison_operator"
13128                             [(match_operand:GPR 1 "register_operand" "r")
13129                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13130             (const_int 0))]
13131   ""
13132   "t<wd>%V0%I2 %1,%2"
13133   [(set_attr "type" "trap")])
13135 ;; Insns related to generating the function prologue and epilogue.
13137 (define_expand "prologue"
13138   [(use (const_int 0))]
13139   ""
13141   rs6000_emit_prologue ();
13142   if (!TARGET_SCHED_PROLOG)
13143     emit_insn (gen_blockage ());
13144   DONE;
13147 (define_insn "*movesi_from_cr_one"
13148   [(match_parallel 0 "mfcr_operation"
13149                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13150                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13151                                      (match_operand 3 "immediate_operand" "n")]
13152                           UNSPEC_MOVESI_FROM_CR))])]
13153   "TARGET_MFCRF"
13154   "*
13156   int mask = 0;
13157   int i;
13158   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13159   {
13160     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13161     operands[4] = GEN_INT (mask);
13162     output_asm_insn (\"mfcr %1,%4\", operands);
13163   }
13164   return \"\";
13166   [(set_attr "type" "mfcrf")])
13168 (define_insn "movesi_from_cr"
13169   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13170         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
13171                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13172                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
13173                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
13174                    UNSPEC_MOVESI_FROM_CR))]
13175   ""
13176   "mfcr %0"
13177   [(set_attr "type" "mfcr")])
13179 (define_insn "*crsave"
13180   [(match_parallel 0 "crsave_operation"
13181                    [(set (match_operand:SI 1 "memory_operand" "=m")
13182                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13183   ""
13184   "stw %2,%1"
13185   [(set_attr "type" "store")])
13187 (define_insn "*stmw"
13188   [(match_parallel 0 "stmw_operation"
13189                    [(set (match_operand:SI 1 "memory_operand" "=m")
13190                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13191   "TARGET_MULTIPLE"
13192   "stmw %2,%1"
13193   [(set_attr "type" "store")
13194    (set_attr "update" "yes")
13195    (set_attr "indexed" "yes")])
13197 ; The following comment applies to:
13198 ;     save_gpregs_*
13199 ;     save_fpregs_*
13200 ;     restore_gpregs*
13201 ;     return_and_restore_gpregs*
13202 ;     return_and_restore_fpregs*
13203 ;     return_and_restore_fpregs_aix*
13205 ; The out-of-line save / restore functions expects one input argument.
13206 ; Since those are not standard call_insn's, we must avoid using
13207 ; MATCH_OPERAND for that argument. That way the register rename
13208 ; optimization will not try to rename this register.
13209 ; Each pattern is repeated for each possible register number used in 
13210 ; various ABIs (r11, r1, and for some functions r12)
13212 (define_insn "*save_gpregs_<mode>_r11"
13213   [(match_parallel 0 "any_parallel_operand"
13214                    [(clobber (reg:P LR_REGNO))
13215                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13216                     (use (reg:P 11))
13217                     (set (match_operand:P 2 "memory_operand" "=m")
13218                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13219   ""
13220   "bl %1"
13221   [(set_attr "type" "branch")
13222    (set_attr "length" "4")])
13224 (define_insn "*save_gpregs_<mode>_r12"
13225   [(match_parallel 0 "any_parallel_operand"
13226                    [(clobber (reg:P LR_REGNO))
13227                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13228                     (use (reg:P 12))
13229                     (set (match_operand:P 2 "memory_operand" "=m")
13230                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13231   ""
13232   "bl %1"
13233   [(set_attr "type" "branch")
13234    (set_attr "length" "4")])
13236 (define_insn "*save_gpregs_<mode>_r1"
13237   [(match_parallel 0 "any_parallel_operand"
13238                    [(clobber (reg:P LR_REGNO))
13239                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13240                     (use (reg:P 1))
13241                     (set (match_operand:P 2 "memory_operand" "=m")
13242                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13243   ""
13244   "bl %1"
13245   [(set_attr "type" "branch")
13246    (set_attr "length" "4")])
13248 (define_insn "*save_fpregs_<mode>_r11"
13249   [(match_parallel 0 "any_parallel_operand"
13250                    [(clobber (reg:P LR_REGNO))
13251                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13252                     (use (reg:P 11))
13253                     (set (match_operand:DF 2 "memory_operand" "=m")
13254                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13255   ""
13256   "bl %1"
13257   [(set_attr "type" "branch")
13258    (set_attr "length" "4")])
13260 (define_insn "*save_fpregs_<mode>_r12"
13261   [(match_parallel 0 "any_parallel_operand"
13262                    [(clobber (reg:P LR_REGNO))
13263                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13264                     (use (reg:P 12))
13265                     (set (match_operand:DF 2 "memory_operand" "=m")
13266                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13267   ""
13268   "bl %1"
13269   [(set_attr "type" "branch")
13270    (set_attr "length" "4")])
13272 (define_insn "*save_fpregs_<mode>_r1"
13273   [(match_parallel 0 "any_parallel_operand"
13274                    [(clobber (reg:P LR_REGNO))
13275                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13276                     (use (reg:P 1))
13277                     (set (match_operand:DF 2 "memory_operand" "=m")
13278                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13279   ""
13280   "bl %1"
13281   [(set_attr "type" "branch")
13282    (set_attr "length" "4")])
13284 ; This is to explain that changes to the stack pointer should
13285 ; not be moved over loads from or stores to stack memory.
13286 (define_insn "stack_tie"
13287   [(match_parallel 0 "tie_operand"
13288                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13289   ""
13290   ""
13291   [(set_attr "length" "0")])
13293 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13294 ; stay behind all restores from the stack, it cannot be reordered to before
13295 ; one.  See PR77687.  This insn is an add or mr, and a stack_tie on the
13296 ; operands of that.
13297 (define_insn "stack_restore_tie"
13298   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13299         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13300                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13301    (set (mem:BLK (match_dup 0)) (const_int 0))
13302    (set (mem:BLK (match_dup 1)) (const_int 0))]
13303   "TARGET_32BIT"
13304   "@
13305    mr %0,%1
13306    add%I2 %0,%1,%2"
13307   [(set_attr "type" "*,add")])
13309 (define_expand "epilogue"
13310   [(use (const_int 0))]
13311   ""
13313   if (!TARGET_SCHED_PROLOG)
13314     emit_insn (gen_blockage ());
13315   rs6000_emit_epilogue (FALSE);
13316   DONE;
13319 ; On some processors, doing the mtcrf one CC register at a time is
13320 ; faster (like on the 604e).  On others, doing them all at once is
13321 ; faster; for instance, on the 601 and 750.
13323 (define_expand "movsi_to_cr_one"
13324   [(set (match_operand:CC 0 "cc_reg_operand" "")
13325         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13326                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13327   ""
13328   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13330 (define_insn "*movsi_to_cr"
13331   [(match_parallel 0 "mtcrf_operation"
13332                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13333                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13334                                      (match_operand 3 "immediate_operand" "n")]
13335                                     UNSPEC_MOVESI_TO_CR))])]
13336  ""
13337  "*
13339   int mask = 0;
13340   int i;
13341   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13342     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13343   operands[4] = GEN_INT (mask);
13344   return \"mtcrf %4,%2\";
13346   [(set_attr "type" "mtcr")])
13348 (define_insn "*mtcrfsi"
13349   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13350         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13351                     (match_operand 2 "immediate_operand" "n")]
13352                    UNSPEC_MOVESI_TO_CR))]
13353   "GET_CODE (operands[0]) == REG
13354    && CR_REGNO_P (REGNO (operands[0]))
13355    && GET_CODE (operands[2]) == CONST_INT
13356    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13357   "mtcrf %R0,%1"
13358   [(set_attr "type" "mtcr")])
13360 ; The load-multiple instructions have similar properties.
13361 ; Note that "load_multiple" is a name known to the machine-independent
13362 ; code that actually corresponds to the PowerPC load-string.
13364 (define_insn "*lmw"
13365   [(match_parallel 0 "lmw_operation"
13366                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13367                          (match_operand:SI 2 "memory_operand" "m"))])]
13368   "TARGET_MULTIPLE"
13369   "lmw %1,%2"
13370   [(set_attr "type" "load")
13371    (set_attr "update" "yes")
13372    (set_attr "indexed" "yes")
13373    (set_attr "cell_micro" "always")])
13375 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13376 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13378 ; The following comment applies to:
13379 ;     save_gpregs_*
13380 ;     save_fpregs_*
13381 ;     restore_gpregs*
13382 ;     return_and_restore_gpregs*
13383 ;     return_and_restore_fpregs*
13384 ;     return_and_restore_fpregs_aix*
13386 ; The out-of-line save / restore functions expects one input argument.
13387 ; Since those are not standard call_insn's, we must avoid using
13388 ; MATCH_OPERAND for that argument. That way the register rename
13389 ; optimization will not try to rename this register.
13390 ; Each pattern is repeated for each possible register number used in 
13391 ; various ABIs (r11, r1, and for some functions r12)
13393 (define_insn "*restore_gpregs_<mode>_r11"
13394  [(match_parallel 0 "any_parallel_operand"
13395                   [(clobber (reg:P LR_REGNO))
13396                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13397                    (use (reg:P 11))
13398                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13399                         (match_operand:P 3 "memory_operand" "m"))])]
13400  ""
13401  "bl %1"
13402  [(set_attr "type" "branch")
13403   (set_attr "length" "4")])
13405 (define_insn "*restore_gpregs_<mode>_r12"
13406  [(match_parallel 0 "any_parallel_operand"
13407                   [(clobber (reg:P LR_REGNO))
13408                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13409                    (use (reg:P 12))
13410                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13411                         (match_operand:P 3 "memory_operand" "m"))])]
13412  ""
13413  "bl %1"
13414  [(set_attr "type" "branch")
13415   (set_attr "length" "4")])
13417 (define_insn "*restore_gpregs_<mode>_r1"
13418  [(match_parallel 0 "any_parallel_operand"
13419                   [(clobber (reg:P LR_REGNO))
13420                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13421                    (use (reg:P 1))
13422                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13423                         (match_operand:P 3 "memory_operand" "m"))])]
13424  ""
13425  "bl %1"
13426  [(set_attr "type" "branch")
13427   (set_attr "length" "4")])
13429 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13430  [(match_parallel 0 "any_parallel_operand"
13431                   [(return)
13432                    (clobber (reg:P LR_REGNO))
13433                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13434                    (use (reg:P 11))
13435                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13436                         (match_operand:P 3 "memory_operand" "m"))])]
13437  ""
13438  "b %1"
13439  [(set_attr "type" "branch")
13440   (set_attr "length" "4")])
13442 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13443  [(match_parallel 0 "any_parallel_operand"
13444                   [(return)
13445                    (clobber (reg:P LR_REGNO))
13446                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13447                    (use (reg:P 12))
13448                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13449                         (match_operand:P 3 "memory_operand" "m"))])]
13450  ""
13451  "b %1"
13452  [(set_attr "type" "branch")
13453   (set_attr "length" "4")])
13455 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13456  [(match_parallel 0 "any_parallel_operand"
13457                   [(return)
13458                    (clobber (reg:P LR_REGNO))
13459                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13460                    (use (reg:P 1))
13461                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13462                         (match_operand:P 3 "memory_operand" "m"))])]
13463  ""
13464  "b %1"
13465  [(set_attr "type" "branch")
13466   (set_attr "length" "4")])
13468 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13469  [(match_parallel 0 "any_parallel_operand"
13470                   [(return)
13471                    (clobber (reg:P LR_REGNO))
13472                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13473                    (use (reg:P 11))
13474                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13475                         (match_operand:DF 3 "memory_operand" "m"))])]
13476  ""
13477  "b %1"
13478  [(set_attr "type" "branch")
13479   (set_attr "length" "4")])
13481 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13482  [(match_parallel 0 "any_parallel_operand"
13483                   [(return)
13484                    (clobber (reg:P LR_REGNO))
13485                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13486                    (use (reg:P 12))
13487                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13488                         (match_operand:DF 3 "memory_operand" "m"))])]
13489  ""
13490  "b %1"
13491  [(set_attr "type" "branch")
13492   (set_attr "length" "4")])
13494 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13495  [(match_parallel 0 "any_parallel_operand"
13496                   [(return)
13497                    (clobber (reg:P LR_REGNO))
13498                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13499                    (use (reg:P 1))
13500                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13501                         (match_operand:DF 3 "memory_operand" "m"))])]
13502  ""
13503  "b %1"
13504  [(set_attr "type" "branch")
13505   (set_attr "length" "4")])
13507 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13508  [(match_parallel 0 "any_parallel_operand"
13509                   [(return)
13510                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13511                    (use (reg:P 11))
13512                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13513                         (match_operand:DF 3 "memory_operand" "m"))])]
13514  ""
13515  "b %1"
13516  [(set_attr "type" "branch")
13517   (set_attr "length" "4")])
13519 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13520  [(match_parallel 0 "any_parallel_operand"
13521                   [(return)
13522                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13523                    (use (reg:P 1))
13524                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13525                         (match_operand:DF 3 "memory_operand" "m"))])]
13526  ""
13527  "b %1"
13528  [(set_attr "type" "branch")
13529   (set_attr "length" "4")])
13531 ; This is used in compiling the unwind routines.
13532 (define_expand "eh_return"
13533   [(use (match_operand 0 "general_operand" ""))]
13534   ""
13535   "
13537   if (TARGET_32BIT)
13538     emit_insn (gen_eh_set_lr_si (operands[0]));
13539   else
13540     emit_insn (gen_eh_set_lr_di (operands[0]));
13541   DONE;
13544 ; We can't expand this before we know where the link register is stored.
13545 (define_insn "eh_set_lr_<mode>"
13546   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13547                     UNSPECV_EH_RR)
13548    (clobber (match_scratch:P 1 "=&b"))]
13549   ""
13550   "#")
13552 (define_split
13553   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13554    (clobber (match_scratch 1 ""))]
13555   "reload_completed"
13556   [(const_int 0)]
13557   "
13559   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13560   DONE;
13563 (define_insn "prefetch"
13564   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13565              (match_operand:SI 1 "const_int_operand" "n")
13566              (match_operand:SI 2 "const_int_operand" "n"))]
13567   ""
13568   "*
13570   if (GET_CODE (operands[0]) == REG)
13571     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13572   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13574   [(set_attr "type" "load")])
13576 ;; Handle -fsplit-stack.
13578 (define_expand "split_stack_prologue"
13579   [(const_int 0)]
13580   ""
13582   rs6000_expand_split_stack_prologue ();
13583   DONE;
13586 (define_expand "load_split_stack_limit"
13587   [(set (match_operand 0)
13588         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13589   ""
13591   emit_insn (gen_rtx_SET (operands[0],
13592                           gen_rtx_UNSPEC (Pmode,
13593                                           gen_rtvec (1, const0_rtx),
13594                                           UNSPEC_STACK_CHECK)));
13595   DONE;
13598 (define_insn "load_split_stack_limit_di"
13599   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13600         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13601   "TARGET_64BIT"
13602   "ld %0,-0x7040(13)"
13603   [(set_attr "type" "load")
13604    (set_attr "update" "no")
13605    (set_attr "indexed" "no")])
13607 (define_insn "load_split_stack_limit_si"
13608   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13609         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13610   "!TARGET_64BIT"
13611   "lwz %0,-0x7020(2)"
13612   [(set_attr "type" "load")
13613    (set_attr "update" "no")
13614    (set_attr "indexed" "no")])
13616 ;; A return instruction which the middle-end doesn't see.
13617 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13618 ;; after the call to __morestack.
13619 (define_insn "split_stack_return"
13620   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13621   ""
13622   "blr"
13623   [(set_attr "type" "jmpreg")])
13625 ;; If there are operand 0 bytes available on the stack, jump to
13626 ;; operand 1.
13627 (define_expand "split_stack_space_check"
13628   [(set (match_dup 2)
13629         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13630    (set (match_dup 3)
13631         (minus (reg STACK_POINTER_REGNUM)
13632                (match_operand 0)))
13633    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13634    (set (pc) (if_then_else
13635               (geu (match_dup 4) (const_int 0))
13636               (label_ref (match_operand 1))
13637               (pc)))]
13638   ""
13640   rs6000_split_stack_space_check (operands[0], operands[1]);
13641   DONE;
13644 (define_insn "bpermd_<mode>"
13645   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13646         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13647                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13648   "TARGET_POPCNTD"
13649   "bpermd %0,%1,%2"
13650   [(set_attr "type" "popcnt")])
13653 ;; Builtin fma support.  Handle 
13654 ;; Note that the conditions for expansion are in the FMA_F iterator.
13656 (define_expand "fma<mode>4"
13657   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13658         (fma:FMA_F
13659           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13660           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13661           (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13662   ""
13663   "")
13665 (define_insn "*fma<mode>4_fpr"
13666   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13667         (fma:SFDF
13668           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13669           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13670           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13671   "TARGET_<MODE>_FPR"
13672   "@
13673    fmadd<Ftrad> %0,%1,%2,%3
13674    xsmadda<Fvsx> %x0,%x1,%x2
13675    xsmaddm<Fvsx> %x0,%x1,%x3"
13676   [(set_attr "type" "fp")
13677    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13679 ; Altivec only has fma and nfms.
13680 (define_expand "fms<mode>4"
13681   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13682         (fma:FMA_F
13683           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13684           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13685           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13686   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13687   "")
13689 (define_insn "*fms<mode>4_fpr"
13690   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13691         (fma:SFDF
13692          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13693          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13694          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13695   "TARGET_<MODE>_FPR"
13696   "@
13697    fmsub<Ftrad> %0,%1,%2,%3
13698    xsmsuba<Fvsx> %x0,%x1,%x2
13699    xsmsubm<Fvsx> %x0,%x1,%x3"
13700   [(set_attr "type" "fp")
13701    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13703 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13704 (define_expand "fnma<mode>4"
13705   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13706         (neg:FMA_F
13707           (fma:FMA_F
13708             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13709             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13710             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13711   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13712   "")
13714 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13715 (define_expand "fnms<mode>4"
13716   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13717         (neg:FMA_F
13718           (fma:FMA_F
13719             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13720             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13721             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13722   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13723   "")
13725 ; Not an official optab name, but used from builtins.
13726 (define_expand "nfma<mode>4"
13727   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13728         (neg:FMA_F
13729           (fma:FMA_F
13730             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13731             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13732             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13733   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13734   "")
13736 (define_insn "*nfma<mode>4_fpr"
13737   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13738         (neg:SFDF
13739          (fma:SFDF
13740           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13741           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13742           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13743   "TARGET_<MODE>_FPR"
13744   "@
13745    fnmadd<Ftrad> %0,%1,%2,%3
13746    xsnmadda<Fvsx> %x0,%x1,%x2
13747    xsnmaddm<Fvsx> %x0,%x1,%x3"
13748   [(set_attr "type" "fp")
13749    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13751 ; Not an official optab name, but used from builtins.
13752 (define_expand "nfms<mode>4"
13753   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13754         (neg:FMA_F
13755           (fma:FMA_F
13756             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13757             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13758             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13759   ""
13760   "")
13762 (define_insn "*nfmssf4_fpr"
13763   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13764         (neg:SFDF
13765          (fma:SFDF
13766           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13767           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13768           (neg:SFDF
13769            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13770   "TARGET_<MODE>_FPR"
13771   "@
13772    fnmsub<Ftrad> %0,%1,%2,%3
13773    xsnmsuba<Fvsx> %x0,%x1,%x2
13774    xsnmsubm<Fvsx> %x0,%x1,%x3"
13775   [(set_attr "type" "fp")
13776    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13779 (define_expand "rs6000_get_timebase"
13780   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13781   ""
13783   if (TARGET_POWERPC64)
13784     emit_insn (gen_rs6000_mftb_di (operands[0]));
13785   else
13786     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13787   DONE;
13790 (define_insn "rs6000_get_timebase_ppc32"
13791   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13792         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13793    (clobber (match_scratch:SI 1 "=r"))
13794    (clobber (match_scratch:CC 2 "=y"))]
13795   "!TARGET_POWERPC64"
13797   if (WORDS_BIG_ENDIAN)
13798     if (TARGET_MFCRF)
13799       {
13800         return "mfspr %0,269\;"
13801                "mfspr %L0,268\;"
13802                "mfspr %1,269\;"
13803                "cmpw %2,%0,%1\;"
13804                "bne- %2,$-16";
13805       }
13806     else
13807       {
13808         return "mftbu %0\;"
13809                "mftb %L0\;"
13810                "mftbu %1\;"
13811                "cmpw %2,%0,%1\;"
13812                "bne- %2,$-16";
13813       }
13814   else
13815     if (TARGET_MFCRF)
13816       {
13817         return "mfspr %L0,269\;"
13818                "mfspr %0,268\;"
13819                "mfspr %1,269\;"
13820                "cmpw %2,%L0,%1\;"
13821                "bne- %2,$-16";
13822       }
13823     else
13824       {
13825         return "mftbu %L0\;"
13826                "mftb %0\;"
13827                "mftbu %1\;"
13828                "cmpw %2,%L0,%1\;"
13829                "bne- %2,$-16";
13830       }
13832   [(set_attr "length" "20")])
13834 (define_insn "rs6000_mftb_<mode>"
13835   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13836         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13837   ""
13839   if (TARGET_MFCRF)
13840     return "mfspr %0,268";
13841   else
13842     return "mftb %0";
13846 (define_insn "rs6000_mffs"
13847   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13848         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13849   "TARGET_HARD_FLOAT && TARGET_FPRS"
13850   "mffs %0")
13852 (define_insn "rs6000_mtfsf"
13853   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13854                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13855                     UNSPECV_MTFSF)]
13856   "TARGET_HARD_FLOAT && TARGET_FPRS"
13857   "mtfsf %0,%1")
13860 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13861 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13862 ;; register that is being loaded.  The fused ops must be physically adjacent.
13864 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13865 ;; before register allocation, and is meant to reduce the lifetime for the
13866 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13867 ;; to use the register that is being load.  The peephole2 then gathers any
13868 ;; other fused possibilities that it can find after register allocation.  If
13869 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13871 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13872 ;; before register allocation, so that we can avoid allocating a temporary base
13873 ;; register that won't be used, and that we try to load into base registers,
13874 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13875 ;; (addis followed by load) even on power8.
13877 (define_split
13878   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13879         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13880   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13881   [(parallel [(set (match_dup 0) (match_dup 2))
13882               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13883               (use (match_dup 3))
13884               (clobber (scratch:DI))])]
13886   operands[2] = fusion_wrap_memory_address (operands[1]);
13887   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13890 (define_insn "*toc_fusionload_<mode>"
13891   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13892         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13893    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13894    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13895    (clobber (match_scratch:DI 3 "=X,&b"))]
13896   "TARGET_TOC_FUSION_INT"
13898   if (base_reg_operand (operands[0], <MODE>mode))
13899     return emit_fusion_gpr_load (operands[0], operands[1]);
13901   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13903   [(set_attr "type" "load")
13904    (set_attr "length" "8")])
13906 (define_insn "*toc_fusionload_di"
13907   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13908         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13909    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13910    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13911    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13912   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13913    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13915   if (base_reg_operand (operands[0], DImode))
13916     return emit_fusion_gpr_load (operands[0], operands[1]);
13918   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13920   [(set_attr "type" "load")
13921    (set_attr "length" "8")])
13924 ;; Find cases where the addis that feeds into a load instruction is either used
13925 ;; once or is the same as the target register, and replace it with the fusion
13926 ;; insn
13928 (define_peephole2
13929   [(set (match_operand:P 0 "base_reg_operand" "")
13930         (match_operand:P 1 "fusion_gpr_addis" ""))
13931    (set (match_operand:INT1 2 "base_reg_operand" "")
13932         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13933   "TARGET_P8_FUSION
13934    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13935                          operands[3])"
13936   [(const_int 0)]
13938   expand_fusion_gpr_load (operands);
13939   DONE;
13942 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13943 ;; reload)
13945 (define_insn "fusion_gpr_load_<mode>"
13946   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13947         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13948                      UNSPEC_FUSION_GPR))]
13949   "TARGET_P8_FUSION"
13951   return emit_fusion_gpr_load (operands[0], operands[1]);
13953   [(set_attr "type" "load")
13954    (set_attr "length" "8")])
13957 ;; ISA 3.0 (power9) fusion support
13958 ;; Merge addis with floating load/store to FPRs (or GPRs).
13959 (define_peephole2
13960   [(set (match_operand:P 0 "base_reg_operand" "")
13961         (match_operand:P 1 "fusion_gpr_addis" ""))
13962    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13963         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13964   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13965    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13966   [(const_int 0)]
13968   expand_fusion_p9_load (operands);
13969   DONE;
13972 (define_peephole2
13973   [(set (match_operand:P 0 "base_reg_operand" "")
13974         (match_operand:P 1 "fusion_gpr_addis" ""))
13975    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13976         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13977   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13978    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13979    && !rtx_equal_p (operands[0], operands[3])"
13980   [(const_int 0)]
13982   expand_fusion_p9_store (operands);
13983   DONE;
13986 (define_peephole2
13987   [(set (match_operand:SDI 0 "int_reg_operand" "")
13988         (match_operand:SDI 1 "upper16_cint_operand" ""))
13989    (set (match_dup 0)
13990         (ior:SDI (match_dup 0)
13991                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
13992   "TARGET_P9_FUSION"
13993   [(set (match_dup 0)
13994         (unspec:SDI [(match_dup 1)
13995                      (match_dup 2)] UNSPEC_FUSION_P9))])
13997 (define_peephole2
13998   [(set (match_operand:SDI 0 "int_reg_operand" "")
13999         (match_operand:SDI 1 "upper16_cint_operand" ""))
14000    (set (match_operand:SDI 2 "int_reg_operand" "")
14001         (ior:SDI (match_dup 0)
14002                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
14003   "TARGET_P9_FUSION
14004    && !rtx_equal_p (operands[0], operands[2])
14005    && peep2_reg_dead_p (2, operands[0])"
14006   [(set (match_dup 2)
14007         (unspec:SDI [(match_dup 1)
14008                      (match_dup 3)] UNSPEC_FUSION_P9))])
14010 ;; Fusion insns, created by the define_peephole2 above (and eventually by
14011 ;; reload).  Because we want to eventually have secondary_reload generate
14012 ;; these, they have to have a single alternative that gives the register
14013 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
14014 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
14015   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
14016         (unspec:GPR_FUSION
14017          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14018          UNSPEC_FUSION_P9))
14019    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14020   "TARGET_P9_FUSION"
14022   /* This insn is a secondary reload insn, which cannot have alternatives.
14023      If we are not loading up register 0, use the power8 fusion instead.  */
14024   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
14025     return emit_fusion_gpr_load (operands[0], operands[1]);
14027   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14029   [(set_attr "type" "load")
14030    (set_attr "length" "8")])
14032 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
14033   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14034         (unspec:GPR_FUSION
14035          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
14036          UNSPEC_FUSION_P9))
14037    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14038   "TARGET_P9_FUSION"
14040   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14042   [(set_attr "type" "store")
14043    (set_attr "length" "8")])
14045 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
14046   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
14047         (unspec:FPR_FUSION
14048          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14049          UNSPEC_FUSION_P9))
14050    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14051   "TARGET_P9_FUSION"
14053   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14055   [(set_attr "type" "fpload")
14056    (set_attr "length" "8")])
14058 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
14059   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14060         (unspec:FPR_FUSION
14061          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
14062          UNSPEC_FUSION_P9))
14063    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14064   "TARGET_P9_FUSION"
14066   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14068   [(set_attr "type" "fpstore")
14069    (set_attr "length" "8")])
14071 (define_insn "*fusion_p9_<mode>_constant"
14072   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
14073         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
14074                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
14075                     UNSPEC_FUSION_P9))] 
14076   "TARGET_P9_FUSION"
14078   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
14079   return "ori %0,%0,%2";
14081   [(set_attr "type" "two")
14082    (set_attr "length" "8")])
14085 ;; Optimize cases where we want to do a D-form load (register+offset) on
14086 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
14087 ;; has generated:
14088 ;;      LFD 0,32(3)
14089 ;;      XXLOR 32,0,0
14091 ;; and we change this to:
14092 ;;      LI 0,32
14093 ;;      LXSDX 32,3,9
14095 (define_peephole2
14096   [(match_scratch:DI 0 "b")
14097    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14098         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
14099    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
14100         (match_dup 1))]
14101   "TARGET_VSX && TARGET_POWERPC64 && TARGET_UPPER_REGS_<MODE>
14102    && !TARGET_P9_DFORM_SCALAR && peep2_reg_dead_p (2, operands[1])"
14103   [(set (match_dup 0)
14104         (match_dup 4))
14105    (set (match_dup 3)
14106         (match_dup 5))]
14108   rtx tmp_reg = operands[0];
14109   rtx mem = operands[2];
14110   rtx addr = XEXP (mem, 0);
14111   rtx add_op0, add_op1, new_addr;
14113   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14114   add_op0 = XEXP (addr, 0);
14115   add_op1 = XEXP (addr, 1);
14116   gcc_assert (REG_P (add_op0));
14117   new_addr = gen_rtx_PLUS (DImode, add_op0, tmp_reg);
14119   operands[4] = add_op1;
14120   operands[5] = change_address (mem, <MODE>mode, new_addr);
14123 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
14124 ;; Altivec register, and the register allocator has generated:
14125 ;;      XXLOR 0,32,32
14126 ;;      STFD 0,32(3)
14128 ;; and we change this to:
14129 ;;      LI 0,32
14130 ;;      STXSDX 32,3,9
14132 (define_peephole2
14133   [(match_scratch:DI 0 "b")
14134    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14135         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14136    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14137         (match_dup 1))]
14138   "TARGET_VSX && TARGET_POWERPC64 && TARGET_UPPER_REGS_<MODE>
14139    && !TARGET_P9_DFORM_SCALAR && peep2_reg_dead_p (2, operands[1])"
14140   [(set (match_dup 0)
14141         (match_dup 4))
14142    (set (match_dup 5)
14143         (match_dup 2))]
14145   rtx tmp_reg = operands[0];
14146   rtx mem = operands[3];
14147   rtx addr = XEXP (mem, 0);
14148   rtx add_op0, add_op1, new_addr;
14150   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14151   add_op0 = XEXP (addr, 0);
14152   add_op1 = XEXP (addr, 1);
14153   gcc_assert (REG_P (add_op0));
14154   new_addr = gen_rtx_PLUS (DImode, add_op0, tmp_reg);
14156   operands[4] = add_op1;
14157   operands[5] = change_address (mem, <MODE>mode, new_addr);
14159    
14161 ;; Miscellaneous ISA 2.06 (power7) instructions
14162 (define_insn "addg6s"
14163   [(set (match_operand:SI 0 "register_operand" "=r")
14164         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14165                     (match_operand:SI 2 "register_operand" "r")]
14166                    UNSPEC_ADDG6S))]
14167   "TARGET_POPCNTD"
14168   "addg6s %0,%1,%2"
14169   [(set_attr "type" "integer")
14170    (set_attr "length" "4")])
14172 (define_insn "cdtbcd"
14173   [(set (match_operand:SI 0 "register_operand" "=r")
14174         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14175                    UNSPEC_CDTBCD))]
14176   "TARGET_POPCNTD"
14177   "cdtbcd %0,%1"
14178   [(set_attr "type" "integer")
14179    (set_attr "length" "4")])
14181 (define_insn "cbcdtd"
14182   [(set (match_operand:SI 0 "register_operand" "=r")
14183         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14184                    UNSPEC_CBCDTD))]
14185   "TARGET_POPCNTD"
14186   "cbcdtd %0,%1"
14187   [(set_attr "type" "integer")
14188    (set_attr "length" "4")])
14190 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14191                                         UNSPEC_DIVEO
14192                                         UNSPEC_DIVEU
14193                                         UNSPEC_DIVEUO])
14195 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
14196                              (UNSPEC_DIVEO      "eo")
14197                              (UNSPEC_DIVEU      "eu")
14198                              (UNSPEC_DIVEUO     "euo")])
14200 (define_insn "div<div_extend>_<mode>"
14201   [(set (match_operand:GPR 0 "register_operand" "=r")
14202         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14203                      (match_operand:GPR 2 "register_operand" "r")]
14204                     UNSPEC_DIV_EXTEND))]
14205   "TARGET_POPCNTD"
14206   "div<wd><div_extend> %0,%1,%2"
14207   [(set_attr "type" "div")
14208    (set_attr "size" "<bits>")])
14211 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14213 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14214 (define_mode_attr FP128_64 [(TF "DF")
14215                             (IF "DF")
14216                             (TD "DI")
14217                             (KF "DI")])
14219 (define_expand "unpack<mode>"
14220   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14221         (unspec:<FP128_64>
14222          [(match_operand:FMOVE128 1 "register_operand" "")
14223           (match_operand:QI 2 "const_0_to_1_operand" "")]
14224          UNSPEC_UNPACK_128BIT))]
14225   "FLOAT128_2REG_P (<MODE>mode)"
14226   "")
14228 (define_insn_and_split "unpack<mode>_dm"
14229   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14230         (unspec:<FP128_64>
14231          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14232           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14233          UNSPEC_UNPACK_128BIT))]
14234   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14235   "#"
14236   "&& reload_completed"
14237   [(set (match_dup 0) (match_dup 3))]
14239   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14241   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14242     {
14243       emit_note (NOTE_INSN_DELETED);
14244       DONE;
14245     }
14247   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14249   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14250    (set_attr "length" "4")])
14252 (define_insn_and_split "unpack<mode>_nodm"
14253   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14254         (unspec:<FP128_64>
14255          [(match_operand:FMOVE128 1 "register_operand" "d,d")
14256           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14257          UNSPEC_UNPACK_128BIT))]
14258   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14259   "#"
14260   "&& reload_completed"
14261   [(set (match_dup 0) (match_dup 3))]
14263   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14265   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14266     {
14267       emit_note (NOTE_INSN_DELETED);
14268       DONE;
14269     }
14271   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14273   [(set_attr "type" "fp,fpstore")
14274    (set_attr "length" "4")])
14276 (define_insn_and_split "pack<mode>"
14277   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14278         (unspec:FMOVE128
14279          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14280           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14281          UNSPEC_PACK_128BIT))]
14282   "FLOAT128_2REG_P (<MODE>mode)"
14283   "@
14284    fmr %L0,%2
14285    #"
14286   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14287   [(set (match_dup 3) (match_dup 1))
14288    (set (match_dup 4) (match_dup 2))]
14290   unsigned dest_hi = REGNO (operands[0]);
14291   unsigned dest_lo = dest_hi + 1;
14293   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14294   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14296   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14297   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14299   [(set_attr "type" "fpsimple,fp")
14300    (set_attr "length" "4,8")])
14302 (define_insn "unpack<mode>"
14303   [(set (match_operand:DI 0 "register_operand" "=d,d")
14304         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14305                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14306          UNSPEC_UNPACK_128BIT))]
14307   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14309   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14310     return ASM_COMMENT_START " xxpermdi to same register";
14312   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14313   return "xxpermdi %x0,%x1,%x1,%3";
14315   [(set_attr "type" "vecperm")])
14317 (define_insn "pack<mode>"
14318   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14319         (unspec:FMOVE128_VSX
14320          [(match_operand:DI 1 "register_operand" "d")
14321           (match_operand:DI 2 "register_operand" "d")]
14322          UNSPEC_PACK_128BIT))]
14323   "TARGET_VSX"
14324   "xxpermdi %x0,%x1,%x2,0"
14325   [(set_attr "type" "vecperm")])
14329 ;; ISA 2.08 IEEE 128-bit floating point support.
14331 (define_insn "add<mode>3"
14332   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14333         (plus:IEEE128
14334          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14335          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14336   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14337   "xsaddqp %0,%1,%2"
14338   [(set_attr "type" "vecfloat")
14339    (set_attr "size" "128")])
14341 (define_insn "sub<mode>3"
14342   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14343         (minus:IEEE128
14344          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14345          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14346   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14347   "xssubqp %0,%1,%2"
14348   [(set_attr "type" "vecfloat")
14349    (set_attr "size" "128")])
14351 (define_insn "mul<mode>3"
14352   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14353         (mult:IEEE128
14354          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14355          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14356   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14357   "xsmulqp %0,%1,%2"
14358   [(set_attr "type" "vecfloat")
14359    (set_attr "size" "128")])
14361 (define_insn "div<mode>3"
14362   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14363         (div:IEEE128
14364          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14365          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14366   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14367   "xsdivqp %0,%1,%2"
14368   [(set_attr "type" "vecdiv")
14369    (set_attr "size" "128")])
14371 (define_insn "sqrt<mode>2"
14372   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14373         (sqrt:IEEE128
14374          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14375   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14376    "xssqrtqp %0,%1"
14377   [(set_attr "type" "vecdiv")
14378    (set_attr "size" "128")])
14380 (define_expand "copysign<mode>3"
14381   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14382    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14383    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14384   "FLOAT128_IEEE_P (<MODE>mode)"
14386   if (TARGET_FLOAT128_HW)
14387     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14388                                          operands[2]));
14389   else
14390     {
14391       rtx tmp = gen_reg_rtx (<MODE>mode);
14392       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14393                                            operands[2], tmp));
14394     }
14395   DONE;
14398 (define_insn "copysign<mode>3_hard"
14399   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14400         (unspec:IEEE128
14401          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14402           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14403          UNSPEC_COPYSIGN))]
14404   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14405    "xscpsgnqp %0,%2,%1"
14406   [(set_attr "type" "vecmove")
14407    (set_attr "size" "128")])
14409 (define_insn "copysign<mode>3_soft"
14410   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14411         (unspec:IEEE128
14412          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14413           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14414           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14415          UNSPEC_COPYSIGN))]
14416   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14417    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14418   [(set_attr "type" "veccomplex")
14419    (set_attr "length" "8")])
14421 (define_insn "neg<mode>2_hw"
14422   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14423         (neg:IEEE128
14424          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14425   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14426   "xsnegqp %0,%1"
14427   [(set_attr "type" "vecmove")
14428    (set_attr "size" "128")])
14431 (define_insn "abs<mode>2_hw"
14432   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14433         (abs:IEEE128
14434          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14435   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14436   "xsabsqp %0,%1"
14437   [(set_attr "type" "vecmove")
14438    (set_attr "size" "128")])
14441 (define_insn "*nabs<mode>2_hw"
14442   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14443         (neg:IEEE128
14444          (abs:IEEE128
14445           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14446   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14447   "xsnabsqp %0,%1"
14448   [(set_attr "type" "vecmove")
14449    (set_attr "size" "128")])
14451 ;; Initially don't worry about doing fusion
14452 (define_insn "*fma<mode>4_hw"
14453   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14454         (fma:IEEE128
14455          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14456          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14457          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14458   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14459   "xsmaddqp %0,%1,%2"
14460   [(set_attr "type" "vecfloat")
14461    (set_attr "size" "128")])
14463 (define_insn "*fms<mode>4_hw"
14464   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14465         (fma:IEEE128
14466          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14467          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14468          (neg:IEEE128
14469           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14470   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14471   "xsmsubqp %0,%1,%2"
14472   [(set_attr "type" "vecfloat")
14473    (set_attr "size" "128")])
14475 (define_insn "*nfma<mode>4_hw"
14476   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14477         (neg:IEEE128
14478          (fma:IEEE128
14479           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14480           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14481           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14482   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14483   "xsnmaddqp %0,%1,%2"
14484   [(set_attr "type" "vecfloat")
14485    (set_attr "size" "128")])
14487 (define_insn "*nfms<mode>4_hw"
14488   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14489         (neg:IEEE128
14490          (fma:IEEE128
14491           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14492           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14493           (neg:IEEE128
14494            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14495   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14496   "xsnmsubqp %0,%1,%2"
14497   [(set_attr "type" "vecfloat")
14498    (set_attr "size" "128")])
14500 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14501   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14502         (float_extend:IEEE128
14503          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14504   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14505   "xscvdpqp %0,%1"
14506   [(set_attr "type" "vecfloat")
14507    (set_attr "size" "128")])
14509 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14510 ;; point is a simple copy.
14511 (define_insn_and_split "extendkftf2"
14512   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14513         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14514   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14515   "@
14516    #
14517    xxlor %x0,%x1,%x1"
14518   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14519   [(const_int 0)]
14521   emit_note (NOTE_INSN_DELETED);
14522   DONE;
14524   [(set_attr "type" "*,veclogical")
14525    (set_attr "length" "0,4")])
14527 (define_insn_and_split "trunctfkf2"
14528   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14529         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14530   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14531   "@
14532    #
14533    xxlor %x0,%x1,%x1"
14534   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14535   [(const_int 0)]
14537   emit_note (NOTE_INSN_DELETED);
14538   DONE;
14540   [(set_attr "type" "*,veclogical")
14541    (set_attr "length" "0,4")])
14543 (define_insn "trunc<mode>df2_hw"
14544   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14545         (float_truncate:DF
14546          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14547   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14548   "xscvqpdp %0,%1"
14549   [(set_attr "type" "vecfloat")
14550    (set_attr "size" "128")])
14552 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14553 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14554 ;; conversion
14555 (define_insn_and_split "trunc<mode>sf2_hw"
14556   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14557         (float_truncate:SF
14558          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14559    (clobber (match_scratch:DF 2 "=v"))]
14560   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14561   "#"
14562   "&& 1"
14563   [(set (match_dup 2)
14564         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14565    (set (match_dup 0)
14566         (float_truncate:SF (match_dup 2)))]
14568   if (GET_CODE (operands[2]) == SCRATCH)
14569     operands[2] = gen_reg_rtx (DFmode);
14571   [(set_attr "type" "vecfloat")
14572    (set_attr "length" "8")])
14574 ;; Conversion between IEEE 128-bit and integer types
14575 (define_insn "fix_<mode>di2_hw"
14576   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14577         (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14578   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14579   "xscvqpsdz %0,%1"
14580   [(set_attr "type" "vecfloat")
14581    (set_attr "size" "128")])
14583 (define_insn "fixuns_<mode>di2_hw"
14584   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14585         (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14586   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14587   "xscvqpudz %0,%1"
14588   [(set_attr "type" "vecfloat")
14589    (set_attr "size" "128")])
14591 (define_insn "fix_<mode>si2_hw"
14592   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14593         (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14594   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14595   "xscvqpswz %0,%1"
14596   [(set_attr "type" "vecfloat")
14597    (set_attr "size" "128")])
14599 (define_insn "fixuns_<mode>si2_hw"
14600   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14601         (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14602   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14603   "xscvqpuwz %0,%1"
14604   [(set_attr "type" "vecfloat")
14605    (set_attr "size" "128")])
14607 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14608 ;; floating point value to 32-bit integer to GPR in order to save it.
14609 (define_insn_and_split "*fix<uns>_<mode>_mem"
14610   [(set (match_operand:SI 0 "memory_operand" "=Z")
14611         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14612    (clobber (match_scratch:SI 2 "=v"))]
14613   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14614   "#"
14615   "&& reload_completed"
14616   [(set (match_dup 2)
14617         (any_fix:SI (match_dup 1)))
14618    (set (match_dup 0)
14619         (match_dup 2))])
14621 (define_insn "float_<mode>di2_hw"
14622   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14623         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14624   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14625   "xscvsdqp %0,%1"
14626   [(set_attr "type" "vecfloat")
14627    (set_attr "size" "128")])
14629 (define_insn_and_split "float_<mode>si2_hw"
14630   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14631         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14632    (clobber (match_scratch:DI 2 "=v"))]
14633   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14634   "#"
14635   "&& 1"
14636   [(set (match_dup 2)
14637         (sign_extend:DI (match_dup 1)))
14638    (set (match_dup 0)
14639         (float:IEEE128 (match_dup 2)))]
14641   if (GET_CODE (operands[2]) == SCRATCH)
14642     operands[2] = gen_reg_rtx (DImode);
14645 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14646   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14647         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14648    (clobber (match_scratch:DI 2 "=X,r,X"))]
14649   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14650   "#"
14651   "&& reload_completed"
14652   [(const_int 0)]
14654   rtx dest = operands[0];
14655   rtx src = operands[1];
14656   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14658   if (altivec_register_operand (src, <QHI:MODE>mode))
14659     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14660   else if (int_reg_operand (src, <QHI:MODE>mode))
14661     {
14662       rtx ext_di = operands[2];
14663       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14664       emit_move_insn (dest_di, ext_di);
14665     }
14666   else if (MEM_P (src))
14667     {
14668       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14669       emit_move_insn (dest_qhi, src);
14670       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14671     }
14672   else
14673     gcc_unreachable ();
14675   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14676   DONE;
14678   [(set_attr "length" "8,12,12")
14679    (set_attr "type" "vecfloat")
14680    (set_attr "size" "128")])
14682 (define_insn "floatuns_<mode>di2_hw"
14683   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14684         (unsigned_float:IEEE128
14685          (match_operand:DI 1 "altivec_register_operand" "v")))]
14686   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14687   "xscvudqp %0,%1"
14688   [(set_attr "type" "vecfloat")
14689    (set_attr "size" "128")])
14691 (define_insn_and_split "floatuns_<mode>si2_hw"
14692   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14693         (unsigned_float:IEEE128
14694          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14695    (clobber (match_scratch:DI 2 "=v"))]
14696   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14697   "#"
14698   "&& 1"
14699   [(set (match_dup 2)
14700         (zero_extend:DI (match_dup 1)))
14701    (set (match_dup 0)
14702         (float:IEEE128 (match_dup 2)))]
14704   if (GET_CODE (operands[2]) == SCRATCH)
14705     operands[2] = gen_reg_rtx (DImode);
14708 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14709   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14710         (unsigned_float:IEEE128
14711          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14712    (clobber (match_scratch:DI 2 "=X,r,X"))]
14713   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14714   "#"
14715   "&& reload_completed"
14716   [(const_int 0)]
14718   rtx dest = operands[0];
14719   rtx src = operands[1];
14720   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14722   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14723     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14724   else if (int_reg_operand (src, <QHI:MODE>mode))
14725     {
14726       rtx ext_di = operands[2];
14727       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14728       emit_move_insn (dest_di, ext_di);
14729     }
14730   else
14731     gcc_unreachable ();
14733   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14734   DONE;
14736   [(set_attr "length" "8,12,8")
14737    (set_attr "type" "vecfloat")
14738    (set_attr "size" "128")])
14740 ;; IEEE 128-bit instructions with round to odd semantics
14741 (define_insn "*trunc<mode>df2_odd"
14742   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14743         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14744                    UNSPEC_ROUND_TO_ODD))]
14745   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14746   "xscvqpdpo %0,%1"
14747   [(set_attr "type" "vecfloat")
14748    (set_attr "size" "128")])
14750 ;; IEEE 128-bit comparisons
14751 (define_insn "*cmp<mode>_hw"
14752   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14753         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14754                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14755   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14756    "xscmpuqp %0,%1,%2"
14757   [(set_attr "type" "veccmp")
14758    (set_attr "size" "128")])
14762 (include "sync.md")
14763 (include "vector.md")
14764 (include "vsx.md")
14765 (include "altivec.md")
14766 (include "spe.md")
14767 (include "dfp.md")
14768 (include "paired.md")
14769 (include "crypto.md")
14770 (include "htm.md")