1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2016 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.
29 (STACK_POINTER_REGNUM 1)
31 (STATIC_CHAIN_REGNUM 11)
32 (HARD_FRAME_POINTER_REGNUM 31)
38 (ARG_POINTER_REGNUM 67)
49 (FIRST_ALTIVEC_REGNO 77)
50 (LAST_ALTIVEC_REGNO 108)
55 (FRAME_POINTER_REGNUM 113)
59 (FIRST_SPE_HIGH_REGNO 117)
60 (LAST_SPE_HIGH_REGNO 148)
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
74 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
81 UNSPEC_LD_MPIC ; load_macho_picbase
82 UNSPEC_RELD_MPIC ; re-load_macho_picbase
83 UNSPEC_MPIC_CORRECT ; macho_correct_pic
97 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
98 UNSPEC_MV_CR_GT ; move_from_CR_gt_bit
116 UNSPEC_MACHOPIC_OFFSET
129 UNSPEC_P8V_RELOAD_FROM_GPR
132 UNSPEC_P8V_RELOAD_FROM_VSX
149 UNSPEC_IEEE128_CONVERT
155 ;; UNSPEC_VOLATILE usage
158 (define_c_enum "unspecv"
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
173 ;; Define an insn type attribute. This is used in function unit delay
177 add,logical,shift,insert,
179 exts,cntlz,popcnt,isel,
180 load,store,fpload,fpstore,vecload,vecstore,
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,
186 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
187 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
188 veclogical,veccmpfx,vecexts,vecmove,
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"))
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"))
221 (const_string "no")))
223 ;; Is this instruction using operands[2] as shift amount, and can that be a
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")
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))
251 (lt (minus (match_dup 0) (pc))
257 ;; Processor type -- this attribute must exactly match the processor_type
258 ;; enumeration in rs6000-opts.h.
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")
294 (include "e300c2c3.md")
295 (include "e500mc.md")
296 (include "e500mc64.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")
310 (include "predicates.md")
311 (include "constraints.md")
313 (include "darwin.md")
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
357 (DI "TARGET_POWERPC64")
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")
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)")
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")
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 "")
429 (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
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")
448 ; Definitions for load to 32-bit fpr register
449 (define_mode_attr f32_lr [(SF "f") (SD "wz")])
450 (define_mode_attr f32_lr2 [(SF "wb") (SD "wn")])
451 (define_mode_attr f32_lm [(SF "m") (SD "Z")])
452 (define_mode_attr f32_lm2 [(SF "wY") (SD "wn")])
453 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
454 (define_mode_attr f32_li2 [(SF "lxssp %0,%1") (SD "lfiwzx %0,%y1")])
455 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
457 ; Definitions for store from 32-bit fpr register
458 (define_mode_attr f32_sr [(SF "f") (SD "wx")])
459 (define_mode_attr f32_sr2 [(SF "wb") (SD "wn")])
460 (define_mode_attr f32_sm [(SF "m") (SD "Z")])
461 (define_mode_attr f32_sm2 [(SF "wY") (SD "wn")])
462 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
463 (define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")])
464 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwx %x1,%y0")])
466 ; Definitions for 32-bit fpr direct move
467 ; At present, the decimal modes are not allowed in the traditional altivec
468 ; registers, so restrict the constraints to just the traditional FPRs.
469 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
471 ; Definitions for 32-bit VSX
472 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
474 ; Definitions for 32-bit use of altivec registers
475 (define_mode_attr f32_av [(SF "wu") (SD "wn")])
477 ; Definitions for 64-bit VSX
478 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
480 ; Definitions for 64-bit direct move
481 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
483 ; Definitions for 64-bit use of altivec registers
484 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
486 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
487 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
489 ; These modes do not fit in integer registers in 32-bit mode.
490 ; but on e500v2, the gpr are 64 bit registers
491 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
493 ; Iterator for reciprocal estimate instructions
494 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
496 ; Iterator for just SF/DF
497 (define_mode_iterator SFDF [SF DF])
499 ; Like SFDF, but a different name to match conditional move where the
500 ; comparison operands may be a different mode than the input operands.
501 (define_mode_iterator SFDF2 [SF DF])
503 ; Iterator for 128-bit floating point that uses the IBM double-double format
504 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
505 (TF "FLOAT128_IBM_P (TFmode)")])
507 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
508 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
509 (TF "FLOAT128_IEEE_P (TFmode)")])
511 ; Iterator for 128-bit floating point
512 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
513 (IF "TARGET_FLOAT128_TYPE")
514 (TF "TARGET_LONG_DOUBLE_128")])
516 ; Iterator for signbit on 64-bit machines with direct move
517 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
518 (TF "FLOAT128_VECTOR_P (TFmode)")])
520 (define_mode_attr Fsignbit [(KF "wa")
523 ; Iterator for ISA 3.0 supported floating point types
524 (define_mode_iterator FP_ISA3 [SF
526 (KF "FLOAT128_IEEE_P (KFmode)")
527 (TF "FLOAT128_IEEE_P (TFmode)")])
529 ; SF/DF suffix for traditional floating instructions
530 (define_mode_attr Ftrad [(SF "s") (DF "")])
532 ; SF/DF suffix for VSX instructions
533 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
535 ; SF/DF constraint for arithmetic on traditional floating point registers
536 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
538 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
539 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
540 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
542 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
544 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
545 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
546 ; instructions added in ISA 2.07 (power8)
547 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
549 ; SF/DF constraint for arithmetic on altivec registers
550 (define_mode_attr Fa [(SF "wu") (DF "wv")])
552 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
553 (define_mode_attr Fs [(SF "s") (DF "d")])
556 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
557 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
559 ; Conditional returns.
560 (define_code_iterator any_return [return simple_return])
561 (define_code_attr return_pred [(return "direct_return ()")
562 (simple_return "1")])
563 (define_code_attr return_str [(return "") (simple_return "simple_")])
566 (define_code_iterator iorxor [ior xor])
568 ; Signed/unsigned variants of ops.
569 (define_code_iterator any_extend [sign_extend zero_extend])
570 (define_code_iterator any_fix [fix unsigned_fix])
571 (define_code_iterator any_float [float unsigned_float])
573 (define_code_attr u [(sign_extend "")
576 (define_code_attr su [(sign_extend "s")
581 (unsigned_float "u")])
583 (define_code_attr az [(sign_extend "a")
588 (unsigned_float "z")])
590 (define_code_attr uns [(fix "")
593 (unsigned_float "uns")])
595 ; Various instructions that come in SI and DI forms.
596 ; A generic w/d attribute, for things like cmpw/cmpd.
597 (define_mode_attr wd [(QI "b")
608 ;; How many bits in this mode?
609 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
612 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
614 ;; ISEL/ISEL64 target selection
615 (define_mode_attr sel [(SI "") (DI "64")])
617 ;; Bitmask for shift instructions
618 (define_mode_attr hH [(SI "h") (DI "H")])
620 ;; A mode twice the size of the given mode
621 (define_mode_attr dmode [(SI "di") (DI "ti")])
622 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
624 ;; Suffix for reload patterns
625 (define_mode_attr ptrsize [(SI "32bit")
628 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
629 (DI "TARGET_64BIT")])
631 (define_mode_attr mptrsize [(SI "si")
634 (define_mode_attr ptrload [(SI "lwz")
637 (define_mode_attr ptrm [(SI "m")
640 (define_mode_attr rreg [(SF "f")
647 (define_mode_attr rreg2 [(SF "f")
650 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
651 (DF "TARGET_FCFID")])
653 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
654 (DF "TARGET_E500_DOUBLE")])
656 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
657 (DF "TARGET_DOUBLE_FLOAT")])
659 ;; Mode iterator for logical operations on 128-bit types
660 (define_mode_iterator BOOL_128 [TI
662 (V16QI "TARGET_ALTIVEC")
663 (V8HI "TARGET_ALTIVEC")
664 (V4SI "TARGET_ALTIVEC")
665 (V4SF "TARGET_ALTIVEC")
666 (V2DI "TARGET_ALTIVEC")
667 (V2DF "TARGET_ALTIVEC")
668 (V1TI "TARGET_ALTIVEC")])
670 ;; For the GPRs we use 3 constraints for register outputs, two that are the
671 ;; same as the output register, and a third where the output register is an
672 ;; early clobber, so we don't have to deal with register overlaps. For the
673 ;; vector types, we prefer to use the vector registers. For TI mode, allow
676 ;; Mode attribute for boolean operation register constraints for output
677 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
679 (V16QI "wa,v,&?r,?r,?r")
680 (V8HI "wa,v,&?r,?r,?r")
681 (V4SI "wa,v,&?r,?r,?r")
682 (V4SF "wa,v,&?r,?r,?r")
683 (V2DI "wa,v,&?r,?r,?r")
684 (V2DF "wa,v,&?r,?r,?r")
685 (V1TI "wa,v,&?r,?r,?r")])
687 ;; Mode attribute for boolean operation register constraints for operand1
688 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
696 (V1TI "wa,v,r,0,r")])
698 ;; Mode attribute for boolean operation register constraints for operand2
699 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
707 (V1TI "wa,v,r,r,0")])
709 ;; Mode attribute for boolean operation register constraints for operand1
710 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
711 ;; is used for operand1 or operand2
712 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
720 (V1TI "wa,v,r,0,0")])
722 ;; Reload iterator for creating the function to allocate a base register to
723 ;; supplement addressing modes.
724 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
725 SF SD SI DF DD DI TI PTI KF IF TF])
727 ;; Iterate over smin, smax
728 (define_code_iterator fp_minmax [smin smax])
730 (define_code_attr minmax [(smin "min")
733 (define_code_attr SMINMAX [(smin "SMIN")
737 ;; Start with fixed-point load and store insns. Here we put only the more
738 ;; complex forms. Basic data transfer is done later.
740 (define_insn "zero_extendqi<mode>2"
741 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,?*wJwK,?*wK")
742 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,*wK")))]
749 [(set_attr "type" "load,shift,fpload,vecperm")])
751 (define_insn_and_split "*zero_extendqi<mode>2_dot"
752 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
753 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
755 (clobber (match_scratch:EXTQI 0 "=r,r"))]
756 "rs6000_gen_cell_microcode"
760 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
762 (zero_extend:EXTQI (match_dup 1)))
764 (compare:CC (match_dup 0)
767 [(set_attr "type" "logical")
768 (set_attr "dot" "yes")
769 (set_attr "length" "4,8")])
771 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
772 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
773 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
775 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
776 (zero_extend:EXTQI (match_dup 1)))]
777 "rs6000_gen_cell_microcode"
781 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
783 (zero_extend:EXTQI (match_dup 1)))
785 (compare:CC (match_dup 0)
788 [(set_attr "type" "logical")
789 (set_attr "dot" "yes")
790 (set_attr "length" "4,8")])
793 (define_insn "zero_extendhi<mode>2"
794 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wJwK,?*wK")
795 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
799 rlwinm %0,%1,0,0xffff
802 [(set_attr "type" "load,shift,fpload,vecperm")])
804 (define_insn_and_split "*zero_extendhi<mode>2_dot"
805 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
806 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
808 (clobber (match_scratch:EXTHI 0 "=r,r"))]
809 "rs6000_gen_cell_microcode"
813 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
815 (zero_extend:EXTHI (match_dup 1)))
817 (compare:CC (match_dup 0)
820 [(set_attr "type" "logical")
821 (set_attr "dot" "yes")
822 (set_attr "length" "4,8")])
824 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
825 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
826 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
828 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
829 (zero_extend:EXTHI (match_dup 1)))]
830 "rs6000_gen_cell_microcode"
834 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
836 (zero_extend:EXTHI (match_dup 1)))
838 (compare:CC (match_dup 0)
841 [(set_attr "type" "logical")
842 (set_attr "dot" "yes")
843 (set_attr "length" "4,8")])
846 (define_insn "zero_extendsi<mode>2"
847 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
848 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
857 xxextractuw %x0,%x1,1"
858 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
860 (define_insn_and_split "*zero_extendsi<mode>2_dot"
861 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
862 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
864 (clobber (match_scratch:EXTSI 0 "=r,r"))]
865 "rs6000_gen_cell_microcode"
869 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
871 (zero_extend:DI (match_dup 1)))
873 (compare:CC (match_dup 0)
876 [(set_attr "type" "shift")
877 (set_attr "dot" "yes")
878 (set_attr "length" "4,8")])
880 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
881 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
882 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
884 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
885 (zero_extend:EXTSI (match_dup 1)))]
886 "rs6000_gen_cell_microcode"
890 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
892 (zero_extend:EXTSI (match_dup 1)))
894 (compare:CC (match_dup 0)
897 [(set_attr "type" "shift")
898 (set_attr "dot" "yes")
899 (set_attr "length" "4,8")])
902 (define_insn "extendqi<mode>2"
903 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
904 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
909 [(set_attr "type" "exts,vecperm")])
911 (define_insn_and_split "*extendqi<mode>2_dot"
912 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
913 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
915 (clobber (match_scratch:EXTQI 0 "=r,r"))]
916 "rs6000_gen_cell_microcode"
920 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
922 (sign_extend:EXTQI (match_dup 1)))
924 (compare:CC (match_dup 0)
927 [(set_attr "type" "exts")
928 (set_attr "dot" "yes")
929 (set_attr "length" "4,8")])
931 (define_insn_and_split "*extendqi<mode>2_dot2"
932 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
933 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
935 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
936 (sign_extend:EXTQI (match_dup 1)))]
937 "rs6000_gen_cell_microcode"
941 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
943 (sign_extend:EXTQI (match_dup 1)))
945 (compare:CC (match_dup 0)
948 [(set_attr "type" "exts")
949 (set_attr "dot" "yes")
950 (set_attr "length" "4,8")])
953 (define_expand "extendhi<mode>2"
954 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
955 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
959 (define_insn "*extendhi<mode>2"
960 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
961 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
962 "rs6000_gen_cell_microcode"
968 [(set_attr "type" "load,exts,fpload,vecperm")
969 (set_attr "sign_extend" "yes")
970 (set_attr "length" "4,4,8,4")])
973 [(set (match_operand:EXTHI 0 "altivec_register_operand")
975 (match_operand:HI 1 "indexed_or_indirect_operand")))]
976 "TARGET_P9_VECTOR && reload_completed"
980 (sign_extend:EXTHI (match_dup 2)))]
982 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));
985 (define_insn "*extendhi<mode>2_noload"
986 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
987 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
988 "!rs6000_gen_cell_microcode"
990 [(set_attr "type" "exts")])
992 (define_insn_and_split "*extendhi<mode>2_dot"
993 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
994 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
996 (clobber (match_scratch:EXTHI 0 "=r,r"))]
997 "rs6000_gen_cell_microcode"
1001 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1003 (sign_extend:EXTHI (match_dup 1)))
1005 (compare:CC (match_dup 0)
1008 [(set_attr "type" "exts")
1009 (set_attr "dot" "yes")
1010 (set_attr "length" "4,8")])
1012 (define_insn_and_split "*extendhi<mode>2_dot2"
1013 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1014 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1016 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1017 (sign_extend:EXTHI (match_dup 1)))]
1018 "rs6000_gen_cell_microcode"
1022 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1024 (sign_extend:EXTHI (match_dup 1)))
1026 (compare:CC (match_dup 0)
1029 [(set_attr "type" "exts")
1030 (set_attr "dot" "yes")
1031 (set_attr "length" "4,8")])
1034 (define_insn "extendsi<mode>2"
1035 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK")
1036 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK")))]
1045 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts")
1046 (set_attr "sign_extend" "yes")])
1048 (define_insn_and_split "*extendsi<mode>2_dot"
1049 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1050 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1052 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1053 "rs6000_gen_cell_microcode"
1057 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1059 (sign_extend:EXTSI (match_dup 1)))
1061 (compare:CC (match_dup 0)
1064 [(set_attr "type" "exts")
1065 (set_attr "dot" "yes")
1066 (set_attr "length" "4,8")])
1068 (define_insn_and_split "*extendsi<mode>2_dot2"
1069 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1070 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1072 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1073 (sign_extend:EXTSI (match_dup 1)))]
1074 "rs6000_gen_cell_microcode"
1078 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1080 (sign_extend:EXTSI (match_dup 1)))
1082 (compare:CC (match_dup 0)
1085 [(set_attr "type" "exts")
1086 (set_attr "dot" "yes")
1087 (set_attr "length" "4,8")])
1089 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1091 (define_insn "*macchwc"
1092 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1093 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1094 (match_operand:SI 2 "gpc_reg_operand" "r")
1097 (match_operand:HI 1 "gpc_reg_operand" "r")))
1098 (match_operand:SI 4 "gpc_reg_operand" "0"))
1100 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1101 (plus:SI (mult:SI (ashiftrt:SI
1109 [(set_attr "type" "halfmul")])
1111 (define_insn "*macchw"
1112 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1113 (plus:SI (mult:SI (ashiftrt:SI
1114 (match_operand:SI 2 "gpc_reg_operand" "r")
1117 (match_operand:HI 1 "gpc_reg_operand" "r")))
1118 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1121 [(set_attr "type" "halfmul")])
1123 (define_insn "*macchwuc"
1124 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1125 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1126 (match_operand:SI 2 "gpc_reg_operand" "r")
1129 (match_operand:HI 1 "gpc_reg_operand" "r")))
1130 (match_operand:SI 4 "gpc_reg_operand" "0"))
1132 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1133 (plus:SI (mult:SI (lshiftrt:SI
1141 [(set_attr "type" "halfmul")])
1143 (define_insn "*macchwu"
1144 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1145 (plus:SI (mult:SI (lshiftrt:SI
1146 (match_operand:SI 2 "gpc_reg_operand" "r")
1149 (match_operand:HI 1 "gpc_reg_operand" "r")))
1150 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1153 [(set_attr "type" "halfmul")])
1155 (define_insn "*machhwc"
1156 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1157 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1158 (match_operand:SI 1 "gpc_reg_operand" "%r")
1161 (match_operand:SI 2 "gpc_reg_operand" "r")
1163 (match_operand:SI 4 "gpc_reg_operand" "0"))
1165 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1166 (plus:SI (mult:SI (ashiftrt:SI
1175 [(set_attr "type" "halfmul")])
1177 (define_insn "*machhw"
1178 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1179 (plus:SI (mult:SI (ashiftrt:SI
1180 (match_operand:SI 1 "gpc_reg_operand" "%r")
1183 (match_operand:SI 2 "gpc_reg_operand" "r")
1185 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1188 [(set_attr "type" "halfmul")])
1190 (define_insn "*machhwuc"
1191 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1192 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1193 (match_operand:SI 1 "gpc_reg_operand" "%r")
1196 (match_operand:SI 2 "gpc_reg_operand" "r")
1198 (match_operand:SI 4 "gpc_reg_operand" "0"))
1200 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1201 (plus:SI (mult:SI (lshiftrt:SI
1210 [(set_attr "type" "halfmul")])
1212 (define_insn "*machhwu"
1213 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1214 (plus:SI (mult:SI (lshiftrt:SI
1215 (match_operand:SI 1 "gpc_reg_operand" "%r")
1218 (match_operand:SI 2 "gpc_reg_operand" "r")
1220 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1223 [(set_attr "type" "halfmul")])
1225 (define_insn "*maclhwc"
1226 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1227 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1228 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1230 (match_operand:HI 2 "gpc_reg_operand" "r")))
1231 (match_operand:SI 4 "gpc_reg_operand" "0"))
1233 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1234 (plus:SI (mult:SI (sign_extend:SI
1241 [(set_attr "type" "halfmul")])
1243 (define_insn "*maclhw"
1244 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1245 (plus:SI (mult:SI (sign_extend:SI
1246 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1248 (match_operand:HI 2 "gpc_reg_operand" "r")))
1249 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1252 [(set_attr "type" "halfmul")])
1254 (define_insn "*maclhwuc"
1255 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1256 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1257 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1259 (match_operand:HI 2 "gpc_reg_operand" "r")))
1260 (match_operand:SI 4 "gpc_reg_operand" "0"))
1262 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1263 (plus:SI (mult:SI (zero_extend:SI
1270 [(set_attr "type" "halfmul")])
1272 (define_insn "*maclhwu"
1273 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1274 (plus:SI (mult:SI (zero_extend:SI
1275 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1277 (match_operand:HI 2 "gpc_reg_operand" "r")))
1278 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1281 [(set_attr "type" "halfmul")])
1283 (define_insn "*nmacchwc"
1284 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1285 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1286 (mult:SI (ashiftrt:SI
1287 (match_operand:SI 2 "gpc_reg_operand" "r")
1290 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1292 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1293 (minus:SI (match_dup 4)
1294 (mult:SI (ashiftrt:SI
1301 [(set_attr "type" "halfmul")])
1303 (define_insn "*nmacchw"
1304 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1305 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1306 (mult:SI (ashiftrt:SI
1307 (match_operand:SI 2 "gpc_reg_operand" "r")
1310 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1313 [(set_attr "type" "halfmul")])
1315 (define_insn "*nmachhwc"
1316 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1317 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1318 (mult:SI (ashiftrt:SI
1319 (match_operand:SI 1 "gpc_reg_operand" "%r")
1322 (match_operand:SI 2 "gpc_reg_operand" "r")
1325 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1326 (minus:SI (match_dup 4)
1327 (mult:SI (ashiftrt:SI
1335 [(set_attr "type" "halfmul")])
1337 (define_insn "*nmachhw"
1338 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1339 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1340 (mult:SI (ashiftrt:SI
1341 (match_operand:SI 1 "gpc_reg_operand" "%r")
1344 (match_operand:SI 2 "gpc_reg_operand" "r")
1348 [(set_attr "type" "halfmul")])
1350 (define_insn "*nmaclhwc"
1351 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1352 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1353 (mult:SI (sign_extend:SI
1354 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1356 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1358 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1359 (minus:SI (match_dup 4)
1360 (mult:SI (sign_extend:SI
1366 [(set_attr "type" "halfmul")])
1368 (define_insn "*nmaclhw"
1369 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1370 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1371 (mult:SI (sign_extend:SI
1372 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1374 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1377 [(set_attr "type" "halfmul")])
1379 (define_insn "*mulchwc"
1380 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1381 (compare:CC (mult:SI (ashiftrt:SI
1382 (match_operand:SI 2 "gpc_reg_operand" "r")
1385 (match_operand:HI 1 "gpc_reg_operand" "r")))
1387 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1388 (mult:SI (ashiftrt:SI
1395 [(set_attr "type" "halfmul")])
1397 (define_insn "*mulchw"
1398 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1399 (mult:SI (ashiftrt:SI
1400 (match_operand:SI 2 "gpc_reg_operand" "r")
1403 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1406 [(set_attr "type" "halfmul")])
1408 (define_insn "*mulchwuc"
1409 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1410 (compare:CC (mult:SI (lshiftrt:SI
1411 (match_operand:SI 2 "gpc_reg_operand" "r")
1414 (match_operand:HI 1 "gpc_reg_operand" "r")))
1416 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1417 (mult:SI (lshiftrt:SI
1424 [(set_attr "type" "halfmul")])
1426 (define_insn "*mulchwu"
1427 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1428 (mult:SI (lshiftrt:SI
1429 (match_operand:SI 2 "gpc_reg_operand" "r")
1432 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1435 [(set_attr "type" "halfmul")])
1437 (define_insn "*mulhhwc"
1438 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1439 (compare:CC (mult:SI (ashiftrt:SI
1440 (match_operand:SI 1 "gpc_reg_operand" "%r")
1443 (match_operand:SI 2 "gpc_reg_operand" "r")
1446 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1447 (mult:SI (ashiftrt:SI
1455 [(set_attr "type" "halfmul")])
1457 (define_insn "*mulhhw"
1458 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1459 (mult:SI (ashiftrt:SI
1460 (match_operand:SI 1 "gpc_reg_operand" "%r")
1463 (match_operand:SI 2 "gpc_reg_operand" "r")
1467 [(set_attr "type" "halfmul")])
1469 (define_insn "*mulhhwuc"
1470 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1471 (compare:CC (mult:SI (lshiftrt:SI
1472 (match_operand:SI 1 "gpc_reg_operand" "%r")
1475 (match_operand:SI 2 "gpc_reg_operand" "r")
1478 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1479 (mult:SI (lshiftrt:SI
1487 [(set_attr "type" "halfmul")])
1489 (define_insn "*mulhhwu"
1490 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1491 (mult:SI (lshiftrt:SI
1492 (match_operand:SI 1 "gpc_reg_operand" "%r")
1495 (match_operand:SI 2 "gpc_reg_operand" "r")
1499 [(set_attr "type" "halfmul")])
1501 (define_insn "*mullhwc"
1502 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1503 (compare:CC (mult:SI (sign_extend:SI
1504 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1506 (match_operand:HI 2 "gpc_reg_operand" "r")))
1508 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1509 (mult:SI (sign_extend:SI
1515 [(set_attr "type" "halfmul")])
1517 (define_insn "*mullhw"
1518 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1519 (mult:SI (sign_extend:SI
1520 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1522 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1525 [(set_attr "type" "halfmul")])
1527 (define_insn "*mullhwuc"
1528 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1529 (compare:CC (mult:SI (zero_extend:SI
1530 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1532 (match_operand:HI 2 "gpc_reg_operand" "r")))
1534 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1535 (mult:SI (zero_extend:SI
1541 [(set_attr "type" "halfmul")])
1543 (define_insn "*mullhwu"
1544 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1545 (mult:SI (zero_extend:SI
1546 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1548 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1551 [(set_attr "type" "halfmul")])
1553 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1554 (define_insn "dlmzb"
1555 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1556 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1557 (match_operand:SI 2 "gpc_reg_operand" "r")]
1559 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1560 (unspec:SI [(match_dup 1)
1566 (define_expand "strlensi"
1567 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1568 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1569 (match_operand:QI 2 "const_int_operand" "")
1570 (match_operand 3 "const_int_operand" "")]
1571 UNSPEC_DLMZB_STRLEN))
1572 (clobber (match_scratch:CC 4 "=x"))]
1573 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1575 rtx result = operands[0];
1576 rtx src = operands[1];
1577 rtx search_char = operands[2];
1578 rtx align = operands[3];
1579 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1580 rtx loop_label, end_label, mem, cr0, cond;
1581 if (search_char != const0_rtx
1582 || GET_CODE (align) != CONST_INT
1583 || INTVAL (align) < 8)
1585 word1 = gen_reg_rtx (SImode);
1586 word2 = gen_reg_rtx (SImode);
1587 scratch_dlmzb = gen_reg_rtx (SImode);
1588 scratch_string = gen_reg_rtx (Pmode);
1589 loop_label = gen_label_rtx ();
1590 end_label = gen_label_rtx ();
1591 addr = force_reg (Pmode, XEXP (src, 0));
1592 emit_move_insn (scratch_string, addr);
1593 emit_label (loop_label);
1594 mem = change_address (src, SImode, scratch_string);
1595 emit_move_insn (word1, mem);
1596 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1597 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1598 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1599 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1600 emit_jump_insn (gen_rtx_SET (pc_rtx,
1601 gen_rtx_IF_THEN_ELSE (VOIDmode,
1607 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1608 emit_jump_insn (gen_rtx_SET (pc_rtx,
1609 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1611 emit_label (end_label);
1612 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1613 emit_insn (gen_subsi3 (result, scratch_string, addr));
1614 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1618 ;; Fixed-point arithmetic insns.
1620 (define_expand "add<mode>3"
1621 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1622 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1623 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1626 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1628 rtx lo0 = gen_lowpart (SImode, operands[0]);
1629 rtx lo1 = gen_lowpart (SImode, operands[1]);
1630 rtx lo2 = gen_lowpart (SImode, operands[2]);
1631 rtx hi0 = gen_highpart (SImode, operands[0]);
1632 rtx hi1 = gen_highpart (SImode, operands[1]);
1633 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1635 if (!reg_or_short_operand (lo2, SImode))
1636 lo2 = force_reg (SImode, lo2);
1637 if (!adde_operand (hi2, SImode))
1638 hi2 = force_reg (SImode, hi2);
1640 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1641 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1645 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1647 rtx tmp = ((!can_create_pseudo_p ()
1648 || rtx_equal_p (operands[0], operands[1]))
1649 ? operands[0] : gen_reg_rtx (<MODE>mode));
1651 HOST_WIDE_INT val = INTVAL (operands[2]);
1652 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1653 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1655 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1658 /* The ordering here is important for the prolog expander.
1659 When space is allocated from the stack, adding 'low' first may
1660 produce a temporary deallocation (which would be bad). */
1661 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1662 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1667 (define_insn "*add<mode>3"
1668 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1669 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1670 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1676 [(set_attr "type" "add")])
1678 (define_insn "addsi3_high"
1679 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1680 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1681 (high:SI (match_operand 2 "" ""))))]
1682 "TARGET_MACHO && !TARGET_64BIT"
1683 "addis %0,%1,ha16(%2)"
1684 [(set_attr "type" "add")])
1686 (define_insn_and_split "*add<mode>3_dot"
1687 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1688 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1689 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1691 (clobber (match_scratch:GPR 0 "=r,r"))]
1692 "<MODE>mode == Pmode"
1696 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1698 (plus:GPR (match_dup 1)
1701 (compare:CC (match_dup 0)
1704 [(set_attr "type" "add")
1705 (set_attr "dot" "yes")
1706 (set_attr "length" "4,8")])
1708 (define_insn_and_split "*add<mode>3_dot2"
1709 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1710 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1711 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1713 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1714 (plus:GPR (match_dup 1)
1716 "<MODE>mode == Pmode"
1720 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1722 (plus:GPR (match_dup 1)
1725 (compare:CC (match_dup 0)
1728 [(set_attr "type" "add")
1729 (set_attr "dot" "yes")
1730 (set_attr "length" "4,8")])
1732 (define_insn_and_split "*add<mode>3_imm_dot"
1733 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1734 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1735 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1737 (clobber (match_scratch:GPR 0 "=r,r"))
1738 (clobber (reg:GPR CA_REGNO))]
1739 "<MODE>mode == Pmode"
1743 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1745 (plus:GPR (match_dup 1)
1748 (compare:CC (match_dup 0)
1751 [(set_attr "type" "add")
1752 (set_attr "dot" "yes")
1753 (set_attr "length" "4,8")])
1755 (define_insn_and_split "*add<mode>3_imm_dot2"
1756 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1757 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1758 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1760 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1761 (plus:GPR (match_dup 1)
1763 (clobber (reg:GPR CA_REGNO))]
1764 "<MODE>mode == Pmode"
1768 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1770 (plus:GPR (match_dup 1)
1773 (compare:CC (match_dup 0)
1776 [(set_attr "type" "add")
1777 (set_attr "dot" "yes")
1778 (set_attr "length" "4,8")])
1780 ;; Split an add that we can't do in one insn into two insns, each of which
1781 ;; does one 16-bit part. This is used by combine. Note that the low-order
1782 ;; add should be last in case the result gets used in an address.
1785 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1786 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1787 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1789 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1790 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1792 HOST_WIDE_INT val = INTVAL (operands[2]);
1793 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1794 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1796 operands[4] = GEN_INT (low);
1797 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1798 operands[3] = GEN_INT (rest);
1799 else if (can_create_pseudo_p ())
1801 operands[3] = gen_reg_rtx (DImode);
1802 emit_move_insn (operands[3], operands[2]);
1803 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1811 (define_insn "add<mode>3_carry"
1812 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1813 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1814 (match_operand:P 2 "reg_or_short_operand" "rI")))
1815 (set (reg:P CA_REGNO)
1816 (ltu:P (plus:P (match_dup 1)
1821 [(set_attr "type" "add")])
1823 (define_insn "*add<mode>3_imm_carry_pos"
1824 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1825 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1826 (match_operand:P 2 "short_cint_operand" "n")))
1827 (set (reg:P CA_REGNO)
1828 (geu:P (match_dup 1)
1829 (match_operand:P 3 "const_int_operand" "n")))]
1830 "INTVAL (operands[2]) > 0
1831 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1833 [(set_attr "type" "add")])
1835 (define_insn "*add<mode>3_imm_carry_0"
1836 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1837 (match_operand:P 1 "gpc_reg_operand" "r"))
1838 (set (reg:P CA_REGNO)
1842 [(set_attr "type" "add")])
1844 (define_insn "*add<mode>3_imm_carry_m1"
1845 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1846 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1848 (set (reg:P CA_REGNO)
1853 [(set_attr "type" "add")])
1855 (define_insn "*add<mode>3_imm_carry_neg"
1856 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1857 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1858 (match_operand:P 2 "short_cint_operand" "n")))
1859 (set (reg:P CA_REGNO)
1860 (gtu:P (match_dup 1)
1861 (match_operand:P 3 "const_int_operand" "n")))]
1862 "INTVAL (operands[2]) < 0
1863 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1865 [(set_attr "type" "add")])
1868 (define_expand "add<mode>3_carry_in"
1870 (set (match_operand:GPR 0 "gpc_reg_operand")
1871 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1872 (match_operand:GPR 2 "adde_operand"))
1873 (reg:GPR CA_REGNO)))
1874 (clobber (reg:GPR CA_REGNO))])]
1877 if (operands[2] == const0_rtx)
1879 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1882 if (operands[2] == constm1_rtx)
1884 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1889 (define_insn "*add<mode>3_carry_in_internal"
1890 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1891 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1892 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1893 (reg:GPR CA_REGNO)))
1894 (clobber (reg:GPR CA_REGNO))]
1897 [(set_attr "type" "add")])
1899 (define_insn "add<mode>3_carry_in_0"
1900 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1901 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1902 (reg:GPR CA_REGNO)))
1903 (clobber (reg:GPR CA_REGNO))]
1906 [(set_attr "type" "add")])
1908 (define_insn "add<mode>3_carry_in_m1"
1909 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1910 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1913 (clobber (reg:GPR CA_REGNO))]
1916 [(set_attr "type" "add")])
1919 (define_expand "one_cmpl<mode>2"
1920 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1921 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1924 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1926 rs6000_split_logical (operands, NOT, false, false, false);
1931 (define_insn "*one_cmpl<mode>2"
1932 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1933 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1937 (define_insn_and_split "*one_cmpl<mode>2_dot"
1938 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1939 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1941 (clobber (match_scratch:GPR 0 "=r,r"))]
1942 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1946 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1948 (not:GPR (match_dup 1)))
1950 (compare:CC (match_dup 0)
1953 [(set_attr "type" "logical")
1954 (set_attr "dot" "yes")
1955 (set_attr "length" "4,8")])
1957 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1958 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1959 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1961 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1962 (not:GPR (match_dup 1)))]
1963 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1967 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1969 (not:GPR (match_dup 1)))
1971 (compare:CC (match_dup 0)
1974 [(set_attr "type" "logical")
1975 (set_attr "dot" "yes")
1976 (set_attr "length" "4,8")])
1979 (define_expand "sub<mode>3"
1980 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1981 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1982 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1985 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1987 rtx lo0 = gen_lowpart (SImode, operands[0]);
1988 rtx lo1 = gen_lowpart (SImode, operands[1]);
1989 rtx lo2 = gen_lowpart (SImode, operands[2]);
1990 rtx hi0 = gen_highpart (SImode, operands[0]);
1991 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1992 rtx hi2 = gen_highpart (SImode, operands[2]);
1994 if (!reg_or_short_operand (lo1, SImode))
1995 lo1 = force_reg (SImode, lo1);
1996 if (!adde_operand (hi1, SImode))
1997 hi1 = force_reg (SImode, hi1);
1999 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2000 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2004 if (short_cint_operand (operands[1], <MODE>mode))
2006 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2011 (define_insn "*subf<mode>3"
2012 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2013 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2014 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2017 [(set_attr "type" "add")])
2019 (define_insn_and_split "*subf<mode>3_dot"
2020 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2021 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2022 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2024 (clobber (match_scratch:GPR 0 "=r,r"))]
2025 "<MODE>mode == Pmode"
2029 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2031 (minus:GPR (match_dup 2)
2034 (compare:CC (match_dup 0)
2037 [(set_attr "type" "add")
2038 (set_attr "dot" "yes")
2039 (set_attr "length" "4,8")])
2041 (define_insn_and_split "*subf<mode>3_dot2"
2042 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2043 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2044 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2046 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2047 (minus:GPR (match_dup 2)
2049 "<MODE>mode == Pmode"
2053 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2055 (minus:GPR (match_dup 2)
2058 (compare:CC (match_dup 0)
2061 [(set_attr "type" "add")
2062 (set_attr "dot" "yes")
2063 (set_attr "length" "4,8")])
2065 (define_insn "subf<mode>3_imm"
2066 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2067 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2068 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2069 (clobber (reg:GPR CA_REGNO))]
2072 [(set_attr "type" "add")])
2075 (define_insn "subf<mode>3_carry"
2076 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2077 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2078 (match_operand:P 1 "gpc_reg_operand" "r")))
2079 (set (reg:P CA_REGNO)
2080 (leu:P (match_dup 1)
2084 [(set_attr "type" "add")])
2086 (define_insn "*subf<mode>3_imm_carry_0"
2087 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2088 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2089 (set (reg:P CA_REGNO)
2094 [(set_attr "type" "add")])
2096 (define_insn "*subf<mode>3_imm_carry_m1"
2097 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2098 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2099 (set (reg:P CA_REGNO)
2103 [(set_attr "type" "add")])
2106 (define_expand "subf<mode>3_carry_in"
2108 (set (match_operand:GPR 0 "gpc_reg_operand")
2109 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2111 (match_operand:GPR 2 "adde_operand")))
2112 (clobber (reg:GPR CA_REGNO))])]
2115 if (operands[2] == const0_rtx)
2117 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2120 if (operands[2] == constm1_rtx)
2122 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2127 (define_insn "*subf<mode>3_carry_in_internal"
2128 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2129 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2131 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2132 (clobber (reg:GPR CA_REGNO))]
2135 [(set_attr "type" "add")])
2137 (define_insn "subf<mode>3_carry_in_0"
2138 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2139 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2140 (reg:GPR CA_REGNO)))
2141 (clobber (reg:GPR CA_REGNO))]
2144 [(set_attr "type" "add")])
2146 (define_insn "subf<mode>3_carry_in_m1"
2147 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2148 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2149 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2151 (clobber (reg:GPR CA_REGNO))]
2154 [(set_attr "type" "add")])
2156 (define_insn "subf<mode>3_carry_in_xx"
2157 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2158 (plus:GPR (reg:GPR CA_REGNO)
2160 (clobber (reg:GPR CA_REGNO))]
2163 [(set_attr "type" "add")])
2166 (define_insn "neg<mode>2"
2167 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2168 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2171 [(set_attr "type" "add")])
2173 (define_insn_and_split "*neg<mode>2_dot"
2174 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2175 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2177 (clobber (match_scratch:GPR 0 "=r,r"))]
2178 "<MODE>mode == Pmode"
2182 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2184 (neg:GPR (match_dup 1)))
2186 (compare:CC (match_dup 0)
2189 [(set_attr "type" "add")
2190 (set_attr "dot" "yes")
2191 (set_attr "length" "4,8")])
2193 (define_insn_and_split "*neg<mode>2_dot2"
2194 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2195 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2197 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2198 (neg:GPR (match_dup 1)))]
2199 "<MODE>mode == Pmode"
2203 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2205 (neg:GPR (match_dup 1)))
2207 (compare:CC (match_dup 0)
2210 [(set_attr "type" "add")
2211 (set_attr "dot" "yes")
2212 (set_attr "length" "4,8")])
2215 (define_insn "clz<mode>2"
2216 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2217 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2220 [(set_attr "type" "cntlz")])
2222 (define_expand "ctz<mode>2"
2224 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2226 (and:GPR (match_dup 1)
2229 (clz:GPR (match_dup 3)))
2230 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2231 (minus:GPR (match_dup 5)
2233 (clobber (reg:GPR CA_REGNO))])]
2238 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2242 operands[2] = gen_reg_rtx (<MODE>mode);
2243 operands[3] = gen_reg_rtx (<MODE>mode);
2244 operands[4] = gen_reg_rtx (<MODE>mode);
2245 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2248 (define_insn "ctz<mode>2_hw"
2249 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2250 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2253 [(set_attr "type" "cntlz")])
2255 (define_expand "ffs<mode>2"
2257 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2259 (and:GPR (match_dup 1)
2262 (clz:GPR (match_dup 3)))
2263 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2264 (minus:GPR (match_dup 5)
2266 (clobber (reg:GPR CA_REGNO))])]
2269 operands[2] = gen_reg_rtx (<MODE>mode);
2270 operands[3] = gen_reg_rtx (<MODE>mode);
2271 operands[4] = gen_reg_rtx (<MODE>mode);
2272 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2276 (define_expand "popcount<mode>2"
2277 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2278 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2279 "TARGET_POPCNTB || TARGET_POPCNTD"
2281 rs6000_emit_popcount (operands[0], operands[1]);
2285 (define_insn "popcntb<mode>2"
2286 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2287 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2291 [(set_attr "type" "popcnt")])
2293 (define_insn "popcntd<mode>2"
2294 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2295 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2298 [(set_attr "type" "popcnt")])
2301 (define_expand "parity<mode>2"
2302 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2303 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2306 rs6000_emit_parity (operands[0], operands[1]);
2310 (define_insn "parity<mode>2_cmpb"
2311 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2312 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2313 "TARGET_CMPB && TARGET_POPCNTB"
2315 [(set_attr "type" "popcnt")])
2318 ;; Since the hardware zeros the upper part of the register, save generating the
2319 ;; AND immediate if we are converting to unsigned
2320 (define_insn "*bswaphi2_extenddi"
2321 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2323 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2326 [(set_attr "length" "4")
2327 (set_attr "type" "load")])
2329 (define_insn "*bswaphi2_extendsi"
2330 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2332 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2335 [(set_attr "length" "4")
2336 (set_attr "type" "load")])
2338 (define_expand "bswaphi2"
2339 [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2341 (match_operand:HI 1 "reg_or_mem_operand" "")))
2342 (clobber (match_scratch:SI 2 ""))])]
2345 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2346 operands[1] = force_reg (HImode, operands[1]);
2349 (define_insn "bswaphi2_internal"
2350 [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2352 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2353 (clobber (match_scratch:SI 2 "=X,X,&r"))]
2359 [(set_attr "length" "4,4,12")
2360 (set_attr "type" "load,store,*")])
2363 [(set (match_operand:HI 0 "gpc_reg_operand" "")
2364 (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2365 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2368 (and:SI (lshiftrt:SI (match_dup 4)
2372 (and:SI (ashift:SI (match_dup 4)
2374 (const_int 65280))) ;; 0xff00
2376 (ior:SI (match_dup 3)
2380 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2381 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2384 (define_insn "*bswapsi2_extenddi"
2385 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2387 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2390 [(set_attr "length" "4")
2391 (set_attr "type" "load")])
2393 (define_expand "bswapsi2"
2394 [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2396 (match_operand:SI 1 "reg_or_mem_operand" "")))]
2399 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2400 operands[1] = force_reg (SImode, operands[1]);
2403 (define_insn "*bswapsi2_internal"
2404 [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2406 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2412 [(set_attr "length" "4,4,12")
2413 (set_attr "type" "load,store,*")])
2415 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2416 ;; zero_extract insns do not change for -mlittle.
2418 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2419 (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2421 [(set (match_dup 0) ; DABC
2422 (rotate:SI (match_dup 1)
2424 (set (match_dup 0) ; DCBC
2425 (ior:SI (and:SI (ashift:SI (match_dup 1)
2427 (const_int 16711680))
2428 (and:SI (match_dup 0)
2429 (const_int -16711681))))
2430 (set (match_dup 0) ; DCBA
2431 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2434 (and:SI (match_dup 0)
2440 (define_expand "bswapdi2"
2441 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2443 (match_operand:DI 1 "reg_or_mem_operand" "")))
2444 (clobber (match_scratch:DI 2 ""))
2445 (clobber (match_scratch:DI 3 ""))])]
2448 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2449 operands[1] = force_reg (DImode, operands[1]);
2451 if (!TARGET_POWERPC64)
2453 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2454 that uses 64-bit registers needs the same scratch registers as 64-bit
2456 emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2461 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2462 (define_insn "*bswapdi2_ldbrx"
2463 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2464 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2465 (clobber (match_scratch:DI 2 "=X,X,&r"))
2466 (clobber (match_scratch:DI 3 "=X,X,&r"))]
2467 "TARGET_POWERPC64 && TARGET_LDBRX
2468 && (REG_P (operands[0]) || REG_P (operands[1]))"
2473 [(set_attr "length" "4,4,36")
2474 (set_attr "type" "load,store,*")])
2476 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2477 (define_insn "*bswapdi2_64bit"
2478 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2479 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2480 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2481 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2482 "TARGET_POWERPC64 && !TARGET_LDBRX
2483 && (REG_P (operands[0]) || REG_P (operands[1]))
2484 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2485 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2487 [(set_attr "length" "16,12,36")])
2490 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2491 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2492 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2493 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2494 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2498 rtx dest = operands[0];
2499 rtx src = operands[1];
2500 rtx op2 = operands[2];
2501 rtx op3 = operands[3];
2502 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2503 BYTES_BIG_ENDIAN ? 4 : 0);
2504 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2505 BYTES_BIG_ENDIAN ? 4 : 0);
2511 addr1 = XEXP (src, 0);
2512 if (GET_CODE (addr1) == PLUS)
2514 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2515 if (TARGET_AVOID_XFORM)
2517 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2521 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2523 else if (TARGET_AVOID_XFORM)
2525 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2530 emit_move_insn (op2, GEN_INT (4));
2531 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2534 word1 = change_address (src, SImode, addr1);
2535 word2 = change_address (src, SImode, addr2);
2537 if (BYTES_BIG_ENDIAN)
2539 emit_insn (gen_bswapsi2 (op3_32, word2));
2540 emit_insn (gen_bswapsi2 (dest_32, word1));
2544 emit_insn (gen_bswapsi2 (op3_32, word1));
2545 emit_insn (gen_bswapsi2 (dest_32, word2));
2548 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2549 emit_insn (gen_iordi3 (dest, dest, op3));
2554 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2555 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2556 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2557 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2558 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2562 rtx dest = operands[0];
2563 rtx src = operands[1];
2564 rtx op2 = operands[2];
2565 rtx op3 = operands[3];
2566 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2567 BYTES_BIG_ENDIAN ? 4 : 0);
2568 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2569 BYTES_BIG_ENDIAN ? 4 : 0);
2575 addr1 = XEXP (dest, 0);
2576 if (GET_CODE (addr1) == PLUS)
2578 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2579 if (TARGET_AVOID_XFORM)
2581 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2585 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2587 else if (TARGET_AVOID_XFORM)
2589 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2594 emit_move_insn (op2, GEN_INT (4));
2595 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2598 word1 = change_address (dest, SImode, addr1);
2599 word2 = change_address (dest, SImode, addr2);
2601 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2603 if (BYTES_BIG_ENDIAN)
2605 emit_insn (gen_bswapsi2 (word1, src_si));
2606 emit_insn (gen_bswapsi2 (word2, op3_si));
2610 emit_insn (gen_bswapsi2 (word2, src_si));
2611 emit_insn (gen_bswapsi2 (word1, op3_si));
2617 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2618 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2619 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2620 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2621 "TARGET_POWERPC64 && reload_completed"
2625 rtx dest = operands[0];
2626 rtx src = operands[1];
2627 rtx op2 = operands[2];
2628 rtx op3 = operands[3];
2629 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2630 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2631 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2632 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2633 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2635 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2636 emit_insn (gen_bswapsi2 (dest_si, src_si));
2637 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2638 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2639 emit_insn (gen_iordi3 (dest, dest, op3));
2643 (define_insn "bswapdi2_32bit"
2644 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2645 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2646 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2647 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2649 [(set_attr "length" "16,12,36")])
2652 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2653 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2654 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2655 "!TARGET_POWERPC64 && reload_completed"
2659 rtx dest = operands[0];
2660 rtx src = operands[1];
2661 rtx op2 = operands[2];
2662 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2663 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2669 addr1 = XEXP (src, 0);
2670 if (GET_CODE (addr1) == PLUS)
2672 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2673 if (TARGET_AVOID_XFORM
2674 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2676 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2680 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2682 else if (TARGET_AVOID_XFORM
2683 || REGNO (addr1) == REGNO (dest2))
2685 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2690 emit_move_insn (op2, GEN_INT (4));
2691 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2694 word1 = change_address (src, SImode, addr1);
2695 word2 = change_address (src, SImode, addr2);
2697 emit_insn (gen_bswapsi2 (dest2, word1));
2698 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2699 thus allowing us to omit an early clobber on the output. */
2700 emit_insn (gen_bswapsi2 (dest1, word2));
2705 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2706 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2707 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2708 "!TARGET_POWERPC64 && reload_completed"
2712 rtx dest = operands[0];
2713 rtx src = operands[1];
2714 rtx op2 = operands[2];
2715 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2716 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2722 addr1 = XEXP (dest, 0);
2723 if (GET_CODE (addr1) == PLUS)
2725 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2726 if (TARGET_AVOID_XFORM)
2728 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2732 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2734 else if (TARGET_AVOID_XFORM)
2736 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2741 emit_move_insn (op2, GEN_INT (4));
2742 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2745 word1 = change_address (dest, SImode, addr1);
2746 word2 = change_address (dest, SImode, addr2);
2748 emit_insn (gen_bswapsi2 (word2, src1));
2749 emit_insn (gen_bswapsi2 (word1, src2));
2754 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2755 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2756 (clobber (match_operand:SI 2 "" ""))]
2757 "!TARGET_POWERPC64 && reload_completed"
2761 rtx dest = operands[0];
2762 rtx src = operands[1];
2763 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2764 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2765 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2766 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2768 emit_insn (gen_bswapsi2 (dest1, src2));
2769 emit_insn (gen_bswapsi2 (dest2, src1));
2774 (define_insn "mul<mode>3"
2775 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2776 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2777 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2782 [(set_attr "type" "mul")
2784 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2786 (match_operand:GPR 2 "short_cint_operand" "")
2787 (const_string "16")]
2788 (const_string "<bits>")))])
2790 (define_insn_and_split "*mul<mode>3_dot"
2791 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2792 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2793 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2795 (clobber (match_scratch:GPR 0 "=r,r"))]
2796 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2800 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2802 (mult:GPR (match_dup 1)
2805 (compare:CC (match_dup 0)
2808 [(set_attr "type" "mul")
2809 (set_attr "size" "<bits>")
2810 (set_attr "dot" "yes")
2811 (set_attr "length" "4,8")])
2813 (define_insn_and_split "*mul<mode>3_dot2"
2814 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2815 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2816 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2818 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2819 (mult:GPR (match_dup 1)
2821 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2825 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2827 (mult:GPR (match_dup 1)
2830 (compare:CC (match_dup 0)
2833 [(set_attr "type" "mul")
2834 (set_attr "size" "<bits>")
2835 (set_attr "dot" "yes")
2836 (set_attr "length" "4,8")])
2839 (define_expand "<su>mul<mode>3_highpart"
2840 [(set (match_operand:GPR 0 "gpc_reg_operand")
2842 (mult:<DMODE> (any_extend:<DMODE>
2843 (match_operand:GPR 1 "gpc_reg_operand"))
2845 (match_operand:GPR 2 "gpc_reg_operand")))
2849 if (<MODE>mode == SImode && TARGET_POWERPC64)
2851 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2856 if (!WORDS_BIG_ENDIAN)
2858 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2864 (define_insn "*<su>mul<mode>3_highpart"
2865 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2867 (mult:<DMODE> (any_extend:<DMODE>
2868 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2870 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2872 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2873 "mulh<wd><u> %0,%1,%2"
2874 [(set_attr "type" "mul")
2875 (set_attr "size" "<bits>")])
2877 (define_insn "<su>mulsi3_highpart_le"
2878 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2880 (mult:DI (any_extend:DI
2881 (match_operand:SI 1 "gpc_reg_operand" "r"))
2883 (match_operand:SI 2 "gpc_reg_operand" "r")))
2885 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2887 [(set_attr "type" "mul")])
2889 (define_insn "<su>muldi3_highpart_le"
2890 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2892 (mult:TI (any_extend:TI
2893 (match_operand:DI 1 "gpc_reg_operand" "r"))
2895 (match_operand:DI 2 "gpc_reg_operand" "r")))
2897 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2899 [(set_attr "type" "mul")
2900 (set_attr "size" "64")])
2902 (define_insn "<su>mulsi3_highpart_64"
2903 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2906 (mult:DI (any_extend:DI
2907 (match_operand:SI 1 "gpc_reg_operand" "r"))
2909 (match_operand:SI 2 "gpc_reg_operand" "r")))
2913 [(set_attr "type" "mul")])
2915 (define_expand "<u>mul<mode><dmode>3"
2916 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2917 (mult:<DMODE> (any_extend:<DMODE>
2918 (match_operand:GPR 1 "gpc_reg_operand"))
2920 (match_operand:GPR 2 "gpc_reg_operand"))))]
2921 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2923 rtx l = gen_reg_rtx (<MODE>mode);
2924 rtx h = gen_reg_rtx (<MODE>mode);
2925 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2926 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2927 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2928 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2932 (define_insn "*maddld4"
2933 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2934 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2935 (match_operand:DI 2 "gpc_reg_operand" "r"))
2936 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2938 "maddld %0,%1,%2,%3"
2939 [(set_attr "type" "mul")])
2941 (define_insn "udiv<mode>3"
2942 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2943 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2944 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2947 [(set_attr "type" "div")
2948 (set_attr "size" "<bits>")])
2951 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2952 ;; modulus. If it isn't a power of two, force operands into register and do
2954 (define_expand "div<mode>3"
2955 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2956 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2957 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2960 if (CONST_INT_P (operands[2])
2961 && INTVAL (operands[2]) > 0
2962 && exact_log2 (INTVAL (operands[2])) >= 0)
2964 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2968 operands[2] = force_reg (<MODE>mode, operands[2]);
2971 (define_insn "*div<mode>3"
2972 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2973 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2974 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2977 [(set_attr "type" "div")
2978 (set_attr "size" "<bits>")])
2980 (define_insn "div<mode>3_sra"
2981 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2982 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2983 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2984 (clobber (reg:GPR CA_REGNO))]
2986 "sra<wd>i %0,%1,%p2\;addze %0,%0"
2987 [(set_attr "type" "two")
2988 (set_attr "length" "8")])
2990 (define_insn_and_split "*div<mode>3_sra_dot"
2991 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2992 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2993 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2995 (clobber (match_scratch:GPR 0 "=r,r"))
2996 (clobber (reg:GPR CA_REGNO))]
2997 "<MODE>mode == Pmode"
2999 sra<wd>i %0,%1,%p2\;addze. %0,%0
3001 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3002 [(parallel [(set (match_dup 0)
3003 (div:GPR (match_dup 1)
3005 (clobber (reg:GPR CA_REGNO))])
3007 (compare:CC (match_dup 0)
3010 [(set_attr "type" "two")
3011 (set_attr "length" "8,12")
3012 (set_attr "cell_micro" "not")])
3014 (define_insn_and_split "*div<mode>3_sra_dot2"
3015 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3016 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3017 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3019 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3020 (div:GPR (match_dup 1)
3022 (clobber (reg:GPR CA_REGNO))]
3023 "<MODE>mode == Pmode"
3025 sra<wd>i %0,%1,%p2\;addze. %0,%0
3027 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3028 [(parallel [(set (match_dup 0)
3029 (div:GPR (match_dup 1)
3031 (clobber (reg:GPR CA_REGNO))])
3033 (compare:CC (match_dup 0)
3036 [(set_attr "type" "two")
3037 (set_attr "length" "8,12")
3038 (set_attr "cell_micro" "not")])
3040 (define_expand "mod<mode>3"
3041 [(set (match_operand:GPR 0 "gpc_reg_operand")
3042 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3043 (match_operand:GPR 2 "reg_or_cint_operand")))]
3050 if (GET_CODE (operands[2]) != CONST_INT
3051 || INTVAL (operands[2]) <= 0
3052 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3057 operands[2] = force_reg (<MODE>mode, operands[2]);
3061 temp1 = gen_reg_rtx (<MODE>mode);
3062 temp2 = gen_reg_rtx (<MODE>mode);
3064 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3065 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3066 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3071 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3072 ;; mod, prefer putting the result of mod into a different register
3073 (define_insn "*mod<mode>3"
3074 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3075 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3076 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3079 [(set_attr "type" "div")
3080 (set_attr "size" "<bits>")])
3083 (define_insn "umod<mode>3"
3084 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3085 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3086 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3089 [(set_attr "type" "div")
3090 (set_attr "size" "<bits>")])
3092 ;; On machines with modulo support, do a combined div/mod the old fashioned
3093 ;; method, since the multiply/subtract is faster than doing the mod instruction
3097 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3098 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3099 (match_operand:GPR 2 "gpc_reg_operand" "")))
3100 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3101 (mod:GPR (match_dup 1)
3104 && ! reg_mentioned_p (operands[0], operands[1])
3105 && ! reg_mentioned_p (operands[0], operands[2])
3106 && ! reg_mentioned_p (operands[3], operands[1])
3107 && ! reg_mentioned_p (operands[3], operands[2])"
3109 (div:GPR (match_dup 1)
3112 (mult:GPR (match_dup 0)
3115 (minus:GPR (match_dup 1)
3119 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3120 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3121 (match_operand:GPR 2 "gpc_reg_operand" "")))
3122 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3123 (umod:GPR (match_dup 1)
3126 && ! reg_mentioned_p (operands[0], operands[1])
3127 && ! reg_mentioned_p (operands[0], operands[2])
3128 && ! reg_mentioned_p (operands[3], operands[1])
3129 && ! reg_mentioned_p (operands[3], operands[2])"
3131 (div:GPR (match_dup 1)
3134 (mult:GPR (match_dup 0)
3137 (minus:GPR (match_dup 1)
3141 ;; Logical instructions
3142 ;; The logical instructions are mostly combined by using match_operator,
3143 ;; but the plain AND insns are somewhat different because there is no
3144 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3145 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3147 (define_expand "and<mode>3"
3148 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3149 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3150 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3153 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3155 rs6000_split_logical (operands, AND, false, false, false);
3159 if (CONST_INT_P (operands[2]))
3161 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3163 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3167 if (logical_const_operand (operands[2], <MODE>mode)
3168 && rs6000_gen_cell_microcode)
3170 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3174 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3176 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3180 operands[2] = force_reg (<MODE>mode, operands[2]);
3185 (define_insn "and<mode>3_imm"
3186 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3187 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3188 (match_operand:GPR 2 "logical_const_operand" "n")))
3189 (clobber (match_scratch:CC 3 "=x"))]
3190 "rs6000_gen_cell_microcode
3191 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3192 "andi%e2. %0,%1,%u2"
3193 [(set_attr "type" "logical")
3194 (set_attr "dot" "yes")])
3196 (define_insn_and_split "*and<mode>3_imm_dot"
3197 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3198 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3199 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3201 (clobber (match_scratch:GPR 0 "=r,r"))
3202 (clobber (match_scratch:CC 4 "=X,x"))]
3203 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3204 && rs6000_gen_cell_microcode
3205 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3209 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3210 [(parallel [(set (match_dup 0)
3211 (and:GPR (match_dup 1)
3213 (clobber (match_dup 4))])
3215 (compare:CC (match_dup 0)
3218 [(set_attr "type" "logical")
3219 (set_attr "dot" "yes")
3220 (set_attr "length" "4,8")])
3222 (define_insn_and_split "*and<mode>3_imm_dot2"
3223 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3224 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3225 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3227 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3228 (and:GPR (match_dup 1)
3230 (clobber (match_scratch:CC 4 "=X,x"))]
3231 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3232 && rs6000_gen_cell_microcode
3233 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3237 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3238 [(parallel [(set (match_dup 0)
3239 (and:GPR (match_dup 1)
3241 (clobber (match_dup 4))])
3243 (compare:CC (match_dup 0)
3246 [(set_attr "type" "logical")
3247 (set_attr "dot" "yes")
3248 (set_attr "length" "4,8")])
3250 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3251 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3252 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3253 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3255 (clobber (match_scratch:GPR 0 "=r,r"))]
3256 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3257 && rs6000_gen_cell_microcode"
3261 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3263 (and:GPR (match_dup 1)
3266 (compare:CC (match_dup 0)
3269 [(set_attr "type" "logical")
3270 (set_attr "dot" "yes")
3271 (set_attr "length" "4,8")])
3273 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3274 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3275 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3276 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3278 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3279 (and:GPR (match_dup 1)
3281 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3282 && rs6000_gen_cell_microcode"
3286 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3288 (and:GPR (match_dup 1)
3291 (compare:CC (match_dup 0)
3294 [(set_attr "type" "logical")
3295 (set_attr "dot" "yes")
3296 (set_attr "length" "4,8")])
3298 (define_insn "*and<mode>3_imm_dot_shifted"
3299 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3302 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3303 (match_operand:SI 4 "const_int_operand" "n"))
3304 (match_operand:GPR 2 "const_int_operand" "n"))
3306 (clobber (match_scratch:GPR 0 "=r"))]
3307 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3308 << INTVAL (operands[4])),
3310 && (<MODE>mode == Pmode
3311 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3312 && rs6000_gen_cell_microcode"
3314 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3315 return "andi%e2. %0,%1,%u2";
3317 [(set_attr "type" "logical")
3318 (set_attr "dot" "yes")])
3321 (define_insn "and<mode>3_mask"
3322 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3323 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3324 (match_operand:GPR 2 "const_int_operand" "n")))]
3325 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3327 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3329 [(set_attr "type" "shift")])
3331 (define_insn_and_split "*and<mode>3_mask_dot"
3332 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3333 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3334 (match_operand:GPR 2 "const_int_operand" "n,n"))
3336 (clobber (match_scratch:GPR 0 "=r,r"))]
3337 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3338 && rs6000_gen_cell_microcode
3339 && !logical_const_operand (operands[2], <MODE>mode)
3340 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3342 if (which_alternative == 0)
3343 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3347 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3349 (and:GPR (match_dup 1)
3352 (compare:CC (match_dup 0)
3355 [(set_attr "type" "shift")
3356 (set_attr "dot" "yes")
3357 (set_attr "length" "4,8")])
3359 (define_insn_and_split "*and<mode>3_mask_dot2"
3360 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3361 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3362 (match_operand:GPR 2 "const_int_operand" "n,n"))
3364 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3365 (and:GPR (match_dup 1)
3367 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3368 && rs6000_gen_cell_microcode
3369 && !logical_const_operand (operands[2], <MODE>mode)
3370 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3372 if (which_alternative == 0)
3373 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3377 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3379 (and:GPR (match_dup 1)
3382 (compare:CC (match_dup 0)
3385 [(set_attr "type" "shift")
3386 (set_attr "dot" "yes")
3387 (set_attr "length" "4,8")])
3390 (define_insn_and_split "*and<mode>3_2insn"
3391 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3392 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3393 (match_operand:GPR 2 "const_int_operand" "n")))]
3394 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3395 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3396 || (logical_const_operand (operands[2], <MODE>mode)
3397 && rs6000_gen_cell_microcode))"
3402 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3405 [(set_attr "type" "shift")
3406 (set_attr "length" "8")])
3408 (define_insn_and_split "*and<mode>3_2insn_dot"
3409 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3410 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3411 (match_operand:GPR 2 "const_int_operand" "n,n"))
3413 (clobber (match_scratch:GPR 0 "=r,r"))]
3414 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3415 && rs6000_gen_cell_microcode
3416 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3417 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3418 || (logical_const_operand (operands[2], <MODE>mode)
3419 && rs6000_gen_cell_microcode))"
3421 "&& reload_completed"
3424 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3427 [(set_attr "type" "shift")
3428 (set_attr "dot" "yes")
3429 (set_attr "length" "8,12")])
3431 (define_insn_and_split "*and<mode>3_2insn_dot2"
3432 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3433 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3434 (match_operand:GPR 2 "const_int_operand" "n,n"))
3436 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3437 (and:GPR (match_dup 1)
3439 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3440 && rs6000_gen_cell_microcode
3441 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3442 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3443 || (logical_const_operand (operands[2], <MODE>mode)
3444 && rs6000_gen_cell_microcode))"
3446 "&& reload_completed"
3449 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3452 [(set_attr "type" "shift")
3453 (set_attr "dot" "yes")
3454 (set_attr "length" "8,12")])
3457 (define_expand "<code><mode>3"
3458 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3459 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3460 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3463 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3465 rs6000_split_logical (operands, <CODE>, false, false, false);
3469 if (non_logical_cint_operand (operands[2], <MODE>mode))
3471 rtx tmp = ((!can_create_pseudo_p ()
3472 || rtx_equal_p (operands[0], operands[1]))
3473 ? operands[0] : gen_reg_rtx (<MODE>mode));
3475 HOST_WIDE_INT value = INTVAL (operands[2]);
3476 HOST_WIDE_INT lo = value & 0xffff;
3477 HOST_WIDE_INT hi = value - lo;
3479 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3480 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3484 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3485 operands[2] = force_reg (<MODE>mode, operands[2]);
3489 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3490 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3491 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3494 (iorxor:GPR (match_dup 1)
3497 (iorxor:GPR (match_dup 3)
3500 operands[3] = ((!can_create_pseudo_p ()
3501 || rtx_equal_p (operands[0], operands[1]))
3502 ? operands[0] : gen_reg_rtx (<MODE>mode));
3504 HOST_WIDE_INT value = INTVAL (operands[2]);
3505 HOST_WIDE_INT lo = value & 0xffff;
3506 HOST_WIDE_INT hi = value - lo;
3508 operands[4] = GEN_INT (hi);
3509 operands[5] = GEN_INT (lo);
3512 (define_insn "*bool<mode>3_imm"
3513 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3514 (match_operator:GPR 3 "boolean_or_operator"
3515 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3516 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3519 [(set_attr "type" "logical")])
3521 (define_insn "*bool<mode>3"
3522 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3523 (match_operator:GPR 3 "boolean_operator"
3524 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3525 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3528 [(set_attr "type" "logical")])
3530 (define_insn_and_split "*bool<mode>3_dot"
3531 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3532 (compare:CC (match_operator:GPR 3 "boolean_operator"
3533 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3534 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3536 (clobber (match_scratch:GPR 0 "=r,r"))]
3537 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3541 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3545 (compare:CC (match_dup 0)
3548 [(set_attr "type" "logical")
3549 (set_attr "dot" "yes")
3550 (set_attr "length" "4,8")])
3552 (define_insn_and_split "*bool<mode>3_dot2"
3553 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3554 (compare:CC (match_operator:GPR 3 "boolean_operator"
3555 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3556 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3558 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3560 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3564 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3568 (compare:CC (match_dup 0)
3571 [(set_attr "type" "logical")
3572 (set_attr "dot" "yes")
3573 (set_attr "length" "4,8")])
3576 (define_insn "*boolc<mode>3"
3577 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3578 (match_operator:GPR 3 "boolean_operator"
3579 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3580 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3583 [(set_attr "type" "logical")])
3585 (define_insn_and_split "*boolc<mode>3_dot"
3586 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3587 (compare:CC (match_operator:GPR 3 "boolean_operator"
3588 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3589 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3591 (clobber (match_scratch:GPR 0 "=r,r"))]
3592 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3596 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3600 (compare:CC (match_dup 0)
3603 [(set_attr "type" "logical")
3604 (set_attr "dot" "yes")
3605 (set_attr "length" "4,8")])
3607 (define_insn_and_split "*boolc<mode>3_dot2"
3608 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3609 (compare:CC (match_operator:GPR 3 "boolean_operator"
3610 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3611 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3613 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3615 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3619 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3623 (compare:CC (match_dup 0)
3626 [(set_attr "type" "logical")
3627 (set_attr "dot" "yes")
3628 (set_attr "length" "4,8")])
3631 (define_insn "*boolcc<mode>3"
3632 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3633 (match_operator:GPR 3 "boolean_operator"
3634 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3635 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3638 [(set_attr "type" "logical")])
3640 (define_insn_and_split "*boolcc<mode>3_dot"
3641 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3642 (compare:CC (match_operator:GPR 3 "boolean_operator"
3643 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3644 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3646 (clobber (match_scratch:GPR 0 "=r,r"))]
3647 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3651 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3655 (compare:CC (match_dup 0)
3658 [(set_attr "type" "logical")
3659 (set_attr "dot" "yes")
3660 (set_attr "length" "4,8")])
3662 (define_insn_and_split "*boolcc<mode>3_dot2"
3663 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3664 (compare:CC (match_operator:GPR 3 "boolean_operator"
3665 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3666 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3668 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3670 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3674 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3678 (compare:CC (match_dup 0)
3681 [(set_attr "type" "logical")
3682 (set_attr "dot" "yes")
3683 (set_attr "length" "4,8")])
3686 ;; TODO: Should have dots of this as well.
3687 (define_insn "*eqv<mode>3"
3688 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3689 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3690 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3693 [(set_attr "type" "logical")])
3695 ;; Rotate-and-mask and insert.
3697 (define_insn "*rotl<mode>3_mask"
3698 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3699 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3700 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3701 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3702 (match_operand:GPR 3 "const_int_operand" "n")))]
3703 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3705 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3707 [(set_attr "type" "shift")
3708 (set_attr "maybe_var_shift" "yes")])
3710 (define_insn_and_split "*rotl<mode>3_mask_dot"
3711 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3713 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3714 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3715 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3716 (match_operand:GPR 3 "const_int_operand" "n,n"))
3718 (clobber (match_scratch:GPR 0 "=r,r"))]
3719 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3720 && rs6000_gen_cell_microcode
3721 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3723 if (which_alternative == 0)
3724 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3728 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3730 (and:GPR (match_dup 4)
3733 (compare:CC (match_dup 0)
3736 [(set_attr "type" "shift")
3737 (set_attr "maybe_var_shift" "yes")
3738 (set_attr "dot" "yes")
3739 (set_attr "length" "4,8")])
3741 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3742 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3744 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3745 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3746 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3747 (match_operand:GPR 3 "const_int_operand" "n,n"))
3749 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3750 (and:GPR (match_dup 4)
3752 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3753 && rs6000_gen_cell_microcode
3754 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3756 if (which_alternative == 0)
3757 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3761 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3763 (and:GPR (match_dup 4)
3766 (compare:CC (match_dup 0)
3769 [(set_attr "type" "shift")
3770 (set_attr "maybe_var_shift" "yes")
3771 (set_attr "dot" "yes")
3772 (set_attr "length" "4,8")])
3774 ; Special case for less-than-0. We can do it with just one machine
3775 ; instruction, but the generic optimizers do not realise it is cheap.
3776 (define_insn "*lt0_disi"
3777 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3778 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3781 "rlwinm %0,%1,1,31,31"
3782 [(set_attr "type" "shift")])
3786 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3787 ; both are an AND so are the same precedence).
3788 (define_insn "*rotl<mode>3_insert"
3789 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3790 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3791 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3792 (match_operand:SI 2 "const_int_operand" "n")])
3793 (match_operand:GPR 3 "const_int_operand" "n"))
3794 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3795 (match_operand:GPR 6 "const_int_operand" "n"))))]
3796 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3797 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3799 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3801 [(set_attr "type" "insert")])
3802 ; FIXME: this needs an attr "size", so that the scheduler can see the
3803 ; difference between rlwimi and rldimi. We also might want dot forms,
3804 ; but not for rlwimi on POWER4 and similar processors.
3806 (define_insn "*rotl<mode>3_insert_2"
3807 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3808 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3809 (match_operand:GPR 6 "const_int_operand" "n"))
3810 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3811 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3812 (match_operand:SI 2 "const_int_operand" "n")])
3813 (match_operand:GPR 3 "const_int_operand" "n"))))]
3814 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3815 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3817 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3819 [(set_attr "type" "insert")])
3821 ; There are also some forms without one of the ANDs.
3822 (define_insn "*rotl<mode>3_insert_3"
3823 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3824 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3825 (match_operand:GPR 4 "const_int_operand" "n"))
3826 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3827 (match_operand:SI 2 "const_int_operand" "n"))))]
3828 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3830 if (<MODE>mode == SImode)
3831 return "rlwimi %0,%1,%h2,0,31-%h2";
3833 return "rldimi %0,%1,%H2,0";
3835 [(set_attr "type" "insert")])
3837 (define_insn "*rotl<mode>3_insert_4"
3838 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3839 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3840 (match_operand:GPR 4 "const_int_operand" "n"))
3841 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3842 (match_operand:SI 2 "const_int_operand" "n"))))]
3843 "<MODE>mode == SImode &&
3844 GET_MODE_PRECISION (<MODE>mode)
3845 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3847 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3848 - INTVAL (operands[2]));
3849 if (<MODE>mode == SImode)
3850 return "rlwimi %0,%1,%h2,32-%h2,31";
3852 return "rldimi %0,%1,%H2,64-%H2";
3854 [(set_attr "type" "insert")])
3856 (define_insn "*rotlsi3_insert_5"
3857 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3858 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3859 (match_operand:SI 2 "const_int_operand" "n,n"))
3860 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3861 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3862 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3863 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3864 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3868 [(set_attr "type" "insert")])
3870 (define_insn "*rotldi3_insert_6"
3871 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3872 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3873 (match_operand:DI 2 "const_int_operand" "n"))
3874 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3875 (match_operand:DI 4 "const_int_operand" "n"))))]
3876 "exact_log2 (-UINTVAL (operands[2])) > 0
3877 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3879 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3880 return "rldimi %0,%3,0,%5";
3882 [(set_attr "type" "insert")
3883 (set_attr "size" "64")])
3885 (define_insn "*rotldi3_insert_7"
3886 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3887 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3888 (match_operand:DI 4 "const_int_operand" "n"))
3889 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3890 (match_operand:DI 2 "const_int_operand" "n"))))]
3891 "exact_log2 (-UINTVAL (operands[2])) > 0
3892 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3894 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3895 return "rldimi %0,%3,0,%5";
3897 [(set_attr "type" "insert")
3898 (set_attr "size" "64")])
3901 ; This handles the important case of multiple-precision shifts. There is
3902 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3904 [(set (match_operand:GPR 0 "gpc_reg_operand")
3905 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3906 (match_operand:SI 3 "const_int_operand"))
3907 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3908 (match_operand:SI 4 "const_int_operand"))))]
3909 "can_create_pseudo_p ()
3910 && INTVAL (operands[3]) + INTVAL (operands[4])
3911 >= GET_MODE_PRECISION (<MODE>mode)"
3913 (lshiftrt:GPR (match_dup 2)
3916 (ior:GPR (and:GPR (match_dup 5)
3918 (ashift:GPR (match_dup 1)
3921 unsigned HOST_WIDE_INT mask = 1;
3922 mask = (mask << INTVAL (operands[3])) - 1;
3923 operands[5] = gen_reg_rtx (<MODE>mode);
3924 operands[6] = GEN_INT (mask);
3928 [(set (match_operand:GPR 0 "gpc_reg_operand")
3929 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3930 (match_operand:SI 4 "const_int_operand"))
3931 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3932 (match_operand:SI 3 "const_int_operand"))))]
3933 "can_create_pseudo_p ()
3934 && INTVAL (operands[3]) + INTVAL (operands[4])
3935 >= GET_MODE_PRECISION (<MODE>mode)"
3937 (lshiftrt:GPR (match_dup 2)
3940 (ior:GPR (and:GPR (match_dup 5)
3942 (ashift:GPR (match_dup 1)
3945 unsigned HOST_WIDE_INT mask = 1;
3946 mask = (mask << INTVAL (operands[3])) - 1;
3947 operands[5] = gen_reg_rtx (<MODE>mode);
3948 operands[6] = GEN_INT (mask);
3952 ; Another important case is setting some bits to 1; we can do that with
3953 ; an insert instruction, in many cases.
3954 (define_insn_and_split "*ior<mode>_mask"
3955 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3956 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3957 (match_operand:GPR 2 "const_int_operand" "n")))
3958 (clobber (match_scratch:GPR 3 "=r"))]
3959 "!logical_const_operand (operands[2], <MODE>mode)
3960 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3966 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3969 (and:GPR (match_dup 1)
3973 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3974 if (GET_CODE (operands[3]) == SCRATCH)
3975 operands[3] = gen_reg_rtx (<MODE>mode);
3976 operands[4] = GEN_INT (ne);
3977 operands[5] = GEN_INT (~UINTVAL (operands[2]));
3979 [(set_attr "type" "two")
3980 (set_attr "length" "8")])
3983 ;; Now the simple shifts.
3985 (define_insn "rotl<mode>3"
3986 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3987 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3988 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3990 "rotl<wd>%I2 %0,%1,%<hH>2"
3991 [(set_attr "type" "shift")
3992 (set_attr "maybe_var_shift" "yes")])
3994 (define_insn "*rotlsi3_64"
3995 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3997 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3998 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4000 "rotlw%I2 %0,%1,%h2"
4001 [(set_attr "type" "shift")
4002 (set_attr "maybe_var_shift" "yes")])
4004 (define_insn_and_split "*rotl<mode>3_dot"
4005 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4006 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4007 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4009 (clobber (match_scratch:GPR 0 "=r,r"))]
4010 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4012 rotl<wd>%I2. %0,%1,%<hH>2
4014 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4016 (rotate:GPR (match_dup 1)
4019 (compare:CC (match_dup 0)
4022 [(set_attr "type" "shift")
4023 (set_attr "maybe_var_shift" "yes")
4024 (set_attr "dot" "yes")
4025 (set_attr "length" "4,8")])
4027 (define_insn_and_split "*rotl<mode>3_dot2"
4028 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4029 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4030 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4032 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4033 (rotate:GPR (match_dup 1)
4035 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4037 rotl<wd>%I2. %0,%1,%<hH>2
4039 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4041 (rotate:GPR (match_dup 1)
4044 (compare:CC (match_dup 0)
4047 [(set_attr "type" "shift")
4048 (set_attr "maybe_var_shift" "yes")
4049 (set_attr "dot" "yes")
4050 (set_attr "length" "4,8")])
4053 (define_insn "ashl<mode>3"
4054 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4055 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4056 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4058 "sl<wd>%I2 %0,%1,%<hH>2"
4059 [(set_attr "type" "shift")
4060 (set_attr "maybe_var_shift" "yes")])
4062 (define_insn "*ashlsi3_64"
4063 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4065 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4066 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4069 [(set_attr "type" "shift")
4070 (set_attr "maybe_var_shift" "yes")])
4072 (define_insn_and_split "*ashl<mode>3_dot"
4073 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4074 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4075 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4077 (clobber (match_scratch:GPR 0 "=r,r"))]
4078 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4080 sl<wd>%I2. %0,%1,%<hH>2
4082 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4084 (ashift:GPR (match_dup 1)
4087 (compare:CC (match_dup 0)
4090 [(set_attr "type" "shift")
4091 (set_attr "maybe_var_shift" "yes")
4092 (set_attr "dot" "yes")
4093 (set_attr "length" "4,8")])
4095 (define_insn_and_split "*ashl<mode>3_dot2"
4096 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4097 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4098 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4100 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4101 (ashift:GPR (match_dup 1)
4103 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4105 sl<wd>%I2. %0,%1,%<hH>2
4107 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4109 (ashift:GPR (match_dup 1)
4112 (compare:CC (match_dup 0)
4115 [(set_attr "type" "shift")
4116 (set_attr "maybe_var_shift" "yes")
4117 (set_attr "dot" "yes")
4118 (set_attr "length" "4,8")])
4120 ;; Pretend we have a memory form of extswsli until register allocation is done
4121 ;; so that we use LWZ to load the value from memory, instead of LWA.
4122 (define_insn_and_split "ashdi3_extswsli"
4123 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4125 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4126 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4131 "&& reload_completed && MEM_P (operands[1])"
4135 (ashift:DI (sign_extend:DI (match_dup 3))
4138 operands[3] = gen_lowpart (SImode, operands[0]);
4140 [(set_attr "type" "shift")
4141 (set_attr "maybe_var_shift" "no")])
4144 (define_insn_and_split "ashdi3_extswsli_dot"
4145 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4148 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4149 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4151 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4158 "&& reload_completed
4159 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4160 || memory_operand (operands[1], SImode))"
4163 rtx dest = operands[0];
4164 rtx src = operands[1];
4165 rtx shift = operands[2];
4166 rtx cr = operands[3];
4173 src2 = gen_lowpart (SImode, dest);
4174 emit_move_insn (src2, src);
4177 if (REGNO (cr) == CR0_REGNO)
4179 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4183 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4184 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4187 [(set_attr "type" "shift")
4188 (set_attr "maybe_var_shift" "no")
4189 (set_attr "dot" "yes")
4190 (set_attr "length" "4,8,8,12")])
4192 (define_insn_and_split "ashdi3_extswsli_dot2"
4193 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4196 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4197 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4199 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4200 (ashift:DI (sign_extend:DI (match_dup 1))
4208 "&& reload_completed
4209 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4210 || memory_operand (operands[1], SImode))"
4213 rtx dest = operands[0];
4214 rtx src = operands[1];
4215 rtx shift = operands[2];
4216 rtx cr = operands[3];
4223 src2 = gen_lowpart (SImode, dest);
4224 emit_move_insn (src2, src);
4227 if (REGNO (cr) == CR0_REGNO)
4229 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4233 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4234 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4237 [(set_attr "type" "shift")
4238 (set_attr "maybe_var_shift" "no")
4239 (set_attr "dot" "yes")
4240 (set_attr "length" "4,8,8,12")])
4242 (define_insn "lshr<mode>3"
4243 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4244 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4245 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4247 "sr<wd>%I2 %0,%1,%<hH>2"
4248 [(set_attr "type" "shift")
4249 (set_attr "maybe_var_shift" "yes")])
4251 (define_insn "*lshrsi3_64"
4252 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4254 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4255 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4258 [(set_attr "type" "shift")
4259 (set_attr "maybe_var_shift" "yes")])
4261 (define_insn_and_split "*lshr<mode>3_dot"
4262 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4263 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4264 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4266 (clobber (match_scratch:GPR 0 "=r,r"))]
4267 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4269 sr<wd>%I2. %0,%1,%<hH>2
4271 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4273 (lshiftrt:GPR (match_dup 1)
4276 (compare:CC (match_dup 0)
4279 [(set_attr "type" "shift")
4280 (set_attr "maybe_var_shift" "yes")
4281 (set_attr "dot" "yes")
4282 (set_attr "length" "4,8")])
4284 (define_insn_and_split "*lshr<mode>3_dot2"
4285 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4286 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4287 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4289 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4290 (lshiftrt:GPR (match_dup 1)
4292 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4294 sr<wd>%I2. %0,%1,%<hH>2
4296 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4298 (lshiftrt:GPR (match_dup 1)
4301 (compare:CC (match_dup 0)
4304 [(set_attr "type" "shift")
4305 (set_attr "maybe_var_shift" "yes")
4306 (set_attr "dot" "yes")
4307 (set_attr "length" "4,8")])
4310 (define_insn "ashr<mode>3"
4311 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4312 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4313 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4314 (clobber (reg:GPR CA_REGNO))]
4316 "sra<wd>%I2 %0,%1,%<hH>2"
4317 [(set_attr "type" "shift")
4318 (set_attr "maybe_var_shift" "yes")])
4320 (define_insn "*ashrsi3_64"
4321 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4323 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4324 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4325 (clobber (reg:SI CA_REGNO))]
4328 [(set_attr "type" "shift")
4329 (set_attr "maybe_var_shift" "yes")])
4331 (define_insn_and_split "*ashr<mode>3_dot"
4332 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4333 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4334 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4336 (clobber (match_scratch:GPR 0 "=r,r"))
4337 (clobber (reg:GPR CA_REGNO))]
4338 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4340 sra<wd>%I2. %0,%1,%<hH>2
4342 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4343 [(parallel [(set (match_dup 0)
4344 (ashiftrt:GPR (match_dup 1)
4346 (clobber (reg:GPR CA_REGNO))])
4348 (compare:CC (match_dup 0)
4351 [(set_attr "type" "shift")
4352 (set_attr "maybe_var_shift" "yes")
4353 (set_attr "dot" "yes")
4354 (set_attr "length" "4,8")])
4356 (define_insn_and_split "*ashr<mode>3_dot2"
4357 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4358 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4359 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4361 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4362 (ashiftrt:GPR (match_dup 1)
4364 (clobber (reg:GPR CA_REGNO))]
4365 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4367 sra<wd>%I2. %0,%1,%<hH>2
4369 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4370 [(parallel [(set (match_dup 0)
4371 (ashiftrt:GPR (match_dup 1)
4373 (clobber (reg:GPR CA_REGNO))])
4375 (compare:CC (match_dup 0)
4378 [(set_attr "type" "shift")
4379 (set_attr "maybe_var_shift" "yes")
4380 (set_attr "dot" "yes")
4381 (set_attr "length" "4,8")])
4383 ;; Builtins to replace a division to generate FRE reciprocal estimate
4384 ;; instructions and the necessary fixup instructions
4385 (define_expand "recip<mode>3"
4386 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4387 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4388 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4389 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4391 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4395 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4396 ;; hardware division. This is only done before register allocation and with
4397 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4398 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4399 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4401 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4402 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4403 (match_operand 2 "gpc_reg_operand" "")))]
4404 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4405 && can_create_pseudo_p () && flag_finite_math_only
4406 && !flag_trapping_math && flag_reciprocal_math"
4409 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4413 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4414 ;; appropriate fixup.
4415 (define_expand "rsqrt<mode>2"
4416 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4417 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4418 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4420 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4424 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4425 ;; modes here, and also add in conditional vsx/power8-vector support to access
4426 ;; values in the traditional Altivec registers if the appropriate
4427 ;; -mupper-regs-{df,sf} option is enabled.
4429 (define_expand "abs<mode>2"
4430 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4431 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4432 "TARGET_<MODE>_INSN"
4435 (define_insn "*abs<mode>2_fpr"
4436 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4437 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4442 [(set_attr "type" "fpsimple")
4443 (set_attr "fp_type" "fp_addsub_<Fs>")])
4445 (define_insn "*nabs<mode>2_fpr"
4446 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4449 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4454 [(set_attr "type" "fpsimple")
4455 (set_attr "fp_type" "fp_addsub_<Fs>")])
4457 (define_expand "neg<mode>2"
4458 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4459 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4460 "TARGET_<MODE>_INSN"
4463 (define_insn "*neg<mode>2_fpr"
4464 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4465 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4470 [(set_attr "type" "fpsimple")
4471 (set_attr "fp_type" "fp_addsub_<Fs>")])
4473 (define_expand "add<mode>3"
4474 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4475 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4476 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4477 "TARGET_<MODE>_INSN"
4480 (define_insn "*add<mode>3_fpr"
4481 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4482 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4483 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4486 fadd<Ftrad> %0,%1,%2
4487 xsadd<Fvsx> %x0,%x1,%x2"
4488 [(set_attr "type" "fp")
4489 (set_attr "fp_type" "fp_addsub_<Fs>")])
4491 (define_expand "sub<mode>3"
4492 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4493 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4494 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4495 "TARGET_<MODE>_INSN"
4498 (define_insn "*sub<mode>3_fpr"
4499 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4500 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4501 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4504 fsub<Ftrad> %0,%1,%2
4505 xssub<Fvsx> %x0,%x1,%x2"
4506 [(set_attr "type" "fp")
4507 (set_attr "fp_type" "fp_addsub_<Fs>")])
4509 (define_expand "mul<mode>3"
4510 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4511 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4512 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4513 "TARGET_<MODE>_INSN"
4516 (define_insn "*mul<mode>3_fpr"
4517 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4518 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4519 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4522 fmul<Ftrad> %0,%1,%2
4523 xsmul<Fvsx> %x0,%x1,%x2"
4524 [(set_attr "type" "dmul")
4525 (set_attr "fp_type" "fp_mul_<Fs>")])
4527 (define_expand "div<mode>3"
4528 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4529 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4530 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4531 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4533 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4534 && can_create_pseudo_p () && flag_finite_math_only
4535 && !flag_trapping_math && flag_reciprocal_math)
4537 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4542 (define_insn "*div<mode>3_fpr"
4543 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4544 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4545 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4546 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4548 fdiv<Ftrad> %0,%1,%2
4549 xsdiv<Fvsx> %x0,%x1,%x2"
4550 [(set_attr "type" "<Fs>div")
4551 (set_attr "fp_type" "fp_div_<Fs>")])
4553 (define_insn "*sqrt<mode>2_internal"
4554 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4555 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4556 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4557 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4560 xssqrt<Fvsx> %x0,%x1"
4561 [(set_attr "type" "<Fs>sqrt")
4562 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4564 (define_expand "sqrt<mode>2"
4565 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4566 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4567 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4568 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4570 if (<MODE>mode == SFmode
4571 && TARGET_RECIP_PRECISION
4572 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4573 && !optimize_function_for_size_p (cfun)
4574 && flag_finite_math_only && !flag_trapping_math
4575 && flag_unsafe_math_optimizations)
4577 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4582 ;; Floating point reciprocal approximation
4583 (define_insn "fre<Fs>"
4584 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4585 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4591 [(set_attr "type" "fp")])
4593 (define_insn "*rsqrt<mode>2"
4594 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4595 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4597 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4599 frsqrte<Ftrad> %0,%1
4600 xsrsqrte<Fvsx> %x0,%x1"
4601 [(set_attr "type" "fp")])
4603 ;; Floating point comparisons
4604 (define_insn "*cmp<mode>_fpr"
4605 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4606 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4607 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4611 xscmpudp %0,%x1,%x2"
4612 [(set_attr "type" "fpcompare")])
4614 ;; Floating point conversions
4615 (define_expand "extendsfdf2"
4616 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4617 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4618 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4621 (define_insn_and_split "*extendsfdf2_fpr"
4622 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4623 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4624 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4630 xscpsgndp %x0,%x1,%x1
4633 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4636 emit_note (NOTE_INSN_DELETED);
4639 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4641 (define_expand "truncdfsf2"
4642 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4643 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4644 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4647 (define_insn "*truncdfsf2_fpr"
4648 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4649 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4650 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4654 [(set_attr "type" "fp")])
4656 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4657 ;; builtins.c and optabs.c that are not correct for IBM long double
4658 ;; when little-endian.
4659 (define_expand "signbit<mode>2"
4661 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4663 (subreg:DI (match_dup 2) 0))
4666 (set (match_operand:SI 0 "gpc_reg_operand" "")
4669 && (TARGET_FPRS || TARGET_E500_DOUBLE)
4670 && (!FLOAT128_IEEE_P (<MODE>mode)
4671 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4673 if (FLOAT128_IEEE_P (<MODE>mode))
4675 if (<MODE>mode == KFmode)
4676 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4677 else if (<MODE>mode == TFmode)
4678 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4683 operands[2] = gen_reg_rtx (DFmode);
4684 operands[3] = gen_reg_rtx (DImode);
4685 if (TARGET_POWERPC64)
4687 operands[4] = gen_reg_rtx (DImode);
4688 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4689 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4690 WORDS_BIG_ENDIAN ? 4 : 0);
4694 operands[4] = gen_reg_rtx (SImode);
4695 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4696 WORDS_BIG_ENDIAN ? 0 : 4);
4697 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4701 (define_expand "copysign<mode>3"
4703 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4705 (neg:SFDF (abs:SFDF (match_dup 1))))
4706 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4707 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4711 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4712 && ((TARGET_PPC_GFXOPT
4713 && !HONOR_NANS (<MODE>mode)
4714 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4716 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4718 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4720 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4725 operands[3] = gen_reg_rtx (<MODE>mode);
4726 operands[4] = gen_reg_rtx (<MODE>mode);
4727 operands[5] = CONST0_RTX (<MODE>mode);
4730 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4732 (define_insn_and_split "signbit<mode>2_dm"
4733 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4735 [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,m,r")]
4737 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4739 "&& reload_completed"
4742 rs6000_split_signbit (operands[0], operands[1]);
4745 [(set_attr "length" "8,8,12")
4746 (set_attr "type" "mftgpr,load,integer")])
4748 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4749 ;; point types, which makes normal SUBREG's problematical. Instead use a
4750 ;; special pattern to avoid using a normal movdi.
4751 (define_insn "signbit<mode>2_dm2"
4752 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4753 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
4756 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4758 [(set_attr "type" "mftgpr")])
4761 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4762 ;; compiler from optimizing -0.0
4763 (define_insn "copysign<mode>3_fcpsgn"
4764 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4765 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4766 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4768 "TARGET_<MODE>_FPR && TARGET_CMPB"
4771 xscpsgndp %x0,%x2,%x1"
4772 [(set_attr "type" "fpsimple")])
4774 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4775 ;; fsel instruction and some auxiliary computations. Then we just have a
4776 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4778 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4779 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4780 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4781 ;; define_splits to make them if made by combine. On VSX machines we have the
4782 ;; min/max instructions.
4784 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4785 ;; to allow either DF/SF to use only traditional registers.
4787 (define_expand "s<minmax><mode>3"
4788 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4789 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4790 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4791 "TARGET_MINMAX_<MODE>"
4793 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4797 (define_insn "*s<minmax><mode>3_vsx"
4798 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4799 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4800 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4801 "TARGET_VSX && TARGET_<MODE>_FPR"
4803 return (TARGET_P9_MINMAX
4804 ? "xs<minmax>cdp %x0,%x1,%x2"
4805 : "xs<minmax>dp %x0,%x1,%x2");
4807 [(set_attr "type" "fp")])
4809 ;; The conditional move instructions allow us to perform max and min operations
4810 ;; even when we don't have the appropriate max/min instruction using the FSEL
4813 (define_insn_and_split "*s<minmax><mode>3_fpr"
4814 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4815 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4816 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4817 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4822 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4826 (define_expand "mov<mode>cc"
4827 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4828 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4829 (match_operand:GPR 2 "gpc_reg_operand" "")
4830 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4834 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4840 ;; We use the BASE_REGS for the isel input operands because, if rA is
4841 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4842 ;; because we may switch the operands and rB may end up being rA.
4844 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4845 ;; leave out the mode in operand 4 and use one pattern, but reload can
4846 ;; change the mode underneath our feet and then gets confused trying
4847 ;; to reload the value.
4848 (define_insn "isel_signed_<mode>"
4849 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4851 (match_operator 1 "scc_comparison_operator"
4852 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4854 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4855 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4858 { return output_isel (operands); }"
4859 [(set_attr "type" "isel")
4860 (set_attr "length" "4")])
4862 (define_insn "isel_unsigned_<mode>"
4863 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4865 (match_operator 1 "scc_comparison_operator"
4866 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4868 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4869 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4872 { return output_isel (operands); }"
4873 [(set_attr "type" "isel")
4874 (set_attr "length" "4")])
4876 ;; These patterns can be useful for combine; they let combine know that
4877 ;; isel can handle reversed comparisons so long as the operands are
4880 (define_insn "*isel_reversed_signed_<mode>"
4881 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4883 (match_operator 1 "scc_rev_comparison_operator"
4884 [(match_operand:CC 4 "cc_reg_operand" "y")
4886 (match_operand:GPR 2 "gpc_reg_operand" "b")
4887 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4890 { return output_isel (operands); }"
4891 [(set_attr "type" "isel")
4892 (set_attr "length" "4")])
4894 (define_insn "*isel_reversed_unsigned_<mode>"
4895 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4897 (match_operator 1 "scc_rev_comparison_operator"
4898 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4900 (match_operand:GPR 2 "gpc_reg_operand" "b")
4901 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4904 { return output_isel (operands); }"
4905 [(set_attr "type" "isel")
4906 (set_attr "length" "4")])
4908 ;; Floating point conditional move
4909 (define_expand "mov<mode>cc"
4910 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4911 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4912 (match_operand:SFDF 2 "gpc_reg_operand" "")
4913 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4914 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4917 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4923 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4924 [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4926 (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4927 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4928 (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4929 (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4930 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4932 [(set_attr "type" "fp")])
4934 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4935 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4937 (match_operator:CCFP 1 "fpmask_comparison_operator"
4938 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4939 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4940 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4941 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4942 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4947 (if_then_else:V2DI (match_dup 1)
4951 (if_then_else:SFDF (ne (match_dup 6)
4956 if (GET_CODE (operands[6]) == SCRATCH)
4957 operands[6] = gen_reg_rtx (V2DImode);
4959 operands[7] = CONSTM1_RTX (V2DImode);
4960 operands[8] = CONST0_RTX (V2DImode);
4962 [(set_attr "length" "8")
4963 (set_attr "type" "vecperm")])
4965 ;; Handle inverting the fpmask comparisons.
4966 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
4967 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4969 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
4970 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4971 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4972 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4973 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4974 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4979 (if_then_else:V2DI (match_dup 9)
4983 (if_then_else:SFDF (ne (match_dup 6)
4988 rtx op1 = operands[1];
4989 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
4991 if (GET_CODE (operands[6]) == SCRATCH)
4992 operands[6] = gen_reg_rtx (V2DImode);
4994 operands[7] = CONSTM1_RTX (V2DImode);
4995 operands[8] = CONST0_RTX (V2DImode);
4997 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
4999 [(set_attr "length" "8")
5000 (set_attr "type" "vecperm")])
5002 (define_insn "*fpmask<mode>"
5003 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5005 (match_operator:CCFP 1 "fpmask_comparison_operator"
5006 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5007 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5008 (match_operand:V2DI 4 "all_ones_constant" "")
5009 (match_operand:V2DI 5 "zero_constant" "")))]
5011 "xscmp%V1dp %x0,%x2,%x3"
5012 [(set_attr "type" "fpcompare")])
5014 (define_insn "*xxsel<mode>"
5015 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5016 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5017 (match_operand:V2DI 2 "zero_constant" ""))
5018 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5019 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5021 "xxsel %x0,%x4,%x3,%x1"
5022 [(set_attr "type" "vecmove")])
5025 ;; Conversions to and from floating-point.
5027 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5028 ; don't want to support putting SImode in FPR registers.
5029 (define_insn "lfiwax"
5030 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5031 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5033 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5039 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5041 ; This split must be run before register allocation because it allocates the
5042 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5043 ; it earlier to allow for the combiner to merge insns together where it might
5044 ; not be needed and also in case the insns are deleted as dead code.
5046 (define_insn_and_split "floatsi<mode>2_lfiwax"
5047 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5048 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5049 (clobber (match_scratch:DI 2 "=wi"))]
5050 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5051 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5057 rtx dest = operands[0];
5058 rtx src = operands[1];
5061 if (!MEM_P (src) && TARGET_POWERPC64
5062 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5063 tmp = convert_to_mode (DImode, src, false);
5067 if (GET_CODE (tmp) == SCRATCH)
5068 tmp = gen_reg_rtx (DImode);
5071 src = rs6000_address_for_fpconvert (src);
5072 emit_insn (gen_lfiwax (tmp, src));
5076 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5077 emit_move_insn (stack, src);
5078 emit_insn (gen_lfiwax (tmp, stack));
5081 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5084 [(set_attr "length" "12")
5085 (set_attr "type" "fpload")])
5087 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5088 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5091 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5092 (clobber (match_scratch:DI 2 "=wi"))]
5093 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5100 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5101 if (GET_CODE (operands[2]) == SCRATCH)
5102 operands[2] = gen_reg_rtx (DImode);
5103 if (TARGET_VSX_SMALL_INTEGER)
5104 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5106 emit_insn (gen_lfiwax (operands[2], operands[1]));
5107 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5110 [(set_attr "length" "8")
5111 (set_attr "type" "fpload")])
5113 (define_insn "lfiwzx"
5114 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5115 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5117 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5122 xxextractuw %x0,%x1,1"
5123 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5125 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5126 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5127 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5128 (clobber (match_scratch:DI 2 "=wi"))]
5129 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5136 rtx dest = operands[0];
5137 rtx src = operands[1];
5140 if (!MEM_P (src) && TARGET_POWERPC64
5141 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5142 tmp = convert_to_mode (DImode, src, true);
5146 if (GET_CODE (tmp) == SCRATCH)
5147 tmp = gen_reg_rtx (DImode);
5150 src = rs6000_address_for_fpconvert (src);
5151 emit_insn (gen_lfiwzx (tmp, src));
5155 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5156 emit_move_insn (stack, src);
5157 emit_insn (gen_lfiwzx (tmp, stack));
5160 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5163 [(set_attr "length" "12")
5164 (set_attr "type" "fpload")])
5166 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5167 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5168 (unsigned_float:SFDF
5170 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5171 (clobber (match_scratch:DI 2 "=wi"))]
5172 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5179 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5180 if (GET_CODE (operands[2]) == SCRATCH)
5181 operands[2] = gen_reg_rtx (DImode);
5182 if (TARGET_VSX_SMALL_INTEGER)
5183 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5185 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5186 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5189 [(set_attr "length" "8")
5190 (set_attr "type" "fpload")])
5192 ; For each of these conversions, there is a define_expand, a define_insn
5193 ; with a '#' template, and a define_split (with C code). The idea is
5194 ; to allow constant folding with the template of the define_insn,
5195 ; then to have the insns split later (between sched1 and final).
5197 (define_expand "floatsidf2"
5198 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5199 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5202 (clobber (match_dup 4))
5203 (clobber (match_dup 5))
5204 (clobber (match_dup 6))])]
5206 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5209 if (TARGET_E500_DOUBLE)
5211 if (!REG_P (operands[1]))
5212 operands[1] = force_reg (SImode, operands[1]);
5213 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5216 else if (TARGET_LFIWAX && TARGET_FCFID)
5218 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5221 else if (TARGET_FCFID)
5223 rtx dreg = operands[1];
5225 dreg = force_reg (SImode, dreg);
5226 dreg = convert_to_mode (DImode, dreg, false);
5227 emit_insn (gen_floatdidf2 (operands[0], dreg));
5231 if (!REG_P (operands[1]))
5232 operands[1] = force_reg (SImode, operands[1]);
5233 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5234 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5235 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5236 operands[5] = gen_reg_rtx (DFmode);
5237 operands[6] = gen_reg_rtx (SImode);
5240 (define_insn_and_split "*floatsidf2_internal"
5241 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5242 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5243 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5244 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5245 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5246 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5247 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5248 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5254 rtx lowword, highword;
5255 gcc_assert (MEM_P (operands[4]));
5256 highword = adjust_address (operands[4], SImode, 0);
5257 lowword = adjust_address (operands[4], SImode, 4);
5258 if (! WORDS_BIG_ENDIAN)
5259 std::swap (lowword, highword);
5261 emit_insn (gen_xorsi3 (operands[6], operands[1],
5262 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5263 emit_move_insn (lowword, operands[6]);
5264 emit_move_insn (highword, operands[2]);
5265 emit_move_insn (operands[5], operands[4]);
5266 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5269 [(set_attr "length" "24")
5270 (set_attr "type" "fp")])
5272 ;; If we don't have a direct conversion to single precision, don't enable this
5273 ;; conversion for 32-bit without fast math, because we don't have the insn to
5274 ;; generate the fixup swizzle to avoid double rounding problems.
5275 (define_expand "floatunssisf2"
5276 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5277 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5278 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5281 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5282 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5283 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5288 if (!REG_P (operands[1]))
5289 operands[1] = force_reg (SImode, operands[1]);
5291 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5293 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5298 rtx dreg = operands[1];
5300 dreg = force_reg (SImode, dreg);
5301 dreg = convert_to_mode (DImode, dreg, true);
5302 emit_insn (gen_floatdisf2 (operands[0], dreg));
5307 (define_expand "floatunssidf2"
5308 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5309 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5312 (clobber (match_dup 4))
5313 (clobber (match_dup 5))])]
5315 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5318 if (TARGET_E500_DOUBLE)
5320 if (!REG_P (operands[1]))
5321 operands[1] = force_reg (SImode, operands[1]);
5322 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5325 else if (TARGET_LFIWZX && TARGET_FCFID)
5327 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5330 else if (TARGET_FCFID)
5332 rtx dreg = operands[1];
5334 dreg = force_reg (SImode, dreg);
5335 dreg = convert_to_mode (DImode, dreg, true);
5336 emit_insn (gen_floatdidf2 (operands[0], dreg));
5340 if (!REG_P (operands[1]))
5341 operands[1] = force_reg (SImode, operands[1]);
5342 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5343 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5344 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5345 operands[5] = gen_reg_rtx (DFmode);
5348 (define_insn_and_split "*floatunssidf2_internal"
5349 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5350 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5351 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5352 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5353 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5354 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5355 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5356 && !(TARGET_FCFID && TARGET_POWERPC64)"
5362 rtx lowword, highword;
5363 gcc_assert (MEM_P (operands[4]));
5364 highword = adjust_address (operands[4], SImode, 0);
5365 lowword = adjust_address (operands[4], SImode, 4);
5366 if (! WORDS_BIG_ENDIAN)
5367 std::swap (lowword, highword);
5369 emit_move_insn (lowword, operands[1]);
5370 emit_move_insn (highword, operands[2]);
5371 emit_move_insn (operands[5], operands[4]);
5372 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5375 [(set_attr "length" "20")
5376 (set_attr "type" "fp")])
5378 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5379 ;; vector registers. These insns favor doing the sign/zero extension in
5380 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5381 ;; extension and then a direct move.
5383 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5384 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5386 (match_operand:QHI 1 "input_operand")))
5387 (clobber (match_scratch:DI 2))
5388 (clobber (match_scratch:DI 3))
5389 (clobber (match_scratch:<QHI:MODE> 4))])]
5390 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5391 && TARGET_VSX_SMALL_INTEGER"
5393 if (MEM_P (operands[1]))
5394 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5397 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5398 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5400 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5401 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5402 (clobber (match_scratch:DI 3 "=X,r,X"))
5403 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5404 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5405 && TARGET_UPPER_REGS_DI && TARGET_VSX_SMALL_INTEGER"
5407 "&& reload_completed"
5410 rtx result = operands[0];
5411 rtx input = operands[1];
5412 rtx di = operands[2];
5416 if (altivec_register_operand (input, <QHI:MODE>mode))
5417 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5420 rtx tmp = operands[3];
5421 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5422 emit_move_insn (di, tmp);
5427 rtx tmp = operands[4];
5428 emit_move_insn (tmp, input);
5429 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5432 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5436 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5437 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5438 (unsigned_float:FP_ISA3
5439 (match_operand:QHI 1 "input_operand" "")))
5440 (clobber (match_scratch:DI 2 ""))
5441 (clobber (match_scratch:DI 3 ""))])]
5442 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5443 && TARGET_VSX_SMALL_INTEGER"
5445 if (MEM_P (operands[1]))
5446 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5449 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5450 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5451 (unsigned_float:FP_ISA3
5452 (match_operand:QHI 1 "reg_or_indexed_operand" "wJwK,r,Z")))
5453 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5454 (clobber (match_scratch:DI 3 "=X,r,X"))]
5455 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5456 && TARGET_VSX_SMALL_INTEGER"
5458 "&& reload_completed"
5461 rtx result = operands[0];
5462 rtx input = operands[1];
5463 rtx di = operands[2];
5465 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5466 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5469 rtx tmp = operands[3];
5470 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5471 emit_move_insn (di, tmp);
5474 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5478 (define_expand "fix_trunc<mode>si2"
5479 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5480 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5481 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5484 if (!<E500_CONVERT>)
5486 rtx src = force_reg (<MODE>mode, operands[1]);
5489 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5492 rtx tmp = gen_reg_rtx (DImode);
5493 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5494 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5501 ; Like the convert to float patterns, this insn must be split before
5502 ; register allocation so that it can allocate the memory slot if it
5504 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5505 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5506 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5507 (clobber (match_scratch:DI 2 "=d"))]
5508 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5509 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5510 && TARGET_STFIWX && can_create_pseudo_p ()"
5515 rtx dest = operands[0];
5516 rtx src = operands[1];
5517 rtx tmp = operands[2];
5519 if (GET_CODE (tmp) == SCRATCH)
5520 tmp = gen_reg_rtx (DImode);
5522 emit_insn (gen_fctiwz_<mode> (tmp, src));
5525 dest = rs6000_address_for_fpconvert (dest);
5526 emit_insn (gen_stfiwx (dest, tmp));
5529 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5531 dest = gen_lowpart (DImode, dest);
5532 emit_move_insn (dest, tmp);
5537 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5538 emit_insn (gen_stfiwx (stack, tmp));
5539 emit_move_insn (dest, stack);
5543 [(set_attr "length" "12")
5544 (set_attr "type" "fp")])
5546 (define_insn_and_split "fix_trunc<mode>si2_internal"
5547 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5548 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5549 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5550 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5551 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5558 gcc_assert (MEM_P (operands[3]));
5559 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5561 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5562 emit_move_insn (operands[3], operands[2]);
5563 emit_move_insn (operands[0], lowword);
5566 [(set_attr "length" "16")
5567 (set_attr "type" "fp")])
5569 (define_expand "fix_trunc<mode>di2"
5570 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5571 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5572 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5576 (define_insn "*fix_trunc<mode>di2_fctidz"
5577 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5578 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5579 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5584 [(set_attr "type" "fp")])
5586 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5587 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5588 (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5589 (clobber (match_scratch:DI 2))])]
5590 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5591 && TARGET_VSX_SMALL_INTEGER"
5593 if (MEM_P (operands[0]))
5594 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5597 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5598 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5600 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5601 (clobber (match_scratch:DI 2 "=X,wi"))]
5602 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5603 && TARGET_VSX_SMALL_INTEGER"
5605 "&& reload_completed"
5608 rtx dest = operands[0];
5609 rtx src = operands[1];
5611 if (vsx_register_operand (dest, <QHI:MODE>mode))
5613 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5614 emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5618 rtx tmp = operands[2];
5619 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5621 emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5622 emit_move_insn (dest, tmp2);
5627 (define_expand "fixuns_trunc<mode>si2"
5628 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5629 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5631 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5635 if (!<E500_CONVERT>)
5637 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5642 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5643 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5644 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5645 (clobber (match_scratch:DI 2 "=d"))]
5646 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5647 && TARGET_STFIWX && can_create_pseudo_p ()"
5652 rtx dest = operands[0];
5653 rtx src = operands[1];
5654 rtx tmp = operands[2];
5656 if (GET_CODE (tmp) == SCRATCH)
5657 tmp = gen_reg_rtx (DImode);
5659 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5662 dest = rs6000_address_for_fpconvert (dest);
5663 emit_insn (gen_stfiwx (dest, tmp));
5666 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5668 dest = gen_lowpart (DImode, dest);
5669 emit_move_insn (dest, tmp);
5674 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5675 emit_insn (gen_stfiwx (stack, tmp));
5676 emit_move_insn (dest, stack);
5680 [(set_attr "length" "12")
5681 (set_attr "type" "fp")])
5683 (define_expand "fixuns_trunc<mode>di2"
5684 [(set (match_operand:DI 0 "register_operand" "")
5685 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5686 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5689 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5690 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5691 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5692 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5697 [(set_attr "type" "fp")])
5699 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5700 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5701 (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5702 (clobber (match_scratch:DI 2))])]
5703 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5704 && TARGET_VSX_SMALL_INTEGER"
5706 if (MEM_P (operands[0]))
5707 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5710 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5711 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5713 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5714 (clobber (match_scratch:DI 2 "=X,wi"))]
5715 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5716 && TARGET_VSX_SMALL_INTEGER"
5718 "&& reload_completed"
5721 rtx dest = operands[0];
5722 rtx src = operands[1];
5724 if (vsx_register_operand (dest, <QHI:MODE>mode))
5726 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5727 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5731 rtx tmp = operands[2];
5732 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5734 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5735 emit_move_insn (dest, tmp2);
5739 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5740 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5741 ; because the first makes it clear that operand 0 is not live
5742 ; before the instruction.
5743 (define_insn "fctiwz_<mode>"
5744 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5745 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5747 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5751 [(set_attr "type" "fp")])
5753 (define_insn "fctiwuz_<mode>"
5754 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5755 (unspec:DI [(unsigned_fix:SI
5756 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5758 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5762 [(set_attr "type" "fp")])
5764 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5765 ;; since the friz instruction does not truncate the value if the floating
5766 ;; point value is < LONG_MIN or > LONG_MAX.
5767 (define_insn "*friz"
5768 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5769 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5770 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5771 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5775 [(set_attr "type" "fp")])
5777 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5778 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5779 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5780 ;; extend it, store it back on the stack from the GPR, load it back into the
5781 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5782 ;; disable using store and load to sign/zero extend the value.
5783 (define_insn_and_split "*round32<mode>2_fprs"
5784 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5786 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5787 (clobber (match_scratch:DI 2 "=d"))
5788 (clobber (match_scratch:DI 3 "=d"))]
5789 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5790 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5791 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5796 rtx dest = operands[0];
5797 rtx src = operands[1];
5798 rtx tmp1 = operands[2];
5799 rtx tmp2 = operands[3];
5800 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5802 if (GET_CODE (tmp1) == SCRATCH)
5803 tmp1 = gen_reg_rtx (DImode);
5804 if (GET_CODE (tmp2) == SCRATCH)
5805 tmp2 = gen_reg_rtx (DImode);
5807 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5808 emit_insn (gen_stfiwx (stack, tmp1));
5809 emit_insn (gen_lfiwax (tmp2, stack));
5810 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5813 [(set_attr "type" "fpload")
5814 (set_attr "length" "16")])
5816 (define_insn_and_split "*roundu32<mode>2_fprs"
5817 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5818 (unsigned_float:SFDF
5819 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5820 (clobber (match_scratch:DI 2 "=d"))
5821 (clobber (match_scratch:DI 3 "=d"))]
5822 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5823 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5824 && can_create_pseudo_p ()"
5829 rtx dest = operands[0];
5830 rtx src = operands[1];
5831 rtx tmp1 = operands[2];
5832 rtx tmp2 = operands[3];
5833 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5835 if (GET_CODE (tmp1) == SCRATCH)
5836 tmp1 = gen_reg_rtx (DImode);
5837 if (GET_CODE (tmp2) == SCRATCH)
5838 tmp2 = gen_reg_rtx (DImode);
5840 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5841 emit_insn (gen_stfiwx (stack, tmp1));
5842 emit_insn (gen_lfiwzx (tmp2, stack));
5843 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5846 [(set_attr "type" "fpload")
5847 (set_attr "length" "16")])
5849 ;; No VSX equivalent to fctid
5850 (define_insn "lrint<mode>di2"
5851 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5852 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5854 "TARGET_<MODE>_FPR && TARGET_FPRND"
5856 [(set_attr "type" "fp")])
5858 (define_insn "btrunc<mode>2"
5859 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5860 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5862 "TARGET_<MODE>_FPR && TARGET_FPRND"
5866 [(set_attr "type" "fp")
5867 (set_attr "fp_type" "fp_addsub_<Fs>")])
5869 (define_insn "ceil<mode>2"
5870 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5871 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5873 "TARGET_<MODE>_FPR && TARGET_FPRND"
5877 [(set_attr "type" "fp")
5878 (set_attr "fp_type" "fp_addsub_<Fs>")])
5880 (define_insn "floor<mode>2"
5881 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5882 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5884 "TARGET_<MODE>_FPR && TARGET_FPRND"
5888 [(set_attr "type" "fp")
5889 (set_attr "fp_type" "fp_addsub_<Fs>")])
5891 ;; No VSX equivalent to frin
5892 (define_insn "round<mode>2"
5893 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5894 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5896 "TARGET_<MODE>_FPR && TARGET_FPRND"
5898 [(set_attr "type" "fp")
5899 (set_attr "fp_type" "fp_addsub_<Fs>")])
5901 (define_insn "*xsrdpi<mode>2"
5902 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5903 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5905 "TARGET_<MODE>_FPR && TARGET_VSX"
5907 [(set_attr "type" "fp")
5908 (set_attr "fp_type" "fp_addsub_<Fs>")])
5910 (define_expand "lround<mode>di2"
5912 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5914 (set (match_operand:DI 0 "gpc_reg_operand" "")
5915 (unspec:DI [(match_dup 2)]
5917 "TARGET_<MODE>_FPR && TARGET_VSX"
5919 operands[2] = gen_reg_rtx (<MODE>mode);
5922 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5923 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5924 ; is only generated for Power8 or later.
5925 (define_insn "stfiwx"
5926 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5927 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5933 [(set_attr "type" "fpstore")])
5935 ;; If we don't have a direct conversion to single precision, don't enable this
5936 ;; conversion for 32-bit without fast math, because we don't have the insn to
5937 ;; generate the fixup swizzle to avoid double rounding problems.
5938 (define_expand "floatsisf2"
5939 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5940 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5941 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5944 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5945 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5946 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5951 if (!REG_P (operands[1]))
5952 operands[1] = force_reg (SImode, operands[1]);
5954 else if (TARGET_FCFIDS && TARGET_LFIWAX)
5956 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5959 else if (TARGET_FCFID && TARGET_LFIWAX)
5961 rtx dfreg = gen_reg_rtx (DFmode);
5962 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5963 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5968 rtx dreg = operands[1];
5970 dreg = force_reg (SImode, dreg);
5971 dreg = convert_to_mode (DImode, dreg, false);
5972 emit_insn (gen_floatdisf2 (operands[0], dreg));
5977 (define_expand "floatdidf2"
5978 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5979 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5980 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5983 (define_insn "*floatdidf2_fpr"
5984 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5985 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5986 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5990 [(set_attr "type" "fp")])
5992 ; Allow the combiner to merge source memory operands to the conversion so that
5993 ; the optimizer/register allocator doesn't try to load the value too early in a
5994 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5995 ; hit. We will split after reload to avoid the trip through the GPRs
5997 (define_insn_and_split "*floatdidf2_mem"
5998 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5999 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6000 (clobber (match_scratch:DI 2 "=d,wi"))]
6001 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6003 "&& reload_completed"
6004 [(set (match_dup 2) (match_dup 1))
6005 (set (match_dup 0) (float:DF (match_dup 2)))]
6007 [(set_attr "length" "8")
6008 (set_attr "type" "fpload")])
6010 (define_expand "floatunsdidf2"
6011 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6013 (match_operand:DI 1 "gpc_reg_operand" "")))]
6014 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6017 (define_insn "*floatunsdidf2_fcfidu"
6018 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6019 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6020 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6024 [(set_attr "type" "fp")
6025 (set_attr "length" "4")])
6027 (define_insn_and_split "*floatunsdidf2_mem"
6028 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6029 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6030 (clobber (match_scratch:DI 2 "=d,wi"))]
6031 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6033 "&& reload_completed"
6034 [(set (match_dup 2) (match_dup 1))
6035 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6037 [(set_attr "length" "8")
6038 (set_attr "type" "fpload")])
6040 (define_expand "floatdisf2"
6041 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6042 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6043 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6044 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6049 rtx val = operands[1];
6050 if (!flag_unsafe_math_optimizations)
6052 rtx label = gen_label_rtx ();
6053 val = gen_reg_rtx (DImode);
6054 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6057 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6062 (define_insn "floatdisf2_fcfids"
6063 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6064 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6065 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6066 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6070 [(set_attr "type" "fp")])
6072 (define_insn_and_split "*floatdisf2_mem"
6073 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6074 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6075 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6076 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6077 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6079 "&& reload_completed"
6083 emit_move_insn (operands[2], operands[1]);
6084 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6087 [(set_attr "length" "8")])
6089 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6090 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6091 ;; from double rounding.
6092 ;; Instead of creating a new cpu type for two FP operations, just use fp
6093 (define_insn_and_split "floatdisf2_internal1"
6094 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6095 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6096 (clobber (match_scratch:DF 2 "=d"))]
6097 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6100 "&& reload_completed"
6102 (float:DF (match_dup 1)))
6104 (float_truncate:SF (match_dup 2)))]
6106 [(set_attr "length" "8")
6107 (set_attr "type" "fp")])
6109 ;; Twiddles bits to avoid double rounding.
6110 ;; Bits that might be truncated when converting to DFmode are replaced
6111 ;; by a bit that won't be lost at that stage, but is below the SFmode
6112 ;; rounding position.
6113 (define_expand "floatdisf2_internal2"
6114 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6116 (clobber (reg:DI CA_REGNO))])
6117 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6119 (set (match_dup 3) (plus:DI (match_dup 3)
6121 (set (match_dup 0) (plus:DI (match_dup 0)
6123 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6125 (set (match_dup 0) (ior:DI (match_dup 0)
6127 (set (match_dup 0) (and:DI (match_dup 0)
6129 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6130 (label_ref (match_operand:DI 2 "" ""))
6132 (set (match_dup 0) (match_dup 1))]
6133 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6137 operands[3] = gen_reg_rtx (DImode);
6138 operands[4] = gen_reg_rtx (CCUNSmode);
6141 (define_expand "floatunsdisf2"
6142 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6143 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6144 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6145 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6148 (define_insn "floatunsdisf2_fcfidus"
6149 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6150 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6151 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6152 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6156 [(set_attr "type" "fp")])
6158 (define_insn_and_split "*floatunsdisf2_mem"
6159 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6160 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6161 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6162 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6163 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6165 "&& reload_completed"
6169 emit_move_insn (operands[2], operands[1]);
6170 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6173 [(set_attr "length" "8")
6174 (set_attr "type" "fpload")])
6176 ;; Define the TImode operations that can be done in a small number
6177 ;; of instructions. The & constraints are to prevent the register
6178 ;; allocator from allocating registers that overlap with the inputs
6179 ;; (for example, having an input in 7,8 and an output in 6,7). We
6180 ;; also allow for the output being the same as one of the inputs.
6182 (define_expand "addti3"
6183 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6184 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6185 (match_operand:TI 2 "reg_or_short_operand" "")))]
6188 rtx lo0 = gen_lowpart (DImode, operands[0]);
6189 rtx lo1 = gen_lowpart (DImode, operands[1]);
6190 rtx lo2 = gen_lowpart (DImode, operands[2]);
6191 rtx hi0 = gen_highpart (DImode, operands[0]);
6192 rtx hi1 = gen_highpart (DImode, operands[1]);
6193 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6195 if (!reg_or_short_operand (lo2, DImode))
6196 lo2 = force_reg (DImode, lo2);
6197 if (!adde_operand (hi2, DImode))
6198 hi2 = force_reg (DImode, hi2);
6200 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6201 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6205 (define_expand "subti3"
6206 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6207 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6208 (match_operand:TI 2 "gpc_reg_operand" "")))]
6211 rtx lo0 = gen_lowpart (DImode, operands[0]);
6212 rtx lo1 = gen_lowpart (DImode, operands[1]);
6213 rtx lo2 = gen_lowpart (DImode, operands[2]);
6214 rtx hi0 = gen_highpart (DImode, operands[0]);
6215 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6216 rtx hi2 = gen_highpart (DImode, operands[2]);
6218 if (!reg_or_short_operand (lo1, DImode))
6219 lo1 = force_reg (DImode, lo1);
6220 if (!adde_operand (hi1, DImode))
6221 hi1 = force_reg (DImode, hi1);
6223 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6224 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6228 ;; 128-bit logical operations expanders
6230 (define_expand "and<mode>3"
6231 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6232 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6233 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6237 (define_expand "ior<mode>3"
6238 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6239 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6240 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6244 (define_expand "xor<mode>3"
6245 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6246 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6247 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6251 (define_expand "one_cmpl<mode>2"
6252 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6253 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6257 (define_expand "nor<mode>3"
6258 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6260 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6261 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6265 (define_expand "andc<mode>3"
6266 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6268 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6269 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6273 ;; Power8 vector logical instructions.
6274 (define_expand "eqv<mode>3"
6275 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6277 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6278 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6279 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6282 ;; Rewrite nand into canonical form
6283 (define_expand "nand<mode>3"
6284 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6286 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6287 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6288 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6291 ;; The canonical form is to have the negated element first, so we need to
6292 ;; reverse arguments.
6293 (define_expand "orc<mode>3"
6294 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6296 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6297 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6298 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6301 ;; 128-bit logical operations insns and split operations
6302 (define_insn_and_split "*and<mode>3_internal"
6303 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6305 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6306 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6309 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6310 return "xxland %x0,%x1,%x2";
6312 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6313 return "vand %0,%1,%2";
6317 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6320 rs6000_split_logical (operands, AND, false, false, false);
6325 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6326 (const_string "veclogical")
6327 (const_string "integer")))
6328 (set (attr "length")
6330 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6333 (match_test "TARGET_POWERPC64")
6335 (const_string "16"))))])
6338 (define_insn_and_split "*bool<mode>3_internal"
6339 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6340 (match_operator:BOOL_128 3 "boolean_or_operator"
6341 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6342 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6345 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6346 return "xxl%q3 %x0,%x1,%x2";
6348 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6349 return "v%q3 %0,%1,%2";
6353 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6356 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6361 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6362 (const_string "veclogical")
6363 (const_string "integer")))
6364 (set (attr "length")
6366 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6369 (match_test "TARGET_POWERPC64")
6371 (const_string "16"))))])
6374 (define_insn_and_split "*boolc<mode>3_internal1"
6375 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6376 (match_operator:BOOL_128 3 "boolean_operator"
6378 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6379 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6380 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6382 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6383 return "xxl%q3 %x0,%x1,%x2";
6385 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6386 return "v%q3 %0,%1,%2";
6390 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6391 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6394 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6399 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6400 (const_string "veclogical")
6401 (const_string "integer")))
6402 (set (attr "length")
6404 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6407 (match_test "TARGET_POWERPC64")
6409 (const_string "16"))))])
6411 (define_insn_and_split "*boolc<mode>3_internal2"
6412 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6413 (match_operator:TI2 3 "boolean_operator"
6415 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6416 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6417 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6419 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6422 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6425 [(set_attr "type" "integer")
6426 (set (attr "length")
6428 (match_test "TARGET_POWERPC64")
6430 (const_string "16")))])
6433 (define_insn_and_split "*boolcc<mode>3_internal1"
6434 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6435 (match_operator:BOOL_128 3 "boolean_operator"
6437 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6439 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6440 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6442 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6443 return "xxl%q3 %x0,%x1,%x2";
6445 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6446 return "v%q3 %0,%1,%2";
6450 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6451 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6454 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6459 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6460 (const_string "veclogical")
6461 (const_string "integer")))
6462 (set (attr "length")
6464 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6467 (match_test "TARGET_POWERPC64")
6469 (const_string "16"))))])
6471 (define_insn_and_split "*boolcc<mode>3_internal2"
6472 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6473 (match_operator:TI2 3 "boolean_operator"
6475 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6477 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6478 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6480 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6483 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6486 [(set_attr "type" "integer")
6487 (set (attr "length")
6489 (match_test "TARGET_POWERPC64")
6491 (const_string "16")))])
6495 (define_insn_and_split "*eqv<mode>3_internal1"
6496 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6499 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6500 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6503 if (vsx_register_operand (operands[0], <MODE>mode))
6504 return "xxleqv %x0,%x1,%x2";
6508 "TARGET_P8_VECTOR && reload_completed
6509 && int_reg_operand (operands[0], <MODE>mode)"
6512 rs6000_split_logical (operands, XOR, true, false, false);
6517 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6518 (const_string "veclogical")
6519 (const_string "integer")))
6520 (set (attr "length")
6522 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6525 (match_test "TARGET_POWERPC64")
6527 (const_string "16"))))])
6529 (define_insn_and_split "*eqv<mode>3_internal2"
6530 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6533 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6534 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6537 "reload_completed && !TARGET_P8_VECTOR"
6540 rs6000_split_logical (operands, XOR, true, false, false);
6543 [(set_attr "type" "integer")
6544 (set (attr "length")
6546 (match_test "TARGET_POWERPC64")
6548 (const_string "16")))])
6550 ;; 128-bit one's complement
6551 (define_insn_and_split "*one_cmpl<mode>3_internal"
6552 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6554 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6557 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6558 return "xxlnor %x0,%x1,%x1";
6560 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6561 return "vnor %0,%1,%1";
6565 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6568 rs6000_split_logical (operands, NOT, false, false, false);
6573 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6574 (const_string "veclogical")
6575 (const_string "integer")))
6576 (set (attr "length")
6578 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6581 (match_test "TARGET_POWERPC64")
6583 (const_string "16"))))])
6586 ;; Now define ways of moving data around.
6588 ;; Set up a register with a value from the GOT table
6590 (define_expand "movsi_got"
6591 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6592 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6593 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6594 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6597 if (GET_CODE (operands[1]) == CONST)
6599 rtx offset = const0_rtx;
6600 HOST_WIDE_INT value;
6602 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6603 value = INTVAL (offset);
6606 rtx tmp = (!can_create_pseudo_p ()
6608 : gen_reg_rtx (Pmode));
6609 emit_insn (gen_movsi_got (tmp, operands[1]));
6610 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6615 operands[2] = rs6000_got_register (operands[1]);
6618 (define_insn "*movsi_got_internal"
6619 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6620 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6621 (match_operand:SI 2 "gpc_reg_operand" "b")]
6623 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6624 "lwz %0,%a1@got(%2)"
6625 [(set_attr "type" "load")])
6627 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6628 ;; didn't get allocated to a hard register.
6630 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6631 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6632 (match_operand:SI 2 "memory_operand" "")]
6634 "DEFAULT_ABI == ABI_V4
6636 && (reload_in_progress || reload_completed)"
6637 [(set (match_dup 0) (match_dup 2))
6638 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6642 ;; For SI, we special-case integers that can't be loaded in one insn. We
6643 ;; do the load 16-bits at a time. We could do this by loading from memory,
6644 ;; and this is even supposed to be faster, but it is simpler not to get
6645 ;; integers in the TOC.
6646 (define_insn "movsi_low"
6647 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6648 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6649 (match_operand 2 "" ""))))]
6650 "TARGET_MACHO && ! TARGET_64BIT"
6651 "lwz %0,lo16(%2)(%1)"
6652 [(set_attr "type" "load")
6653 (set_attr "length" "4")])
6655 ;; MR LA LWZ LFIWZX LXSIWZX
6656 ;; STW STFIWX STXSIWX LI LIS
6657 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6658 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6659 ;; MF%1 MT%0 MT%0 NOP
6660 (define_insn "*movsi_internal1"
6661 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6662 "=r, r, r, ?*wI, ?*wH,
6664 r, ?*wIwH, ?*wJwK, ?*wK, ?*wJwK,
6665 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6668 (match_operand:SI 1 "input_operand"
6675 "!TARGET_SINGLE_FPU &&
6676 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6703 "*, *, load, fpload, fpload,
6704 store, fpstore, fpstore, *, *,
6705 *, veclogical, vecsimple, vecsimple, vecsimple,
6706 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6716 (define_insn "*movsi_internal1_single"
6717 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6718 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6719 "TARGET_SINGLE_FPU &&
6720 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6735 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6736 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6738 ;; Split a load of a large constant into the appropriate two-insn
6742 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6743 (match_operand:SI 1 "const_int_operand" ""))]
6744 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6745 && (INTVAL (operands[1]) & 0xffff) != 0"
6749 (ior:SI (match_dup 0)
6753 if (rs6000_emit_set_const (operands[0], operands[1]))
6759 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6761 [(set (match_operand:DI 0 "altivec_register_operand")
6762 (match_operand:DI 1 "xxspltib_constant_split"))]
6763 "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
6766 rtx op0 = operands[0];
6767 rtx op1 = operands[1];
6768 int r = REGNO (op0);
6769 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6771 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6772 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6776 (define_insn "*mov<mode>_internal2"
6777 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6778 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6780 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6786 [(set_attr "type" "cmp,logical,cmp")
6787 (set_attr "dot" "yes")
6788 (set_attr "length" "4,4,8")])
6791 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6792 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6794 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6796 [(set (match_dup 0) (match_dup 1))
6798 (compare:CC (match_dup 0)
6802 (define_expand "mov<mode>"
6803 [(set (match_operand:INT 0 "general_operand" "")
6804 (match_operand:INT 1 "any_operand" ""))]
6806 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6808 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
6809 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
6810 ;; MTVSRWZ MF%1 MT%1 NOP
6811 (define_insn "*mov<mode>_internal"
6812 [(set (match_operand:QHI 0 "nonimmediate_operand"
6813 "=r, r, ?*wJwK, m, Z, r,
6814 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
6815 ?*wJwK, r, *c*l, *h")
6817 (match_operand:QHI 1 "input_operand"
6818 "r, m, Z, r, wJwK, i,
6819 wJwK, O, wM, wB, wS, ?*wJwK,
6822 "gpc_reg_operand (operands[0], <MODE>mode)
6823 || gpc_reg_operand (operands[1], <MODE>mode)"
6842 "*, load, fpload, store, fpstore, *,
6843 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
6844 mffgpr, mfjmpr, mtjmpr, *")
6852 ;; Here is how to move condition codes around. When we store CC data in
6853 ;; an integer register or memory, we store just the high-order 4 bits.
6854 ;; This lets us not shift in the most common case of CR0.
6855 (define_expand "movcc"
6856 [(set (match_operand:CC 0 "nonimmediate_operand" "")
6857 (match_operand:CC 1 "nonimmediate_operand" ""))]
6861 (define_insn "*movcc_internal1"
6862 [(set (match_operand:CC 0 "nonimmediate_operand"
6863 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
6864 (match_operand:CC 1 "general_operand"
6865 " y,r, r,O,x,y,r,I,h, r,m,r"))]
6866 "register_operand (operands[0], CCmode)
6867 || register_operand (operands[1], CCmode)"
6871 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6874 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6882 (cond [(eq_attr "alternative" "0,3")
6883 (const_string "cr_logical")
6884 (eq_attr "alternative" "1,2")
6885 (const_string "mtcr")
6886 (eq_attr "alternative" "6,7")
6887 (const_string "integer")
6888 (eq_attr "alternative" "8")
6889 (const_string "mfjmpr")
6890 (eq_attr "alternative" "9")
6891 (const_string "mtjmpr")
6892 (eq_attr "alternative" "10")
6893 (const_string "load")
6894 (eq_attr "alternative" "11")
6895 (const_string "store")
6896 (match_test "TARGET_MFCRF")
6897 (const_string "mfcrf")
6899 (const_string "mfcr")))
6900 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6902 ;; For floating-point, we normally deal with the floating-point registers
6903 ;; unless -msoft-float is used. The sole exception is that parameter passing
6904 ;; can produce floating-point values in fixed-point registers. Unless the
6905 ;; value is a simple constant or already in memory, we deal with this by
6906 ;; allocating memory and copying the value explicitly via that memory location.
6908 ;; Move 32-bit binary/decimal floating point
6909 (define_expand "mov<mode>"
6910 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6911 (match_operand:FMOVE32 1 "any_operand" ""))]
6913 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6916 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6917 (match_operand:FMOVE32 1 "const_double_operand" ""))]
6919 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6920 || (GET_CODE (operands[0]) == SUBREG
6921 && GET_CODE (SUBREG_REG (operands[0])) == REG
6922 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6923 [(set (match_dup 2) (match_dup 3))]
6928 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6930 if (! TARGET_POWERPC64)
6931 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6933 operands[2] = gen_lowpart (SImode, operands[0]);
6935 operands[3] = gen_int_mode (l, SImode);
6938 (define_insn "mov<mode>_hardfloat"
6939 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
6940 "=!r, <f32_lr>, <f32_lr2>, <f32_av>, m, <f32_sm>,
6941 <f32_sm2>, Z, <f32_vsx>, !r, ?<f32_dm>, ?r,
6942 f, <f32_vsx>, !r, *c*l, !r, *h")
6943 (match_operand:FMOVE32 1 "input_operand"
6944 "m, <f32_lm>, <f32_lm2>, Z, r, <f32_sr>,
6945 <f32_sr2>, <f32_av>, <zero_fp>, <zero_fp>, r, <f32_dm>,
6946 f, <f32_vsx>, r, r, *h, 0"))]
6947 "(gpc_reg_operand (operands[0], <MODE>mode)
6948 || gpc_reg_operand (operands[1], <MODE>mode))
6949 && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6964 xscpsgndp %x0,%x1,%x1
6969 [(set_attr "type" "load,fpload,fpload,fpload,store,fpstore,fpstore,fpstore,veclogical,integer,mffgpr,mftgpr,fpsimple,fpsimple,*,mtjmpr,mfjmpr,*")])
6971 (define_insn "*mov<mode>_softfloat"
6972 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6973 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6974 "(gpc_reg_operand (operands[0], <MODE>mode)
6975 || gpc_reg_operand (operands[1], <MODE>mode))
6976 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6988 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6989 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6992 ;; Move 64-bit binary/decimal floating point
6993 (define_expand "mov<mode>"
6994 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6995 (match_operand:FMOVE64 1 "any_operand" ""))]
6997 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7000 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7001 (match_operand:FMOVE64 1 "const_int_operand" ""))]
7002 "! TARGET_POWERPC64 && reload_completed
7003 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7004 || (GET_CODE (operands[0]) == SUBREG
7005 && GET_CODE (SUBREG_REG (operands[0])) == REG
7006 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7007 [(set (match_dup 2) (match_dup 4))
7008 (set (match_dup 3) (match_dup 1))]
7011 int endian = (WORDS_BIG_ENDIAN == 0);
7012 HOST_WIDE_INT value = INTVAL (operands[1]);
7014 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7015 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7016 operands[4] = GEN_INT (value >> 32);
7017 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7021 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7022 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7023 "! TARGET_POWERPC64 && reload_completed
7024 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7025 || (GET_CODE (operands[0]) == SUBREG
7026 && GET_CODE (SUBREG_REG (operands[0])) == REG
7027 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7028 [(set (match_dup 2) (match_dup 4))
7029 (set (match_dup 3) (match_dup 5))]
7032 int endian = (WORDS_BIG_ENDIAN == 0);
7035 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7037 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7038 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7039 operands[4] = gen_int_mode (l[endian], SImode);
7040 operands[5] = gen_int_mode (l[1 - endian], SImode);
7044 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7045 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7046 "TARGET_POWERPC64 && reload_completed
7047 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7048 || (GET_CODE (operands[0]) == SUBREG
7049 && GET_CODE (SUBREG_REG (operands[0])) == REG
7050 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7051 [(set (match_dup 2) (match_dup 3))]
7054 int endian = (WORDS_BIG_ENDIAN == 0);
7058 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7060 operands[2] = gen_lowpart (DImode, operands[0]);
7061 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7062 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7063 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7065 operands[3] = gen_int_mode (val, DImode);
7068 ;; Don't have reload use general registers to load a constant. It is
7069 ;; less efficient than loading the constant into an FP register, since
7070 ;; it will probably be used there.
7072 ;; The move constraints are ordered to prefer floating point registers before
7073 ;; general purpose registers to avoid doing a store and a load to get the value
7074 ;; into a floating point register when it is needed for a floating point
7075 ;; operation. Prefer traditional floating point registers over VSX registers,
7076 ;; since the D-form version of the memory instructions does not need a GPR for
7077 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7080 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7081 ;; except for 0.0 which can be created on VSX with an xor instruction.
7083 (define_insn "*mov<mode>_hardfloat32"
7084 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7085 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7086 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7087 && (gpc_reg_operand (operands[0], <MODE>mode)
7088 || gpc_reg_operand (operands[1], <MODE>mode))"
7103 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7104 (set_attr "size" "64")
7105 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7107 (define_insn "*mov<mode>_softfloat32"
7108 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7109 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7111 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
7112 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
7113 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
7114 && (gpc_reg_operand (operands[0], <MODE>mode)
7115 || gpc_reg_operand (operands[1], <MODE>mode))"
7117 [(set_attr "type" "store,load,two,*,*,*")
7118 (set_attr "length" "8,8,8,8,12,16")])
7120 ; ld/std require word-aligned displacements -> 'Y' constraint.
7121 ; List Y->r and r->Y before r->r for reload.
7122 (define_insn "*mov<mode>_hardfloat64"
7123 [(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>")
7124 (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"))]
7125 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7126 && (gpc_reg_operand (operands[0], <MODE>mode)
7127 || gpc_reg_operand (operands[1], <MODE>mode))"
7149 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7150 (set_attr "size" "64")
7151 (set_attr "length" "4")])
7153 (define_insn "*mov<mode>_softfloat64"
7154 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7155 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7156 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7157 && (gpc_reg_operand (operands[0], <MODE>mode)
7158 || gpc_reg_operand (operands[1], <MODE>mode))"
7169 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7170 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7172 (define_expand "mov<mode>"
7173 [(set (match_operand:FMOVE128 0 "general_operand" "")
7174 (match_operand:FMOVE128 1 "any_operand" ""))]
7176 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7178 ;; It's important to list Y->r and r->Y before r->r because otherwise
7179 ;; reload, given m->r, will try to pick r->r and reload it, which
7180 ;; doesn't make progress.
7182 ;; We can't split little endian direct moves of TDmode, because the words are
7183 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7184 ;; problematical. Don't allow direct move for this case.
7186 (define_insn_and_split "*mov<mode>_64bit_dm"
7187 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7188 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7189 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7190 && FLOAT128_2REG_P (<MODE>mode)
7191 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7192 && (gpc_reg_operand (operands[0], <MODE>mode)
7193 || gpc_reg_operand (operands[1], <MODE>mode))"
7195 "&& reload_completed"
7197 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7198 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7200 (define_insn_and_split "*movtd_64bit_nodm"
7201 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7202 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7203 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7204 && (gpc_reg_operand (operands[0], TDmode)
7205 || gpc_reg_operand (operands[1], TDmode))"
7207 "&& reload_completed"
7209 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7210 [(set_attr "length" "8,8,8,12,12,8")])
7212 (define_insn_and_split "*mov<mode>_32bit"
7213 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7214 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7215 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7216 && (FLOAT128_2REG_P (<MODE>mode)
7217 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7218 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7219 && (gpc_reg_operand (operands[0], <MODE>mode)
7220 || gpc_reg_operand (operands[1], <MODE>mode))"
7222 "&& reload_completed"
7224 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7225 [(set_attr "length" "8,8,8,8,20,20,16")])
7227 (define_insn_and_split "*mov<mode>_softfloat"
7228 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7229 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7230 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7231 && (gpc_reg_operand (operands[0], <MODE>mode)
7232 || gpc_reg_operand (operands[1], <MODE>mode))"
7234 "&& reload_completed"
7236 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7237 [(set_attr "length" "20,20,16")])
7239 (define_expand "extenddf<mode>2"
7240 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7241 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7242 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7243 && TARGET_LONG_DOUBLE_128"
7245 if (FLOAT128_IEEE_P (<MODE>mode))
7246 rs6000_expand_float128_convert (operands[0], operands[1], false);
7247 else if (TARGET_E500_DOUBLE)
7249 gcc_assert (<MODE>mode == TFmode);
7250 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7252 else if (TARGET_VSX)
7254 if (<MODE>mode == TFmode)
7255 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7256 else if (<MODE>mode == IFmode)
7257 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7263 rtx zero = gen_reg_rtx (DFmode);
7264 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7266 if (<MODE>mode == TFmode)
7267 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7268 else if (<MODE>mode == IFmode)
7269 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7276 ;; Allow memory operands for the source to be created by the combiner.
7277 (define_insn_and_split "extenddf<mode>2_fprs"
7278 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7279 (float_extend:IBM128
7280 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7281 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7282 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7283 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7285 "&& reload_completed"
7286 [(set (match_dup 3) (match_dup 1))
7287 (set (match_dup 4) (match_dup 2))]
7289 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7290 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7292 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7293 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7296 (define_insn_and_split "extenddf<mode>2_vsx"
7297 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7298 (float_extend:IBM128
7299 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7300 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7302 "&& reload_completed"
7303 [(set (match_dup 2) (match_dup 1))
7304 (set (match_dup 3) (match_dup 4))]
7306 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7307 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7309 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7310 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7311 operands[4] = CONST0_RTX (DFmode);
7314 (define_expand "extendsf<mode>2"
7315 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7316 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7318 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7319 && TARGET_LONG_DOUBLE_128"
7321 if (FLOAT128_IEEE_P (<MODE>mode))
7322 rs6000_expand_float128_convert (operands[0], operands[1], false);
7325 rtx tmp = gen_reg_rtx (DFmode);
7326 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7327 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7332 (define_expand "trunc<mode>df2"
7333 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7334 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7336 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7337 && TARGET_LONG_DOUBLE_128"
7339 if (FLOAT128_IEEE_P (<MODE>mode))
7341 rs6000_expand_float128_convert (operands[0], operands[1], false);
7346 (define_insn_and_split "trunc<mode>df2_internal1"
7347 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7349 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7350 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7351 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7355 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7358 emit_note (NOTE_INSN_DELETED);
7361 [(set_attr "type" "fpsimple")])
7363 (define_insn "trunc<mode>df2_internal2"
7364 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7365 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7366 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7367 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7369 [(set_attr "type" "fp")
7370 (set_attr "fp_type" "fp_addsub_d")])
7372 (define_expand "trunc<mode>sf2"
7373 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7374 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7376 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7377 && TARGET_LONG_DOUBLE_128"
7379 if (FLOAT128_IEEE_P (<MODE>mode))
7380 rs6000_expand_float128_convert (operands[0], operands[1], false);
7381 else if (TARGET_E500_DOUBLE)
7383 gcc_assert (<MODE>mode == TFmode);
7384 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7386 else if (<MODE>mode == TFmode)
7387 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7388 else if (<MODE>mode == IFmode)
7389 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7395 (define_insn_and_split "trunc<mode>sf2_fprs"
7396 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7397 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7398 (clobber (match_scratch:DF 2 "=d"))]
7399 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7400 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7402 "&& reload_completed"
7404 (float_truncate:DF (match_dup 1)))
7406 (float_truncate:SF (match_dup 2)))]
7409 (define_expand "floatsi<mode>2"
7410 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7411 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7413 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7414 && TARGET_LONG_DOUBLE_128"
7416 if (FLOAT128_IEEE_P (<MODE>mode))
7417 rs6000_expand_float128_convert (operands[0], operands[1], false);
7420 rtx tmp = gen_reg_rtx (DFmode);
7421 expand_float (tmp, operands[1], false);
7422 if (<MODE>mode == TFmode)
7423 emit_insn (gen_extenddftf2 (operands[0], tmp));
7424 else if (<MODE>mode == IFmode)
7425 emit_insn (gen_extenddfif2 (operands[0], tmp));
7432 ; fadd, but rounding towards zero.
7433 ; This is probably not the optimal code sequence.
7434 (define_insn "fix_trunc_helper<mode>"
7435 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7436 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7437 UNSPEC_FIX_TRUNC_TF))
7438 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7439 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7440 && FLOAT128_IBM_P (<MODE>mode)"
7441 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7442 [(set_attr "type" "fp")
7443 (set_attr "length" "20")])
7445 (define_expand "fix_trunc<mode>si2"
7446 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7447 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7449 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7451 if (FLOAT128_IEEE_P (<MODE>mode))
7452 rs6000_expand_float128_convert (operands[0], operands[1], false);
7453 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7454 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7455 else if (<MODE>mode == TFmode)
7456 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7457 else if (<MODE>mode == IFmode)
7458 emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7464 (define_expand "fix_trunc<mode>si2_fprs"
7465 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7466 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7467 (clobber (match_dup 2))
7468 (clobber (match_dup 3))
7469 (clobber (match_dup 4))
7470 (clobber (match_dup 5))])]
7471 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7473 operands[2] = gen_reg_rtx (DFmode);
7474 operands[3] = gen_reg_rtx (DFmode);
7475 operands[4] = gen_reg_rtx (DImode);
7476 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7479 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7480 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7481 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7482 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7483 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7484 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7485 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7486 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7492 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7495 gcc_assert (MEM_P (operands[5]));
7496 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7498 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7499 emit_move_insn (operands[5], operands[4]);
7500 emit_move_insn (operands[0], lowword);
7504 (define_expand "fix_trunc<mode>di2"
7505 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7506 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7507 "TARGET_FLOAT128_TYPE"
7509 rs6000_expand_float128_convert (operands[0], operands[1], false);
7513 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7514 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7515 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7516 "TARGET_FLOAT128_TYPE"
7518 rs6000_expand_float128_convert (operands[0], operands[1], true);
7522 (define_expand "floatdi<mode>2"
7523 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7524 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7525 "TARGET_FLOAT128_TYPE"
7527 rs6000_expand_float128_convert (operands[0], operands[1], false);
7531 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7532 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7533 (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7534 "TARGET_FLOAT128_TYPE"
7536 rs6000_expand_float128_convert (operands[0], operands[1], true);
7540 (define_expand "neg<mode>2"
7541 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7542 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7543 "FLOAT128_IEEE_P (<MODE>mode)
7544 || (FLOAT128_IBM_P (<MODE>mode)
7545 && TARGET_HARD_FLOAT
7546 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7549 if (FLOAT128_IEEE_P (<MODE>mode))
7551 if (TARGET_FLOAT128_HW)
7553 if (<MODE>mode == TFmode)
7554 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7555 else if (<MODE>mode == KFmode)
7556 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7560 else if (TARGET_FLOAT128_TYPE)
7562 if (<MODE>mode == TFmode)
7563 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7564 else if (<MODE>mode == KFmode)
7565 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7571 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7572 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7574 operands[1], <MODE>mode);
7576 if (target && !rtx_equal_p (target, operands[0]))
7577 emit_move_insn (operands[0], target);
7583 (define_insn "neg<mode>2_internal"
7584 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7585 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7586 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7589 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7590 return \"fneg %L0,%L1\;fneg %0,%1\";
7592 return \"fneg %0,%1\;fneg %L0,%L1\";
7594 [(set_attr "type" "fpsimple")
7595 (set_attr "length" "8")])
7597 (define_expand "abs<mode>2"
7598 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7599 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7600 "FLOAT128_IEEE_P (<MODE>mode)
7601 || (FLOAT128_IBM_P (<MODE>mode)
7602 && TARGET_HARD_FLOAT
7603 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7608 if (FLOAT128_IEEE_P (<MODE>mode))
7610 if (TARGET_FLOAT128_HW)
7612 if (<MODE>mode == TFmode)
7613 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7614 else if (<MODE>mode == KFmode)
7615 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7620 else if (TARGET_FLOAT128_TYPE)
7622 if (<MODE>mode == TFmode)
7623 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7624 else if (<MODE>mode == KFmode)
7625 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7634 label = gen_label_rtx ();
7635 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7637 if (flag_finite_math_only && !flag_trapping_math)
7638 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7640 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7642 else if (<MODE>mode == TFmode)
7643 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7644 else if (<MODE>mode == TFmode)
7645 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7652 (define_expand "abs<mode>2_internal"
7653 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7654 (match_operand:IBM128 1 "gpc_reg_operand" ""))
7655 (set (match_dup 3) (match_dup 5))
7656 (set (match_dup 5) (abs:DF (match_dup 5)))
7657 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7658 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7659 (label_ref (match_operand 2 "" ""))
7661 (set (match_dup 6) (neg:DF (match_dup 6)))]
7662 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7663 && TARGET_LONG_DOUBLE_128"
7666 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7667 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7668 operands[3] = gen_reg_rtx (DFmode);
7669 operands[4] = gen_reg_rtx (CCFPmode);
7670 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7671 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7675 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7678 (define_expand "ieee_128bit_negative_zero"
7679 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7680 "TARGET_FLOAT128_TYPE"
7682 rtvec v = rtvec_alloc (16);
7685 for (i = 0; i < 16; i++)
7686 RTVEC_ELT (v, i) = const0_rtx;
7688 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7689 RTVEC_ELT (v, high) = GEN_INT (0x80);
7691 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7695 ;; IEEE 128-bit negate
7697 ;; We have 2 insns here for negate and absolute value. The first uses
7698 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7699 ;; insns, and second insn after the first split pass loads up the bit to
7700 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
7701 ;; neg/abs to create the constant just once.
7703 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7704 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7705 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7706 (clobber (match_scratch:V16QI 2 "=v"))]
7707 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7710 [(parallel [(set (match_dup 0)
7711 (neg:IEEE128 (match_dup 1)))
7712 (use (match_dup 2))])]
7714 if (GET_CODE (operands[2]) == SCRATCH)
7715 operands[2] = gen_reg_rtx (V16QImode);
7717 operands[3] = gen_reg_rtx (V16QImode);
7718 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7720 [(set_attr "length" "8")
7721 (set_attr "type" "vecsimple")])
7723 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7724 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7725 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7726 (use (match_operand:V16QI 2 "register_operand" "v"))]
7727 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7728 "xxlxor %x0,%x1,%x2"
7729 [(set_attr "type" "veclogical")])
7731 ;; IEEE 128-bit absolute value
7732 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7733 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7734 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7735 (clobber (match_scratch:V16QI 2 "=v"))]
7736 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7739 [(parallel [(set (match_dup 0)
7740 (abs:IEEE128 (match_dup 1)))
7741 (use (match_dup 2))])]
7743 if (GET_CODE (operands[2]) == SCRATCH)
7744 operands[2] = gen_reg_rtx (V16QImode);
7746 operands[3] = gen_reg_rtx (V16QImode);
7747 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7749 [(set_attr "length" "8")
7750 (set_attr "type" "vecsimple")])
7752 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7753 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7754 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7755 (use (match_operand:V16QI 2 "register_operand" "v"))]
7756 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7757 "xxlandc %x0,%x1,%x2"
7758 [(set_attr "type" "veclogical")])
7760 ;; IEEE 128-bit negative absolute value
7761 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7762 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7765 (match_operand:IEEE128 1 "register_operand" "wa"))))
7766 (clobber (match_scratch:V16QI 2 "=v"))]
7767 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
7768 && FLOAT128_IEEE_P (<MODE>mode)"
7771 [(parallel [(set (match_dup 0)
7772 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7773 (use (match_dup 2))])]
7775 if (GET_CODE (operands[2]) == SCRATCH)
7776 operands[2] = gen_reg_rtx (V16QImode);
7778 operands[3] = gen_reg_rtx (V16QImode);
7779 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7781 [(set_attr "length" "8")
7782 (set_attr "type" "vecsimple")])
7784 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7785 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7788 (match_operand:IEEE128 1 "register_operand" "wa"))))
7789 (use (match_operand:V16QI 2 "register_operand" "v"))]
7790 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7792 [(set_attr "type" "veclogical")])
7794 ;; Float128 conversion functions. These expand to library function calls.
7795 ;; We use expand to convert from IBM double double to IEEE 128-bit
7796 ;; and trunc for the opposite.
7797 (define_expand "extendiftf2"
7798 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7799 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7800 "TARGET_FLOAT128_TYPE"
7802 rs6000_expand_float128_convert (operands[0], operands[1], false);
7806 (define_expand "extendifkf2"
7807 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7808 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7809 "TARGET_FLOAT128_TYPE"
7811 rs6000_expand_float128_convert (operands[0], operands[1], false);
7815 (define_expand "extendtfkf2"
7816 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7817 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7818 "TARGET_FLOAT128_TYPE"
7820 rs6000_expand_float128_convert (operands[0], operands[1], false);
7824 (define_expand "trunciftf2"
7825 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7826 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7827 "TARGET_FLOAT128_TYPE"
7829 rs6000_expand_float128_convert (operands[0], operands[1], false);
7833 (define_expand "truncifkf2"
7834 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7835 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7836 "TARGET_FLOAT128_TYPE"
7838 rs6000_expand_float128_convert (operands[0], operands[1], false);
7842 (define_expand "trunckftf2"
7843 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7844 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7845 "TARGET_FLOAT128_TYPE"
7847 rs6000_expand_float128_convert (operands[0], operands[1], false);
7851 (define_expand "trunctfif2"
7852 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7853 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7854 "TARGET_FLOAT128_TYPE"
7856 rs6000_expand_float128_convert (operands[0], operands[1], false);
7861 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
7862 ;; must have 3 arguments, and scratch register constraint must be a single
7865 ;; Reload patterns to support gpr load/store with misaligned mem.
7866 ;; and multiple gpr load/store at offset >= 0xfffc
7867 (define_expand "reload_<mode>_store"
7868 [(parallel [(match_operand 0 "memory_operand" "=m")
7869 (match_operand 1 "gpc_reg_operand" "r")
7870 (match_operand:GPR 2 "register_operand" "=&b")])]
7873 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7877 (define_expand "reload_<mode>_load"
7878 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7879 (match_operand 1 "memory_operand" "m")
7880 (match_operand:GPR 2 "register_operand" "=b")])]
7883 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7888 ;; Reload patterns for various types using the vector registers. We may need
7889 ;; an additional base register to convert the reg+offset addressing to reg+reg
7890 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7891 ;; index register for gpr registers.
7892 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7893 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7894 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7895 (match_operand:P 2 "register_operand" "=b")])]
7898 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7902 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7903 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7904 (match_operand:RELOAD 1 "memory_operand" "m")
7905 (match_operand:P 2 "register_operand" "=b")])]
7908 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7913 ;; Reload sometimes tries to move the address to a GPR, and can generate
7914 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
7915 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7917 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7918 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7919 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7920 (match_operand:P 2 "reg_or_cint_operand" "rI"))
7922 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7924 "&& reload_completed"
7926 (plus:P (match_dup 1)
7929 (and:P (match_dup 0)
7932 ;; Power8 merge instructions to allow direct move to/from floating point
7933 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
7934 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
7935 ;; value, since it is allocated in reload and not all of the flow information
7936 ;; is setup for it. We have two patterns to do the two moves between gprs and
7937 ;; fprs. There isn't a dependancy between the two, but we could potentially
7938 ;; schedule other instructions between the two instructions.
7940 (define_insn "p8_fmrgow_<mode>"
7941 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7943 (match_operand:DF 1 "register_operand" "d")
7944 (match_operand:DF 2 "register_operand" "d")]
7945 UNSPEC_P8V_FMRGOW))]
7946 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7948 [(set_attr "type" "fpsimple")])
7950 (define_insn "p8_mtvsrwz"
7951 [(set (match_operand:DF 0 "register_operand" "=d")
7952 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7953 UNSPEC_P8V_MTVSRWZ))]
7954 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7956 [(set_attr "type" "mftgpr")])
7958 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7959 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7960 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7961 UNSPEC_P8V_RELOAD_FROM_GPR))
7962 (clobber (match_operand:IF 2 "register_operand" "=d"))]
7963 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7965 "&& reload_completed"
7968 rtx dest = operands[0];
7969 rtx src = operands[1];
7970 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7971 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7972 rtx gpr_hi_reg = gen_highpart (SImode, src);
7973 rtx gpr_lo_reg = gen_lowpart (SImode, src);
7975 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7976 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7977 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7980 [(set_attr "length" "12")
7981 (set_attr "type" "three")])
7983 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7984 (define_insn "p8_mtvsrd_df"
7985 [(set (match_operand:DF 0 "register_operand" "=wa")
7986 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7987 UNSPEC_P8V_MTVSRD))]
7988 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7990 [(set_attr "type" "mftgpr")])
7992 (define_insn "p8_xxpermdi_<mode>"
7993 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7994 (unspec:FMOVE128_GPR [
7995 (match_operand:DF 1 "register_operand" "wa")
7996 (match_operand:DF 2 "register_operand" "wa")]
7997 UNSPEC_P8V_XXPERMDI))]
7998 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7999 "xxpermdi %x0,%x1,%x2,0"
8000 [(set_attr "type" "vecperm")])
8002 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8003 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8004 (unspec:FMOVE128_GPR
8005 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8006 UNSPEC_P8V_RELOAD_FROM_GPR))
8007 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8008 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8010 "&& reload_completed"
8013 rtx dest = operands[0];
8014 rtx src = operands[1];
8015 /* You might think that we could use op0 as one temp and a DF clobber
8016 as op2, but you'd be wrong. Secondary reload move patterns don't
8017 check for overlap of the clobber and the destination. */
8018 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8019 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8020 rtx gpr_hi_reg = gen_highpart (DImode, src);
8021 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8023 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8024 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8025 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8028 [(set_attr "length" "12")
8029 (set_attr "type" "three")])
8032 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8033 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8035 && (int_reg_operand (operands[0], <MODE>mode)
8036 || int_reg_operand (operands[1], <MODE>mode))
8037 && (!TARGET_DIRECT_MOVE_128
8038 || (!vsx_register_operand (operands[0], <MODE>mode)
8039 && !vsx_register_operand (operands[1], <MODE>mode)))"
8041 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8043 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8044 ;; type is stored internally as double precision in the VSX registers, we have
8045 ;; to convert it from the vector format.
8046 (define_insn "p8_mtvsrd_sf"
8047 [(set (match_operand:SF 0 "register_operand" "=wa")
8048 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8049 UNSPEC_P8V_MTVSRD))]
8050 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8052 [(set_attr "type" "mftgpr")])
8054 (define_insn_and_split "reload_vsx_from_gprsf"
8055 [(set (match_operand:SF 0 "register_operand" "=wa")
8056 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8057 UNSPEC_P8V_RELOAD_FROM_GPR))
8058 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8059 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8061 "&& reload_completed"
8064 rtx op0 = operands[0];
8065 rtx op1 = operands[1];
8066 rtx op2 = operands[2];
8067 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8069 /* Move SF value to upper 32-bits for xscvspdpn. */
8070 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8071 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8072 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8075 [(set_attr "length" "8")
8076 (set_attr "type" "two")])
8078 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8079 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8080 ;; and then doing a move of that.
8081 (define_insn "p8_mfvsrd_3_<mode>"
8082 [(set (match_operand:DF 0 "register_operand" "=r")
8083 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8084 UNSPEC_P8V_RELOAD_FROM_VSX))]
8085 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8087 [(set_attr "type" "mftgpr")])
8089 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8090 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8091 (unspec:FMOVE128_GPR
8092 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8093 UNSPEC_P8V_RELOAD_FROM_VSX))
8094 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8095 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8097 "&& reload_completed"
8100 rtx dest = operands[0];
8101 rtx src = operands[1];
8102 rtx tmp = operands[2];
8103 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8104 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8106 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8107 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
8108 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8111 [(set_attr "length" "12")
8112 (set_attr "type" "three")])
8114 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8115 ;; type is stored internally as double precision, we have to convert it to the
8118 (define_insn_and_split "reload_gpr_from_vsxsf"
8119 [(set (match_operand:SF 0 "register_operand" "=r")
8120 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8121 UNSPEC_P8V_RELOAD_FROM_VSX))
8122 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8123 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8125 "&& reload_completed"
8128 rtx op0 = operands[0];
8129 rtx op1 = operands[1];
8130 rtx op2 = operands[2];
8131 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8133 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8134 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8135 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8138 [(set_attr "length" "12")
8139 (set_attr "type" "three")])
8141 (define_insn "p8_mfvsrd_4_disf"
8142 [(set (match_operand:DI 0 "register_operand" "=r")
8143 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8144 UNSPEC_P8V_RELOAD_FROM_VSX))]
8145 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8147 [(set_attr "type" "mftgpr")])
8150 ;; Next come the multi-word integer load and store and the load and store
8153 ;; List r->r after r->Y, otherwise reload will try to reload a
8154 ;; non-offsettable address by using r->r which won't make progress.
8155 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8156 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8158 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8159 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8160 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8163 (define_insn "*movdi_internal32"
8164 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8165 "=Y, r, r, ^m, ^d, ^d,
8166 r, ^wY, $Z, ^wb, $wv, ^wi,
8167 *wo, *wo, *wv, *wi, *wi, *wv,
8170 (match_operand:DI 1 "input_operand"
8172 IJKnGHF, wb, wv, wY, Z, wi,
8173 Oj, wM, OjwM, Oj, wM, wS,
8177 && (gpc_reg_operand (operands[0], DImode)
8178 || gpc_reg_operand (operands[1], DImode))"
8200 "store, load, *, fpstore, fpload, fpsimple,
8201 *, fpstore, fpstore, fpload, fpload, veclogical,
8202 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8204 (set_attr "size" "64")])
8207 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8208 (match_operand:DI 1 "const_int_operand" ""))]
8209 "! TARGET_POWERPC64 && reload_completed
8210 && gpr_or_gpr_p (operands[0], operands[1])
8211 && !direct_move_p (operands[0], operands[1])"
8212 [(set (match_dup 2) (match_dup 4))
8213 (set (match_dup 3) (match_dup 1))]
8216 HOST_WIDE_INT value = INTVAL (operands[1]);
8217 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8219 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8221 operands[4] = GEN_INT (value >> 32);
8222 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8226 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8227 (match_operand:DIFD 1 "input_operand" ""))]
8228 "reload_completed && !TARGET_POWERPC64
8229 && gpr_or_gpr_p (operands[0], operands[1])
8230 && !direct_move_p (operands[0], operands[1])"
8232 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8234 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8235 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8236 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8237 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8238 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8239 (define_insn "*movdi_internal64"
8240 [(set (match_operand:DI 0 "nonimmediate_operand"
8242 ^m, ^d, ^d, ^Y, $Z, $wb,
8243 $wv, ^wi, *wo, *wo, *wv, *wi,
8244 *wi, *wv, *wv, r, *h, *h,
8245 ?*r, ?*wg, ?*r, ?*wj")
8247 (match_operand:DI 1 "input_operand"
8249 d, m, d, wb, wv, wY,
8250 Z, wi, Oj, wM, OjwM, Oj,
8251 wM, wS, wB, *h, r, 0,
8255 && (gpc_reg_operand (operands[0], DImode)
8256 || gpc_reg_operand (operands[1], DImode))"
8287 "store, load, *, *, *, *,
8288 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8289 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8290 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8291 mftgpr, mffgpr, mftgpr, mffgpr")
8293 (set_attr "size" "64")
8301 ; Some DImode loads are best done as a load of -1 followed by a mask
8304 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8305 (match_operand:DI 1 "const_int_operand"))]
8307 && num_insns_constant (operands[1], DImode) > 1
8308 && rs6000_is_valid_and_mask (operands[1], DImode)"
8312 (and:DI (match_dup 0)
8316 ;; Split a load of a large constant into the appropriate five-instruction
8317 ;; sequence. Handle anything in a constant number of insns.
8318 ;; When non-easy constants can go in the TOC, this should use
8319 ;; easy_fp_constant predicate.
8321 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8322 (match_operand:DI 1 "const_int_operand" ""))]
8323 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8324 [(set (match_dup 0) (match_dup 2))
8325 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8328 if (rs6000_emit_set_const (operands[0], operands[1]))
8335 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8336 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8337 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8338 [(set (match_dup 0) (match_dup 2))
8339 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8342 if (rs6000_emit_set_const (operands[0], operands[1]))
8349 [(set (match_operand:DI 0 "altivec_register_operand" "")
8350 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8351 "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8354 rtx op0 = operands[0];
8355 rtx op1 = operands[1];
8356 int r = REGNO (op0);
8357 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8359 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8360 if (op1 != const0_rtx && op1 != constm1_rtx)
8362 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8363 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8368 ;; Split integer constants that can be loaded with XXSPLTIB and a
8369 ;; sign extend operation.
8371 [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8372 (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8373 "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8376 rtx op0 = operands[0];
8377 rtx op1 = operands[1];
8378 int r = REGNO (op0);
8379 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8381 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8382 if (<MODE>mode == DImode)
8383 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8384 else if (<MODE>mode == SImode)
8385 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8386 else if (<MODE>mode == HImode)
8388 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8389 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8395 ;; TImode/PTImode is similar, except that we usually want to compute the
8396 ;; address into a register and use lsi/stsi (the exception is during reload).
8398 (define_insn "*mov<mode>_string"
8399 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8400 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8402 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8403 && (gpc_reg_operand (operands[0], <MODE>mode)
8404 || gpc_reg_operand (operands[1], <MODE>mode))"
8407 switch (which_alternative)
8413 return \"stswi %1,%P0,16\";
8418 /* If the address is not used in the output, we can use lsi. Otherwise,
8419 fall through to generating four loads. */
8421 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8422 return \"lswi %0,%P1,16\";
8430 [(set_attr "type" "store,store,load,load,*,*")
8431 (set_attr "update" "yes")
8432 (set_attr "indexed" "yes")
8433 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8434 (const_string "always")
8435 (const_string "conditional")))])
8437 (define_insn "*mov<mode>_ppc64"
8438 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8439 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8440 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8441 && (gpc_reg_operand (operands[0], <MODE>mode)
8442 || gpc_reg_operand (operands[1], <MODE>mode)))"
8444 return rs6000_output_move_128bit (operands);
8446 [(set_attr "type" "store,store,load,load,*,*")
8447 (set_attr "length" "8")])
8450 [(set (match_operand:TI2 0 "int_reg_operand" "")
8451 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8453 && (VECTOR_MEM_NONE_P (<MODE>mode)
8454 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8455 [(set (match_dup 2) (match_dup 4))
8456 (set (match_dup 3) (match_dup 5))]
8459 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8461 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8463 if (CONST_WIDE_INT_P (operands[1]))
8465 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8466 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8468 else if (CONST_INT_P (operands[1]))
8470 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8471 operands[5] = operands[1];
8478 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8479 (match_operand:TI2 1 "input_operand" ""))]
8481 && gpr_or_gpr_p (operands[0], operands[1])
8482 && !direct_move_p (operands[0], operands[1])
8483 && !quad_load_store_p (operands[0], operands[1])"
8485 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8487 (define_expand "load_multiple"
8488 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8489 (match_operand:SI 1 "" ""))
8490 (use (match_operand:SI 2 "" ""))])]
8491 "TARGET_STRING && !TARGET_POWERPC64"
8499 /* Support only loading a constant number of fixed-point registers from
8500 memory and only bother with this if more than two; the machine
8501 doesn't support more than eight. */
8502 if (GET_CODE (operands[2]) != CONST_INT
8503 || INTVAL (operands[2]) <= 2
8504 || INTVAL (operands[2]) > 8
8505 || GET_CODE (operands[1]) != MEM
8506 || GET_CODE (operands[0]) != REG
8507 || REGNO (operands[0]) >= 32)
8510 count = INTVAL (operands[2]);
8511 regno = REGNO (operands[0]);
8513 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8514 op1 = replace_equiv_address (operands[1],
8515 force_reg (SImode, XEXP (operands[1], 0)));
8517 for (i = 0; i < count; i++)
8518 XVECEXP (operands[3], 0, i)
8519 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8520 adjust_address_nv (op1, SImode, i * 4));
8523 (define_insn "*ldmsi8"
8524 [(match_parallel 0 "load_multiple_operation"
8525 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8526 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8527 (set (match_operand:SI 3 "gpc_reg_operand" "")
8528 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8529 (set (match_operand:SI 4 "gpc_reg_operand" "")
8530 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8531 (set (match_operand:SI 5 "gpc_reg_operand" "")
8532 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8533 (set (match_operand:SI 6 "gpc_reg_operand" "")
8534 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8535 (set (match_operand:SI 7 "gpc_reg_operand" "")
8536 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8537 (set (match_operand:SI 8 "gpc_reg_operand" "")
8538 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8539 (set (match_operand:SI 9 "gpc_reg_operand" "")
8540 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8541 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8543 { return rs6000_output_load_multiple (operands); }"
8544 [(set_attr "type" "load")
8545 (set_attr "update" "yes")
8546 (set_attr "indexed" "yes")
8547 (set_attr "length" "32")])
8549 (define_insn "*ldmsi7"
8550 [(match_parallel 0 "load_multiple_operation"
8551 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8552 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8553 (set (match_operand:SI 3 "gpc_reg_operand" "")
8554 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8555 (set (match_operand:SI 4 "gpc_reg_operand" "")
8556 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8557 (set (match_operand:SI 5 "gpc_reg_operand" "")
8558 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8559 (set (match_operand:SI 6 "gpc_reg_operand" "")
8560 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8561 (set (match_operand:SI 7 "gpc_reg_operand" "")
8562 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8563 (set (match_operand:SI 8 "gpc_reg_operand" "")
8564 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8565 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8567 { return rs6000_output_load_multiple (operands); }"
8568 [(set_attr "type" "load")
8569 (set_attr "update" "yes")
8570 (set_attr "indexed" "yes")
8571 (set_attr "length" "32")])
8573 (define_insn "*ldmsi6"
8574 [(match_parallel 0 "load_multiple_operation"
8575 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8576 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8577 (set (match_operand:SI 3 "gpc_reg_operand" "")
8578 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8579 (set (match_operand:SI 4 "gpc_reg_operand" "")
8580 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8581 (set (match_operand:SI 5 "gpc_reg_operand" "")
8582 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8583 (set (match_operand:SI 6 "gpc_reg_operand" "")
8584 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8585 (set (match_operand:SI 7 "gpc_reg_operand" "")
8586 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8587 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8589 { return rs6000_output_load_multiple (operands); }"
8590 [(set_attr "type" "load")
8591 (set_attr "update" "yes")
8592 (set_attr "indexed" "yes")
8593 (set_attr "length" "32")])
8595 (define_insn "*ldmsi5"
8596 [(match_parallel 0 "load_multiple_operation"
8597 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8598 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8599 (set (match_operand:SI 3 "gpc_reg_operand" "")
8600 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8601 (set (match_operand:SI 4 "gpc_reg_operand" "")
8602 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8603 (set (match_operand:SI 5 "gpc_reg_operand" "")
8604 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8605 (set (match_operand:SI 6 "gpc_reg_operand" "")
8606 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8607 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8609 { return rs6000_output_load_multiple (operands); }"
8610 [(set_attr "type" "load")
8611 (set_attr "update" "yes")
8612 (set_attr "indexed" "yes")
8613 (set_attr "length" "32")])
8615 (define_insn "*ldmsi4"
8616 [(match_parallel 0 "load_multiple_operation"
8617 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8618 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8619 (set (match_operand:SI 3 "gpc_reg_operand" "")
8620 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8621 (set (match_operand:SI 4 "gpc_reg_operand" "")
8622 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8623 (set (match_operand:SI 5 "gpc_reg_operand" "")
8624 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8625 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8627 { return rs6000_output_load_multiple (operands); }"
8628 [(set_attr "type" "load")
8629 (set_attr "update" "yes")
8630 (set_attr "indexed" "yes")
8631 (set_attr "length" "32")])
8633 (define_insn "*ldmsi3"
8634 [(match_parallel 0 "load_multiple_operation"
8635 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8636 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8637 (set (match_operand:SI 3 "gpc_reg_operand" "")
8638 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8639 (set (match_operand:SI 4 "gpc_reg_operand" "")
8640 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8641 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8643 { return rs6000_output_load_multiple (operands); }"
8644 [(set_attr "type" "load")
8645 (set_attr "update" "yes")
8646 (set_attr "indexed" "yes")
8647 (set_attr "length" "32")])
8649 (define_expand "store_multiple"
8650 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8651 (match_operand:SI 1 "" ""))
8652 (clobber (scratch:SI))
8653 (use (match_operand:SI 2 "" ""))])]
8654 "TARGET_STRING && !TARGET_POWERPC64"
8663 /* Support only storing a constant number of fixed-point registers to
8664 memory and only bother with this if more than two; the machine
8665 doesn't support more than eight. */
8666 if (GET_CODE (operands[2]) != CONST_INT
8667 || INTVAL (operands[2]) <= 2
8668 || INTVAL (operands[2]) > 8
8669 || GET_CODE (operands[0]) != MEM
8670 || GET_CODE (operands[1]) != REG
8671 || REGNO (operands[1]) >= 32)
8674 count = INTVAL (operands[2]);
8675 regno = REGNO (operands[1]);
8677 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8678 to = force_reg (SImode, XEXP (operands[0], 0));
8679 op0 = replace_equiv_address (operands[0], to);
8681 XVECEXP (operands[3], 0, 0)
8682 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8683 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8684 gen_rtx_SCRATCH (SImode));
8686 for (i = 1; i < count; i++)
8687 XVECEXP (operands[3], 0, i + 1)
8688 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8689 gen_rtx_REG (SImode, regno + i));
8692 (define_insn "*stmsi8"
8693 [(match_parallel 0 "store_multiple_operation"
8694 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8695 (match_operand:SI 2 "gpc_reg_operand" "r"))
8696 (clobber (match_scratch:SI 3 "=X"))
8697 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8698 (match_operand:SI 4 "gpc_reg_operand" "r"))
8699 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8700 (match_operand:SI 5 "gpc_reg_operand" "r"))
8701 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8702 (match_operand:SI 6 "gpc_reg_operand" "r"))
8703 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8704 (match_operand:SI 7 "gpc_reg_operand" "r"))
8705 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8706 (match_operand:SI 8 "gpc_reg_operand" "r"))
8707 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8708 (match_operand:SI 9 "gpc_reg_operand" "r"))
8709 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8710 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8711 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8713 [(set_attr "type" "store")
8714 (set_attr "update" "yes")
8715 (set_attr "indexed" "yes")
8716 (set_attr "cell_micro" "always")])
8718 (define_insn "*stmsi7"
8719 [(match_parallel 0 "store_multiple_operation"
8720 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8721 (match_operand:SI 2 "gpc_reg_operand" "r"))
8722 (clobber (match_scratch:SI 3 "=X"))
8723 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8724 (match_operand:SI 4 "gpc_reg_operand" "r"))
8725 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8726 (match_operand:SI 5 "gpc_reg_operand" "r"))
8727 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8728 (match_operand:SI 6 "gpc_reg_operand" "r"))
8729 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8730 (match_operand:SI 7 "gpc_reg_operand" "r"))
8731 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8732 (match_operand:SI 8 "gpc_reg_operand" "r"))
8733 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8734 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8735 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8737 [(set_attr "type" "store")
8738 (set_attr "update" "yes")
8739 (set_attr "indexed" "yes")
8740 (set_attr "cell_micro" "always")])
8742 (define_insn "*stmsi6"
8743 [(match_parallel 0 "store_multiple_operation"
8744 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8745 (match_operand:SI 2 "gpc_reg_operand" "r"))
8746 (clobber (match_scratch:SI 3 "=X"))
8747 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8748 (match_operand:SI 4 "gpc_reg_operand" "r"))
8749 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8750 (match_operand:SI 5 "gpc_reg_operand" "r"))
8751 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8752 (match_operand:SI 6 "gpc_reg_operand" "r"))
8753 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8754 (match_operand:SI 7 "gpc_reg_operand" "r"))
8755 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8756 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8757 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8759 [(set_attr "type" "store")
8760 (set_attr "update" "yes")
8761 (set_attr "indexed" "yes")
8762 (set_attr "cell_micro" "always")])
8764 (define_insn "*stmsi5"
8765 [(match_parallel 0 "store_multiple_operation"
8766 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8767 (match_operand:SI 2 "gpc_reg_operand" "r"))
8768 (clobber (match_scratch:SI 3 "=X"))
8769 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8770 (match_operand:SI 4 "gpc_reg_operand" "r"))
8771 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8772 (match_operand:SI 5 "gpc_reg_operand" "r"))
8773 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8774 (match_operand:SI 6 "gpc_reg_operand" "r"))
8775 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8776 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8777 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8779 [(set_attr "type" "store")
8780 (set_attr "update" "yes")
8781 (set_attr "indexed" "yes")
8782 (set_attr "cell_micro" "always")])
8784 (define_insn "*stmsi4"
8785 [(match_parallel 0 "store_multiple_operation"
8786 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8787 (match_operand:SI 2 "gpc_reg_operand" "r"))
8788 (clobber (match_scratch:SI 3 "=X"))
8789 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8790 (match_operand:SI 4 "gpc_reg_operand" "r"))
8791 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8792 (match_operand:SI 5 "gpc_reg_operand" "r"))
8793 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8794 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8795 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8797 [(set_attr "type" "store")
8798 (set_attr "update" "yes")
8799 (set_attr "indexed" "yes")
8800 (set_attr "cell_micro" "always")])
8802 (define_insn "*stmsi3"
8803 [(match_parallel 0 "store_multiple_operation"
8804 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8805 (match_operand:SI 2 "gpc_reg_operand" "r"))
8806 (clobber (match_scratch:SI 3 "=X"))
8807 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8808 (match_operand:SI 4 "gpc_reg_operand" "r"))
8809 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8810 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8811 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8813 [(set_attr "type" "store")
8814 (set_attr "update" "yes")
8815 (set_attr "indexed" "yes")
8816 (set_attr "cell_micro" "always")])
8818 (define_expand "setmemsi"
8819 [(parallel [(set (match_operand:BLK 0 "" "")
8820 (match_operand 2 "const_int_operand" ""))
8821 (use (match_operand:SI 1 "" ""))
8822 (use (match_operand:SI 3 "" ""))])]
8826 /* If value to set is not zero, use the library routine. */
8827 if (operands[2] != const0_rtx)
8830 if (expand_block_clear (operands))
8836 ;; String/block compare insn.
8837 ;; Argument 0 is the target (result)
8838 ;; Argument 1 is the destination
8839 ;; Argument 2 is the source
8840 ;; Argument 3 is the length
8841 ;; Argument 4 is the alignment
8843 (define_expand "cmpmemsi"
8844 [(parallel [(set (match_operand:SI 0)
8845 (compare:SI (match_operand:BLK 1)
8846 (match_operand:BLK 2)))
8847 (use (match_operand:SI 3))
8848 (use (match_operand:SI 4))])]
8851 if (expand_block_compare (operands))
8857 ;; String/block move insn.
8858 ;; Argument 0 is the destination
8859 ;; Argument 1 is the source
8860 ;; Argument 2 is the length
8861 ;; Argument 3 is the alignment
8863 (define_expand "movmemsi"
8864 [(parallel [(set (match_operand:BLK 0 "" "")
8865 (match_operand:BLK 1 "" ""))
8866 (use (match_operand:SI 2 "" ""))
8867 (use (match_operand:SI 3 "" ""))])]
8871 if (expand_block_move (operands))
8877 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
8878 ;; register allocator doesn't have a clue about allocating 8 word registers.
8879 ;; rD/rS = r5 is preferred, efficient form.
8880 (define_expand "movmemsi_8reg"
8881 [(parallel [(set (match_operand 0 "" "")
8882 (match_operand 1 "" ""))
8883 (use (match_operand 2 "" ""))
8884 (use (match_operand 3 "" ""))
8885 (clobber (reg:SI 5))
8886 (clobber (reg:SI 6))
8887 (clobber (reg:SI 7))
8888 (clobber (reg:SI 8))
8889 (clobber (reg:SI 9))
8890 (clobber (reg:SI 10))
8891 (clobber (reg:SI 11))
8892 (clobber (reg:SI 12))
8893 (clobber (match_scratch:SI 4 ""))])]
8898 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8899 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8900 (use (match_operand:SI 2 "immediate_operand" "i"))
8901 (use (match_operand:SI 3 "immediate_operand" "i"))
8902 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8903 (clobber (reg:SI 6))
8904 (clobber (reg:SI 7))
8905 (clobber (reg:SI 8))
8906 (clobber (reg:SI 9))
8907 (clobber (reg:SI 10))
8908 (clobber (reg:SI 11))
8909 (clobber (reg:SI 12))
8910 (clobber (match_scratch:SI 5 "=X"))]
8912 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8913 || INTVAL (operands[2]) == 0)
8914 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8915 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8916 && REGNO (operands[4]) == 5"
8917 "lswi %4,%1,%2\;stswi %4,%0,%2"
8918 [(set_attr "type" "store")
8919 (set_attr "update" "yes")
8920 (set_attr "indexed" "yes")
8921 (set_attr "cell_micro" "always")
8922 (set_attr "length" "8")])
8924 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
8925 ;; register allocator doesn't have a clue about allocating 6 word registers.
8926 ;; rD/rS = r5 is preferred, efficient form.
8927 (define_expand "movmemsi_6reg"
8928 [(parallel [(set (match_operand 0 "" "")
8929 (match_operand 1 "" ""))
8930 (use (match_operand 2 "" ""))
8931 (use (match_operand 3 "" ""))
8932 (clobber (reg:SI 5))
8933 (clobber (reg:SI 6))
8934 (clobber (reg:SI 7))
8935 (clobber (reg:SI 8))
8936 (clobber (reg:SI 9))
8937 (clobber (reg:SI 10))
8938 (clobber (match_scratch:SI 4 ""))])]
8943 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8944 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8945 (use (match_operand:SI 2 "immediate_operand" "i"))
8946 (use (match_operand:SI 3 "immediate_operand" "i"))
8947 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8948 (clobber (reg:SI 6))
8949 (clobber (reg:SI 7))
8950 (clobber (reg:SI 8))
8951 (clobber (reg:SI 9))
8952 (clobber (reg:SI 10))
8953 (clobber (match_scratch:SI 5 "=X"))]
8955 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8956 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8957 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8958 && REGNO (operands[4]) == 5"
8959 "lswi %4,%1,%2\;stswi %4,%0,%2"
8960 [(set_attr "type" "store")
8961 (set_attr "update" "yes")
8962 (set_attr "indexed" "yes")
8963 (set_attr "cell_micro" "always")
8964 (set_attr "length" "8")])
8966 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8967 ;; problems with TImode.
8968 ;; rD/rS = r5 is preferred, efficient form.
8969 (define_expand "movmemsi_4reg"
8970 [(parallel [(set (match_operand 0 "" "")
8971 (match_operand 1 "" ""))
8972 (use (match_operand 2 "" ""))
8973 (use (match_operand 3 "" ""))
8974 (clobber (reg:SI 5))
8975 (clobber (reg:SI 6))
8976 (clobber (reg:SI 7))
8977 (clobber (reg:SI 8))
8978 (clobber (match_scratch:SI 4 ""))])]
8983 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8984 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8985 (use (match_operand:SI 2 "immediate_operand" "i"))
8986 (use (match_operand:SI 3 "immediate_operand" "i"))
8987 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8988 (clobber (reg:SI 6))
8989 (clobber (reg:SI 7))
8990 (clobber (reg:SI 8))
8991 (clobber (match_scratch:SI 5 "=X"))]
8993 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8994 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8995 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8996 && REGNO (operands[4]) == 5"
8997 "lswi %4,%1,%2\;stswi %4,%0,%2"
8998 [(set_attr "type" "store")
8999 (set_attr "update" "yes")
9000 (set_attr "indexed" "yes")
9001 (set_attr "cell_micro" "always")
9002 (set_attr "length" "8")])
9004 ;; Move up to 8 bytes at a time.
9005 (define_expand "movmemsi_2reg"
9006 [(parallel [(set (match_operand 0 "" "")
9007 (match_operand 1 "" ""))
9008 (use (match_operand 2 "" ""))
9009 (use (match_operand 3 "" ""))
9010 (clobber (match_scratch:DI 4 ""))
9011 (clobber (match_scratch:SI 5 ""))])]
9012 "TARGET_STRING && ! TARGET_POWERPC64"
9016 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9017 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9018 (use (match_operand:SI 2 "immediate_operand" "i"))
9019 (use (match_operand:SI 3 "immediate_operand" "i"))
9020 (clobber (match_scratch:DI 4 "=&r"))
9021 (clobber (match_scratch:SI 5 "=X"))]
9022 "TARGET_STRING && ! TARGET_POWERPC64
9023 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9024 "lswi %4,%1,%2\;stswi %4,%0,%2"
9025 [(set_attr "type" "store")
9026 (set_attr "update" "yes")
9027 (set_attr "indexed" "yes")
9028 (set_attr "cell_micro" "always")
9029 (set_attr "length" "8")])
9031 ;; Move up to 4 bytes at a time.
9032 (define_expand "movmemsi_1reg"
9033 [(parallel [(set (match_operand 0 "" "")
9034 (match_operand 1 "" ""))
9035 (use (match_operand 2 "" ""))
9036 (use (match_operand 3 "" ""))
9037 (clobber (match_scratch:SI 4 ""))
9038 (clobber (match_scratch:SI 5 ""))])]
9043 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9044 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9045 (use (match_operand:SI 2 "immediate_operand" "i"))
9046 (use (match_operand:SI 3 "immediate_operand" "i"))
9047 (clobber (match_scratch:SI 4 "=&r"))
9048 (clobber (match_scratch:SI 5 "=X"))]
9049 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9050 "lswi %4,%1,%2\;stswi %4,%0,%2"
9051 [(set_attr "type" "store")
9052 (set_attr "update" "yes")
9053 (set_attr "indexed" "yes")
9054 (set_attr "cell_micro" "always")
9055 (set_attr "length" "8")])
9057 ;; Define insns that do load or store with update. Some of these we can
9058 ;; get by using pre-decrement or pre-increment, but the hardware can also
9059 ;; do cases where the increment is not the size of the object.
9061 ;; In all these cases, we use operands 0 and 1 for the register being
9062 ;; incremented because those are the operands that local-alloc will
9063 ;; tie and these are the pair most likely to be tieable (and the ones
9064 ;; that will benefit the most).
9066 (define_insn "*movdi_update1"
9067 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9068 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9069 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9070 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9071 (plus:DI (match_dup 1) (match_dup 2)))]
9072 "TARGET_POWERPC64 && TARGET_UPDATE
9073 && (!avoiding_indexed_address_p (DImode)
9074 || !gpc_reg_operand (operands[2], DImode))"
9078 [(set_attr "type" "load")
9079 (set_attr "update" "yes")
9080 (set_attr "indexed" "yes,no")])
9082 (define_insn "movdi_<mode>_update"
9083 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9084 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9085 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9086 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9087 (plus:P (match_dup 1) (match_dup 2)))]
9088 "TARGET_POWERPC64 && TARGET_UPDATE
9089 && (!avoiding_indexed_address_p (Pmode)
9090 || !gpc_reg_operand (operands[2], Pmode)
9091 || (REG_P (operands[0])
9092 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9096 [(set_attr "type" "store")
9097 (set_attr "update" "yes")
9098 (set_attr "indexed" "yes,no")])
9100 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9101 ;; needed for stack allocation, even if the user passes -mno-update.
9102 (define_insn "movdi_<mode>_update_stack"
9103 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9104 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9105 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9106 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9107 (plus:P (match_dup 1) (match_dup 2)))]
9112 [(set_attr "type" "store")
9113 (set_attr "update" "yes")
9114 (set_attr "indexed" "yes,no")])
9116 (define_insn "*movsi_update1"
9117 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9118 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9119 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9120 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9121 (plus:SI (match_dup 1) (match_dup 2)))]
9123 && (!avoiding_indexed_address_p (SImode)
9124 || !gpc_reg_operand (operands[2], SImode))"
9128 [(set_attr "type" "load")
9129 (set_attr "update" "yes")
9130 (set_attr "indexed" "yes,no")])
9132 (define_insn "*movsi_update2"
9133 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9135 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9136 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9137 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9138 (plus:DI (match_dup 1) (match_dup 2)))]
9139 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9140 && !avoiding_indexed_address_p (DImode)"
9142 [(set_attr "type" "load")
9143 (set_attr "sign_extend" "yes")
9144 (set_attr "update" "yes")
9145 (set_attr "indexed" "yes")])
9147 (define_insn "movsi_update"
9148 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9149 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9150 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9151 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9152 (plus:SI (match_dup 1) (match_dup 2)))]
9154 && (!avoiding_indexed_address_p (SImode)
9155 || !gpc_reg_operand (operands[2], SImode)
9156 || (REG_P (operands[0])
9157 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9161 [(set_attr "type" "store")
9162 (set_attr "update" "yes")
9163 (set_attr "indexed" "yes,no")])
9165 ;; This is an unconditional pattern; needed for stack allocation, even
9166 ;; if the user passes -mno-update.
9167 (define_insn "movsi_update_stack"
9168 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9169 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9170 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9171 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9172 (plus:SI (match_dup 1) (match_dup 2)))]
9177 [(set_attr "type" "store")
9178 (set_attr "update" "yes")
9179 (set_attr "indexed" "yes,no")])
9181 (define_insn "*movhi_update1"
9182 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9183 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9184 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9185 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9186 (plus:SI (match_dup 1) (match_dup 2)))]
9188 && (!avoiding_indexed_address_p (SImode)
9189 || !gpc_reg_operand (operands[2], SImode))"
9193 [(set_attr "type" "load")
9194 (set_attr "update" "yes")
9195 (set_attr "indexed" "yes,no")])
9197 (define_insn "*movhi_update2"
9198 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9200 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9201 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9202 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9203 (plus:SI (match_dup 1) (match_dup 2)))]
9205 && (!avoiding_indexed_address_p (SImode)
9206 || !gpc_reg_operand (operands[2], SImode))"
9210 [(set_attr "type" "load")
9211 (set_attr "update" "yes")
9212 (set_attr "indexed" "yes,no")])
9214 (define_insn "*movhi_update3"
9215 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9217 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9218 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9219 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9220 (plus:SI (match_dup 1) (match_dup 2)))]
9221 "TARGET_UPDATE && rs6000_gen_cell_microcode
9222 && (!avoiding_indexed_address_p (SImode)
9223 || !gpc_reg_operand (operands[2], SImode))"
9227 [(set_attr "type" "load")
9228 (set_attr "sign_extend" "yes")
9229 (set_attr "update" "yes")
9230 (set_attr "indexed" "yes,no")])
9232 (define_insn "*movhi_update4"
9233 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9234 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9235 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9236 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9237 (plus:SI (match_dup 1) (match_dup 2)))]
9239 && (!avoiding_indexed_address_p (SImode)
9240 || !gpc_reg_operand (operands[2], SImode))"
9244 [(set_attr "type" "store")
9245 (set_attr "update" "yes")
9246 (set_attr "indexed" "yes,no")])
9248 (define_insn "*movqi_update1"
9249 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9250 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9251 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9252 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9253 (plus:SI (match_dup 1) (match_dup 2)))]
9255 && (!avoiding_indexed_address_p (SImode)
9256 || !gpc_reg_operand (operands[2], SImode))"
9260 [(set_attr "type" "load")
9261 (set_attr "update" "yes")
9262 (set_attr "indexed" "yes,no")])
9264 (define_insn "*movqi_update2"
9265 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9267 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9268 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9269 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9270 (plus:SI (match_dup 1) (match_dup 2)))]
9272 && (!avoiding_indexed_address_p (SImode)
9273 || !gpc_reg_operand (operands[2], SImode))"
9277 [(set_attr "type" "load")
9278 (set_attr "update" "yes")
9279 (set_attr "indexed" "yes,no")])
9281 (define_insn "*movqi_update3"
9282 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9283 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9284 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9285 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9286 (plus:SI (match_dup 1) (match_dup 2)))]
9288 && (!avoiding_indexed_address_p (SImode)
9289 || !gpc_reg_operand (operands[2], SImode))"
9293 [(set_attr "type" "store")
9294 (set_attr "update" "yes")
9295 (set_attr "indexed" "yes,no")])
9297 (define_insn "*movsf_update1"
9298 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9299 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9300 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9301 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9302 (plus:SI (match_dup 1) (match_dup 2)))]
9303 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9304 && (!avoiding_indexed_address_p (SImode)
9305 || !gpc_reg_operand (operands[2], SImode))"
9309 [(set_attr "type" "fpload")
9310 (set_attr "update" "yes")
9311 (set_attr "indexed" "yes,no")])
9313 (define_insn "*movsf_update2"
9314 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9315 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9316 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9317 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9318 (plus:SI (match_dup 1) (match_dup 2)))]
9319 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9320 && (!avoiding_indexed_address_p (SImode)
9321 || !gpc_reg_operand (operands[2], SImode))"
9325 [(set_attr "type" "fpstore")
9326 (set_attr "update" "yes")
9327 (set_attr "indexed" "yes,no")])
9329 (define_insn "*movsf_update3"
9330 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9331 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9332 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9333 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9334 (plus:SI (match_dup 1) (match_dup 2)))]
9335 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9336 && (!avoiding_indexed_address_p (SImode)
9337 || !gpc_reg_operand (operands[2], SImode))"
9341 [(set_attr "type" "load")
9342 (set_attr "update" "yes")
9343 (set_attr "indexed" "yes,no")])
9345 (define_insn "*movsf_update4"
9346 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9347 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9348 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9349 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9350 (plus:SI (match_dup 1) (match_dup 2)))]
9351 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9352 && (!avoiding_indexed_address_p (SImode)
9353 || !gpc_reg_operand (operands[2], SImode))"
9357 [(set_attr "type" "store")
9358 (set_attr "update" "yes")
9359 (set_attr "indexed" "yes,no")])
9361 (define_insn "*movdf_update1"
9362 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9363 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9364 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9365 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9366 (plus:SI (match_dup 1) (match_dup 2)))]
9367 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9368 && (!avoiding_indexed_address_p (SImode)
9369 || !gpc_reg_operand (operands[2], SImode))"
9373 [(set_attr "type" "fpload")
9374 (set_attr "update" "yes")
9375 (set_attr "indexed" "yes,no")
9376 (set_attr "size" "64")])
9378 (define_insn "*movdf_update2"
9379 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9380 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9381 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9382 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9383 (plus:SI (match_dup 1) (match_dup 2)))]
9384 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9385 && (!avoiding_indexed_address_p (SImode)
9386 || !gpc_reg_operand (operands[2], SImode))"
9390 [(set_attr "type" "fpstore")
9391 (set_attr "update" "yes")
9392 (set_attr "indexed" "yes,no")])
9395 ;; After inserting conditional returns we can sometimes have
9396 ;; unnecessary register moves. Unfortunately we cannot have a
9397 ;; modeless peephole here, because some single SImode sets have early
9398 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9399 ;; sequences, using get_attr_length here will smash the operands
9400 ;; array. Neither is there an early_cobbler_p predicate.
9401 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9402 ;; Also this optimization interferes with scalars going into
9403 ;; altivec registers (the code does reloading through the FPRs).
9405 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9406 (match_operand:DF 1 "any_operand" ""))
9407 (set (match_operand:DF 2 "gpc_reg_operand" "")
9409 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9410 && !TARGET_UPPER_REGS_DF
9411 && peep2_reg_dead_p (2, operands[0])"
9412 [(set (match_dup 2) (match_dup 1))])
9415 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9416 (match_operand:SF 1 "any_operand" ""))
9417 (set (match_operand:SF 2 "gpc_reg_operand" "")
9419 "!TARGET_UPPER_REGS_SF
9420 && peep2_reg_dead_p (2, operands[0])"
9421 [(set (match_dup 2) (match_dup 1))])
9426 ;; Mode attributes for different ABIs.
9427 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9428 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9429 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9430 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9432 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9433 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9434 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9435 (match_operand 4 "" "g")))
9436 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9437 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9439 (clobber (reg:SI LR_REGNO))]
9440 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9442 if (TARGET_CMODEL != CMODEL_SMALL)
9443 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9446 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9448 "&& TARGET_TLS_MARKERS"
9450 (unspec:TLSmode [(match_dup 1)
9453 (parallel [(set (match_dup 0)
9454 (call (mem:TLSmode (match_dup 3))
9456 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9457 (clobber (reg:SI LR_REGNO))])]
9459 [(set_attr "type" "two")
9460 (set (attr "length")
9461 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9465 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9466 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9467 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9468 (match_operand 4 "" "g")))
9469 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9470 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9472 (clobber (reg:SI LR_REGNO))]
9473 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9477 if (TARGET_SECURE_PLT && flag_pic == 2)
9478 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9480 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9483 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9485 "&& TARGET_TLS_MARKERS"
9487 (unspec:TLSmode [(match_dup 1)
9490 (parallel [(set (match_dup 0)
9491 (call (mem:TLSmode (match_dup 3))
9493 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9494 (clobber (reg:SI LR_REGNO))])]
9496 [(set_attr "type" "two")
9497 (set_attr "length" "8")])
9499 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9500 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9501 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9502 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9504 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9505 "addi %0,%1,%2@got@tlsgd"
9506 "&& TARGET_CMODEL != CMODEL_SMALL"
9509 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9511 (lo_sum:TLSmode (match_dup 3)
9512 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9515 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9517 [(set (attr "length")
9518 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9522 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9523 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9525 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9526 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9528 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9529 "addis %0,%1,%2@got@tlsgd@ha"
9530 [(set_attr "length" "4")])
9532 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9533 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9534 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9535 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9536 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9538 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9539 "addi %0,%1,%2@got@tlsgd@l"
9540 [(set_attr "length" "4")])
9542 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9543 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9544 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9545 (match_operand 2 "" "g")))
9546 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9548 (clobber (reg:SI LR_REGNO))]
9549 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9550 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9551 "bl %z1(%3@tlsgd)\;nop"
9552 [(set_attr "type" "branch")
9553 (set_attr "length" "8")])
9555 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9556 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9557 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9558 (match_operand 2 "" "g")))
9559 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9561 (clobber (reg:SI LR_REGNO))]
9562 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9566 if (TARGET_SECURE_PLT && flag_pic == 2)
9567 return "bl %z1+32768(%3@tlsgd)@plt";
9568 return "bl %z1(%3@tlsgd)@plt";
9570 return "bl %z1(%3@tlsgd)";
9572 [(set_attr "type" "branch")
9573 (set_attr "length" "4")])
9575 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9576 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9577 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9578 (match_operand 3 "" "g")))
9579 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9581 (clobber (reg:SI LR_REGNO))]
9582 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9584 if (TARGET_CMODEL != CMODEL_SMALL)
9585 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9588 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9590 "&& TARGET_TLS_MARKERS"
9592 (unspec:TLSmode [(match_dup 1)]
9594 (parallel [(set (match_dup 0)
9595 (call (mem:TLSmode (match_dup 2))
9597 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9598 (clobber (reg:SI LR_REGNO))])]
9600 [(set_attr "type" "two")
9601 (set (attr "length")
9602 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9606 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9607 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9608 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9609 (match_operand 3 "" "g")))
9610 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9612 (clobber (reg:SI LR_REGNO))]
9613 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9617 if (TARGET_SECURE_PLT && flag_pic == 2)
9618 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9620 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9623 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9625 "&& TARGET_TLS_MARKERS"
9627 (unspec:TLSmode [(match_dup 1)]
9629 (parallel [(set (match_dup 0)
9630 (call (mem:TLSmode (match_dup 2))
9632 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9633 (clobber (reg:SI LR_REGNO))])]
9635 [(set_attr "length" "8")])
9637 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9638 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9639 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9641 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9642 "addi %0,%1,%&@got@tlsld"
9643 "&& TARGET_CMODEL != CMODEL_SMALL"
9646 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9648 (lo_sum:TLSmode (match_dup 2)
9649 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9652 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9654 [(set (attr "length")
9655 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9659 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9660 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9662 (unspec:TLSmode [(const_int 0)
9663 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9665 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9666 "addis %0,%1,%&@got@tlsld@ha"
9667 [(set_attr "length" "4")])
9669 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9670 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9671 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9672 (unspec:TLSmode [(const_int 0)
9673 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9675 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9676 "addi %0,%1,%&@got@tlsld@l"
9677 [(set_attr "length" "4")])
9679 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9680 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9681 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9682 (match_operand 2 "" "g")))
9683 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9684 (clobber (reg:SI LR_REGNO))]
9685 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9686 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9687 "bl %z1(%&@tlsld)\;nop"
9688 [(set_attr "type" "branch")
9689 (set_attr "length" "8")])
9691 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9692 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9693 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9694 (match_operand 2 "" "g")))
9695 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9696 (clobber (reg:SI LR_REGNO))]
9697 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9701 if (TARGET_SECURE_PLT && flag_pic == 2)
9702 return "bl %z1+32768(%&@tlsld)@plt";
9703 return "bl %z1(%&@tlsld)@plt";
9705 return "bl %z1(%&@tlsld)";
9707 [(set_attr "type" "branch")
9708 (set_attr "length" "4")])
9710 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9711 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9712 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9713 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9716 "addi %0,%1,%2@dtprel")
9718 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9719 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9720 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9721 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9722 UNSPEC_TLSDTPRELHA))]
9724 "addis %0,%1,%2@dtprel@ha")
9726 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9727 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9728 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9729 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9730 UNSPEC_TLSDTPRELLO))]
9732 "addi %0,%1,%2@dtprel@l")
9734 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9735 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9736 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9737 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9738 UNSPEC_TLSGOTDTPREL))]
9740 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9741 "&& TARGET_CMODEL != CMODEL_SMALL"
9744 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9746 (lo_sum:TLSmode (match_dup 3)
9747 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9750 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9752 [(set (attr "length")
9753 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9757 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9758 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9760 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9761 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9762 UNSPEC_TLSGOTDTPREL)))]
9763 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9764 "addis %0,%1,%2@got@dtprel@ha"
9765 [(set_attr "length" "4")])
9767 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9768 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9769 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9770 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9771 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9772 UNSPEC_TLSGOTDTPREL)))]
9773 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9774 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9775 [(set_attr "length" "4")])
9777 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9778 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9779 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9780 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9783 "addi %0,%1,%2@tprel")
9785 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9786 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9787 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9788 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9789 UNSPEC_TLSTPRELHA))]
9791 "addis %0,%1,%2@tprel@ha")
9793 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9794 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9795 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9796 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9797 UNSPEC_TLSTPRELLO))]
9799 "addi %0,%1,%2@tprel@l")
9801 ;; "b" output constraint here and on tls_tls input to support linker tls
9802 ;; optimization. The linker may edit the instructions emitted by a
9803 ;; tls_got_tprel/tls_tls pair to addis,addi.
9804 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9805 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9806 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9807 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9808 UNSPEC_TLSGOTTPREL))]
9810 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9811 "&& TARGET_CMODEL != CMODEL_SMALL"
9814 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9816 (lo_sum:TLSmode (match_dup 3)
9817 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9820 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9822 [(set (attr "length")
9823 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9827 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9828 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9830 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9831 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9832 UNSPEC_TLSGOTTPREL)))]
9833 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9834 "addis %0,%1,%2@got@tprel@ha"
9835 [(set_attr "length" "4")])
9837 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9838 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9839 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9840 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9841 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9842 UNSPEC_TLSGOTTPREL)))]
9843 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9844 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9845 [(set_attr "length" "4")])
9847 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9848 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9849 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9850 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9852 "TARGET_ELF && HAVE_AS_TLS"
9855 (define_expand "tls_get_tpointer"
9856 [(set (match_operand:SI 0 "gpc_reg_operand" "")
9857 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9858 "TARGET_XCOFF && HAVE_AS_TLS"
9861 emit_insn (gen_tls_get_tpointer_internal ());
9862 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9866 (define_insn "tls_get_tpointer_internal"
9868 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9869 (clobber (reg:SI LR_REGNO))]
9870 "TARGET_XCOFF && HAVE_AS_TLS"
9871 "bla __get_tpointer")
9873 (define_expand "tls_get_addr<mode>"
9874 [(set (match_operand:P 0 "gpc_reg_operand" "")
9875 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9876 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9877 "TARGET_XCOFF && HAVE_AS_TLS"
9880 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9881 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9882 emit_insn (gen_tls_get_addr_internal<mode> ());
9883 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9887 (define_insn "tls_get_addr_internal<mode>"
9889 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9893 (clobber (reg:P 11))
9894 (clobber (reg:CC CR0_REGNO))
9895 (clobber (reg:P LR_REGNO))]
9896 "TARGET_XCOFF && HAVE_AS_TLS"
9897 "bla __tls_get_addr")
9899 ;; Next come insns related to the calling sequence.
9901 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9902 ;; We move the back-chain and decrement the stack pointer.
9904 (define_expand "allocate_stack"
9905 [(set (match_operand 0 "gpc_reg_operand" "")
9906 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9908 (minus (reg 1) (match_dup 1)))]
9911 { rtx chain = gen_reg_rtx (Pmode);
9912 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9914 rtx insn, par, set, mem;
9916 emit_move_insn (chain, stack_bot);
9918 /* Check stack bounds if necessary. */
9919 if (crtl->limit_stack)
9922 available = expand_binop (Pmode, sub_optab,
9923 stack_pointer_rtx, stack_limit_rtx,
9924 NULL_RTX, 1, OPTAB_WIDEN);
9925 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9928 if (GET_CODE (operands[1]) != CONST_INT
9929 || INTVAL (operands[1]) < -32767
9930 || INTVAL (operands[1]) > 32768)
9932 neg_op0 = gen_reg_rtx (Pmode);
9934 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9936 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9939 neg_op0 = GEN_INT (- INTVAL (operands[1]));
9941 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9942 : gen_movdi_di_update_stack))
9943 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9945 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9946 it now and set the alias set/attributes. The above gen_*_update
9947 calls will generate a PARALLEL with the MEM set being the first
9949 par = PATTERN (insn);
9950 gcc_assert (GET_CODE (par) == PARALLEL);
9951 set = XVECEXP (par, 0, 0);
9952 gcc_assert (GET_CODE (set) == SET);
9953 mem = SET_DEST (set);
9954 gcc_assert (MEM_P (mem));
9955 MEM_NOTRAP_P (mem) = 1;
9956 set_mem_alias_set (mem, get_frame_alias_set ());
9958 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9962 ;; These patterns say how to save and restore the stack pointer. We need not
9963 ;; save the stack pointer at function level since we are careful to
9964 ;; preserve the backchain. At block level, we have to restore the backchain
9965 ;; when we restore the stack pointer.
9967 ;; For nonlocal gotos, we must save both the stack pointer and its
9968 ;; backchain and restore both. Note that in the nonlocal case, the
9969 ;; save area is a memory location.
9971 (define_expand "save_stack_function"
9972 [(match_operand 0 "any_operand" "")
9973 (match_operand 1 "any_operand" "")]
9977 (define_expand "restore_stack_function"
9978 [(match_operand 0 "any_operand" "")
9979 (match_operand 1 "any_operand" "")]
9983 ;; Adjust stack pointer (op0) to a new value (op1).
9984 ;; First copy old stack backchain to new location, and ensure that the
9985 ;; scheduler won't reorder the sp assignment before the backchain write.
9986 (define_expand "restore_stack_block"
9987 [(set (match_dup 2) (match_dup 3))
9988 (set (match_dup 4) (match_dup 2))
9990 (set (match_operand 0 "register_operand" "")
9991 (match_operand 1 "register_operand" ""))]
9997 operands[1] = force_reg (Pmode, operands[1]);
9998 operands[2] = gen_reg_rtx (Pmode);
9999 operands[3] = gen_frame_mem (Pmode, operands[0]);
10000 operands[4] = gen_frame_mem (Pmode, operands[1]);
10001 p = rtvec_alloc (1);
10002 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10004 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10007 (define_expand "save_stack_nonlocal"
10008 [(set (match_dup 3) (match_dup 4))
10009 (set (match_operand 0 "memory_operand" "") (match_dup 3))
10010 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10014 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10016 /* Copy the backchain to the first word, sp to the second. */
10017 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10018 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10019 operands[3] = gen_reg_rtx (Pmode);
10020 operands[4] = gen_frame_mem (Pmode, operands[1]);
10023 (define_expand "restore_stack_nonlocal"
10024 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10025 (set (match_dup 3) (match_dup 4))
10026 (set (match_dup 5) (match_dup 2))
10028 (set (match_operand 0 "register_operand" "") (match_dup 3))]
10032 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10035 /* Restore the backchain from the first word, sp from the second. */
10036 operands[2] = gen_reg_rtx (Pmode);
10037 operands[3] = gen_reg_rtx (Pmode);
10038 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10039 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10040 operands[5] = gen_frame_mem (Pmode, operands[3]);
10041 p = rtvec_alloc (1);
10042 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10044 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10047 ;; TOC register handling.
10049 ;; Code to initialize the TOC register...
10051 (define_insn "load_toc_aix_si"
10052 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10053 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10054 (use (reg:SI 2))])]
10055 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10059 extern int need_toc_init;
10061 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10062 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10063 operands[2] = gen_rtx_REG (Pmode, 2);
10064 return \"lwz %0,%1(%2)\";
10066 [(set_attr "type" "load")
10067 (set_attr "update" "no")
10068 (set_attr "indexed" "no")])
10070 (define_insn "load_toc_aix_di"
10071 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10072 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10073 (use (reg:DI 2))])]
10074 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10078 extern int need_toc_init;
10080 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10081 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10083 strcat (buf, \"@toc\");
10084 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10085 operands[2] = gen_rtx_REG (Pmode, 2);
10086 return \"ld %0,%1(%2)\";
10088 [(set_attr "type" "load")
10089 (set_attr "update" "no")
10090 (set_attr "indexed" "no")])
10092 (define_insn "load_toc_v4_pic_si"
10093 [(set (reg:SI LR_REGNO)
10094 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10095 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10096 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10097 [(set_attr "type" "branch")
10098 (set_attr "length" "4")])
10100 (define_expand "load_toc_v4_PIC_1"
10101 [(parallel [(set (reg:SI LR_REGNO)
10102 (match_operand:SI 0 "immediate_operand" "s"))
10103 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10104 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10105 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10108 (define_insn "load_toc_v4_PIC_1_normal"
10109 [(set (reg:SI LR_REGNO)
10110 (match_operand:SI 0 "immediate_operand" "s"))
10111 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10112 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10113 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10114 "bcl 20,31,%0\\n%0:"
10115 [(set_attr "type" "branch")
10116 (set_attr "length" "4")
10117 (set_attr "cannot_copy" "yes")])
10119 (define_insn "load_toc_v4_PIC_1_476"
10120 [(set (reg:SI LR_REGNO)
10121 (match_operand:SI 0 "immediate_operand" "s"))
10122 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10123 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10124 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10128 static char templ[32];
10130 get_ppc476_thunk_name (name);
10131 sprintf (templ, \"bl %s\\n%%0:\", name);
10134 [(set_attr "type" "branch")
10135 (set_attr "length" "4")
10136 (set_attr "cannot_copy" "yes")])
10138 (define_expand "load_toc_v4_PIC_1b"
10139 [(parallel [(set (reg:SI LR_REGNO)
10140 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10141 (label_ref (match_operand 1 "" ""))]
10144 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10147 (define_insn "load_toc_v4_PIC_1b_normal"
10148 [(set (reg:SI LR_REGNO)
10149 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10150 (label_ref (match_operand 1 "" ""))]
10153 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10154 "bcl 20,31,$+8\;.long %0-$"
10155 [(set_attr "type" "branch")
10156 (set_attr "length" "8")])
10158 (define_insn "load_toc_v4_PIC_1b_476"
10159 [(set (reg:SI LR_REGNO)
10160 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10161 (label_ref (match_operand 1 "" ""))]
10164 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10168 static char templ[32];
10170 get_ppc476_thunk_name (name);
10171 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10174 [(set_attr "type" "branch")
10175 (set_attr "length" "16")])
10177 (define_insn "load_toc_v4_PIC_2"
10178 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10179 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10180 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10181 (match_operand:SI 3 "immediate_operand" "s")))))]
10182 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10184 [(set_attr "type" "load")])
10186 (define_insn "load_toc_v4_PIC_3b"
10187 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10188 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10190 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10191 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10192 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10193 "addis %0,%1,%2-%3@ha")
10195 (define_insn "load_toc_v4_PIC_3c"
10196 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10197 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10198 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10199 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10200 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10201 "addi %0,%1,%2-%3@l")
10203 ;; If the TOC is shared over a translation unit, as happens with all
10204 ;; the kinds of PIC that we support, we need to restore the TOC
10205 ;; pointer only when jumping over units of translation.
10206 ;; On Darwin, we need to reload the picbase.
10208 (define_expand "builtin_setjmp_receiver"
10209 [(use (label_ref (match_operand 0 "" "")))]
10210 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10211 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10212 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10216 if (DEFAULT_ABI == ABI_DARWIN)
10218 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10219 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10223 crtl->uses_pic_offset_table = 1;
10224 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10225 CODE_LABEL_NUMBER (operands[0]));
10226 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10228 emit_insn (gen_load_macho_picbase (tmplabrtx));
10229 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10230 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10234 rs6000_emit_load_toc_table (FALSE);
10238 ;; Largetoc support
10239 (define_insn "*largetoc_high"
10240 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10242 (unspec [(match_operand:DI 1 "" "")
10243 (match_operand:DI 2 "gpc_reg_operand" "b")]
10245 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10246 "addis %0,%2,%1@toc@ha")
10248 (define_insn "*largetoc_high_aix<mode>"
10249 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10251 (unspec [(match_operand:P 1 "" "")
10252 (match_operand:P 2 "gpc_reg_operand" "b")]
10254 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10255 "addis %0,%1@u(%2)")
10257 (define_insn "*largetoc_high_plus"
10258 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10261 (unspec [(match_operand:DI 1 "" "")
10262 (match_operand:DI 2 "gpc_reg_operand" "b")]
10264 (match_operand:DI 3 "add_cint_operand" "n"))))]
10265 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10266 "addis %0,%2,%1+%3@toc@ha")
10268 (define_insn "*largetoc_high_plus_aix<mode>"
10269 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10272 (unspec [(match_operand:P 1 "" "")
10273 (match_operand:P 2 "gpc_reg_operand" "b")]
10275 (match_operand:P 3 "add_cint_operand" "n"))))]
10276 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10277 "addis %0,%1+%3@u(%2)")
10279 (define_insn "*largetoc_low"
10280 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10281 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10282 (match_operand:DI 2 "" "")))]
10283 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10286 (define_insn "*largetoc_low_aix<mode>"
10287 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10288 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10289 (match_operand:P 2 "" "")))]
10290 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10293 (define_insn_and_split "*tocref<mode>"
10294 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10295 (match_operand:P 1 "small_toc_ref" "R"))]
10298 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10299 [(set (match_dup 0) (high:P (match_dup 1)))
10300 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10302 ;; Elf specific ways of loading addresses for non-PIC code.
10303 ;; The output of this could be r0, but we make a very strong
10304 ;; preference for a base register because it will usually
10305 ;; be needed there.
10306 (define_insn "elf_high"
10307 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10308 (high:SI (match_operand 1 "" "")))]
10309 "TARGET_ELF && ! TARGET_64BIT"
10312 (define_insn "elf_low"
10313 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10314 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10315 (match_operand 2 "" "")))]
10316 "TARGET_ELF && ! TARGET_64BIT"
10319 ;; Call and call_value insns
10320 (define_expand "call"
10321 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10322 (match_operand 1 "" ""))
10323 (use (match_operand 2 "" ""))
10324 (clobber (reg:SI LR_REGNO))])]
10329 if (MACHOPIC_INDIRECT)
10330 operands[0] = machopic_indirect_call_target (operands[0]);
10333 gcc_assert (GET_CODE (operands[0]) == MEM);
10334 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10336 operands[0] = XEXP (operands[0], 0);
10338 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10340 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10344 if (GET_CODE (operands[0]) != SYMBOL_REF
10345 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10347 if (INTVAL (operands[2]) & CALL_LONG)
10348 operands[0] = rs6000_longcall_ref (operands[0]);
10350 switch (DEFAULT_ABI)
10354 operands[0] = force_reg (Pmode, operands[0]);
10358 gcc_unreachable ();
10363 (define_expand "call_value"
10364 [(parallel [(set (match_operand 0 "" "")
10365 (call (mem:SI (match_operand 1 "address_operand" ""))
10366 (match_operand 2 "" "")))
10367 (use (match_operand 3 "" ""))
10368 (clobber (reg:SI LR_REGNO))])]
10373 if (MACHOPIC_INDIRECT)
10374 operands[1] = machopic_indirect_call_target (operands[1]);
10377 gcc_assert (GET_CODE (operands[1]) == MEM);
10378 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10380 operands[1] = XEXP (operands[1], 0);
10382 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10384 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10388 if (GET_CODE (operands[1]) != SYMBOL_REF
10389 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10391 if (INTVAL (operands[3]) & CALL_LONG)
10392 operands[1] = rs6000_longcall_ref (operands[1]);
10394 switch (DEFAULT_ABI)
10398 operands[1] = force_reg (Pmode, operands[1]);
10402 gcc_unreachable ();
10407 ;; Call to function in current module. No TOC pointer reload needed.
10408 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10409 ;; either the function was not prototyped, or it was prototyped as a
10410 ;; variable argument function. It is > 0 if FP registers were passed
10411 ;; and < 0 if they were not.
10413 (define_insn "*call_local32"
10414 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10415 (match_operand 1 "" "g,g"))
10416 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10417 (clobber (reg:SI LR_REGNO))]
10418 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10421 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10422 output_asm_insn (\"crxor 6,6,6\", operands);
10424 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10425 output_asm_insn (\"creqv 6,6,6\", operands);
10427 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10429 [(set_attr "type" "branch")
10430 (set_attr "length" "4,8")])
10432 (define_insn "*call_local64"
10433 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10434 (match_operand 1 "" "g,g"))
10435 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10436 (clobber (reg:SI LR_REGNO))]
10437 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10440 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10441 output_asm_insn (\"crxor 6,6,6\", operands);
10443 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10444 output_asm_insn (\"creqv 6,6,6\", operands);
10446 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10448 [(set_attr "type" "branch")
10449 (set_attr "length" "4,8")])
10451 (define_insn "*call_value_local32"
10452 [(set (match_operand 0 "" "")
10453 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10454 (match_operand 2 "" "g,g")))
10455 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10456 (clobber (reg:SI LR_REGNO))]
10457 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10460 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10461 output_asm_insn (\"crxor 6,6,6\", operands);
10463 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10464 output_asm_insn (\"creqv 6,6,6\", operands);
10466 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10468 [(set_attr "type" "branch")
10469 (set_attr "length" "4,8")])
10472 (define_insn "*call_value_local64"
10473 [(set (match_operand 0 "" "")
10474 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10475 (match_operand 2 "" "g,g")))
10476 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10477 (clobber (reg:SI LR_REGNO))]
10478 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10481 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10482 output_asm_insn (\"crxor 6,6,6\", operands);
10484 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10485 output_asm_insn (\"creqv 6,6,6\", operands);
10487 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10489 [(set_attr "type" "branch")
10490 (set_attr "length" "4,8")])
10493 ;; A function pointer under System V is just a normal pointer
10494 ;; operands[0] is the function pointer
10495 ;; operands[1] is the stack size to clean up
10496 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10497 ;; which indicates how to set cr1
10499 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10500 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10501 (match_operand 1 "" "g,g,g,g"))
10502 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10503 (clobber (reg:SI LR_REGNO))]
10504 "DEFAULT_ABI == ABI_V4
10505 || DEFAULT_ABI == ABI_DARWIN"
10507 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10508 output_asm_insn ("crxor 6,6,6", operands);
10510 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10511 output_asm_insn ("creqv 6,6,6", operands);
10515 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10516 (set_attr "length" "4,4,8,8")])
10518 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10519 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10520 (match_operand 1 "" "g,g"))
10521 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10522 (clobber (reg:SI LR_REGNO))]
10523 "(DEFAULT_ABI == ABI_DARWIN
10524 || (DEFAULT_ABI == ABI_V4
10525 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10527 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10528 output_asm_insn ("crxor 6,6,6", operands);
10530 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10531 output_asm_insn ("creqv 6,6,6", operands);
10534 return output_call(insn, operands, 0, 2);
10536 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10538 gcc_assert (!TARGET_SECURE_PLT);
10539 return "bl %z0@plt";
10545 "DEFAULT_ABI == ABI_V4
10546 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10547 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10548 [(parallel [(call (mem:SI (match_dup 0))
10550 (use (match_dup 2))
10551 (use (match_dup 3))
10552 (clobber (reg:SI LR_REGNO))])]
10554 operands[3] = pic_offset_table_rtx;
10556 [(set_attr "type" "branch,branch")
10557 (set_attr "length" "4,8")])
10559 (define_insn "*call_nonlocal_sysv_secure<mode>"
10560 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10561 (match_operand 1 "" "g,g"))
10562 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10563 (use (match_operand:SI 3 "register_operand" "r,r"))
10564 (clobber (reg:SI LR_REGNO))]
10565 "(DEFAULT_ABI == ABI_V4
10566 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10567 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10569 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10570 output_asm_insn ("crxor 6,6,6", operands);
10572 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10573 output_asm_insn ("creqv 6,6,6", operands);
10576 /* The magic 32768 offset here and in the other sysv call insns
10577 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10578 See sysv4.h:toc_section. */
10579 return "bl %z0+32768@plt";
10581 return "bl %z0@plt";
10583 [(set_attr "type" "branch,branch")
10584 (set_attr "length" "4,8")])
10586 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10587 [(set (match_operand 0 "" "")
10588 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10589 (match_operand 2 "" "g,g,g,g")))
10590 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10591 (clobber (reg:SI LR_REGNO))]
10592 "DEFAULT_ABI == ABI_V4
10593 || DEFAULT_ABI == ABI_DARWIN"
10595 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10596 output_asm_insn ("crxor 6,6,6", operands);
10598 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10599 output_asm_insn ("creqv 6,6,6", operands);
10603 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10604 (set_attr "length" "4,4,8,8")])
10606 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10607 [(set (match_operand 0 "" "")
10608 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10609 (match_operand 2 "" "g,g")))
10610 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10611 (clobber (reg:SI LR_REGNO))]
10612 "(DEFAULT_ABI == ABI_DARWIN
10613 || (DEFAULT_ABI == ABI_V4
10614 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10616 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10617 output_asm_insn ("crxor 6,6,6", operands);
10619 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10620 output_asm_insn ("creqv 6,6,6", operands);
10623 return output_call(insn, operands, 1, 3);
10625 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10627 gcc_assert (!TARGET_SECURE_PLT);
10628 return "bl %z1@plt";
10634 "DEFAULT_ABI == ABI_V4
10635 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10636 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10637 [(parallel [(set (match_dup 0)
10638 (call (mem:SI (match_dup 1))
10640 (use (match_dup 3))
10641 (use (match_dup 4))
10642 (clobber (reg:SI LR_REGNO))])]
10644 operands[4] = pic_offset_table_rtx;
10646 [(set_attr "type" "branch,branch")
10647 (set_attr "length" "4,8")])
10649 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10650 [(set (match_operand 0 "" "")
10651 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10652 (match_operand 2 "" "g,g")))
10653 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10654 (use (match_operand:SI 4 "register_operand" "r,r"))
10655 (clobber (reg:SI LR_REGNO))]
10656 "(DEFAULT_ABI == ABI_V4
10657 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10658 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10660 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10661 output_asm_insn ("crxor 6,6,6", operands);
10663 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10664 output_asm_insn ("creqv 6,6,6", operands);
10667 return "bl %z1+32768@plt";
10669 return "bl %z1@plt";
10671 [(set_attr "type" "branch,branch")
10672 (set_attr "length" "4,8")])
10675 ;; Call to AIX abi function in the same module.
10677 (define_insn "*call_local_aix<mode>"
10678 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10679 (match_operand 1 "" "g"))
10680 (clobber (reg:P LR_REGNO))]
10681 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10683 [(set_attr "type" "branch")
10684 (set_attr "length" "4")])
10686 (define_insn "*call_value_local_aix<mode>"
10687 [(set (match_operand 0 "" "")
10688 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10689 (match_operand 2 "" "g")))
10690 (clobber (reg:P LR_REGNO))]
10691 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10693 [(set_attr "type" "branch")
10694 (set_attr "length" "4")])
10696 ;; Call to AIX abi function which may be in another module.
10697 ;; Restore the TOC pointer (r2) after the call.
10699 (define_insn "*call_nonlocal_aix<mode>"
10700 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10701 (match_operand 1 "" "g"))
10702 (clobber (reg:P LR_REGNO))]
10703 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10705 [(set_attr "type" "branch")
10706 (set_attr "length" "8")])
10708 (define_insn "*call_value_nonlocal_aix<mode>"
10709 [(set (match_operand 0 "" "")
10710 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10711 (match_operand 2 "" "g")))
10712 (clobber (reg:P LR_REGNO))]
10713 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10715 [(set_attr "type" "branch")
10716 (set_attr "length" "8")])
10718 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10719 ;; Operand0 is the addresss of the function to call
10720 ;; Operand2 is the location in the function descriptor to load r2 from
10721 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10723 (define_insn "*call_indirect_aix<mode>"
10724 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10725 (match_operand 1 "" "g,g"))
10726 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10727 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10728 (clobber (reg:P LR_REGNO))]
10729 "DEFAULT_ABI == ABI_AIX"
10730 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10731 [(set_attr "type" "jmpreg")
10732 (set_attr "length" "12")])
10734 (define_insn "*call_value_indirect_aix<mode>"
10735 [(set (match_operand 0 "" "")
10736 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10737 (match_operand 2 "" "g,g")))
10738 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10739 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10740 (clobber (reg:P LR_REGNO))]
10741 "DEFAULT_ABI == ABI_AIX"
10742 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10743 [(set_attr "type" "jmpreg")
10744 (set_attr "length" "12")])
10746 ;; Call to indirect functions with the ELFv2 ABI.
10747 ;; Operand0 is the addresss of the function to call
10748 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10750 (define_insn "*call_indirect_elfv2<mode>"
10751 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10752 (match_operand 1 "" "g,g"))
10753 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10754 (clobber (reg:P LR_REGNO))]
10755 "DEFAULT_ABI == ABI_ELFv2"
10756 "b%T0l\;<ptrload> 2,%2(1)"
10757 [(set_attr "type" "jmpreg")
10758 (set_attr "length" "8")])
10760 (define_insn "*call_value_indirect_elfv2<mode>"
10761 [(set (match_operand 0 "" "")
10762 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10763 (match_operand 2 "" "g,g")))
10764 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10765 (clobber (reg:P LR_REGNO))]
10766 "DEFAULT_ABI == ABI_ELFv2"
10767 "b%T1l\;<ptrload> 2,%3(1)"
10768 [(set_attr "type" "jmpreg")
10769 (set_attr "length" "8")])
10772 ;; Call subroutine returning any type.
10773 (define_expand "untyped_call"
10774 [(parallel [(call (match_operand 0 "" "")
10776 (match_operand 1 "" "")
10777 (match_operand 2 "" "")])]
10783 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10785 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10787 rtx set = XVECEXP (operands[2], 0, i);
10788 emit_move_insn (SET_DEST (set), SET_SRC (set));
10791 /* The optimizer does not know that the call sets the function value
10792 registers we stored in the result block. We avoid problems by
10793 claiming that all hard registers are used and clobbered at this
10795 emit_insn (gen_blockage ());
10800 ;; sibling call patterns
10801 (define_expand "sibcall"
10802 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10803 (match_operand 1 "" ""))
10804 (use (match_operand 2 "" ""))
10810 if (MACHOPIC_INDIRECT)
10811 operands[0] = machopic_indirect_call_target (operands[0]);
10814 gcc_assert (GET_CODE (operands[0]) == MEM);
10815 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10817 operands[0] = XEXP (operands[0], 0);
10819 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10821 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10826 (define_expand "sibcall_value"
10827 [(parallel [(set (match_operand 0 "register_operand" "")
10828 (call (mem:SI (match_operand 1 "address_operand" ""))
10829 (match_operand 2 "" "")))
10830 (use (match_operand 3 "" ""))
10836 if (MACHOPIC_INDIRECT)
10837 operands[1] = machopic_indirect_call_target (operands[1]);
10840 gcc_assert (GET_CODE (operands[1]) == MEM);
10841 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10843 operands[1] = XEXP (operands[1], 0);
10845 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10847 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10852 (define_insn "*sibcall_local32"
10853 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10854 (match_operand 1 "" "g,g"))
10855 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10857 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10860 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10861 output_asm_insn (\"crxor 6,6,6\", operands);
10863 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10864 output_asm_insn (\"creqv 6,6,6\", operands);
10866 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10868 [(set_attr "type" "branch")
10869 (set_attr "length" "4,8")])
10871 (define_insn "*sibcall_local64"
10872 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10873 (match_operand 1 "" "g,g"))
10874 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10876 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10879 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10880 output_asm_insn (\"crxor 6,6,6\", operands);
10882 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10883 output_asm_insn (\"creqv 6,6,6\", operands);
10885 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10887 [(set_attr "type" "branch")
10888 (set_attr "length" "4,8")])
10890 (define_insn "*sibcall_value_local32"
10891 [(set (match_operand 0 "" "")
10892 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10893 (match_operand 2 "" "g,g")))
10894 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10896 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10899 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10900 output_asm_insn (\"crxor 6,6,6\", operands);
10902 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10903 output_asm_insn (\"creqv 6,6,6\", operands);
10905 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10907 [(set_attr "type" "branch")
10908 (set_attr "length" "4,8")])
10910 (define_insn "*sibcall_value_local64"
10911 [(set (match_operand 0 "" "")
10912 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10913 (match_operand 2 "" "g,g")))
10914 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10916 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10919 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10920 output_asm_insn (\"crxor 6,6,6\", operands);
10922 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10923 output_asm_insn (\"creqv 6,6,6\", operands);
10925 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10927 [(set_attr "type" "branch")
10928 (set_attr "length" "4,8")])
10930 (define_insn "*sibcall_nonlocal_sysv<mode>"
10931 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10932 (match_operand 1 "" ""))
10933 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10935 "(DEFAULT_ABI == ABI_DARWIN
10936 || DEFAULT_ABI == ABI_V4)
10937 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10940 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10941 output_asm_insn (\"crxor 6,6,6\", operands);
10943 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10944 output_asm_insn (\"creqv 6,6,6\", operands);
10946 if (which_alternative >= 2)
10948 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10950 gcc_assert (!TARGET_SECURE_PLT);
10951 return \"b %z0@plt\";
10956 [(set_attr "type" "branch")
10957 (set_attr "length" "4,8,4,8")])
10959 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10960 [(set (match_operand 0 "" "")
10961 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10962 (match_operand 2 "" "")))
10963 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10965 "(DEFAULT_ABI == ABI_DARWIN
10966 || DEFAULT_ABI == ABI_V4)
10967 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10970 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10971 output_asm_insn (\"crxor 6,6,6\", operands);
10973 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10974 output_asm_insn (\"creqv 6,6,6\", operands);
10976 if (which_alternative >= 2)
10978 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10980 gcc_assert (!TARGET_SECURE_PLT);
10981 return \"b %z1@plt\";
10986 [(set_attr "type" "branch")
10987 (set_attr "length" "4,8,4,8")])
10989 ;; AIX ABI sibling call patterns.
10991 (define_insn "*sibcall_aix<mode>"
10992 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10993 (match_operand 1 "" "g,g"))
10995 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10999 [(set_attr "type" "branch")
11000 (set_attr "length" "4")])
11002 (define_insn "*sibcall_value_aix<mode>"
11003 [(set (match_operand 0 "" "")
11004 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11005 (match_operand 2 "" "g,g")))
11007 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11011 [(set_attr "type" "branch")
11012 (set_attr "length" "4")])
11014 (define_expand "sibcall_epilogue"
11015 [(use (const_int 0))]
11018 if (!TARGET_SCHED_PROLOG)
11019 emit_insn (gen_blockage ());
11020 rs6000_emit_epilogue (TRUE);
11024 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11025 ;; all of memory. This blocks insns from being moved across this point.
11027 (define_insn "blockage"
11028 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11032 (define_expand "probe_stack_address"
11033 [(use (match_operand 0 "address_operand"))]
11036 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11037 MEM_VOLATILE_P (operands[0]) = 1;
11040 emit_insn (gen_probe_stack_di (operands[0]));
11042 emit_insn (gen_probe_stack_si (operands[0]));
11046 (define_insn "probe_stack_<mode>"
11047 [(set (match_operand:P 0 "memory_operand" "=m")
11048 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11051 operands[1] = gen_rtx_REG (Pmode, 0);
11052 return "st<wd>%U0%X0 %1,%0";
11054 [(set_attr "type" "store")
11055 (set (attr "update")
11056 (if_then_else (match_operand 0 "update_address_mem")
11057 (const_string "yes")
11058 (const_string "no")))
11059 (set (attr "indexed")
11060 (if_then_else (match_operand 0 "indexed_address_mem")
11061 (const_string "yes")
11062 (const_string "no")))
11063 (set_attr "length" "4")])
11065 (define_insn "probe_stack_range<P:mode>"
11066 [(set (match_operand:P 0 "register_operand" "=r")
11067 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11068 (match_operand:P 2 "register_operand" "r")]
11069 UNSPECV_PROBE_STACK_RANGE))]
11071 "* return output_probe_stack_range (operands[0], operands[2]);"
11072 [(set_attr "type" "three")])
11074 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11075 ;; signed & unsigned, and one type of branch.
11077 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11078 ;; insns, and branches.
11080 (define_expand "cbranch<mode>4"
11081 [(use (match_operator 0 "rs6000_cbranch_operator"
11082 [(match_operand:GPR 1 "gpc_reg_operand" "")
11083 (match_operand:GPR 2 "reg_or_short_operand" "")]))
11084 (use (match_operand 3 ""))]
11088 /* Take care of the possibility that operands[2] might be negative but
11089 this might be a logical operation. That insn doesn't exist. */
11090 if (GET_CODE (operands[2]) == CONST_INT
11091 && INTVAL (operands[2]) < 0)
11093 operands[2] = force_reg (<MODE>mode, operands[2]);
11094 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11095 GET_MODE (operands[0]),
11096 operands[1], operands[2]);
11099 rs6000_emit_cbranch (<MODE>mode, operands);
11103 (define_expand "cbranch<mode>4"
11104 [(use (match_operator 0 "rs6000_cbranch_operator"
11105 [(match_operand:FP 1 "gpc_reg_operand" "")
11106 (match_operand:FP 2 "gpc_reg_operand" "")]))
11107 (use (match_operand 3 ""))]
11111 rs6000_emit_cbranch (<MODE>mode, operands);
11115 (define_expand "cstore<mode>4_signed"
11116 [(use (match_operator 1 "signed_comparison_operator"
11117 [(match_operand:P 2 "gpc_reg_operand")
11118 (match_operand:P 3 "gpc_reg_operand")]))
11119 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11122 enum rtx_code cond_code = GET_CODE (operands[1]);
11124 rtx op0 = operands[0];
11125 rtx op1 = operands[2];
11126 rtx op2 = operands[3];
11128 if (cond_code == GE || cond_code == LT)
11130 cond_code = swap_condition (cond_code);
11131 std::swap (op1, op2);
11134 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11135 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11136 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11138 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11139 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11140 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11142 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11144 if (cond_code == LE)
11145 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11148 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11149 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11150 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11156 (define_expand "cstore<mode>4_unsigned"
11157 [(use (match_operator 1 "unsigned_comparison_operator"
11158 [(match_operand:P 2 "gpc_reg_operand")
11159 (match_operand:P 3 "reg_or_short_operand")]))
11160 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11163 enum rtx_code cond_code = GET_CODE (operands[1]);
11165 rtx op0 = operands[0];
11166 rtx op1 = operands[2];
11167 rtx op2 = operands[3];
11169 if (cond_code == GEU || cond_code == LTU)
11171 cond_code = swap_condition (cond_code);
11172 std::swap (op1, op2);
11175 if (!gpc_reg_operand (op1, <MODE>mode))
11176 op1 = force_reg (<MODE>mode, op1);
11177 if (!reg_or_short_operand (op2, <MODE>mode))
11178 op2 = force_reg (<MODE>mode, op2);
11180 rtx tmp = gen_reg_rtx (<MODE>mode);
11181 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11183 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11184 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11186 if (cond_code == LEU)
11187 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11189 emit_insn (gen_neg<mode>2 (op0, tmp2));
11194 (define_expand "cstore_si_as_di"
11195 [(use (match_operator 1 "unsigned_comparison_operator"
11196 [(match_operand:SI 2 "gpc_reg_operand")
11197 (match_operand:SI 3 "reg_or_short_operand")]))
11198 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11201 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11202 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11204 operands[2] = force_reg (SImode, operands[2]);
11205 operands[3] = force_reg (SImode, operands[3]);
11206 rtx op1 = gen_reg_rtx (DImode);
11207 rtx op2 = gen_reg_rtx (DImode);
11208 convert_move (op1, operands[2], uns_flag);
11209 convert_move (op2, operands[3], uns_flag);
11211 if (cond_code == GT || cond_code == LE)
11213 cond_code = swap_condition (cond_code);
11214 std::swap (op1, op2);
11217 rtx tmp = gen_reg_rtx (DImode);
11218 rtx tmp2 = gen_reg_rtx (DImode);
11219 emit_insn (gen_subdi3 (tmp, op1, op2));
11220 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11226 gcc_unreachable ();
11231 tmp3 = gen_reg_rtx (DImode);
11232 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11236 convert_move (operands[0], tmp3, 1);
11241 (define_expand "cstore<mode>4_signed_imm"
11242 [(use (match_operator 1 "signed_comparison_operator"
11243 [(match_operand:GPR 2 "gpc_reg_operand")
11244 (match_operand:GPR 3 "immediate_operand")]))
11245 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11248 bool invert = false;
11250 enum rtx_code cond_code = GET_CODE (operands[1]);
11252 rtx op0 = operands[0];
11253 rtx op1 = operands[2];
11254 HOST_WIDE_INT val = INTVAL (operands[3]);
11256 if (cond_code == GE || cond_code == GT)
11258 cond_code = reverse_condition (cond_code);
11262 if (cond_code == LE)
11265 rtx tmp = gen_reg_rtx (<MODE>mode);
11266 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11267 rtx x = gen_reg_rtx (<MODE>mode);
11269 emit_insn (gen_and<mode>3 (x, op1, tmp));
11271 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11275 rtx tmp = gen_reg_rtx (<MODE>mode);
11276 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11280 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11281 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11286 (define_expand "cstore<mode>4_unsigned_imm"
11287 [(use (match_operator 1 "unsigned_comparison_operator"
11288 [(match_operand:GPR 2 "gpc_reg_operand")
11289 (match_operand:GPR 3 "immediate_operand")]))
11290 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11293 bool invert = false;
11295 enum rtx_code cond_code = GET_CODE (operands[1]);
11297 rtx op0 = operands[0];
11298 rtx op1 = operands[2];
11299 HOST_WIDE_INT val = INTVAL (operands[3]);
11301 if (cond_code == GEU || cond_code == GTU)
11303 cond_code = reverse_condition (cond_code);
11307 if (cond_code == LEU)
11310 rtx tmp = gen_reg_rtx (<MODE>mode);
11311 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11312 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11313 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11314 rtx x = gen_reg_rtx (<MODE>mode);
11316 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11318 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11322 rtx tmp = gen_reg_rtx (<MODE>mode);
11323 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11327 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11328 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11333 (define_expand "cstore<mode>4"
11334 [(use (match_operator 1 "rs6000_cbranch_operator"
11335 [(match_operand:GPR 2 "gpc_reg_operand")
11336 (match_operand:GPR 3 "reg_or_short_operand")]))
11337 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11340 /* Use ISEL if the user asked for it. */
11342 rs6000_emit_sISEL (<MODE>mode, operands);
11344 /* Expanding EQ and NE directly to some machine instructions does not help
11345 but does hurt combine. So don't. */
11346 else if (GET_CODE (operands[1]) == EQ)
11347 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11348 else if (<MODE>mode == Pmode
11349 && GET_CODE (operands[1]) == NE)
11350 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11351 else if (GET_CODE (operands[1]) == NE)
11353 rtx tmp = gen_reg_rtx (<MODE>mode);
11354 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11355 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11358 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11359 etc. combinations magically work out just right. */
11360 else if (<MODE>mode == Pmode
11361 && unsigned_comparison_operator (operands[1], VOIDmode))
11362 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11363 operands[2], operands[3]));
11365 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11366 else if (<MODE>mode == SImode && Pmode == DImode)
11367 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11368 operands[2], operands[3]));
11370 /* For signed comparisons against a constant, we can do some simple
11372 else if (signed_comparison_operator (operands[1], VOIDmode)
11373 && CONST_INT_P (operands[3]))
11374 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11375 operands[2], operands[3]));
11377 /* And similarly for unsigned comparisons. */
11378 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11379 && CONST_INT_P (operands[3]))
11380 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11381 operands[2], operands[3]));
11383 /* We also do not want to use mfcr for signed comparisons. */
11384 else if (<MODE>mode == Pmode
11385 && signed_comparison_operator (operands[1], VOIDmode))
11386 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11387 operands[2], operands[3]));
11389 /* Everything else, use the mfcr brute force. */
11391 rs6000_emit_sCOND (<MODE>mode, operands);
11396 (define_expand "cstore<mode>4"
11397 [(use (match_operator 1 "rs6000_cbranch_operator"
11398 [(match_operand:FP 2 "gpc_reg_operand")
11399 (match_operand:FP 3 "gpc_reg_operand")]))
11400 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11403 rs6000_emit_sCOND (<MODE>mode, operands);
11408 (define_expand "stack_protect_set"
11409 [(match_operand 0 "memory_operand" "")
11410 (match_operand 1 "memory_operand" "")]
11413 #ifdef TARGET_THREAD_SSP_OFFSET
11414 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11415 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11416 operands[1] = gen_rtx_MEM (Pmode, addr);
11419 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11421 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11425 (define_insn "stack_protect_setsi"
11426 [(set (match_operand:SI 0 "memory_operand" "=m")
11427 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11428 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11430 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11431 [(set_attr "type" "three")
11432 (set_attr "length" "12")])
11434 (define_insn "stack_protect_setdi"
11435 [(set (match_operand:DI 0 "memory_operand" "=Y")
11436 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11437 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11439 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11440 [(set_attr "type" "three")
11441 (set_attr "length" "12")])
11443 (define_expand "stack_protect_test"
11444 [(match_operand 0 "memory_operand" "")
11445 (match_operand 1 "memory_operand" "")
11446 (match_operand 2 "" "")]
11449 rtx test, op0, op1;
11450 #ifdef TARGET_THREAD_SSP_OFFSET
11451 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11452 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11453 operands[1] = gen_rtx_MEM (Pmode, addr);
11456 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11457 test = gen_rtx_EQ (VOIDmode, op0, op1);
11458 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11462 (define_insn "stack_protect_testsi"
11463 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11464 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11465 (match_operand:SI 2 "memory_operand" "m,m")]
11467 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11468 (clobber (match_scratch:SI 3 "=&r,&r"))]
11471 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11472 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11473 [(set_attr "length" "16,20")])
11475 (define_insn "stack_protect_testdi"
11476 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11477 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11478 (match_operand:DI 2 "memory_operand" "Y,Y")]
11480 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11481 (clobber (match_scratch:DI 3 "=&r,&r"))]
11484 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11485 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11486 [(set_attr "length" "16,20")])
11489 ;; Here are the actual compare insns.
11490 (define_insn "*cmp<mode>_signed"
11491 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11492 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11493 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11495 "cmp<wd>%I2 %0,%1,%2"
11496 [(set_attr "type" "cmp")])
11498 (define_insn "*cmp<mode>_unsigned"
11499 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11500 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11501 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11503 "cmpl<wd>%I2 %0,%1,%2"
11504 [(set_attr "type" "cmp")])
11506 ;; If we are comparing a register for equality with a large constant,
11507 ;; we can do this with an XOR followed by a compare. But this is profitable
11508 ;; only if the large constant is only used for the comparison (and in this
11509 ;; case we already have a register to reuse as scratch).
11511 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11512 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11515 [(set (match_operand:SI 0 "register_operand")
11516 (match_operand:SI 1 "logical_const_operand" ""))
11517 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11519 (match_operand:SI 2 "logical_const_operand" "")]))
11520 (set (match_operand:CC 4 "cc_reg_operand" "")
11521 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11524 (if_then_else (match_operator 6 "equality_operator"
11525 [(match_dup 4) (const_int 0)])
11526 (match_operand 7 "" "")
11527 (match_operand 8 "" "")))]
11528 "peep2_reg_dead_p (3, operands[0])
11529 && peep2_reg_dead_p (4, operands[4])
11530 && REGNO (operands[0]) != REGNO (operands[5])"
11531 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11532 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11533 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11536 /* Get the constant we are comparing against, and see what it looks like
11537 when sign-extended from 16 to 32 bits. Then see what constant we could
11538 XOR with SEXTC to get the sign-extended value. */
11539 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11541 operands[1], operands[2]);
11542 HOST_WIDE_INT c = INTVAL (cnst);
11543 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11544 HOST_WIDE_INT xorv = c ^ sextc;
11546 operands[9] = GEN_INT (xorv);
11547 operands[10] = GEN_INT (sextc);
11550 ;; The following two insns don't exist as single insns, but if we provide
11551 ;; them, we can swap an add and compare, which will enable us to overlap more
11552 ;; of the required delay between a compare and branch. We generate code for
11553 ;; them by splitting.
11556 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11557 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11558 (match_operand:SI 2 "short_cint_operand" "i")))
11559 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11560 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11563 [(set_attr "length" "8")])
11566 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11567 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11568 (match_operand:SI 2 "u_short_cint_operand" "i")))
11569 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11570 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11573 [(set_attr "length" "8")])
11576 [(set (match_operand:CC 3 "cc_reg_operand" "")
11577 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11578 (match_operand:SI 2 "short_cint_operand" "")))
11579 (set (match_operand:SI 0 "gpc_reg_operand" "")
11580 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11582 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11583 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11586 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11587 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11588 (match_operand:SI 2 "u_short_cint_operand" "")))
11589 (set (match_operand:SI 0 "gpc_reg_operand" "")
11590 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11592 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11593 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11595 ;; Only need to compare second words if first words equal
11596 (define_insn "*cmp<mode>_internal1"
11597 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11598 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11599 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11600 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11601 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11602 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11603 [(set_attr "type" "fpcompare")
11604 (set_attr "length" "12")])
11606 (define_insn_and_split "*cmp<mode>_internal2"
11607 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11608 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11609 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11610 (clobber (match_scratch:DF 3 "=d"))
11611 (clobber (match_scratch:DF 4 "=d"))
11612 (clobber (match_scratch:DF 5 "=d"))
11613 (clobber (match_scratch:DF 6 "=d"))
11614 (clobber (match_scratch:DF 7 "=d"))
11615 (clobber (match_scratch:DF 8 "=d"))
11616 (clobber (match_scratch:DF 9 "=d"))
11617 (clobber (match_scratch:DF 10 "=d"))
11618 (clobber (match_scratch:GPR 11 "=b"))]
11619 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11620 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11622 "&& reload_completed"
11623 [(set (match_dup 3) (match_dup 14))
11624 (set (match_dup 4) (match_dup 15))
11625 (set (match_dup 9) (abs:DF (match_dup 5)))
11626 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11627 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11628 (label_ref (match_dup 12))
11630 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11631 (set (pc) (label_ref (match_dup 13)))
11633 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11634 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11635 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11636 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11639 REAL_VALUE_TYPE rv;
11640 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11641 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11643 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11644 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11645 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11646 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11647 operands[12] = gen_label_rtx ();
11648 operands[13] = gen_label_rtx ();
11650 operands[14] = force_const_mem (DFmode,
11651 const_double_from_real_value (rv, DFmode));
11652 operands[15] = force_const_mem (DFmode,
11653 const_double_from_real_value (dconst0,
11658 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11659 operands[14] = gen_const_mem (DFmode, tocref);
11660 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11661 operands[15] = gen_const_mem (DFmode, tocref);
11662 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11663 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11667 ;; Now we have the scc insns. We can do some combinations because of the
11668 ;; way the machine works.
11670 ;; Note that this is probably faster if we can put an insn between the
11671 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11672 ;; cases the insns below which don't use an intermediate CR field will
11673 ;; be used instead.
11675 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11676 (match_operator:SI 1 "scc_comparison_operator"
11677 [(match_operand 2 "cc_reg_operand" "y")
11680 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11681 [(set (attr "type")
11682 (cond [(match_test "TARGET_MFCRF")
11683 (const_string "mfcrf")
11685 (const_string "mfcr")))
11686 (set_attr "length" "8")])
11688 ;; Same as above, but get the GT bit.
11689 (define_insn "move_from_CR_gt_bit"
11690 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11691 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11692 "TARGET_HARD_FLOAT && !TARGET_FPRS"
11693 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11694 [(set_attr "type" "mfcr")
11695 (set_attr "length" "8")])
11697 ;; Same as above, but get the OV/ORDERED bit.
11698 (define_insn "move_from_CR_ov_bit"
11699 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11700 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11703 "mfcr %0\;rlwinm %0,%0,%t1,1"
11704 [(set_attr "type" "mfcr")
11705 (set_attr "length" "8")])
11708 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11709 (match_operator:DI 1 "scc_comparison_operator"
11710 [(match_operand 2 "cc_reg_operand" "y")
11713 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11714 [(set (attr "type")
11715 (cond [(match_test "TARGET_MFCRF")
11716 (const_string "mfcrf")
11718 (const_string "mfcr")))
11719 (set_attr "length" "8")])
11722 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11723 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11724 [(match_operand 2 "cc_reg_operand" "y,y")
11727 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11728 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11731 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11733 [(set_attr "type" "shift")
11734 (set_attr "dot" "yes")
11735 (set_attr "length" "8,16")])
11738 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11739 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11740 [(match_operand 2 "cc_reg_operand" "")
11743 (set (match_operand:SI 3 "gpc_reg_operand" "")
11744 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11745 "TARGET_32BIT && reload_completed"
11746 [(set (match_dup 3)
11747 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11749 (compare:CC (match_dup 3)
11754 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11755 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11756 [(match_operand 2 "cc_reg_operand" "y")
11758 (match_operand:SI 3 "const_int_operand" "n")))]
11762 int is_bit = ccr_bit (operands[1], 1);
11763 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11766 if (is_bit >= put_bit)
11767 count = is_bit - put_bit;
11769 count = 32 - (put_bit - is_bit);
11771 operands[4] = GEN_INT (count);
11772 operands[5] = GEN_INT (put_bit);
11774 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11776 [(set (attr "type")
11777 (cond [(match_test "TARGET_MFCRF")
11778 (const_string "mfcrf")
11780 (const_string "mfcr")))
11781 (set_attr "length" "8")])
11784 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11786 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11787 [(match_operand 2 "cc_reg_operand" "y,y")
11789 (match_operand:SI 3 "const_int_operand" "n,n"))
11791 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11792 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11797 int is_bit = ccr_bit (operands[1], 1);
11798 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11801 /* Force split for non-cc0 compare. */
11802 if (which_alternative == 1)
11805 if (is_bit >= put_bit)
11806 count = is_bit - put_bit;
11808 count = 32 - (put_bit - is_bit);
11810 operands[5] = GEN_INT (count);
11811 operands[6] = GEN_INT (put_bit);
11813 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11815 [(set_attr "type" "shift")
11816 (set_attr "dot" "yes")
11817 (set_attr "length" "8,16")])
11820 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11822 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11823 [(match_operand 2 "cc_reg_operand" "")
11825 (match_operand:SI 3 "const_int_operand" ""))
11827 (set (match_operand:SI 4 "gpc_reg_operand" "")
11828 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11831 [(set (match_dup 4)
11832 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11835 (compare:CC (match_dup 4)
11840 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11843 (define_insn_and_split "eq<mode>3"
11844 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11845 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11846 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11847 (clobber (match_scratch:GPR 3 "=r"))
11848 (clobber (match_scratch:GPR 4 "=r"))]
11852 [(set (match_dup 4)
11853 (clz:GPR (match_dup 3)))
11855 (lshiftrt:GPR (match_dup 4)
11858 operands[3] = rs6000_emit_eqne (<MODE>mode,
11859 operands[1], operands[2], operands[3]);
11861 if (GET_CODE (operands[4]) == SCRATCH)
11862 operands[4] = gen_reg_rtx (<MODE>mode);
11864 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11866 [(set (attr "length")
11867 (if_then_else (match_test "operands[2] == const0_rtx")
11869 (const_string "12")))])
11871 (define_insn_and_split "ne<mode>3"
11872 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11873 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11874 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11875 (clobber (match_scratch:P 3 "=r"))
11876 (clobber (match_scratch:P 4 "=r"))
11877 (clobber (reg:P CA_REGNO))]
11881 [(parallel [(set (match_dup 4)
11882 (plus:P (match_dup 3)
11884 (set (reg:P CA_REGNO)
11885 (ne:P (match_dup 3)
11887 (parallel [(set (match_dup 0)
11888 (plus:P (plus:P (not:P (match_dup 4))
11891 (clobber (reg:P CA_REGNO))])]
11893 operands[3] = rs6000_emit_eqne (<MODE>mode,
11894 operands[1], operands[2], operands[3]);
11896 if (GET_CODE (operands[4]) == SCRATCH)
11897 operands[4] = gen_reg_rtx (<MODE>mode);
11899 [(set (attr "length")
11900 (if_then_else (match_test "operands[2] == const0_rtx")
11902 (const_string "12")))])
11904 (define_insn_and_split "*neg_eq_<mode>"
11905 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11906 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11907 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11908 (clobber (match_scratch:P 3 "=r"))
11909 (clobber (match_scratch:P 4 "=r"))
11910 (clobber (reg:P CA_REGNO))]
11914 [(parallel [(set (match_dup 4)
11915 (plus:P (match_dup 3)
11917 (set (reg:P CA_REGNO)
11918 (ne:P (match_dup 3)
11920 (parallel [(set (match_dup 0)
11921 (plus:P (reg:P CA_REGNO)
11923 (clobber (reg:P CA_REGNO))])]
11925 operands[3] = rs6000_emit_eqne (<MODE>mode,
11926 operands[1], operands[2], operands[3]);
11928 if (GET_CODE (operands[4]) == SCRATCH)
11929 operands[4] = gen_reg_rtx (<MODE>mode);
11931 [(set (attr "length")
11932 (if_then_else (match_test "operands[2] == const0_rtx")
11934 (const_string "12")))])
11936 (define_insn_and_split "*neg_ne_<mode>"
11937 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11938 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11939 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11940 (clobber (match_scratch:P 3 "=r"))
11941 (clobber (match_scratch:P 4 "=r"))
11942 (clobber (reg:P CA_REGNO))]
11946 [(parallel [(set (match_dup 4)
11947 (neg:P (match_dup 3)))
11948 (set (reg:P CA_REGNO)
11949 (eq:P (match_dup 3)
11951 (parallel [(set (match_dup 0)
11952 (plus:P (reg:P CA_REGNO)
11954 (clobber (reg:P CA_REGNO))])]
11956 operands[3] = rs6000_emit_eqne (<MODE>mode,
11957 operands[1], operands[2], operands[3]);
11959 if (GET_CODE (operands[4]) == SCRATCH)
11960 operands[4] = gen_reg_rtx (<MODE>mode);
11962 [(set (attr "length")
11963 (if_then_else (match_test "operands[2] == const0_rtx")
11965 (const_string "12")))])
11967 (define_insn_and_split "*plus_eq_<mode>"
11968 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11969 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11970 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11971 (match_operand:P 3 "gpc_reg_operand" "r")))
11972 (clobber (match_scratch:P 4 "=r"))
11973 (clobber (match_scratch:P 5 "=r"))
11974 (clobber (reg:P CA_REGNO))]
11978 [(parallel [(set (match_dup 5)
11979 (neg:P (match_dup 4)))
11980 (set (reg:P CA_REGNO)
11981 (eq:P (match_dup 4)
11983 (parallel [(set (match_dup 0)
11984 (plus:P (match_dup 3)
11986 (clobber (reg:P CA_REGNO))])]
11988 operands[4] = rs6000_emit_eqne (<MODE>mode,
11989 operands[1], operands[2], operands[4]);
11991 if (GET_CODE (operands[5]) == SCRATCH)
11992 operands[5] = gen_reg_rtx (<MODE>mode);
11994 [(set (attr "length")
11995 (if_then_else (match_test "operands[2] == const0_rtx")
11997 (const_string "12")))])
11999 (define_insn_and_split "*plus_ne_<mode>"
12000 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12001 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12002 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12003 (match_operand:P 3 "gpc_reg_operand" "r")))
12004 (clobber (match_scratch:P 4 "=r"))
12005 (clobber (match_scratch:P 5 "=r"))
12006 (clobber (reg:P CA_REGNO))]
12010 [(parallel [(set (match_dup 5)
12011 (plus:P (match_dup 4)
12013 (set (reg:P CA_REGNO)
12014 (ne:P (match_dup 4)
12016 (parallel [(set (match_dup 0)
12017 (plus:P (match_dup 3)
12019 (clobber (reg:P CA_REGNO))])]
12021 operands[4] = rs6000_emit_eqne (<MODE>mode,
12022 operands[1], operands[2], operands[4]);
12024 if (GET_CODE (operands[5]) == SCRATCH)
12025 operands[5] = gen_reg_rtx (<MODE>mode);
12027 [(set (attr "length")
12028 (if_then_else (match_test "operands[2] == const0_rtx")
12030 (const_string "12")))])
12032 (define_insn_and_split "*minus_eq_<mode>"
12033 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12034 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12035 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12036 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12037 (clobber (match_scratch:P 4 "=r"))
12038 (clobber (match_scratch:P 5 "=r"))
12039 (clobber (reg:P CA_REGNO))]
12043 [(parallel [(set (match_dup 5)
12044 (plus:P (match_dup 4)
12046 (set (reg:P CA_REGNO)
12047 (ne:P (match_dup 4)
12049 (parallel [(set (match_dup 0)
12050 (plus:P (plus:P (match_dup 3)
12053 (clobber (reg:P CA_REGNO))])]
12055 operands[4] = rs6000_emit_eqne (<MODE>mode,
12056 operands[1], operands[2], operands[4]);
12058 if (GET_CODE (operands[5]) == SCRATCH)
12059 operands[5] = gen_reg_rtx (<MODE>mode);
12061 [(set (attr "length")
12062 (if_then_else (match_test "operands[2] == const0_rtx")
12064 (const_string "12")))])
12066 (define_insn_and_split "*minus_ne_<mode>"
12067 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12068 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12069 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12070 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12071 (clobber (match_scratch:P 4 "=r"))
12072 (clobber (match_scratch:P 5 "=r"))
12073 (clobber (reg:P CA_REGNO))]
12077 [(parallel [(set (match_dup 5)
12078 (neg:P (match_dup 4)))
12079 (set (reg:P CA_REGNO)
12080 (eq:P (match_dup 4)
12082 (parallel [(set (match_dup 0)
12083 (plus:P (plus:P (match_dup 3)
12086 (clobber (reg:P CA_REGNO))])]
12088 operands[4] = rs6000_emit_eqne (<MODE>mode,
12089 operands[1], operands[2], operands[4]);
12091 if (GET_CODE (operands[5]) == SCRATCH)
12092 operands[5] = gen_reg_rtx (<MODE>mode);
12094 [(set (attr "length")
12095 (if_then_else (match_test "operands[2] == const0_rtx")
12097 (const_string "12")))])
12099 (define_insn_and_split "*eqsi3_ext<mode>"
12100 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12101 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12102 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12103 (clobber (match_scratch:SI 3 "=r"))
12104 (clobber (match_scratch:SI 4 "=r"))]
12108 [(set (match_dup 4)
12109 (clz:SI (match_dup 3)))
12112 (lshiftrt:SI (match_dup 4)
12115 operands[3] = rs6000_emit_eqne (SImode,
12116 operands[1], operands[2], operands[3]);
12118 if (GET_CODE (operands[4]) == SCRATCH)
12119 operands[4] = gen_reg_rtx (SImode);
12121 [(set (attr "length")
12122 (if_then_else (match_test "operands[2] == const0_rtx")
12124 (const_string "12")))])
12126 (define_insn_and_split "*nesi3_ext<mode>"
12127 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12128 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12129 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12130 (clobber (match_scratch:SI 3 "=r"))
12131 (clobber (match_scratch:SI 4 "=r"))
12132 (clobber (match_scratch:EXTSI 5 "=r"))]
12136 [(set (match_dup 4)
12137 (clz:SI (match_dup 3)))
12140 (lshiftrt:SI (match_dup 4)
12143 (xor:EXTSI (match_dup 5)
12146 operands[3] = rs6000_emit_eqne (SImode,
12147 operands[1], operands[2], operands[3]);
12149 if (GET_CODE (operands[4]) == SCRATCH)
12150 operands[4] = gen_reg_rtx (SImode);
12151 if (GET_CODE (operands[5]) == SCRATCH)
12152 operands[5] = gen_reg_rtx (<MODE>mode);
12154 [(set (attr "length")
12155 (if_then_else (match_test "operands[2] == const0_rtx")
12156 (const_string "12")
12157 (const_string "16")))])
12159 ;; Define both directions of branch and return. If we need a reload
12160 ;; register, we'd rather use CR0 since it is much easier to copy a
12161 ;; register CC value to there.
12165 (if_then_else (match_operator 1 "branch_comparison_operator"
12167 "cc_reg_operand" "y")
12169 (label_ref (match_operand 0 "" ""))
12174 return output_cbranch (operands[1], \"%l0\", 0, insn);
12176 [(set_attr "type" "branch")])
12180 (if_then_else (match_operator 0 "branch_comparison_operator"
12182 "cc_reg_operand" "y")
12189 return output_cbranch (operands[0], NULL, 0, insn);
12191 [(set_attr "type" "jmpreg")
12192 (set_attr "length" "4")])
12196 (if_then_else (match_operator 1 "branch_comparison_operator"
12198 "cc_reg_operand" "y")
12201 (label_ref (match_operand 0 "" ""))))]
12205 return output_cbranch (operands[1], \"%l0\", 1, insn);
12207 [(set_attr "type" "branch")])
12211 (if_then_else (match_operator 0 "branch_comparison_operator"
12213 "cc_reg_operand" "y")
12220 return output_cbranch (operands[0], NULL, 1, insn);
12222 [(set_attr "type" "jmpreg")
12223 (set_attr "length" "4")])
12225 ;; Logic on condition register values.
12227 ; This pattern matches things like
12228 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12229 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12231 ; which are generated by the branch logic.
12232 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12234 (define_insn "*cceq_ior_compare"
12235 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12236 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12237 [(match_operator:SI 2
12238 "branch_positive_comparison_operator"
12240 "cc_reg_operand" "y,y")
12242 (match_operator:SI 4
12243 "branch_positive_comparison_operator"
12245 "cc_reg_operand" "0,y")
12249 "cr%q1 %E0,%j2,%j4"
12250 [(set_attr "type" "cr_logical,delayed_cr")])
12252 ; Why is the constant -1 here, but 1 in the previous pattern?
12253 ; Because ~1 has all but the low bit set.
12255 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12256 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12257 [(not:SI (match_operator:SI 2
12258 "branch_positive_comparison_operator"
12260 "cc_reg_operand" "y,y")
12262 (match_operator:SI 4
12263 "branch_positive_comparison_operator"
12265 "cc_reg_operand" "0,y")
12269 "cr%q1 %E0,%j2,%j4"
12270 [(set_attr "type" "cr_logical,delayed_cr")])
12272 (define_insn "*cceq_rev_compare"
12273 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12274 (compare:CCEQ (match_operator:SI 1
12275 "branch_positive_comparison_operator"
12277 "cc_reg_operand" "0,y")
12282 [(set_attr "type" "cr_logical,delayed_cr")])
12284 ;; If we are comparing the result of two comparisons, this can be done
12285 ;; using creqv or crxor.
12287 (define_insn_and_split ""
12288 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12289 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12290 [(match_operand 2 "cc_reg_operand" "y")
12292 (match_operator 3 "branch_comparison_operator"
12293 [(match_operand 4 "cc_reg_operand" "y")
12298 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12302 int positive_1, positive_2;
12304 positive_1 = branch_positive_comparison_operator (operands[1],
12305 GET_MODE (operands[1]));
12306 positive_2 = branch_positive_comparison_operator (operands[3],
12307 GET_MODE (operands[3]));
12310 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12311 GET_CODE (operands[1])),
12313 operands[2], const0_rtx);
12314 else if (GET_MODE (operands[1]) != SImode)
12315 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12316 operands[2], const0_rtx);
12319 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12320 GET_CODE (operands[3])),
12322 operands[4], const0_rtx);
12323 else if (GET_MODE (operands[3]) != SImode)
12324 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12325 operands[4], const0_rtx);
12327 if (positive_1 == positive_2)
12329 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12330 operands[5] = constm1_rtx;
12334 operands[5] = const1_rtx;
12338 ;; Unconditional branch and return.
12340 (define_insn "jump"
12342 (label_ref (match_operand 0 "" "")))]
12345 [(set_attr "type" "branch")])
12347 (define_insn "<return_str>return"
12351 [(set_attr "type" "jmpreg")])
12353 (define_expand "indirect_jump"
12354 [(set (pc) (match_operand 0 "register_operand" ""))])
12356 (define_insn "*indirect_jump<mode>"
12357 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12362 [(set_attr "type" "jmpreg")])
12364 ;; Table jump for switch statements:
12365 (define_expand "tablejump"
12366 [(use (match_operand 0 "" ""))
12367 (use (label_ref (match_operand 1 "" "")))]
12372 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12374 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12378 (define_expand "tablejumpsi"
12379 [(set (match_dup 3)
12380 (plus:SI (match_operand:SI 0 "" "")
12382 (parallel [(set (pc) (match_dup 3))
12383 (use (label_ref (match_operand 1 "" "")))])]
12386 { operands[0] = force_reg (SImode, operands[0]);
12387 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12388 operands[3] = gen_reg_rtx (SImode);
12391 (define_expand "tablejumpdi"
12392 [(set (match_dup 4)
12393 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12395 (plus:DI (match_dup 4)
12397 (parallel [(set (pc) (match_dup 3))
12398 (use (label_ref (match_operand 1 "" "")))])]
12401 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12402 operands[3] = gen_reg_rtx (DImode);
12403 operands[4] = gen_reg_rtx (DImode);
12406 (define_insn "*tablejump<mode>_internal1"
12408 (match_operand:P 0 "register_operand" "c,*l"))
12409 (use (label_ref (match_operand 1 "" "")))]
12414 [(set_attr "type" "jmpreg")])
12417 [(unspec [(const_int 0)] UNSPEC_NOP)]
12421 (define_insn "group_ending_nop"
12422 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12426 if (rs6000_cpu_attr == CPU_POWER6)
12427 return \"ori 1,1,0\";
12428 return \"ori 2,2,0\";
12431 ;; Define the subtract-one-and-jump insns, starting with the template
12432 ;; so loop.c knows what to generate.
12434 (define_expand "doloop_end"
12435 [(use (match_operand 0 "" "")) ; loop pseudo
12436 (use (match_operand 1 "" ""))] ; label
12442 if (GET_MODE (operands[0]) != DImode)
12444 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12448 if (GET_MODE (operands[0]) != SImode)
12450 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12455 (define_expand "ctr<mode>"
12456 [(parallel [(set (pc)
12457 (if_then_else (ne (match_operand:P 0 "register_operand" "")
12459 (label_ref (match_operand 1 "" ""))
12462 (plus:P (match_dup 0)
12464 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12465 (clobber (match_scratch:CC 2 ""))
12466 (clobber (match_scratch:P 3 ""))])]
12470 ;; We need to be able to do this for any operand, including MEM, or we
12471 ;; will cause reload to blow up since we don't allow output reloads on
12473 ;; For the length attribute to be calculated correctly, the
12474 ;; label MUST be operand 0.
12475 ;; The UNSPEC is present to prevent combine creating this pattern.
12477 (define_insn "*ctr<mode>_internal1"
12479 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12481 (label_ref (match_operand 0 "" ""))
12483 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12484 (plus:P (match_dup 1)
12486 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12487 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12488 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12492 if (which_alternative != 0)
12494 else if (get_attr_length (insn) == 4)
12495 return \"bdnz %l0\";
12497 return \"bdz $+8\;b %l0\";
12499 [(set_attr "type" "branch")
12500 (set_attr "length" "*,16,20,20")])
12502 (define_insn "*ctr<mode>_internal2"
12504 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12507 (label_ref (match_operand 0 "" ""))))
12508 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12509 (plus:P (match_dup 1)
12511 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12512 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12513 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12517 if (which_alternative != 0)
12519 else if (get_attr_length (insn) == 4)
12520 return \"bdz %l0\";
12522 return \"bdnz $+8\;b %l0\";
12524 [(set_attr "type" "branch")
12525 (set_attr "length" "*,16,20,20")])
12527 ;; Similar but use EQ
12529 (define_insn "*ctr<mode>_internal5"
12531 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12533 (label_ref (match_operand 0 "" ""))
12535 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12536 (plus:P (match_dup 1)
12538 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12539 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12540 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12544 if (which_alternative != 0)
12546 else if (get_attr_length (insn) == 4)
12547 return \"bdz %l0\";
12549 return \"bdnz $+8\;b %l0\";
12551 [(set_attr "type" "branch")
12552 (set_attr "length" "*,16,20,20")])
12554 (define_insn "*ctr<mode>_internal6"
12556 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12559 (label_ref (match_operand 0 "" ""))))
12560 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12561 (plus:P (match_dup 1)
12563 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12564 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12565 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12569 if (which_alternative != 0)
12571 else if (get_attr_length (insn) == 4)
12572 return \"bdnz %l0\";
12574 return \"bdz $+8\;b %l0\";
12576 [(set_attr "type" "branch")
12577 (set_attr "length" "*,16,20,20")])
12579 ;; Now the splitters if we could not allocate the CTR register
12583 (if_then_else (match_operator 2 "comparison_operator"
12584 [(match_operand:P 1 "gpc_reg_operand" "")
12586 (match_operand 5 "" "")
12587 (match_operand 6 "" "")))
12588 (set (match_operand:P 0 "int_reg_operand" "")
12589 (plus:P (match_dup 1) (const_int -1)))
12590 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12591 (clobber (match_scratch:CC 3 ""))
12592 (clobber (match_scratch:P 4 ""))]
12594 [(set (match_dup 3)
12595 (compare:CC (match_dup 1)
12598 (plus:P (match_dup 1)
12600 (set (pc) (if_then_else (match_dup 7)
12604 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12605 operands[3], const0_rtx); }")
12609 (if_then_else (match_operator 2 "comparison_operator"
12610 [(match_operand:P 1 "gpc_reg_operand" "")
12612 (match_operand 5 "" "")
12613 (match_operand 6 "" "")))
12614 (set (match_operand:P 0 "nonimmediate_operand" "")
12615 (plus:P (match_dup 1) (const_int -1)))
12616 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12617 (clobber (match_scratch:CC 3 ""))
12618 (clobber (match_scratch:P 4 ""))]
12619 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12620 [(set (match_dup 3)
12621 (compare:CC (match_dup 1)
12624 (plus:P (match_dup 1)
12628 (set (pc) (if_then_else (match_dup 7)
12632 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12633 operands[3], const0_rtx); }")
12635 (define_insn "trap"
12636 [(trap_if (const_int 1) (const_int 0))]
12639 [(set_attr "type" "trap")])
12641 (define_expand "ctrap<mode>4"
12642 [(trap_if (match_operator 0 "ordered_comparison_operator"
12643 [(match_operand:GPR 1 "register_operand")
12644 (match_operand:GPR 2 "reg_or_short_operand")])
12645 (match_operand 3 "zero_constant" ""))]
12650 [(trap_if (match_operator 0 "ordered_comparison_operator"
12651 [(match_operand:GPR 1 "register_operand" "r")
12652 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12655 "t<wd>%V0%I2 %1,%2"
12656 [(set_attr "type" "trap")])
12658 ;; Insns related to generating the function prologue and epilogue.
12660 (define_expand "prologue"
12661 [(use (const_int 0))]
12664 rs6000_emit_prologue ();
12665 if (!TARGET_SCHED_PROLOG)
12666 emit_insn (gen_blockage ());
12670 (define_insn "*movesi_from_cr_one"
12671 [(match_parallel 0 "mfcr_operation"
12672 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12673 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12674 (match_operand 3 "immediate_operand" "n")]
12675 UNSPEC_MOVESI_FROM_CR))])]
12681 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12683 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12684 operands[4] = GEN_INT (mask);
12685 output_asm_insn (\"mfcr %1,%4\", operands);
12689 [(set_attr "type" "mfcrf")])
12691 (define_insn "movesi_from_cr"
12692 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12693 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12694 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12695 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12696 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12697 UNSPEC_MOVESI_FROM_CR))]
12700 [(set_attr "type" "mfcr")])
12702 (define_insn "*crsave"
12703 [(match_parallel 0 "crsave_operation"
12704 [(set (match_operand:SI 1 "memory_operand" "=m")
12705 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12708 [(set_attr "type" "store")])
12710 (define_insn "*stmw"
12711 [(match_parallel 0 "stmw_operation"
12712 [(set (match_operand:SI 1 "memory_operand" "=m")
12713 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12716 [(set_attr "type" "store")
12717 (set_attr "update" "yes")
12718 (set_attr "indexed" "yes")])
12720 ; The following comment applies to:
12724 ; return_and_restore_gpregs*
12725 ; return_and_restore_fpregs*
12726 ; return_and_restore_fpregs_aix*
12728 ; The out-of-line save / restore functions expects one input argument.
12729 ; Since those are not standard call_insn's, we must avoid using
12730 ; MATCH_OPERAND for that argument. That way the register rename
12731 ; optimization will not try to rename this register.
12732 ; Each pattern is repeated for each possible register number used in
12733 ; various ABIs (r11, r1, and for some functions r12)
12735 (define_insn "*save_gpregs_<mode>_r11"
12736 [(match_parallel 0 "any_parallel_operand"
12737 [(clobber (reg:P LR_REGNO))
12738 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12740 (set (match_operand:P 2 "memory_operand" "=m")
12741 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12744 [(set_attr "type" "branch")
12745 (set_attr "length" "4")])
12747 (define_insn "*save_gpregs_<mode>_r12"
12748 [(match_parallel 0 "any_parallel_operand"
12749 [(clobber (reg:P LR_REGNO))
12750 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12752 (set (match_operand:P 2 "memory_operand" "=m")
12753 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12756 [(set_attr "type" "branch")
12757 (set_attr "length" "4")])
12759 (define_insn "*save_gpregs_<mode>_r1"
12760 [(match_parallel 0 "any_parallel_operand"
12761 [(clobber (reg:P LR_REGNO))
12762 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12764 (set (match_operand:P 2 "memory_operand" "=m")
12765 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12768 [(set_attr "type" "branch")
12769 (set_attr "length" "4")])
12771 (define_insn "*save_fpregs_<mode>_r11"
12772 [(match_parallel 0 "any_parallel_operand"
12773 [(clobber (reg:P LR_REGNO))
12774 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12776 (set (match_operand:DF 2 "memory_operand" "=m")
12777 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12780 [(set_attr "type" "branch")
12781 (set_attr "length" "4")])
12783 (define_insn "*save_fpregs_<mode>_r12"
12784 [(match_parallel 0 "any_parallel_operand"
12785 [(clobber (reg:P LR_REGNO))
12786 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12788 (set (match_operand:DF 2 "memory_operand" "=m")
12789 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12792 [(set_attr "type" "branch")
12793 (set_attr "length" "4")])
12795 (define_insn "*save_fpregs_<mode>_r1"
12796 [(match_parallel 0 "any_parallel_operand"
12797 [(clobber (reg:P LR_REGNO))
12798 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12800 (set (match_operand:DF 2 "memory_operand" "=m")
12801 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12804 [(set_attr "type" "branch")
12805 (set_attr "length" "4")])
12807 ; This is to explain that changes to the stack pointer should
12808 ; not be moved over loads from or stores to stack memory.
12809 (define_insn "stack_tie"
12810 [(match_parallel 0 "tie_operand"
12811 [(set (mem:BLK (reg 1)) (const_int 0))])]
12814 [(set_attr "length" "0")])
12816 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12817 ; stay behind all restores from the stack, it cannot be reordered to before
12818 ; one. See PR77687. This insn is an add or mr, and a stack_tie on the
12819 ; operands of that.
12820 (define_insn "stack_restore_tie"
12821 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12822 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12823 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12824 (set (mem:BLK (match_dup 0)) (const_int 0))
12825 (set (mem:BLK (match_dup 1)) (const_int 0))]
12830 [(set_attr "type" "*,add")])
12832 (define_expand "epilogue"
12833 [(use (const_int 0))]
12836 if (!TARGET_SCHED_PROLOG)
12837 emit_insn (gen_blockage ());
12838 rs6000_emit_epilogue (FALSE);
12842 ; On some processors, doing the mtcrf one CC register at a time is
12843 ; faster (like on the 604e). On others, doing them all at once is
12844 ; faster; for instance, on the 601 and 750.
12846 (define_expand "movsi_to_cr_one"
12847 [(set (match_operand:CC 0 "cc_reg_operand" "")
12848 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12849 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12851 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12853 (define_insn "*movsi_to_cr"
12854 [(match_parallel 0 "mtcrf_operation"
12855 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12856 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12857 (match_operand 3 "immediate_operand" "n")]
12858 UNSPEC_MOVESI_TO_CR))])]
12864 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12865 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12866 operands[4] = GEN_INT (mask);
12867 return \"mtcrf %4,%2\";
12869 [(set_attr "type" "mtcr")])
12871 (define_insn "*mtcrfsi"
12872 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12873 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12874 (match_operand 2 "immediate_operand" "n")]
12875 UNSPEC_MOVESI_TO_CR))]
12876 "GET_CODE (operands[0]) == REG
12877 && CR_REGNO_P (REGNO (operands[0]))
12878 && GET_CODE (operands[2]) == CONST_INT
12879 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12881 [(set_attr "type" "mtcr")])
12883 ; The load-multiple instructions have similar properties.
12884 ; Note that "load_multiple" is a name known to the machine-independent
12885 ; code that actually corresponds to the PowerPC load-string.
12887 (define_insn "*lmw"
12888 [(match_parallel 0 "lmw_operation"
12889 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12890 (match_operand:SI 2 "memory_operand" "m"))])]
12893 [(set_attr "type" "load")
12894 (set_attr "update" "yes")
12895 (set_attr "indexed" "yes")
12896 (set_attr "cell_micro" "always")])
12898 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12899 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
12901 ; The following comment applies to:
12905 ; return_and_restore_gpregs*
12906 ; return_and_restore_fpregs*
12907 ; return_and_restore_fpregs_aix*
12909 ; The out-of-line save / restore functions expects one input argument.
12910 ; Since those are not standard call_insn's, we must avoid using
12911 ; MATCH_OPERAND for that argument. That way the register rename
12912 ; optimization will not try to rename this register.
12913 ; Each pattern is repeated for each possible register number used in
12914 ; various ABIs (r11, r1, and for some functions r12)
12916 (define_insn "*restore_gpregs_<mode>_r11"
12917 [(match_parallel 0 "any_parallel_operand"
12918 [(clobber (reg:P LR_REGNO))
12919 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12921 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12922 (match_operand:P 3 "memory_operand" "m"))])]
12925 [(set_attr "type" "branch")
12926 (set_attr "length" "4")])
12928 (define_insn "*restore_gpregs_<mode>_r12"
12929 [(match_parallel 0 "any_parallel_operand"
12930 [(clobber (reg:P LR_REGNO))
12931 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12933 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12934 (match_operand:P 3 "memory_operand" "m"))])]
12937 [(set_attr "type" "branch")
12938 (set_attr "length" "4")])
12940 (define_insn "*restore_gpregs_<mode>_r1"
12941 [(match_parallel 0 "any_parallel_operand"
12942 [(clobber (reg:P LR_REGNO))
12943 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12945 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12946 (match_operand:P 3 "memory_operand" "m"))])]
12949 [(set_attr "type" "branch")
12950 (set_attr "length" "4")])
12952 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12953 [(match_parallel 0 "any_parallel_operand"
12955 (clobber (reg:P LR_REGNO))
12956 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12958 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12959 (match_operand:P 3 "memory_operand" "m"))])]
12962 [(set_attr "type" "branch")
12963 (set_attr "length" "4")])
12965 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12966 [(match_parallel 0 "any_parallel_operand"
12968 (clobber (reg:P LR_REGNO))
12969 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12971 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12972 (match_operand:P 3 "memory_operand" "m"))])]
12975 [(set_attr "type" "branch")
12976 (set_attr "length" "4")])
12978 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12979 [(match_parallel 0 "any_parallel_operand"
12981 (clobber (reg:P LR_REGNO))
12982 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12984 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12985 (match_operand:P 3 "memory_operand" "m"))])]
12988 [(set_attr "type" "branch")
12989 (set_attr "length" "4")])
12991 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12992 [(match_parallel 0 "any_parallel_operand"
12994 (clobber (reg:P LR_REGNO))
12995 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12997 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12998 (match_operand:DF 3 "memory_operand" "m"))])]
13001 [(set_attr "type" "branch")
13002 (set_attr "length" "4")])
13004 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13005 [(match_parallel 0 "any_parallel_operand"
13007 (clobber (reg:P LR_REGNO))
13008 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13010 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13011 (match_operand:DF 3 "memory_operand" "m"))])]
13014 [(set_attr "type" "branch")
13015 (set_attr "length" "4")])
13017 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13018 [(match_parallel 0 "any_parallel_operand"
13020 (clobber (reg:P LR_REGNO))
13021 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13023 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13024 (match_operand:DF 3 "memory_operand" "m"))])]
13027 [(set_attr "type" "branch")
13028 (set_attr "length" "4")])
13030 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13031 [(match_parallel 0 "any_parallel_operand"
13033 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13035 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13036 (match_operand:DF 3 "memory_operand" "m"))])]
13039 [(set_attr "type" "branch")
13040 (set_attr "length" "4")])
13042 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13043 [(match_parallel 0 "any_parallel_operand"
13045 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13047 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13048 (match_operand:DF 3 "memory_operand" "m"))])]
13051 [(set_attr "type" "branch")
13052 (set_attr "length" "4")])
13054 ; This is used in compiling the unwind routines.
13055 (define_expand "eh_return"
13056 [(use (match_operand 0 "general_operand" ""))]
13061 emit_insn (gen_eh_set_lr_si (operands[0]));
13063 emit_insn (gen_eh_set_lr_di (operands[0]));
13067 ; We can't expand this before we know where the link register is stored.
13068 (define_insn "eh_set_lr_<mode>"
13069 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13071 (clobber (match_scratch:P 1 "=&b"))]
13076 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13077 (clobber (match_scratch 1 ""))]
13082 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13086 (define_insn "prefetch"
13087 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13088 (match_operand:SI 1 "const_int_operand" "n")
13089 (match_operand:SI 2 "const_int_operand" "n"))]
13093 if (GET_CODE (operands[0]) == REG)
13094 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13095 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13097 [(set_attr "type" "load")])
13099 ;; Handle -fsplit-stack.
13101 (define_expand "split_stack_prologue"
13105 rs6000_expand_split_stack_prologue ();
13109 (define_expand "load_split_stack_limit"
13110 [(set (match_operand 0)
13111 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13114 emit_insn (gen_rtx_SET (operands[0],
13115 gen_rtx_UNSPEC (Pmode,
13116 gen_rtvec (1, const0_rtx),
13117 UNSPEC_STACK_CHECK)));
13121 (define_insn "load_split_stack_limit_di"
13122 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13123 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13125 "ld %0,-0x7040(13)"
13126 [(set_attr "type" "load")
13127 (set_attr "update" "no")
13128 (set_attr "indexed" "no")])
13130 (define_insn "load_split_stack_limit_si"
13131 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13132 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13134 "lwz %0,-0x7020(2)"
13135 [(set_attr "type" "load")
13136 (set_attr "update" "no")
13137 (set_attr "indexed" "no")])
13139 ;; A return instruction which the middle-end doesn't see.
13140 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13141 ;; after the call to __morestack.
13142 (define_insn "split_stack_return"
13143 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13146 [(set_attr "type" "jmpreg")])
13148 ;; If there are operand 0 bytes available on the stack, jump to
13150 (define_expand "split_stack_space_check"
13151 [(set (match_dup 2)
13152 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13154 (minus (reg STACK_POINTER_REGNUM)
13155 (match_operand 0)))
13156 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13157 (set (pc) (if_then_else
13158 (geu (match_dup 4) (const_int 0))
13159 (label_ref (match_operand 1))
13163 rs6000_split_stack_space_check (operands[0], operands[1]);
13167 (define_insn "bpermd_<mode>"
13168 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13169 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13170 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13173 [(set_attr "type" "popcnt")])
13176 ;; Builtin fma support. Handle
13177 ;; Note that the conditions for expansion are in the FMA_F iterator.
13179 (define_expand "fma<mode>4"
13180 [(set (match_operand:FMA_F 0 "register_operand" "")
13182 (match_operand:FMA_F 1 "register_operand" "")
13183 (match_operand:FMA_F 2 "register_operand" "")
13184 (match_operand:FMA_F 3 "register_operand" "")))]
13188 (define_insn "*fma<mode>4_fpr"
13189 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13191 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13192 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13193 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13194 "TARGET_<MODE>_FPR"
13196 fmadd<Ftrad> %0,%1,%2,%3
13197 xsmadda<Fvsx> %x0,%x1,%x2
13198 xsmaddm<Fvsx> %x0,%x1,%x3"
13199 [(set_attr "type" "fp")
13200 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13202 ; Altivec only has fma and nfms.
13203 (define_expand "fms<mode>4"
13204 [(set (match_operand:FMA_F 0 "register_operand" "")
13206 (match_operand:FMA_F 1 "register_operand" "")
13207 (match_operand:FMA_F 2 "register_operand" "")
13208 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
13209 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13212 (define_insn "*fms<mode>4_fpr"
13213 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13215 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13216 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13217 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13218 "TARGET_<MODE>_FPR"
13220 fmsub<Ftrad> %0,%1,%2,%3
13221 xsmsuba<Fvsx> %x0,%x1,%x2
13222 xsmsubm<Fvsx> %x0,%x1,%x3"
13223 [(set_attr "type" "fp")
13224 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13226 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13227 (define_expand "fnma<mode>4"
13228 [(set (match_operand:FMA_F 0 "register_operand" "")
13231 (match_operand:FMA_F 1 "register_operand" "")
13232 (match_operand:FMA_F 2 "register_operand" "")
13233 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13234 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13237 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13238 (define_expand "fnms<mode>4"
13239 [(set (match_operand:FMA_F 0 "register_operand" "")
13242 (match_operand:FMA_F 1 "register_operand" "")
13243 (match_operand:FMA_F 2 "register_operand" "")
13244 (match_operand:FMA_F 3 "register_operand" ""))))]
13245 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13248 ; Not an official optab name, but used from builtins.
13249 (define_expand "nfma<mode>4"
13250 [(set (match_operand:FMA_F 0 "register_operand" "")
13253 (match_operand:FMA_F 1 "register_operand" "")
13254 (match_operand:FMA_F 2 "register_operand" "")
13255 (match_operand:FMA_F 3 "register_operand" ""))))]
13256 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13259 (define_insn "*nfma<mode>4_fpr"
13260 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13263 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13264 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13265 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13266 "TARGET_<MODE>_FPR"
13268 fnmadd<Ftrad> %0,%1,%2,%3
13269 xsnmadda<Fvsx> %x0,%x1,%x2
13270 xsnmaddm<Fvsx> %x0,%x1,%x3"
13271 [(set_attr "type" "fp")
13272 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13274 ; Not an official optab name, but used from builtins.
13275 (define_expand "nfms<mode>4"
13276 [(set (match_operand:FMA_F 0 "register_operand" "")
13279 (match_operand:FMA_F 1 "register_operand" "")
13280 (match_operand:FMA_F 2 "register_operand" "")
13281 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13285 (define_insn "*nfmssf4_fpr"
13286 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13289 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13290 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13292 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13293 "TARGET_<MODE>_FPR"
13295 fnmsub<Ftrad> %0,%1,%2,%3
13296 xsnmsuba<Fvsx> %x0,%x1,%x2
13297 xsnmsubm<Fvsx> %x0,%x1,%x3"
13298 [(set_attr "type" "fp")
13299 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13302 (define_expand "rs6000_get_timebase"
13303 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13306 if (TARGET_POWERPC64)
13307 emit_insn (gen_rs6000_mftb_di (operands[0]));
13309 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13313 (define_insn "rs6000_get_timebase_ppc32"
13314 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13315 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13316 (clobber (match_scratch:SI 1 "=r"))
13317 (clobber (match_scratch:CC 2 "=y"))]
13318 "!TARGET_POWERPC64"
13320 if (WORDS_BIG_ENDIAN)
13323 return "mfspr %0,269\;"
13331 return "mftbu %0\;"
13340 return "mfspr %L0,269\;"
13348 return "mftbu %L0\;"
13355 [(set_attr "length" "20")])
13357 (define_insn "rs6000_mftb_<mode>"
13358 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13359 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13363 return "mfspr %0,268";
13369 (define_insn "rs6000_mffs"
13370 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13371 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13372 "TARGET_HARD_FLOAT && TARGET_FPRS"
13375 (define_insn "rs6000_mtfsf"
13376 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13377 (match_operand:DF 1 "gpc_reg_operand" "d")]
13379 "TARGET_HARD_FLOAT && TARGET_FPRS"
13383 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13384 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13385 ;; register that is being loaded. The fused ops must be physically adjacent.
13387 ;; There are two parts to addis fusion. The support for fused TOCs occur
13388 ;; before register allocation, and is meant to reduce the lifetime for the
13389 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13390 ;; to use the register that is being load. The peephole2 then gathers any
13391 ;; other fused possibilities that it can find after register allocation. If
13392 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13394 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13395 ;; before register allocation, so that we can avoid allocating a temporary base
13396 ;; register that won't be used, and that we try to load into base registers,
13397 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13398 ;; (addis followed by load) even on power8.
13401 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13402 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13403 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13404 [(parallel [(set (match_dup 0) (match_dup 2))
13405 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13406 (use (match_dup 3))
13407 (clobber (scratch:DI))])]
13409 operands[2] = fusion_wrap_memory_address (operands[1]);
13410 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13413 (define_insn "*toc_fusionload_<mode>"
13414 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13415 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13416 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13417 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13418 (clobber (match_scratch:DI 3 "=X,&b"))]
13419 "TARGET_TOC_FUSION_INT"
13421 if (base_reg_operand (operands[0], <MODE>mode))
13422 return emit_fusion_gpr_load (operands[0], operands[1]);
13424 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13426 [(set_attr "type" "load")
13427 (set_attr "length" "8")])
13429 (define_insn "*toc_fusionload_di"
13430 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13431 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13432 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13433 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13434 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13435 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13436 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13438 if (base_reg_operand (operands[0], DImode))
13439 return emit_fusion_gpr_load (operands[0], operands[1]);
13441 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13443 [(set_attr "type" "load")
13444 (set_attr "length" "8")])
13447 ;; Find cases where the addis that feeds into a load instruction is either used
13448 ;; once or is the same as the target register, and replace it with the fusion
13452 [(set (match_operand:P 0 "base_reg_operand" "")
13453 (match_operand:P 1 "fusion_gpr_addis" ""))
13454 (set (match_operand:INT1 2 "base_reg_operand" "")
13455 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13457 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13461 expand_fusion_gpr_load (operands);
13465 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13468 (define_insn "fusion_gpr_load_<mode>"
13469 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13470 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13471 UNSPEC_FUSION_GPR))]
13474 return emit_fusion_gpr_load (operands[0], operands[1]);
13476 [(set_attr "type" "load")
13477 (set_attr "length" "8")])
13480 ;; ISA 3.0 (power9) fusion support
13481 ;; Merge addis with floating load/store to FPRs (or GPRs).
13483 [(set (match_operand:P 0 "base_reg_operand" "")
13484 (match_operand:P 1 "fusion_gpr_addis" ""))
13485 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13486 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13487 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13488 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13491 expand_fusion_p9_load (operands);
13496 [(set (match_operand:P 0 "base_reg_operand" "")
13497 (match_operand:P 1 "fusion_gpr_addis" ""))
13498 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13499 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13500 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13501 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13502 && !rtx_equal_p (operands[0], operands[3])"
13505 expand_fusion_p9_store (operands);
13510 [(set (match_operand:SDI 0 "int_reg_operand" "")
13511 (match_operand:SDI 1 "upper16_cint_operand" ""))
13513 (ior:SDI (match_dup 0)
13514 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13516 [(set (match_dup 0)
13517 (unspec:SDI [(match_dup 1)
13518 (match_dup 2)] UNSPEC_FUSION_P9))])
13521 [(set (match_operand:SDI 0 "int_reg_operand" "")
13522 (match_operand:SDI 1 "upper16_cint_operand" ""))
13523 (set (match_operand:SDI 2 "int_reg_operand" "")
13524 (ior:SDI (match_dup 0)
13525 (match_operand:SDI 3 "u_short_cint_operand" "")))]
13527 && !rtx_equal_p (operands[0], operands[2])
13528 && peep2_reg_dead_p (2, operands[0])"
13529 [(set (match_dup 2)
13530 (unspec:SDI [(match_dup 1)
13531 (match_dup 3)] UNSPEC_FUSION_P9))])
13533 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13534 ;; reload). Because we want to eventually have secondary_reload generate
13535 ;; these, they have to have a single alternative that gives the register
13536 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13537 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13538 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13540 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13542 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13545 /* This insn is a secondary reload insn, which cannot have alternatives.
13546 If we are not loading up register 0, use the power8 fusion instead. */
13547 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13548 return emit_fusion_gpr_load (operands[0], operands[1]);
13550 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13552 [(set_attr "type" "load")
13553 (set_attr "length" "8")])
13555 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13556 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13558 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13560 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13563 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13565 [(set_attr "type" "store")
13566 (set_attr "length" "8")])
13568 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13569 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13571 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13573 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13576 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13578 [(set_attr "type" "fpload")
13579 (set_attr "length" "8")])
13581 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13582 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13584 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13586 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13589 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13591 [(set_attr "type" "fpstore")
13592 (set_attr "length" "8")])
13594 (define_insn "*fusion_p9_<mode>_constant"
13595 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13596 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13597 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13598 UNSPEC_FUSION_P9))]
13601 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13602 return "ori %0,%0,%2";
13604 [(set_attr "type" "two")
13605 (set_attr "length" "8")])
13608 ;; Miscellaneous ISA 2.06 (power7) instructions
13609 (define_insn "addg6s"
13610 [(set (match_operand:SI 0 "register_operand" "=r")
13611 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13612 (match_operand:SI 2 "register_operand" "r")]
13616 [(set_attr "type" "integer")
13617 (set_attr "length" "4")])
13619 (define_insn "cdtbcd"
13620 [(set (match_operand:SI 0 "register_operand" "=r")
13621 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13625 [(set_attr "type" "integer")
13626 (set_attr "length" "4")])
13628 (define_insn "cbcdtd"
13629 [(set (match_operand:SI 0 "register_operand" "=r")
13630 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13634 [(set_attr "type" "integer")
13635 (set_attr "length" "4")])
13637 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13642 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13643 (UNSPEC_DIVEO "eo")
13644 (UNSPEC_DIVEU "eu")
13645 (UNSPEC_DIVEUO "euo")])
13647 (define_insn "div<div_extend>_<mode>"
13648 [(set (match_operand:GPR 0 "register_operand" "=r")
13649 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13650 (match_operand:GPR 2 "register_operand" "r")]
13651 UNSPEC_DIV_EXTEND))]
13653 "div<wd><div_extend> %0,%1,%2"
13654 [(set_attr "type" "div")
13655 (set_attr "size" "<bits>")])
13658 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13660 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13661 (define_mode_attr FP128_64 [(TF "DF")
13666 (define_expand "unpack<mode>"
13667 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13669 [(match_operand:FMOVE128 1 "register_operand" "")
13670 (match_operand:QI 2 "const_0_to_1_operand" "")]
13671 UNSPEC_UNPACK_128BIT))]
13672 "FLOAT128_2REG_P (<MODE>mode)"
13675 (define_insn_and_split "unpack<mode>_dm"
13676 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13678 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13679 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13680 UNSPEC_UNPACK_128BIT))]
13681 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13683 "&& reload_completed"
13684 [(set (match_dup 0) (match_dup 3))]
13686 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13688 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13690 emit_note (NOTE_INSN_DELETED);
13694 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13696 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13697 (set_attr "length" "4")])
13699 (define_insn_and_split "unpack<mode>_nodm"
13700 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13702 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13703 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13704 UNSPEC_UNPACK_128BIT))]
13705 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13707 "&& reload_completed"
13708 [(set (match_dup 0) (match_dup 3))]
13710 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13712 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13714 emit_note (NOTE_INSN_DELETED);
13718 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13720 [(set_attr "type" "fp,fpstore")
13721 (set_attr "length" "4")])
13723 (define_insn_and_split "pack<mode>"
13724 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13726 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13727 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13728 UNSPEC_PACK_128BIT))]
13729 "FLOAT128_2REG_P (<MODE>mode)"
13733 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13734 [(set (match_dup 3) (match_dup 1))
13735 (set (match_dup 4) (match_dup 2))]
13737 unsigned dest_hi = REGNO (operands[0]);
13738 unsigned dest_lo = dest_hi + 1;
13740 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13741 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13743 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13744 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13746 [(set_attr "type" "fpsimple,fp")
13747 (set_attr "length" "4,8")])
13749 (define_insn "unpack<mode>"
13750 [(set (match_operand:DI 0 "register_operand" "=d,d")
13751 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13752 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13753 UNSPEC_UNPACK_128BIT))]
13754 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13756 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13757 return ASM_COMMENT_START " xxpermdi to same register";
13759 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13760 return "xxpermdi %x0,%x1,%x1,%3";
13762 [(set_attr "type" "vecperm")])
13764 (define_insn "pack<mode>"
13765 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13766 (unspec:FMOVE128_VSX
13767 [(match_operand:DI 1 "register_operand" "d")
13768 (match_operand:DI 2 "register_operand" "d")]
13769 UNSPEC_PACK_128BIT))]
13771 "xxpermdi %x0,%x1,%x2,0"
13772 [(set_attr "type" "vecperm")])
13776 ;; ISA 2.08 IEEE 128-bit floating point support.
13778 (define_insn "add<mode>3"
13779 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13781 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13782 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13783 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13785 [(set_attr "type" "vecfloat")
13786 (set_attr "size" "128")])
13788 (define_insn "sub<mode>3"
13789 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13791 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13792 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13793 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13795 [(set_attr "type" "vecfloat")
13796 (set_attr "size" "128")])
13798 (define_insn "mul<mode>3"
13799 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13801 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13802 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13803 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13805 [(set_attr "type" "vecfloat")
13806 (set_attr "size" "128")])
13808 (define_insn "div<mode>3"
13809 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13811 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13812 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13813 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13815 [(set_attr "type" "vecdiv")
13816 (set_attr "size" "128")])
13818 (define_insn "sqrt<mode>2"
13819 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13821 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13822 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13824 [(set_attr "type" "vecdiv")
13825 (set_attr "size" "128")])
13827 (define_expand "copysign<mode>3"
13828 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13829 (use (match_operand:IEEE128 1 "altivec_register_operand"))
13830 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13831 "FLOAT128_IEEE_P (<MODE>mode)"
13833 if (TARGET_FLOAT128_HW)
13834 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13838 rtx tmp = gen_reg_rtx (<MODE>mode);
13839 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13840 operands[2], tmp));
13845 (define_insn "copysign<mode>3_hard"
13846 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13848 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13849 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13851 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13852 "xscpsgnqp %0,%2,%1"
13853 [(set_attr "type" "vecmove")
13854 (set_attr "size" "128")])
13856 (define_insn "copysign<mode>3_soft"
13857 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13859 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13860 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13861 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
13863 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13864 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13865 [(set_attr "type" "veccomplex")
13866 (set_attr "length" "8")])
13868 (define_insn "neg<mode>2_hw"
13869 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13871 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13872 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13874 [(set_attr "type" "vecmove")
13875 (set_attr "size" "128")])
13878 (define_insn "abs<mode>2_hw"
13879 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13881 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13882 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13884 [(set_attr "type" "vecmove")
13885 (set_attr "size" "128")])
13888 (define_insn "*nabs<mode>2_hw"
13889 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13892 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13893 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13895 [(set_attr "type" "vecmove")
13896 (set_attr "size" "128")])
13898 ;; Initially don't worry about doing fusion
13899 (define_insn "*fma<mode>4_hw"
13900 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13902 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13903 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13904 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13905 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13906 "xsmaddqp %0,%1,%2"
13907 [(set_attr "type" "vecfloat")
13908 (set_attr "size" "128")])
13910 (define_insn "*fms<mode>4_hw"
13911 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13913 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13914 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13916 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13917 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13918 "xsmsubqp %0,%1,%2"
13919 [(set_attr "type" "vecfloat")
13920 (set_attr "size" "128")])
13922 (define_insn "*nfma<mode>4_hw"
13923 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13926 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13927 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13928 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13929 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13930 "xsnmaddqp %0,%1,%2"
13931 [(set_attr "type" "vecfloat")
13932 (set_attr "size" "128")])
13934 (define_insn "*nfms<mode>4_hw"
13935 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13938 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13939 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13941 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13942 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13943 "xsnmsubqp %0,%1,%2"
13944 [(set_attr "type" "vecfloat")
13945 (set_attr "size" "128")])
13947 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13948 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13949 (float_extend:IEEE128
13950 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13951 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13953 [(set_attr "type" "vecfloat")
13954 (set_attr "size" "128")])
13956 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13957 ;; point is a simple copy.
13958 (define_insn_and_split "extendkftf2"
13959 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13960 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13961 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13965 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13968 emit_note (NOTE_INSN_DELETED);
13971 [(set_attr "type" "*,veclogical")
13972 (set_attr "length" "0,4")])
13974 (define_insn_and_split "trunctfkf2"
13975 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13976 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13977 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13981 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13984 emit_note (NOTE_INSN_DELETED);
13987 [(set_attr "type" "*,veclogical")
13988 (set_attr "length" "0,4")])
13990 (define_insn "trunc<mode>df2_hw"
13991 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13993 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13994 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13996 [(set_attr "type" "vecfloat")
13997 (set_attr "size" "128")])
13999 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14000 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14002 (define_insn_and_split "trunc<mode>sf2_hw"
14003 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14005 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14006 (clobber (match_scratch:DF 2 "=v"))]
14007 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14010 [(set (match_dup 2)
14011 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14013 (float_truncate:SF (match_dup 2)))]
14015 if (GET_CODE (operands[2]) == SCRATCH)
14016 operands[2] = gen_reg_rtx (DFmode);
14018 [(set_attr "type" "vecfloat")
14019 (set_attr "length" "8")])
14021 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
14022 ;; allowed in the traditional floating point registers. Use V2DImode so that
14023 ;; we can get a value in an Altivec register.
14025 (define_insn_and_split "fix<uns>_<mode>si2_hw"
14026 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
14027 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
14028 (clobber (match_scratch:V2DI 2 "=v,v"))]
14029 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14034 convert_float128_to_int (operands, <CODE>);
14037 [(set_attr "length" "8")
14038 (set_attr "type" "mftgpr,fpstore")])
14040 (define_insn_and_split "fix<uns>_<mode>di2_hw"
14041 [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
14042 (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
14043 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
14044 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14049 convert_float128_to_int (operands, <CODE>);
14052 [(set_attr "length" "8")
14053 (set_attr "type" "mftgpr,vecsimple,fpstore")])
14055 (define_insn_and_split "float<uns>_<mode>si2_hw"
14056 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
14057 (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
14058 (clobber (match_scratch:V2DI 2 "=v,v"))]
14059 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14064 convert_int_to_float128 (operands, <CODE>);
14067 [(set_attr "length" "8")
14068 (set_attr "type" "vecfloat")])
14070 (define_insn_and_split "float<uns>_<mode>di2_hw"
14071 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14072 (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
14073 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
14074 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14079 convert_int_to_float128 (operands, <CODE>);
14082 [(set_attr "length" "8")
14083 (set_attr "type" "vecfloat")])
14085 ;; Integer conversion instructions, using V2DImode to get an Altivec register
14086 (define_insn "*xscvqp<su>wz_<mode>"
14087 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
14090 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
14091 UNSPEC_IEEE128_CONVERT))]
14092 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14093 "xscvqp<su>wz %0,%1"
14094 [(set_attr "type" "vecfloat")
14095 (set_attr "size" "128")])
14097 (define_insn "*xscvqp<su>dz_<mode>"
14098 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
14101 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
14102 UNSPEC_IEEE128_CONVERT))]
14103 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14104 "xscvqp<su>dz %0,%1"
14105 [(set_attr "type" "vecfloat")
14106 (set_attr "size" "128")])
14108 (define_insn "*xscv<su>dqp_<mode>"
14109 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14111 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
14112 UNSPEC_IEEE128_CONVERT)))]
14113 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14114 "xscv<su>dqp %0,%1"
14115 [(set_attr "type" "vecfloat")
14116 (set_attr "size" "128")])
14118 (define_insn "*ieee128_mfvsrd_64bit"
14119 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
14120 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
14121 UNSPEC_IEEE128_MOVE))]
14122 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
14127 [(set_attr "type" "mftgpr,fpstore,veclogical")])
14130 (define_insn "*ieee128_mfvsrd_32bit"
14131 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
14132 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
14133 UNSPEC_IEEE128_MOVE))]
14134 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
14138 [(set_attr "type" "fpstore,veclogical")])
14140 (define_insn "*ieee128_mfvsrwz"
14141 [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
14142 (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
14143 UNSPEC_IEEE128_MOVE))]
14144 "TARGET_FLOAT128_HW"
14148 [(set_attr "type" "mftgpr,fpstore")])
14150 ;; 0 says do sign-extension, 1 says zero-extension
14151 (define_insn "*ieee128_mtvsrw"
14152 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
14153 (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
14154 (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
14155 UNSPEC_IEEE128_MOVE))]
14156 "TARGET_FLOAT128_HW"
14162 [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
14165 (define_insn "*ieee128_mtvsrd_64bit"
14166 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
14167 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
14168 UNSPEC_IEEE128_MOVE))]
14169 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
14174 [(set_attr "type" "mffgpr,fpload,veclogical")])
14176 (define_insn "*ieee128_mtvsrd_32bit"
14177 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
14178 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
14179 UNSPEC_IEEE128_MOVE))]
14180 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
14184 [(set_attr "type" "fpload,veclogical")])
14186 ;; IEEE 128-bit instructions with round to odd semantics
14187 (define_insn "*trunc<mode>df2_odd"
14188 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14189 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14190 UNSPEC_ROUND_TO_ODD))]
14191 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14193 [(set_attr "type" "vecfloat")
14194 (set_attr "size" "128")])
14196 ;; IEEE 128-bit comparisons
14197 (define_insn "*cmp<mode>_hw"
14198 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14199 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14200 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14201 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14202 "xscmpuqp %0,%1,%2"
14203 [(set_attr "type" "veccmp")
14204 (set_attr "size" "128")])
14208 (include "sync.md")
14209 (include "vector.md")
14211 (include "altivec.md")
14214 (include "paired.md")
14215 (include "crypto.md")