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 ; Everything we can extend QImode to.
329 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
331 ; Everything we can extend HImode to.
332 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
334 ; Everything we can extend SImode to.
335 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
337 ; QImode or HImode for small atomic ops
338 (define_mode_iterator QHI [QI HI])
340 ; QImode, HImode, SImode for fused ops only for GPR loads
341 (define_mode_iterator QHSI [QI HI SI])
343 ; HImode or SImode for sign extended fusion ops
344 (define_mode_iterator HSI [HI SI])
346 ; SImode or DImode, even if DImode doesn't fit in GPRs.
347 (define_mode_iterator SDI [SI DI])
349 ; Types that can be fused with an ADDIS instruction to load or store a GPR
350 ; register that has reg+offset addressing.
351 (define_mode_iterator GPR_FUSION [QI
354 (DI "TARGET_POWERPC64")
356 (DF "TARGET_POWERPC64")])
358 ; Types that can be fused with an ADDIS instruction to load or store a FPR
359 ; register that has reg+offset addressing.
360 (define_mode_iterator FPR_FUSION [DI SF DF])
362 ; The size of a pointer. Also, the size of the value that a record-condition
363 ; (one with a '.') will compare; and the size used for arithmetic carries.
364 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
366 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
367 ; PTImode is GPR only)
368 (define_mode_iterator TI2 [TI PTI])
370 ; Any hardware-supported floating-point mode
371 (define_mode_iterator FP [
372 (SF "TARGET_HARD_FLOAT
373 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
374 (DF "TARGET_HARD_FLOAT
375 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
376 (TF "TARGET_HARD_FLOAT
377 && (TARGET_FPRS || TARGET_E500_DOUBLE)
378 && TARGET_LONG_DOUBLE_128")
379 (IF "TARGET_LONG_DOUBLE_128")
380 (KF "TARGET_FLOAT128_TYPE")
384 ; Any fma capable floating-point mode.
385 (define_mode_iterator FMA_F [
386 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
387 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
388 || VECTOR_UNIT_VSX_P (DFmode)")
389 (V2SF "TARGET_PAIRED_FLOAT")
390 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
391 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
392 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
393 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
396 ; Floating point move iterators to combine binary and decimal moves
397 (define_mode_iterator FMOVE32 [SF SD])
398 (define_mode_iterator FMOVE64 [DF DD])
399 (define_mode_iterator FMOVE64X [DI DF DD])
400 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
401 (IF "TARGET_LONG_DOUBLE_128")
402 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
404 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
405 (IF "FLOAT128_2REG_P (IFmode)")
406 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
408 ; Iterators for 128 bit types for direct move
409 (define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE")
417 (KF "FLOAT128_VECTOR_P (KFmode)")
418 (TF "FLOAT128_VECTOR_P (TFmode)")])
420 ; Iterator for 128-bit VSX types for pack/unpack
421 (define_mode_iterator FMOVE128_VSX [V1TI KF])
423 ; Whether a floating point move is ok, don't allow SD without hardware FP
424 (define_mode_attr fmove_ok [(SF "")
426 (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
429 ; Convert REAL_VALUE to the appropriate bits
430 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
431 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
432 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
433 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
435 ; Whether 0.0 has an all-zero bit pattern
436 (define_mode_attr zero_fp [(SF "j")
445 ; Definitions for load to 32-bit fpr register
446 (define_mode_attr f32_lr [(SF "f") (SD "wz")])
447 (define_mode_attr f32_lr2 [(SF "wb") (SD "wn")])
448 (define_mode_attr f32_lm [(SF "m") (SD "Z")])
449 (define_mode_attr f32_lm2 [(SF "wY") (SD "wn")])
450 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
451 (define_mode_attr f32_li2 [(SF "lxssp %0,%1") (SD "lfiwzx %0,%y1")])
452 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
454 ; Definitions for store from 32-bit fpr register
455 (define_mode_attr f32_sr [(SF "f") (SD "wx")])
456 (define_mode_attr f32_sr2 [(SF "wb") (SD "wn")])
457 (define_mode_attr f32_sm [(SF "m") (SD "Z")])
458 (define_mode_attr f32_sm2 [(SF "wY") (SD "wn")])
459 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
460 (define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")])
461 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwx %x1,%y0")])
463 ; Definitions for 32-bit fpr direct move
464 ; At present, the decimal modes are not allowed in the traditional altivec
465 ; registers, so restrict the constraints to just the traditional FPRs.
466 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
468 ; Definitions for 32-bit VSX
469 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
471 ; Definitions for 32-bit use of altivec registers
472 (define_mode_attr f32_av [(SF "wu") (SD "wn")])
474 ; Definitions for 64-bit VSX
475 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
477 ; Definitions for 64-bit direct move
478 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
480 ; Definitions for 64-bit use of altivec registers
481 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
483 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
484 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
486 ; These modes do not fit in integer registers in 32-bit mode.
487 ; but on e500v2, the gpr are 64 bit registers
488 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
490 ; Iterator for reciprocal estimate instructions
491 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
493 ; Iterator for just SF/DF
494 (define_mode_iterator SFDF [SF DF])
496 ; Like SFDF, but a different name to match conditional move where the
497 ; comparison operands may be a different mode than the input operands.
498 (define_mode_iterator SFDF2 [SF DF])
500 ; Iterator for 128-bit floating point that uses the IBM double-double format
501 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
502 (TF "FLOAT128_IBM_P (TFmode)")])
504 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
505 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
506 (TF "FLOAT128_IEEE_P (TFmode)")])
508 ; Iterator for 128-bit floating point
509 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
510 (IF "TARGET_FLOAT128_TYPE")
511 (TF "TARGET_LONG_DOUBLE_128")])
513 ; Iterator for signbit on 64-bit machines with direct move
514 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
515 (TF "FLOAT128_VECTOR_P (TFmode)")])
517 (define_mode_attr Fsignbit [(KF "wa")
520 ; Iterator for ISA 3.0 supported floating point types
521 (define_mode_iterator FP_ISA3 [SF
523 (KF "FLOAT128_IEEE_P (KFmode)")
524 (TF "FLOAT128_IEEE_P (TFmode)")])
526 ; SF/DF suffix for traditional floating instructions
527 (define_mode_attr Ftrad [(SF "s") (DF "")])
529 ; SF/DF suffix for VSX instructions
530 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
532 ; SF/DF constraint for arithmetic on traditional floating point registers
533 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
535 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
536 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
537 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
539 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
541 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
542 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
543 ; instructions added in ISA 2.07 (power8)
544 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
546 ; SF/DF constraint for arithmetic on altivec registers
547 (define_mode_attr Fa [(SF "wu") (DF "wv")])
549 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
550 (define_mode_attr Fs [(SF "s") (DF "d")])
553 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
554 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
556 ; Conditional returns.
557 (define_code_iterator any_return [return simple_return])
558 (define_code_attr return_pred [(return "direct_return ()")
559 (simple_return "1")])
560 (define_code_attr return_str [(return "") (simple_return "simple_")])
563 (define_code_iterator iorxor [ior xor])
565 ; Signed/unsigned variants of ops.
566 (define_code_iterator any_extend [sign_extend zero_extend])
567 (define_code_iterator any_fix [fix unsigned_fix])
568 (define_code_iterator any_float [float unsigned_float])
570 (define_code_attr u [(sign_extend "")
573 (define_code_attr su [(sign_extend "s")
578 (unsigned_float "u")])
580 (define_code_attr az [(sign_extend "a")
585 (unsigned_float "z")])
587 (define_code_attr uns [(fix "")
590 (unsigned_float "uns")])
592 ; Various instructions that come in SI and DI forms.
593 ; A generic w/d attribute, for things like cmpw/cmpd.
594 (define_mode_attr wd [(QI "b")
605 ;; How many bits in this mode?
606 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
609 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
611 ;; ISEL/ISEL64 target selection
612 (define_mode_attr sel [(SI "") (DI "64")])
614 ;; Bitmask for shift instructions
615 (define_mode_attr hH [(SI "h") (DI "H")])
617 ;; A mode twice the size of the given mode
618 (define_mode_attr dmode [(SI "di") (DI "ti")])
619 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
621 ;; Suffix for reload patterns
622 (define_mode_attr ptrsize [(SI "32bit")
625 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
626 (DI "TARGET_64BIT")])
628 (define_mode_attr mptrsize [(SI "si")
631 (define_mode_attr ptrload [(SI "lwz")
634 (define_mode_attr ptrm [(SI "m")
637 (define_mode_attr rreg [(SF "f")
644 (define_mode_attr rreg2 [(SF "f")
647 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
648 (DF "TARGET_FCFID")])
650 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
651 (DF "TARGET_E500_DOUBLE")])
653 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
654 (DF "TARGET_DOUBLE_FLOAT")])
656 ;; Mode iterator for logical operations on 128-bit types
657 (define_mode_iterator BOOL_128 [TI
659 (V16QI "TARGET_ALTIVEC")
660 (V8HI "TARGET_ALTIVEC")
661 (V4SI "TARGET_ALTIVEC")
662 (V4SF "TARGET_ALTIVEC")
663 (V2DI "TARGET_ALTIVEC")
664 (V2DF "TARGET_ALTIVEC")
665 (V1TI "TARGET_ALTIVEC")])
667 ;; For the GPRs we use 3 constraints for register outputs, two that are the
668 ;; same as the output register, and a third where the output register is an
669 ;; early clobber, so we don't have to deal with register overlaps. For the
670 ;; vector types, we prefer to use the vector registers. For TI mode, allow
673 ;; Mode attribute for boolean operation register constraints for output
674 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
676 (V16QI "wa,v,&?r,?r,?r")
677 (V8HI "wa,v,&?r,?r,?r")
678 (V4SI "wa,v,&?r,?r,?r")
679 (V4SF "wa,v,&?r,?r,?r")
680 (V2DI "wa,v,&?r,?r,?r")
681 (V2DF "wa,v,&?r,?r,?r")
682 (V1TI "wa,v,&?r,?r,?r")])
684 ;; Mode attribute for boolean operation register constraints for operand1
685 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
693 (V1TI "wa,v,r,0,r")])
695 ;; Mode attribute for boolean operation register constraints for operand2
696 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
704 (V1TI "wa,v,r,r,0")])
706 ;; Mode attribute for boolean operation register constraints for operand1
707 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
708 ;; is used for operand1 or operand2
709 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
717 (V1TI "wa,v,r,0,0")])
719 ;; Reload iterator for creating the function to allocate a base register to
720 ;; supplement addressing modes.
721 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
722 SF SD SI DF DD DI TI PTI KF IF TF])
724 ;; Iterate over smin, smax
725 (define_code_iterator fp_minmax [smin smax])
727 (define_code_attr minmax [(smin "min")
730 (define_code_attr SMINMAX [(smin "SMIN")
734 ;; Start with fixed-point load and store insns. Here we put only the more
735 ;; complex forms. Basic data transfer is done later.
737 (define_insn "zero_extendqi<mode>2"
738 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
739 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
744 [(set_attr "type" "load,shift")])
746 (define_insn_and_split "*zero_extendqi<mode>2_dot"
747 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
748 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
750 (clobber (match_scratch:EXTQI 0 "=r,r"))]
751 "rs6000_gen_cell_microcode"
755 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
757 (zero_extend:EXTQI (match_dup 1)))
759 (compare:CC (match_dup 0)
762 [(set_attr "type" "logical")
763 (set_attr "dot" "yes")
764 (set_attr "length" "4,8")])
766 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
767 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
768 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
770 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
771 (zero_extend:EXTQI (match_dup 1)))]
772 "rs6000_gen_cell_microcode"
776 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
778 (zero_extend:EXTQI (match_dup 1)))
780 (compare:CC (match_dup 0)
783 [(set_attr "type" "logical")
784 (set_attr "dot" "yes")
785 (set_attr "length" "4,8")])
788 (define_insn "zero_extendhi<mode>2"
789 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
790 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
794 rlwinm %0,%1,0,0xffff"
795 [(set_attr "type" "load,shift")])
797 (define_insn_and_split "*zero_extendhi<mode>2_dot"
798 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
799 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
801 (clobber (match_scratch:EXTHI 0 "=r,r"))]
802 "rs6000_gen_cell_microcode"
806 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
808 (zero_extend:EXTHI (match_dup 1)))
810 (compare:CC (match_dup 0)
813 [(set_attr "type" "logical")
814 (set_attr "dot" "yes")
815 (set_attr "length" "4,8")])
817 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
818 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
819 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
821 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
822 (zero_extend:EXTHI (match_dup 1)))]
823 "rs6000_gen_cell_microcode"
827 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
829 (zero_extend:EXTHI (match_dup 1)))
831 (compare:CC (match_dup 0)
834 [(set_attr "type" "logical")
835 (set_attr "dot" "yes")
836 (set_attr "length" "4,8")])
839 (define_insn "zero_extendsi<mode>2"
840 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
841 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
850 xxextractuw %x0,%x1,1"
851 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
853 (define_insn_and_split "*zero_extendsi<mode>2_dot"
854 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
855 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
857 (clobber (match_scratch:EXTSI 0 "=r,r"))]
858 "rs6000_gen_cell_microcode"
862 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
864 (zero_extend:DI (match_dup 1)))
866 (compare:CC (match_dup 0)
869 [(set_attr "type" "shift")
870 (set_attr "dot" "yes")
871 (set_attr "length" "4,8")])
873 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
874 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
875 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
877 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
878 (zero_extend:EXTSI (match_dup 1)))]
879 "rs6000_gen_cell_microcode"
883 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
885 (zero_extend:EXTSI (match_dup 1)))
887 (compare:CC (match_dup 0)
890 [(set_attr "type" "shift")
891 (set_attr "dot" "yes")
892 (set_attr "length" "4,8")])
895 (define_insn "extendqi<mode>2"
896 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
897 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
900 [(set_attr "type" "exts")])
902 (define_insn_and_split "*extendqi<mode>2_dot"
903 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
904 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
906 (clobber (match_scratch:EXTQI 0 "=r,r"))]
907 "rs6000_gen_cell_microcode"
911 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
913 (sign_extend:EXTQI (match_dup 1)))
915 (compare:CC (match_dup 0)
918 [(set_attr "type" "exts")
919 (set_attr "dot" "yes")
920 (set_attr "length" "4,8")])
922 (define_insn_and_split "*extendqi<mode>2_dot2"
923 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
924 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
926 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
927 (sign_extend:EXTQI (match_dup 1)))]
928 "rs6000_gen_cell_microcode"
932 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
934 (sign_extend:EXTQI (match_dup 1)))
936 (compare:CC (match_dup 0)
939 [(set_attr "type" "exts")
940 (set_attr "dot" "yes")
941 (set_attr "length" "4,8")])
944 (define_expand "extendhi<mode>2"
945 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
946 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
950 (define_insn "*extendhi<mode>2"
951 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
952 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
953 "rs6000_gen_cell_microcode"
957 [(set_attr "type" "load,exts")
958 (set_attr "sign_extend" "yes")])
960 (define_insn "*extendhi<mode>2_noload"
961 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
962 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
963 "!rs6000_gen_cell_microcode"
965 [(set_attr "type" "exts")])
967 (define_insn_and_split "*extendhi<mode>2_dot"
968 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
969 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
971 (clobber (match_scratch:EXTHI 0 "=r,r"))]
972 "rs6000_gen_cell_microcode"
976 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
978 (sign_extend:EXTHI (match_dup 1)))
980 (compare:CC (match_dup 0)
983 [(set_attr "type" "exts")
984 (set_attr "dot" "yes")
985 (set_attr "length" "4,8")])
987 (define_insn_and_split "*extendhi<mode>2_dot2"
988 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
989 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
991 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
992 (sign_extend:EXTHI (match_dup 1)))]
993 "rs6000_gen_cell_microcode"
997 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
999 (sign_extend:EXTHI (match_dup 1)))
1001 (compare:CC (match_dup 0)
1004 [(set_attr "type" "exts")
1005 (set_attr "dot" "yes")
1006 (set_attr "length" "4,8")])
1009 (define_insn "extendsi<mode>2"
1010 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK")
1011 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK")))]
1020 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts")
1021 (set_attr "sign_extend" "yes")])
1023 (define_insn_and_split "*extendsi<mode>2_dot"
1024 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1025 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1027 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1028 "rs6000_gen_cell_microcode"
1032 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1034 (sign_extend:EXTSI (match_dup 1)))
1036 (compare:CC (match_dup 0)
1039 [(set_attr "type" "exts")
1040 (set_attr "dot" "yes")
1041 (set_attr "length" "4,8")])
1043 (define_insn_and_split "*extendsi<mode>2_dot2"
1044 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1045 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1047 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1048 (sign_extend:EXTSI (match_dup 1)))]
1049 "rs6000_gen_cell_microcode"
1053 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1055 (sign_extend:EXTSI (match_dup 1)))
1057 (compare:CC (match_dup 0)
1060 [(set_attr "type" "exts")
1061 (set_attr "dot" "yes")
1062 (set_attr "length" "4,8")])
1064 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1066 (define_insn "*macchwc"
1067 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1068 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1069 (match_operand:SI 2 "gpc_reg_operand" "r")
1072 (match_operand:HI 1 "gpc_reg_operand" "r")))
1073 (match_operand:SI 4 "gpc_reg_operand" "0"))
1075 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1076 (plus:SI (mult:SI (ashiftrt:SI
1084 [(set_attr "type" "halfmul")])
1086 (define_insn "*macchw"
1087 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1088 (plus:SI (mult:SI (ashiftrt:SI
1089 (match_operand:SI 2 "gpc_reg_operand" "r")
1092 (match_operand:HI 1 "gpc_reg_operand" "r")))
1093 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1096 [(set_attr "type" "halfmul")])
1098 (define_insn "*macchwuc"
1099 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1100 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1101 (match_operand:SI 2 "gpc_reg_operand" "r")
1104 (match_operand:HI 1 "gpc_reg_operand" "r")))
1105 (match_operand:SI 4 "gpc_reg_operand" "0"))
1107 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1108 (plus:SI (mult:SI (lshiftrt:SI
1116 [(set_attr "type" "halfmul")])
1118 (define_insn "*macchwu"
1119 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1120 (plus:SI (mult:SI (lshiftrt:SI
1121 (match_operand:SI 2 "gpc_reg_operand" "r")
1124 (match_operand:HI 1 "gpc_reg_operand" "r")))
1125 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1128 [(set_attr "type" "halfmul")])
1130 (define_insn "*machhwc"
1131 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1132 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1133 (match_operand:SI 1 "gpc_reg_operand" "%r")
1136 (match_operand:SI 2 "gpc_reg_operand" "r")
1138 (match_operand:SI 4 "gpc_reg_operand" "0"))
1140 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1141 (plus:SI (mult:SI (ashiftrt:SI
1150 [(set_attr "type" "halfmul")])
1152 (define_insn "*machhw"
1153 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1154 (plus:SI (mult:SI (ashiftrt:SI
1155 (match_operand:SI 1 "gpc_reg_operand" "%r")
1158 (match_operand:SI 2 "gpc_reg_operand" "r")
1160 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1163 [(set_attr "type" "halfmul")])
1165 (define_insn "*machhwuc"
1166 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1167 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1168 (match_operand:SI 1 "gpc_reg_operand" "%r")
1171 (match_operand:SI 2 "gpc_reg_operand" "r")
1173 (match_operand:SI 4 "gpc_reg_operand" "0"))
1175 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1176 (plus:SI (mult:SI (lshiftrt:SI
1185 [(set_attr "type" "halfmul")])
1187 (define_insn "*machhwu"
1188 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1189 (plus:SI (mult:SI (lshiftrt:SI
1190 (match_operand:SI 1 "gpc_reg_operand" "%r")
1193 (match_operand:SI 2 "gpc_reg_operand" "r")
1195 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1198 [(set_attr "type" "halfmul")])
1200 (define_insn "*maclhwc"
1201 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1202 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1203 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1205 (match_operand:HI 2 "gpc_reg_operand" "r")))
1206 (match_operand:SI 4 "gpc_reg_operand" "0"))
1208 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1209 (plus:SI (mult:SI (sign_extend:SI
1216 [(set_attr "type" "halfmul")])
1218 (define_insn "*maclhw"
1219 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1220 (plus:SI (mult:SI (sign_extend:SI
1221 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1223 (match_operand:HI 2 "gpc_reg_operand" "r")))
1224 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1227 [(set_attr "type" "halfmul")])
1229 (define_insn "*maclhwuc"
1230 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1231 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1232 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1234 (match_operand:HI 2 "gpc_reg_operand" "r")))
1235 (match_operand:SI 4 "gpc_reg_operand" "0"))
1237 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1238 (plus:SI (mult:SI (zero_extend:SI
1245 [(set_attr "type" "halfmul")])
1247 (define_insn "*maclhwu"
1248 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1249 (plus:SI (mult:SI (zero_extend:SI
1250 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1252 (match_operand:HI 2 "gpc_reg_operand" "r")))
1253 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1256 [(set_attr "type" "halfmul")])
1258 (define_insn "*nmacchwc"
1259 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1260 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1261 (mult:SI (ashiftrt:SI
1262 (match_operand:SI 2 "gpc_reg_operand" "r")
1265 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1267 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1268 (minus:SI (match_dup 4)
1269 (mult:SI (ashiftrt:SI
1276 [(set_attr "type" "halfmul")])
1278 (define_insn "*nmacchw"
1279 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1280 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1281 (mult:SI (ashiftrt:SI
1282 (match_operand:SI 2 "gpc_reg_operand" "r")
1285 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1288 [(set_attr "type" "halfmul")])
1290 (define_insn "*nmachhwc"
1291 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1292 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1293 (mult:SI (ashiftrt:SI
1294 (match_operand:SI 1 "gpc_reg_operand" "%r")
1297 (match_operand:SI 2 "gpc_reg_operand" "r")
1300 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1301 (minus:SI (match_dup 4)
1302 (mult:SI (ashiftrt:SI
1310 [(set_attr "type" "halfmul")])
1312 (define_insn "*nmachhw"
1313 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1314 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1315 (mult:SI (ashiftrt:SI
1316 (match_operand:SI 1 "gpc_reg_operand" "%r")
1319 (match_operand:SI 2 "gpc_reg_operand" "r")
1323 [(set_attr "type" "halfmul")])
1325 (define_insn "*nmaclhwc"
1326 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1327 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1328 (mult:SI (sign_extend:SI
1329 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1331 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1333 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1334 (minus:SI (match_dup 4)
1335 (mult:SI (sign_extend:SI
1341 [(set_attr "type" "halfmul")])
1343 (define_insn "*nmaclhw"
1344 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1345 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1346 (mult:SI (sign_extend:SI
1347 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1349 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1352 [(set_attr "type" "halfmul")])
1354 (define_insn "*mulchwc"
1355 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1356 (compare:CC (mult:SI (ashiftrt:SI
1357 (match_operand:SI 2 "gpc_reg_operand" "r")
1360 (match_operand:HI 1 "gpc_reg_operand" "r")))
1362 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1363 (mult:SI (ashiftrt:SI
1370 [(set_attr "type" "halfmul")])
1372 (define_insn "*mulchw"
1373 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1374 (mult:SI (ashiftrt:SI
1375 (match_operand:SI 2 "gpc_reg_operand" "r")
1378 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1381 [(set_attr "type" "halfmul")])
1383 (define_insn "*mulchwuc"
1384 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1385 (compare:CC (mult:SI (lshiftrt:SI
1386 (match_operand:SI 2 "gpc_reg_operand" "r")
1389 (match_operand:HI 1 "gpc_reg_operand" "r")))
1391 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1392 (mult:SI (lshiftrt:SI
1399 [(set_attr "type" "halfmul")])
1401 (define_insn "*mulchwu"
1402 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1403 (mult:SI (lshiftrt:SI
1404 (match_operand:SI 2 "gpc_reg_operand" "r")
1407 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1410 [(set_attr "type" "halfmul")])
1412 (define_insn "*mulhhwc"
1413 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1414 (compare:CC (mult:SI (ashiftrt:SI
1415 (match_operand:SI 1 "gpc_reg_operand" "%r")
1418 (match_operand:SI 2 "gpc_reg_operand" "r")
1421 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1422 (mult:SI (ashiftrt:SI
1430 [(set_attr "type" "halfmul")])
1432 (define_insn "*mulhhw"
1433 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1434 (mult:SI (ashiftrt:SI
1435 (match_operand:SI 1 "gpc_reg_operand" "%r")
1438 (match_operand:SI 2 "gpc_reg_operand" "r")
1442 [(set_attr "type" "halfmul")])
1444 (define_insn "*mulhhwuc"
1445 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1446 (compare:CC (mult:SI (lshiftrt:SI
1447 (match_operand:SI 1 "gpc_reg_operand" "%r")
1450 (match_operand:SI 2 "gpc_reg_operand" "r")
1453 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1454 (mult:SI (lshiftrt:SI
1462 [(set_attr "type" "halfmul")])
1464 (define_insn "*mulhhwu"
1465 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1466 (mult:SI (lshiftrt:SI
1467 (match_operand:SI 1 "gpc_reg_operand" "%r")
1470 (match_operand:SI 2 "gpc_reg_operand" "r")
1474 [(set_attr "type" "halfmul")])
1476 (define_insn "*mullhwc"
1477 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1478 (compare:CC (mult:SI (sign_extend:SI
1479 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1481 (match_operand:HI 2 "gpc_reg_operand" "r")))
1483 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1484 (mult:SI (sign_extend:SI
1490 [(set_attr "type" "halfmul")])
1492 (define_insn "*mullhw"
1493 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1494 (mult:SI (sign_extend:SI
1495 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1497 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1500 [(set_attr "type" "halfmul")])
1502 (define_insn "*mullhwuc"
1503 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1504 (compare:CC (mult:SI (zero_extend:SI
1505 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1507 (match_operand:HI 2 "gpc_reg_operand" "r")))
1509 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1510 (mult:SI (zero_extend:SI
1516 [(set_attr "type" "halfmul")])
1518 (define_insn "*mullhwu"
1519 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1520 (mult:SI (zero_extend:SI
1521 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1523 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1526 [(set_attr "type" "halfmul")])
1528 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1529 (define_insn "dlmzb"
1530 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1531 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1532 (match_operand:SI 2 "gpc_reg_operand" "r")]
1534 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1535 (unspec:SI [(match_dup 1)
1541 (define_expand "strlensi"
1542 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1543 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1544 (match_operand:QI 2 "const_int_operand" "")
1545 (match_operand 3 "const_int_operand" "")]
1546 UNSPEC_DLMZB_STRLEN))
1547 (clobber (match_scratch:CC 4 "=x"))]
1548 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1550 rtx result = operands[0];
1551 rtx src = operands[1];
1552 rtx search_char = operands[2];
1553 rtx align = operands[3];
1554 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1555 rtx loop_label, end_label, mem, cr0, cond;
1556 if (search_char != const0_rtx
1557 || GET_CODE (align) != CONST_INT
1558 || INTVAL (align) < 8)
1560 word1 = gen_reg_rtx (SImode);
1561 word2 = gen_reg_rtx (SImode);
1562 scratch_dlmzb = gen_reg_rtx (SImode);
1563 scratch_string = gen_reg_rtx (Pmode);
1564 loop_label = gen_label_rtx ();
1565 end_label = gen_label_rtx ();
1566 addr = force_reg (Pmode, XEXP (src, 0));
1567 emit_move_insn (scratch_string, addr);
1568 emit_label (loop_label);
1569 mem = change_address (src, SImode, scratch_string);
1570 emit_move_insn (word1, mem);
1571 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1572 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1573 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1574 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1575 emit_jump_insn (gen_rtx_SET (pc_rtx,
1576 gen_rtx_IF_THEN_ELSE (VOIDmode,
1582 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1583 emit_jump_insn (gen_rtx_SET (pc_rtx,
1584 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1586 emit_label (end_label);
1587 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1588 emit_insn (gen_subsi3 (result, scratch_string, addr));
1589 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1593 ;; Fixed-point arithmetic insns.
1595 (define_expand "add<mode>3"
1596 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1597 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1598 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1601 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1603 rtx lo0 = gen_lowpart (SImode, operands[0]);
1604 rtx lo1 = gen_lowpart (SImode, operands[1]);
1605 rtx lo2 = gen_lowpart (SImode, operands[2]);
1606 rtx hi0 = gen_highpart (SImode, operands[0]);
1607 rtx hi1 = gen_highpart (SImode, operands[1]);
1608 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1610 if (!reg_or_short_operand (lo2, SImode))
1611 lo2 = force_reg (SImode, lo2);
1612 if (!adde_operand (hi2, SImode))
1613 hi2 = force_reg (SImode, hi2);
1615 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1616 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1620 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1622 rtx tmp = ((!can_create_pseudo_p ()
1623 || rtx_equal_p (operands[0], operands[1]))
1624 ? operands[0] : gen_reg_rtx (<MODE>mode));
1626 HOST_WIDE_INT val = INTVAL (operands[2]);
1627 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1628 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1630 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1633 /* The ordering here is important for the prolog expander.
1634 When space is allocated from the stack, adding 'low' first may
1635 produce a temporary deallocation (which would be bad). */
1636 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1637 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1642 (define_insn "*add<mode>3"
1643 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1644 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1645 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1651 [(set_attr "type" "add")])
1653 (define_insn "addsi3_high"
1654 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1655 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1656 (high:SI (match_operand 2 "" ""))))]
1657 "TARGET_MACHO && !TARGET_64BIT"
1658 "addis %0,%1,ha16(%2)"
1659 [(set_attr "type" "add")])
1661 (define_insn_and_split "*add<mode>3_dot"
1662 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1663 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1664 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1666 (clobber (match_scratch:GPR 0 "=r,r"))]
1667 "<MODE>mode == Pmode"
1671 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1673 (plus:GPR (match_dup 1)
1676 (compare:CC (match_dup 0)
1679 [(set_attr "type" "add")
1680 (set_attr "dot" "yes")
1681 (set_attr "length" "4,8")])
1683 (define_insn_and_split "*add<mode>3_dot2"
1684 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1685 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1686 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1688 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1689 (plus:GPR (match_dup 1)
1691 "<MODE>mode == Pmode"
1695 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1697 (plus:GPR (match_dup 1)
1700 (compare:CC (match_dup 0)
1703 [(set_attr "type" "add")
1704 (set_attr "dot" "yes")
1705 (set_attr "length" "4,8")])
1707 (define_insn_and_split "*add<mode>3_imm_dot"
1708 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1709 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1710 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1712 (clobber (match_scratch:GPR 0 "=r,r"))
1713 (clobber (reg:GPR CA_REGNO))]
1714 "<MODE>mode == Pmode"
1718 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1720 (plus:GPR (match_dup 1)
1723 (compare:CC (match_dup 0)
1726 [(set_attr "type" "add")
1727 (set_attr "dot" "yes")
1728 (set_attr "length" "4,8")])
1730 (define_insn_and_split "*add<mode>3_imm_dot2"
1731 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1732 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1733 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1735 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1736 (plus:GPR (match_dup 1)
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 ;; Split an add that we can't do in one insn into two insns, each of which
1756 ;; does one 16-bit part. This is used by combine. Note that the low-order
1757 ;; add should be last in case the result gets used in an address.
1760 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1761 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1762 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1764 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1765 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1767 HOST_WIDE_INT val = INTVAL (operands[2]);
1768 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1769 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1771 operands[4] = GEN_INT (low);
1772 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1773 operands[3] = GEN_INT (rest);
1774 else if (can_create_pseudo_p ())
1776 operands[3] = gen_reg_rtx (DImode);
1777 emit_move_insn (operands[3], operands[2]);
1778 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1786 (define_insn "add<mode>3_carry"
1787 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1788 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1789 (match_operand:P 2 "reg_or_short_operand" "rI")))
1790 (set (reg:P CA_REGNO)
1791 (ltu:P (plus:P (match_dup 1)
1796 [(set_attr "type" "add")])
1798 (define_insn "*add<mode>3_imm_carry_pos"
1799 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1800 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1801 (match_operand:P 2 "short_cint_operand" "n")))
1802 (set (reg:P CA_REGNO)
1803 (geu:P (match_dup 1)
1804 (match_operand:P 3 "const_int_operand" "n")))]
1805 "INTVAL (operands[2]) > 0
1806 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1808 [(set_attr "type" "add")])
1810 (define_insn "*add<mode>3_imm_carry_0"
1811 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1812 (match_operand:P 1 "gpc_reg_operand" "r"))
1813 (set (reg:P CA_REGNO)
1817 [(set_attr "type" "add")])
1819 (define_insn "*add<mode>3_imm_carry_m1"
1820 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1821 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1823 (set (reg:P CA_REGNO)
1828 [(set_attr "type" "add")])
1830 (define_insn "*add<mode>3_imm_carry_neg"
1831 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1832 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1833 (match_operand:P 2 "short_cint_operand" "n")))
1834 (set (reg:P CA_REGNO)
1835 (gtu:P (match_dup 1)
1836 (match_operand:P 3 "const_int_operand" "n")))]
1837 "INTVAL (operands[2]) < 0
1838 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1840 [(set_attr "type" "add")])
1843 (define_expand "add<mode>3_carry_in"
1845 (set (match_operand:GPR 0 "gpc_reg_operand")
1846 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1847 (match_operand:GPR 2 "adde_operand"))
1848 (reg:GPR CA_REGNO)))
1849 (clobber (reg:GPR CA_REGNO))])]
1852 if (operands[2] == const0_rtx)
1854 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1857 if (operands[2] == constm1_rtx)
1859 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1864 (define_insn "*add<mode>3_carry_in_internal"
1865 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1866 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1867 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1868 (reg:GPR CA_REGNO)))
1869 (clobber (reg:GPR CA_REGNO))]
1872 [(set_attr "type" "add")])
1874 (define_insn "add<mode>3_carry_in_0"
1875 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1876 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1877 (reg:GPR CA_REGNO)))
1878 (clobber (reg:GPR CA_REGNO))]
1881 [(set_attr "type" "add")])
1883 (define_insn "add<mode>3_carry_in_m1"
1884 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1885 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1888 (clobber (reg:GPR CA_REGNO))]
1891 [(set_attr "type" "add")])
1894 (define_expand "one_cmpl<mode>2"
1895 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1896 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1899 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1901 rs6000_split_logical (operands, NOT, false, false, false);
1906 (define_insn "*one_cmpl<mode>2"
1907 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1908 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1912 (define_insn_and_split "*one_cmpl<mode>2_dot"
1913 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1914 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1916 (clobber (match_scratch:GPR 0 "=r,r"))]
1917 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1921 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1923 (not:GPR (match_dup 1)))
1925 (compare:CC (match_dup 0)
1928 [(set_attr "type" "logical")
1929 (set_attr "dot" "yes")
1930 (set_attr "length" "4,8")])
1932 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1933 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1934 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1936 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1937 (not:GPR (match_dup 1)))]
1938 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1942 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1944 (not:GPR (match_dup 1)))
1946 (compare:CC (match_dup 0)
1949 [(set_attr "type" "logical")
1950 (set_attr "dot" "yes")
1951 (set_attr "length" "4,8")])
1954 (define_expand "sub<mode>3"
1955 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1956 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1957 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1960 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1962 rtx lo0 = gen_lowpart (SImode, operands[0]);
1963 rtx lo1 = gen_lowpart (SImode, operands[1]);
1964 rtx lo2 = gen_lowpart (SImode, operands[2]);
1965 rtx hi0 = gen_highpart (SImode, operands[0]);
1966 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1967 rtx hi2 = gen_highpart (SImode, operands[2]);
1969 if (!reg_or_short_operand (lo1, SImode))
1970 lo1 = force_reg (SImode, lo1);
1971 if (!adde_operand (hi1, SImode))
1972 hi1 = force_reg (SImode, hi1);
1974 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1975 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1979 if (short_cint_operand (operands[1], <MODE>mode))
1981 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1986 (define_insn "*subf<mode>3"
1987 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1988 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1989 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1992 [(set_attr "type" "add")])
1994 (define_insn_and_split "*subf<mode>3_dot"
1995 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1996 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1997 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1999 (clobber (match_scratch:GPR 0 "=r,r"))]
2000 "<MODE>mode == Pmode"
2004 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2006 (minus:GPR (match_dup 2)
2009 (compare:CC (match_dup 0)
2012 [(set_attr "type" "add")
2013 (set_attr "dot" "yes")
2014 (set_attr "length" "4,8")])
2016 (define_insn_and_split "*subf<mode>3_dot2"
2017 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2018 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2019 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2021 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2022 (minus:GPR (match_dup 2)
2024 "<MODE>mode == Pmode"
2028 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2030 (minus:GPR (match_dup 2)
2033 (compare:CC (match_dup 0)
2036 [(set_attr "type" "add")
2037 (set_attr "dot" "yes")
2038 (set_attr "length" "4,8")])
2040 (define_insn "subf<mode>3_imm"
2041 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2042 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2043 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2044 (clobber (reg:GPR CA_REGNO))]
2047 [(set_attr "type" "add")])
2050 (define_insn "subf<mode>3_carry"
2051 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2052 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2053 (match_operand:P 1 "gpc_reg_operand" "r")))
2054 (set (reg:P CA_REGNO)
2055 (leu:P (match_dup 1)
2059 [(set_attr "type" "add")])
2061 (define_insn "*subf<mode>3_imm_carry_0"
2062 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2063 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2064 (set (reg:P CA_REGNO)
2069 [(set_attr "type" "add")])
2071 (define_insn "*subf<mode>3_imm_carry_m1"
2072 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2073 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2074 (set (reg:P CA_REGNO)
2078 [(set_attr "type" "add")])
2081 (define_expand "subf<mode>3_carry_in"
2083 (set (match_operand:GPR 0 "gpc_reg_operand")
2084 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2086 (match_operand:GPR 2 "adde_operand")))
2087 (clobber (reg:GPR CA_REGNO))])]
2090 if (operands[2] == const0_rtx)
2092 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2095 if (operands[2] == constm1_rtx)
2097 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2102 (define_insn "*subf<mode>3_carry_in_internal"
2103 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2104 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2106 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2107 (clobber (reg:GPR CA_REGNO))]
2110 [(set_attr "type" "add")])
2112 (define_insn "subf<mode>3_carry_in_0"
2113 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2114 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2115 (reg:GPR CA_REGNO)))
2116 (clobber (reg:GPR CA_REGNO))]
2119 [(set_attr "type" "add")])
2121 (define_insn "subf<mode>3_carry_in_m1"
2122 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2123 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2124 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2126 (clobber (reg:GPR CA_REGNO))]
2129 [(set_attr "type" "add")])
2131 (define_insn "subf<mode>3_carry_in_xx"
2132 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2133 (plus:GPR (reg:GPR CA_REGNO)
2135 (clobber (reg:GPR CA_REGNO))]
2138 [(set_attr "type" "add")])
2141 (define_insn "neg<mode>2"
2142 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2143 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2146 [(set_attr "type" "add")])
2148 (define_insn_and_split "*neg<mode>2_dot"
2149 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2150 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2152 (clobber (match_scratch:GPR 0 "=r,r"))]
2153 "<MODE>mode == Pmode"
2157 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2159 (neg:GPR (match_dup 1)))
2161 (compare:CC (match_dup 0)
2164 [(set_attr "type" "add")
2165 (set_attr "dot" "yes")
2166 (set_attr "length" "4,8")])
2168 (define_insn_and_split "*neg<mode>2_dot2"
2169 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2170 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2172 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2173 (neg:GPR (match_dup 1)))]
2174 "<MODE>mode == Pmode"
2178 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2180 (neg:GPR (match_dup 1)))
2182 (compare:CC (match_dup 0)
2185 [(set_attr "type" "add")
2186 (set_attr "dot" "yes")
2187 (set_attr "length" "4,8")])
2190 (define_insn "clz<mode>2"
2191 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2192 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2195 [(set_attr "type" "cntlz")])
2197 (define_expand "ctz<mode>2"
2199 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2201 (and:GPR (match_dup 1)
2204 (clz:GPR (match_dup 3)))
2205 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2206 (minus:GPR (match_dup 5)
2208 (clobber (reg:GPR CA_REGNO))])]
2213 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2217 operands[2] = gen_reg_rtx (<MODE>mode);
2218 operands[3] = gen_reg_rtx (<MODE>mode);
2219 operands[4] = gen_reg_rtx (<MODE>mode);
2220 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2223 (define_insn "ctz<mode>2_hw"
2224 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2225 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2228 [(set_attr "type" "cntlz")])
2230 (define_expand "ffs<mode>2"
2232 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2234 (and:GPR (match_dup 1)
2237 (clz:GPR (match_dup 3)))
2238 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2239 (minus:GPR (match_dup 5)
2241 (clobber (reg:GPR CA_REGNO))])]
2244 operands[2] = gen_reg_rtx (<MODE>mode);
2245 operands[3] = gen_reg_rtx (<MODE>mode);
2246 operands[4] = gen_reg_rtx (<MODE>mode);
2247 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2251 (define_expand "popcount<mode>2"
2252 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2253 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2254 "TARGET_POPCNTB || TARGET_POPCNTD"
2256 rs6000_emit_popcount (operands[0], operands[1]);
2260 (define_insn "popcntb<mode>2"
2261 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2262 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2266 [(set_attr "type" "popcnt")])
2268 (define_insn "popcntd<mode>2"
2269 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2270 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2273 [(set_attr "type" "popcnt")])
2276 (define_expand "parity<mode>2"
2277 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2278 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2281 rs6000_emit_parity (operands[0], operands[1]);
2285 (define_insn "parity<mode>2_cmpb"
2286 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2287 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2288 "TARGET_CMPB && TARGET_POPCNTB"
2290 [(set_attr "type" "popcnt")])
2293 ;; Since the hardware zeros the upper part of the register, save generating the
2294 ;; AND immediate if we are converting to unsigned
2295 (define_insn "*bswaphi2_extenddi"
2296 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2298 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2301 [(set_attr "length" "4")
2302 (set_attr "type" "load")])
2304 (define_insn "*bswaphi2_extendsi"
2305 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2307 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2310 [(set_attr "length" "4")
2311 (set_attr "type" "load")])
2313 (define_expand "bswaphi2"
2314 [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2316 (match_operand:HI 1 "reg_or_mem_operand" "")))
2317 (clobber (match_scratch:SI 2 ""))])]
2320 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2321 operands[1] = force_reg (HImode, operands[1]);
2324 (define_insn "bswaphi2_internal"
2325 [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2327 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2328 (clobber (match_scratch:SI 2 "=X,X,&r"))]
2334 [(set_attr "length" "4,4,12")
2335 (set_attr "type" "load,store,*")])
2338 [(set (match_operand:HI 0 "gpc_reg_operand" "")
2339 (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2340 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2343 (and:SI (lshiftrt:SI (match_dup 4)
2347 (and:SI (ashift:SI (match_dup 4)
2349 (const_int 65280))) ;; 0xff00
2351 (ior:SI (match_dup 3)
2355 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2356 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2359 (define_insn "*bswapsi2_extenddi"
2360 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2362 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2365 [(set_attr "length" "4")
2366 (set_attr "type" "load")])
2368 (define_expand "bswapsi2"
2369 [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2371 (match_operand:SI 1 "reg_or_mem_operand" "")))]
2374 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2375 operands[1] = force_reg (SImode, operands[1]);
2378 (define_insn "*bswapsi2_internal"
2379 [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2381 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2387 [(set_attr "length" "4,4,12")
2388 (set_attr "type" "load,store,*")])
2390 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2391 ;; zero_extract insns do not change for -mlittle.
2393 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2394 (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2396 [(set (match_dup 0) ; DABC
2397 (rotate:SI (match_dup 1)
2399 (set (match_dup 0) ; DCBC
2400 (ior:SI (and:SI (ashift:SI (match_dup 1)
2402 (const_int 16711680))
2403 (and:SI (match_dup 0)
2404 (const_int -16711681))))
2405 (set (match_dup 0) ; DCBA
2406 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2409 (and:SI (match_dup 0)
2415 (define_expand "bswapdi2"
2416 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2418 (match_operand:DI 1 "reg_or_mem_operand" "")))
2419 (clobber (match_scratch:DI 2 ""))
2420 (clobber (match_scratch:DI 3 ""))])]
2423 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2424 operands[1] = force_reg (DImode, operands[1]);
2426 if (!TARGET_POWERPC64)
2428 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2429 that uses 64-bit registers needs the same scratch registers as 64-bit
2431 emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2436 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2437 (define_insn "*bswapdi2_ldbrx"
2438 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2439 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2440 (clobber (match_scratch:DI 2 "=X,X,&r"))
2441 (clobber (match_scratch:DI 3 "=X,X,&r"))]
2442 "TARGET_POWERPC64 && TARGET_LDBRX
2443 && (REG_P (operands[0]) || REG_P (operands[1]))"
2448 [(set_attr "length" "4,4,36")
2449 (set_attr "type" "load,store,*")])
2451 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2452 (define_insn "*bswapdi2_64bit"
2453 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2454 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2455 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2456 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2457 "TARGET_POWERPC64 && !TARGET_LDBRX
2458 && (REG_P (operands[0]) || REG_P (operands[1]))
2459 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2460 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2462 [(set_attr "length" "16,12,36")])
2465 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2466 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2467 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2468 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2469 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2473 rtx dest = operands[0];
2474 rtx src = operands[1];
2475 rtx op2 = operands[2];
2476 rtx op3 = operands[3];
2477 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2478 BYTES_BIG_ENDIAN ? 4 : 0);
2479 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2480 BYTES_BIG_ENDIAN ? 4 : 0);
2486 addr1 = XEXP (src, 0);
2487 if (GET_CODE (addr1) == PLUS)
2489 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2490 if (TARGET_AVOID_XFORM)
2492 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2496 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2498 else if (TARGET_AVOID_XFORM)
2500 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2505 emit_move_insn (op2, GEN_INT (4));
2506 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2509 word1 = change_address (src, SImode, addr1);
2510 word2 = change_address (src, SImode, addr2);
2512 if (BYTES_BIG_ENDIAN)
2514 emit_insn (gen_bswapsi2 (op3_32, word2));
2515 emit_insn (gen_bswapsi2 (dest_32, word1));
2519 emit_insn (gen_bswapsi2 (op3_32, word1));
2520 emit_insn (gen_bswapsi2 (dest_32, word2));
2523 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2524 emit_insn (gen_iordi3 (dest, dest, op3));
2529 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2530 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2531 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2532 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2533 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2537 rtx dest = operands[0];
2538 rtx src = operands[1];
2539 rtx op2 = operands[2];
2540 rtx op3 = operands[3];
2541 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2542 BYTES_BIG_ENDIAN ? 4 : 0);
2543 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2544 BYTES_BIG_ENDIAN ? 4 : 0);
2550 addr1 = XEXP (dest, 0);
2551 if (GET_CODE (addr1) == PLUS)
2553 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2554 if (TARGET_AVOID_XFORM)
2556 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2560 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2562 else if (TARGET_AVOID_XFORM)
2564 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2569 emit_move_insn (op2, GEN_INT (4));
2570 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2573 word1 = change_address (dest, SImode, addr1);
2574 word2 = change_address (dest, SImode, addr2);
2576 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2578 if (BYTES_BIG_ENDIAN)
2580 emit_insn (gen_bswapsi2 (word1, src_si));
2581 emit_insn (gen_bswapsi2 (word2, op3_si));
2585 emit_insn (gen_bswapsi2 (word2, src_si));
2586 emit_insn (gen_bswapsi2 (word1, op3_si));
2592 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2593 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2594 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2595 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2596 "TARGET_POWERPC64 && reload_completed"
2600 rtx dest = operands[0];
2601 rtx src = operands[1];
2602 rtx op2 = operands[2];
2603 rtx op3 = operands[3];
2604 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2605 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2606 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2607 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2608 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2610 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2611 emit_insn (gen_bswapsi2 (dest_si, src_si));
2612 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2613 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2614 emit_insn (gen_iordi3 (dest, dest, op3));
2618 (define_insn "bswapdi2_32bit"
2619 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2620 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2621 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2622 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2624 [(set_attr "length" "16,12,36")])
2627 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2628 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2629 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2630 "!TARGET_POWERPC64 && reload_completed"
2634 rtx dest = operands[0];
2635 rtx src = operands[1];
2636 rtx op2 = operands[2];
2637 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2638 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2644 addr1 = XEXP (src, 0);
2645 if (GET_CODE (addr1) == PLUS)
2647 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2648 if (TARGET_AVOID_XFORM
2649 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2651 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2655 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2657 else if (TARGET_AVOID_XFORM
2658 || REGNO (addr1) == REGNO (dest2))
2660 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2665 emit_move_insn (op2, GEN_INT (4));
2666 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2669 word1 = change_address (src, SImode, addr1);
2670 word2 = change_address (src, SImode, addr2);
2672 emit_insn (gen_bswapsi2 (dest2, word1));
2673 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2674 thus allowing us to omit an early clobber on the output. */
2675 emit_insn (gen_bswapsi2 (dest1, word2));
2680 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2681 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2682 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2683 "!TARGET_POWERPC64 && reload_completed"
2687 rtx dest = operands[0];
2688 rtx src = operands[1];
2689 rtx op2 = operands[2];
2690 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2691 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2697 addr1 = XEXP (dest, 0);
2698 if (GET_CODE (addr1) == PLUS)
2700 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2701 if (TARGET_AVOID_XFORM)
2703 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2707 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2709 else if (TARGET_AVOID_XFORM)
2711 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2716 emit_move_insn (op2, GEN_INT (4));
2717 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2720 word1 = change_address (dest, SImode, addr1);
2721 word2 = change_address (dest, SImode, addr2);
2723 emit_insn (gen_bswapsi2 (word2, src1));
2724 emit_insn (gen_bswapsi2 (word1, src2));
2729 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2730 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2731 (clobber (match_operand:SI 2 "" ""))]
2732 "!TARGET_POWERPC64 && reload_completed"
2736 rtx dest = operands[0];
2737 rtx src = operands[1];
2738 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2739 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2740 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2741 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2743 emit_insn (gen_bswapsi2 (dest1, src2));
2744 emit_insn (gen_bswapsi2 (dest2, src1));
2749 (define_insn "mul<mode>3"
2750 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2751 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2752 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2757 [(set_attr "type" "mul")
2759 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2761 (match_operand:GPR 2 "short_cint_operand" "")
2762 (const_string "16")]
2763 (const_string "<bits>")))])
2765 (define_insn_and_split "*mul<mode>3_dot"
2766 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2767 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2768 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2770 (clobber (match_scratch:GPR 0 "=r,r"))]
2771 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2775 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2777 (mult:GPR (match_dup 1)
2780 (compare:CC (match_dup 0)
2783 [(set_attr "type" "mul")
2784 (set_attr "size" "<bits>")
2785 (set_attr "dot" "yes")
2786 (set_attr "length" "4,8")])
2788 (define_insn_and_split "*mul<mode>3_dot2"
2789 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2790 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2791 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2793 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2794 (mult:GPR (match_dup 1)
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")])
2814 (define_expand "<su>mul<mode>3_highpart"
2815 [(set (match_operand:GPR 0 "gpc_reg_operand")
2817 (mult:<DMODE> (any_extend:<DMODE>
2818 (match_operand:GPR 1 "gpc_reg_operand"))
2820 (match_operand:GPR 2 "gpc_reg_operand")))
2824 if (<MODE>mode == SImode && TARGET_POWERPC64)
2826 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2831 if (!WORDS_BIG_ENDIAN)
2833 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2839 (define_insn "*<su>mul<mode>3_highpart"
2840 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2842 (mult:<DMODE> (any_extend:<DMODE>
2843 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2845 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2847 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2848 "mulh<wd><u> %0,%1,%2"
2849 [(set_attr "type" "mul")
2850 (set_attr "size" "<bits>")])
2852 (define_insn "<su>mulsi3_highpart_le"
2853 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2855 (mult:DI (any_extend:DI
2856 (match_operand:SI 1 "gpc_reg_operand" "r"))
2858 (match_operand:SI 2 "gpc_reg_operand" "r")))
2860 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2862 [(set_attr "type" "mul")])
2864 (define_insn "<su>muldi3_highpart_le"
2865 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2867 (mult:TI (any_extend:TI
2868 (match_operand:DI 1 "gpc_reg_operand" "r"))
2870 (match_operand:DI 2 "gpc_reg_operand" "r")))
2872 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2874 [(set_attr "type" "mul")
2875 (set_attr "size" "64")])
2877 (define_insn "<su>mulsi3_highpart_64"
2878 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2881 (mult:DI (any_extend:DI
2882 (match_operand:SI 1 "gpc_reg_operand" "r"))
2884 (match_operand:SI 2 "gpc_reg_operand" "r")))
2888 [(set_attr "type" "mul")])
2890 (define_expand "<u>mul<mode><dmode>3"
2891 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2892 (mult:<DMODE> (any_extend:<DMODE>
2893 (match_operand:GPR 1 "gpc_reg_operand"))
2895 (match_operand:GPR 2 "gpc_reg_operand"))))]
2896 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2898 rtx l = gen_reg_rtx (<MODE>mode);
2899 rtx h = gen_reg_rtx (<MODE>mode);
2900 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2901 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2902 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2903 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2907 (define_insn "*maddld4"
2908 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2909 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2910 (match_operand:DI 2 "gpc_reg_operand" "r"))
2911 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2913 "maddld %0,%1,%2,%3"
2914 [(set_attr "type" "mul")])
2916 (define_insn "udiv<mode>3"
2917 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2918 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2919 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2922 [(set_attr "type" "div")
2923 (set_attr "size" "<bits>")])
2926 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2927 ;; modulus. If it isn't a power of two, force operands into register and do
2929 (define_expand "div<mode>3"
2930 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2931 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2932 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2935 if (CONST_INT_P (operands[2])
2936 && INTVAL (operands[2]) > 0
2937 && exact_log2 (INTVAL (operands[2])) >= 0)
2939 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2943 operands[2] = force_reg (<MODE>mode, operands[2]);
2946 (define_insn "*div<mode>3"
2947 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2948 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2949 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2952 [(set_attr "type" "div")
2953 (set_attr "size" "<bits>")])
2955 (define_insn "div<mode>3_sra"
2956 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2957 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2958 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2959 (clobber (reg:GPR CA_REGNO))]
2961 "sra<wd>i %0,%1,%p2\;addze %0,%0"
2962 [(set_attr "type" "two")
2963 (set_attr "length" "8")])
2965 (define_insn_and_split "*div<mode>3_sra_dot"
2966 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2967 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2968 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2970 (clobber (match_scratch:GPR 0 "=r,r"))
2971 (clobber (reg:GPR CA_REGNO))]
2972 "<MODE>mode == Pmode"
2974 sra<wd>i %0,%1,%p2\;addze. %0,%0
2976 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2977 [(parallel [(set (match_dup 0)
2978 (div:GPR (match_dup 1)
2980 (clobber (reg:GPR CA_REGNO))])
2982 (compare:CC (match_dup 0)
2985 [(set_attr "type" "two")
2986 (set_attr "length" "8,12")
2987 (set_attr "cell_micro" "not")])
2989 (define_insn_and_split "*div<mode>3_sra_dot2"
2990 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2991 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2992 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2994 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2995 (div:GPR (match_dup 1)
2997 (clobber (reg:GPR CA_REGNO))]
2998 "<MODE>mode == Pmode"
3000 sra<wd>i %0,%1,%p2\;addze. %0,%0
3002 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3003 [(parallel [(set (match_dup 0)
3004 (div:GPR (match_dup 1)
3006 (clobber (reg:GPR CA_REGNO))])
3008 (compare:CC (match_dup 0)
3011 [(set_attr "type" "two")
3012 (set_attr "length" "8,12")
3013 (set_attr "cell_micro" "not")])
3015 (define_expand "mod<mode>3"
3016 [(set (match_operand:GPR 0 "gpc_reg_operand")
3017 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3018 (match_operand:GPR 2 "reg_or_cint_operand")))]
3025 if (GET_CODE (operands[2]) != CONST_INT
3026 || INTVAL (operands[2]) <= 0
3027 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3032 operands[2] = force_reg (<MODE>mode, operands[2]);
3036 temp1 = gen_reg_rtx (<MODE>mode);
3037 temp2 = gen_reg_rtx (<MODE>mode);
3039 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3040 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3041 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3046 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3047 ;; mod, prefer putting the result of mod into a different register
3048 (define_insn "*mod<mode>3"
3049 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3050 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3051 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3054 [(set_attr "type" "div")
3055 (set_attr "size" "<bits>")])
3058 (define_insn "umod<mode>3"
3059 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3060 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3061 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3064 [(set_attr "type" "div")
3065 (set_attr "size" "<bits>")])
3067 ;; On machines with modulo support, do a combined div/mod the old fashioned
3068 ;; method, since the multiply/subtract is faster than doing the mod instruction
3072 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3073 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3074 (match_operand:GPR 2 "gpc_reg_operand" "")))
3075 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3076 (mod:GPR (match_dup 1)
3079 && ! reg_mentioned_p (operands[0], operands[1])
3080 && ! reg_mentioned_p (operands[0], operands[2])
3081 && ! reg_mentioned_p (operands[3], operands[1])
3082 && ! reg_mentioned_p (operands[3], operands[2])"
3084 (div:GPR (match_dup 1)
3087 (mult:GPR (match_dup 0)
3090 (minus:GPR (match_dup 1)
3094 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3095 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3096 (match_operand:GPR 2 "gpc_reg_operand" "")))
3097 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3098 (umod:GPR (match_dup 1)
3101 && ! reg_mentioned_p (operands[0], operands[1])
3102 && ! reg_mentioned_p (operands[0], operands[2])
3103 && ! reg_mentioned_p (operands[3], operands[1])
3104 && ! reg_mentioned_p (operands[3], operands[2])"
3106 (div:GPR (match_dup 1)
3109 (mult:GPR (match_dup 0)
3112 (minus:GPR (match_dup 1)
3116 ;; Logical instructions
3117 ;; The logical instructions are mostly combined by using match_operator,
3118 ;; but the plain AND insns are somewhat different because there is no
3119 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3120 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3122 (define_expand "and<mode>3"
3123 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3124 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3125 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3128 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3130 rs6000_split_logical (operands, AND, false, false, false);
3134 if (CONST_INT_P (operands[2]))
3136 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3138 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3142 if (logical_const_operand (operands[2], <MODE>mode)
3143 && rs6000_gen_cell_microcode)
3145 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3149 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3151 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3155 operands[2] = force_reg (<MODE>mode, operands[2]);
3160 (define_insn "and<mode>3_imm"
3161 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3162 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3163 (match_operand:GPR 2 "logical_const_operand" "n")))
3164 (clobber (match_scratch:CC 3 "=x"))]
3165 "rs6000_gen_cell_microcode
3166 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3167 "andi%e2. %0,%1,%u2"
3168 [(set_attr "type" "logical")
3169 (set_attr "dot" "yes")])
3171 (define_insn_and_split "*and<mode>3_imm_dot"
3172 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3173 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3174 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3176 (clobber (match_scratch:GPR 0 "=r,r"))
3177 (clobber (match_scratch:CC 4 "=X,x"))]
3178 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3179 && rs6000_gen_cell_microcode
3180 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3184 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3185 [(parallel [(set (match_dup 0)
3186 (and:GPR (match_dup 1)
3188 (clobber (match_dup 4))])
3190 (compare:CC (match_dup 0)
3193 [(set_attr "type" "logical")
3194 (set_attr "dot" "yes")
3195 (set_attr "length" "4,8")])
3197 (define_insn_and_split "*and<mode>3_imm_dot2"
3198 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3199 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3200 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3202 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3203 (and:GPR (match_dup 1)
3205 (clobber (match_scratch:CC 4 "=X,x"))]
3206 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3207 && rs6000_gen_cell_microcode
3208 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3212 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3213 [(parallel [(set (match_dup 0)
3214 (and:GPR (match_dup 1)
3216 (clobber (match_dup 4))])
3218 (compare:CC (match_dup 0)
3221 [(set_attr "type" "logical")
3222 (set_attr "dot" "yes")
3223 (set_attr "length" "4,8")])
3225 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3226 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3227 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3228 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3230 (clobber (match_scratch:GPR 0 "=r,r"))]
3231 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3232 && rs6000_gen_cell_microcode"
3236 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3238 (and:GPR (match_dup 1)
3241 (compare:CC (match_dup 0)
3244 [(set_attr "type" "logical")
3245 (set_attr "dot" "yes")
3246 (set_attr "length" "4,8")])
3248 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3249 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3250 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3251 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3253 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3254 (and:GPR (match_dup 1)
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<mode>3_imm_dot_shifted"
3274 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3277 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3278 (match_operand:SI 4 "const_int_operand" "n"))
3279 (match_operand:GPR 2 "const_int_operand" "n"))
3281 (clobber (match_scratch:GPR 0 "=r"))]
3282 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3283 << INTVAL (operands[4])),
3285 && (<MODE>mode == Pmode
3286 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3287 && rs6000_gen_cell_microcode"
3289 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3290 return "andi%e2. %0,%1,%u2";
3292 [(set_attr "type" "logical")
3293 (set_attr "dot" "yes")])
3296 (define_insn "and<mode>3_mask"
3297 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3298 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3299 (match_operand:GPR 2 "const_int_operand" "n")))]
3300 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3302 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3304 [(set_attr "type" "shift")])
3306 (define_insn_and_split "*and<mode>3_mask_dot"
3307 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3308 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3309 (match_operand:GPR 2 "const_int_operand" "n,n"))
3311 (clobber (match_scratch:GPR 0 "=r,r"))]
3312 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3313 && rs6000_gen_cell_microcode
3314 && !logical_const_operand (operands[2], <MODE>mode)
3315 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3317 if (which_alternative == 0)
3318 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3322 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3324 (and:GPR (match_dup 1)
3327 (compare:CC (match_dup 0)
3330 [(set_attr "type" "shift")
3331 (set_attr "dot" "yes")
3332 (set_attr "length" "4,8")])
3334 (define_insn_and_split "*and<mode>3_mask_dot2"
3335 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3336 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3337 (match_operand:GPR 2 "const_int_operand" "n,n"))
3339 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3340 (and:GPR (match_dup 1)
3342 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3343 && rs6000_gen_cell_microcode
3344 && !logical_const_operand (operands[2], <MODE>mode)
3345 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3347 if (which_alternative == 0)
3348 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3352 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3354 (and:GPR (match_dup 1)
3357 (compare:CC (match_dup 0)
3360 [(set_attr "type" "shift")
3361 (set_attr "dot" "yes")
3362 (set_attr "length" "4,8")])
3365 (define_insn_and_split "*and<mode>3_2insn"
3366 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3367 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3368 (match_operand:GPR 2 "const_int_operand" "n")))]
3369 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3370 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3371 || (logical_const_operand (operands[2], <MODE>mode)
3372 && rs6000_gen_cell_microcode))"
3377 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3380 [(set_attr "type" "shift")
3381 (set_attr "length" "8")])
3383 (define_insn_and_split "*and<mode>3_2insn_dot"
3384 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3385 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3386 (match_operand:GPR 2 "const_int_operand" "n,n"))
3388 (clobber (match_scratch:GPR 0 "=r,r"))]
3389 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3390 && rs6000_gen_cell_microcode
3391 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3392 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3393 || (logical_const_operand (operands[2], <MODE>mode)
3394 && rs6000_gen_cell_microcode))"
3396 "&& reload_completed"
3399 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3402 [(set_attr "type" "shift")
3403 (set_attr "dot" "yes")
3404 (set_attr "length" "8,12")])
3406 (define_insn_and_split "*and<mode>3_2insn_dot2"
3407 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3408 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3409 (match_operand:GPR 2 "const_int_operand" "n,n"))
3411 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3412 (and:GPR (match_dup 1)
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, 2);
3427 [(set_attr "type" "shift")
3428 (set_attr "dot" "yes")
3429 (set_attr "length" "8,12")])
3432 (define_expand "<code><mode>3"
3433 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3434 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3435 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3438 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3440 rs6000_split_logical (operands, <CODE>, false, false, false);
3444 if (non_logical_cint_operand (operands[2], <MODE>mode))
3446 rtx tmp = ((!can_create_pseudo_p ()
3447 || rtx_equal_p (operands[0], operands[1]))
3448 ? operands[0] : gen_reg_rtx (<MODE>mode));
3450 HOST_WIDE_INT value = INTVAL (operands[2]);
3451 HOST_WIDE_INT lo = value & 0xffff;
3452 HOST_WIDE_INT hi = value - lo;
3454 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3455 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3459 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3460 operands[2] = force_reg (<MODE>mode, operands[2]);
3464 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3465 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3466 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3469 (iorxor:GPR (match_dup 1)
3472 (iorxor:GPR (match_dup 3)
3475 operands[3] = ((!can_create_pseudo_p ()
3476 || rtx_equal_p (operands[0], operands[1]))
3477 ? operands[0] : gen_reg_rtx (<MODE>mode));
3479 HOST_WIDE_INT value = INTVAL (operands[2]);
3480 HOST_WIDE_INT lo = value & 0xffff;
3481 HOST_WIDE_INT hi = value - lo;
3483 operands[4] = GEN_INT (hi);
3484 operands[5] = GEN_INT (lo);
3487 (define_insn "*bool<mode>3_imm"
3488 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3489 (match_operator:GPR 3 "boolean_or_operator"
3490 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3491 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3494 [(set_attr "type" "logical")])
3496 (define_insn "*bool<mode>3"
3497 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3498 (match_operator:GPR 3 "boolean_operator"
3499 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3500 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3503 [(set_attr "type" "logical")])
3505 (define_insn_and_split "*bool<mode>3_dot"
3506 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3507 (compare:CC (match_operator:GPR 3 "boolean_operator"
3508 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3509 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3511 (clobber (match_scratch:GPR 0 "=r,r"))]
3512 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3516 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3520 (compare:CC (match_dup 0)
3523 [(set_attr "type" "logical")
3524 (set_attr "dot" "yes")
3525 (set_attr "length" "4,8")])
3527 (define_insn_and_split "*bool<mode>3_dot2"
3528 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3529 (compare:CC (match_operator:GPR 3 "boolean_operator"
3530 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3531 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3533 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3535 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3539 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3543 (compare:CC (match_dup 0)
3546 [(set_attr "type" "logical")
3547 (set_attr "dot" "yes")
3548 (set_attr "length" "4,8")])
3551 (define_insn "*boolc<mode>3"
3552 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3553 (match_operator:GPR 3 "boolean_operator"
3554 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3555 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3558 [(set_attr "type" "logical")])
3560 (define_insn_and_split "*boolc<mode>3_dot"
3561 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3562 (compare:CC (match_operator:GPR 3 "boolean_operator"
3563 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3564 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3566 (clobber (match_scratch:GPR 0 "=r,r"))]
3567 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3571 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3575 (compare:CC (match_dup 0)
3578 [(set_attr "type" "logical")
3579 (set_attr "dot" "yes")
3580 (set_attr "length" "4,8")])
3582 (define_insn_and_split "*boolc<mode>3_dot2"
3583 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3584 (compare:CC (match_operator:GPR 3 "boolean_operator"
3585 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3586 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3588 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3590 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3594 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3598 (compare:CC (match_dup 0)
3601 [(set_attr "type" "logical")
3602 (set_attr "dot" "yes")
3603 (set_attr "length" "4,8")])
3606 (define_insn "*boolcc<mode>3"
3607 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3608 (match_operator:GPR 3 "boolean_operator"
3609 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3610 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3613 [(set_attr "type" "logical")])
3615 (define_insn_and_split "*boolcc<mode>3_dot"
3616 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3617 (compare:CC (match_operator:GPR 3 "boolean_operator"
3618 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3619 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3621 (clobber (match_scratch:GPR 0 "=r,r"))]
3622 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3626 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3630 (compare:CC (match_dup 0)
3633 [(set_attr "type" "logical")
3634 (set_attr "dot" "yes")
3635 (set_attr "length" "4,8")])
3637 (define_insn_and_split "*boolcc<mode>3_dot2"
3638 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3639 (compare:CC (match_operator:GPR 3 "boolean_operator"
3640 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3641 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3643 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3645 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3649 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3653 (compare:CC (match_dup 0)
3656 [(set_attr "type" "logical")
3657 (set_attr "dot" "yes")
3658 (set_attr "length" "4,8")])
3661 ;; TODO: Should have dots of this as well.
3662 (define_insn "*eqv<mode>3"
3663 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3664 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3665 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3668 [(set_attr "type" "logical")])
3670 ;; Rotate-and-mask and insert.
3672 (define_insn "*rotl<mode>3_mask"
3673 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3674 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3675 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3676 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3677 (match_operand:GPR 3 "const_int_operand" "n")))]
3678 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3680 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3682 [(set_attr "type" "shift")
3683 (set_attr "maybe_var_shift" "yes")])
3685 (define_insn_and_split "*rotl<mode>3_mask_dot"
3686 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3688 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3689 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3690 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3691 (match_operand:GPR 3 "const_int_operand" "n,n"))
3693 (clobber (match_scratch:GPR 0 "=r,r"))]
3694 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3695 && rs6000_gen_cell_microcode
3696 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3698 if (which_alternative == 0)
3699 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3703 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3705 (and:GPR (match_dup 4)
3708 (compare:CC (match_dup 0)
3711 [(set_attr "type" "shift")
3712 (set_attr "maybe_var_shift" "yes")
3713 (set_attr "dot" "yes")
3714 (set_attr "length" "4,8")])
3716 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3717 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3719 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3720 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3721 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3722 (match_operand:GPR 3 "const_int_operand" "n,n"))
3724 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3725 (and:GPR (match_dup 4)
3727 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3728 && rs6000_gen_cell_microcode
3729 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3731 if (which_alternative == 0)
3732 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3736 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3738 (and:GPR (match_dup 4)
3741 (compare:CC (match_dup 0)
3744 [(set_attr "type" "shift")
3745 (set_attr "maybe_var_shift" "yes")
3746 (set_attr "dot" "yes")
3747 (set_attr "length" "4,8")])
3749 ; Special case for less-than-0. We can do it with just one machine
3750 ; instruction, but the generic optimizers do not realise it is cheap.
3751 (define_insn "*lt0_disi"
3752 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3753 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3756 "rlwinm %0,%1,1,31,31"
3757 [(set_attr "type" "shift")])
3761 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3762 ; both are an AND so are the same precedence).
3763 (define_insn "*rotl<mode>3_insert"
3764 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3765 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3766 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3767 (match_operand:SI 2 "const_int_operand" "n")])
3768 (match_operand:GPR 3 "const_int_operand" "n"))
3769 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3770 (match_operand:GPR 6 "const_int_operand" "n"))))]
3771 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3772 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3774 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3776 [(set_attr "type" "insert")])
3777 ; FIXME: this needs an attr "size", so that the scheduler can see the
3778 ; difference between rlwimi and rldimi. We also might want dot forms,
3779 ; but not for rlwimi on POWER4 and similar processors.
3781 (define_insn "*rotl<mode>3_insert_2"
3782 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3783 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3784 (match_operand:GPR 6 "const_int_operand" "n"))
3785 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3786 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3787 (match_operand:SI 2 "const_int_operand" "n")])
3788 (match_operand:GPR 3 "const_int_operand" "n"))))]
3789 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3790 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3792 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3794 [(set_attr "type" "insert")])
3796 ; There are also some forms without one of the ANDs.
3797 (define_insn "*rotl<mode>3_insert_3"
3798 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3799 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3800 (match_operand:GPR 4 "const_int_operand" "n"))
3801 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3802 (match_operand:SI 2 "const_int_operand" "n"))))]
3803 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3805 if (<MODE>mode == SImode)
3806 return "rlwimi %0,%1,%h2,0,31-%h2";
3808 return "rldimi %0,%1,%H2,0";
3810 [(set_attr "type" "insert")])
3812 (define_insn "*rotl<mode>3_insert_4"
3813 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3814 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3815 (match_operand:GPR 4 "const_int_operand" "n"))
3816 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3817 (match_operand:SI 2 "const_int_operand" "n"))))]
3818 "<MODE>mode == SImode &&
3819 GET_MODE_PRECISION (<MODE>mode)
3820 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3822 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3823 - INTVAL (operands[2]));
3824 if (<MODE>mode == SImode)
3825 return "rlwimi %0,%1,%h2,32-%h2,31";
3827 return "rldimi %0,%1,%H2,64-%H2";
3829 [(set_attr "type" "insert")])
3832 ; This handles the important case of multiple-precision shifts. There is
3833 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3835 [(set (match_operand:GPR 0 "gpc_reg_operand")
3836 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3837 (match_operand:SI 3 "const_int_operand"))
3838 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3839 (match_operand:SI 4 "const_int_operand"))))]
3840 "can_create_pseudo_p ()
3841 && INTVAL (operands[3]) + INTVAL (operands[4])
3842 >= GET_MODE_PRECISION (<MODE>mode)"
3844 (lshiftrt:GPR (match_dup 2)
3847 (ior:GPR (and:GPR (match_dup 5)
3849 (ashift:GPR (match_dup 1)
3852 unsigned HOST_WIDE_INT mask = 1;
3853 mask = (mask << INTVAL (operands[3])) - 1;
3854 operands[5] = gen_reg_rtx (<MODE>mode);
3855 operands[6] = GEN_INT (mask);
3859 [(set (match_operand:GPR 0 "gpc_reg_operand")
3860 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3861 (match_operand:SI 4 "const_int_operand"))
3862 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3863 (match_operand:SI 3 "const_int_operand"))))]
3864 "can_create_pseudo_p ()
3865 && INTVAL (operands[3]) + INTVAL (operands[4])
3866 >= GET_MODE_PRECISION (<MODE>mode)"
3868 (lshiftrt:GPR (match_dup 2)
3871 (ior:GPR (and:GPR (match_dup 5)
3873 (ashift:GPR (match_dup 1)
3876 unsigned HOST_WIDE_INT mask = 1;
3877 mask = (mask << INTVAL (operands[3])) - 1;
3878 operands[5] = gen_reg_rtx (<MODE>mode);
3879 operands[6] = GEN_INT (mask);
3883 ; Another important case is setting some bits to 1; we can do that with
3884 ; an insert instruction, in many cases.
3885 (define_insn_and_split "*ior<mode>_mask"
3886 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3887 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3888 (match_operand:GPR 2 "const_int_operand" "n")))
3889 (clobber (match_scratch:GPR 3 "=r"))]
3890 "!logical_const_operand (operands[2], <MODE>mode)
3891 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3897 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3900 (and:GPR (match_dup 1)
3904 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3905 if (GET_CODE (operands[3]) == SCRATCH)
3906 operands[3] = gen_reg_rtx (<MODE>mode);
3907 operands[4] = GEN_INT (ne);
3908 operands[5] = GEN_INT (~UINTVAL (operands[2]));
3910 [(set_attr "type" "two")
3911 (set_attr "length" "8")])
3914 ;; Now the simple shifts.
3916 (define_insn "rotl<mode>3"
3917 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3918 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3919 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3921 "rotl<wd>%I2 %0,%1,%<hH>2"
3922 [(set_attr "type" "shift")
3923 (set_attr "maybe_var_shift" "yes")])
3925 (define_insn "*rotlsi3_64"
3926 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3928 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3929 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3931 "rotlw%I2 %0,%1,%h2"
3932 [(set_attr "type" "shift")
3933 (set_attr "maybe_var_shift" "yes")])
3935 (define_insn_and_split "*rotl<mode>3_dot"
3936 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3937 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3938 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3940 (clobber (match_scratch:GPR 0 "=r,r"))]
3941 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3943 rotl<wd>%I2. %0,%1,%<hH>2
3945 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3947 (rotate:GPR (match_dup 1)
3950 (compare:CC (match_dup 0)
3953 [(set_attr "type" "shift")
3954 (set_attr "maybe_var_shift" "yes")
3955 (set_attr "dot" "yes")
3956 (set_attr "length" "4,8")])
3958 (define_insn_and_split "*rotl<mode>3_dot2"
3959 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3960 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3961 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3963 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3964 (rotate:GPR (match_dup 1)
3966 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3968 rotl<wd>%I2. %0,%1,%<hH>2
3970 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3972 (rotate:GPR (match_dup 1)
3975 (compare:CC (match_dup 0)
3978 [(set_attr "type" "shift")
3979 (set_attr "maybe_var_shift" "yes")
3980 (set_attr "dot" "yes")
3981 (set_attr "length" "4,8")])
3984 (define_insn "ashl<mode>3"
3985 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3986 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3987 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3989 "sl<wd>%I2 %0,%1,%<hH>2"
3990 [(set_attr "type" "shift")
3991 (set_attr "maybe_var_shift" "yes")])
3993 (define_insn "*ashlsi3_64"
3994 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3996 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3997 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4000 [(set_attr "type" "shift")
4001 (set_attr "maybe_var_shift" "yes")])
4003 (define_insn_and_split "*ashl<mode>3_dot"
4004 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4005 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4006 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4008 (clobber (match_scratch:GPR 0 "=r,r"))]
4009 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4011 sl<wd>%I2. %0,%1,%<hH>2
4013 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4015 (ashift:GPR (match_dup 1)
4018 (compare:CC (match_dup 0)
4021 [(set_attr "type" "shift")
4022 (set_attr "maybe_var_shift" "yes")
4023 (set_attr "dot" "yes")
4024 (set_attr "length" "4,8")])
4026 (define_insn_and_split "*ashl<mode>3_dot2"
4027 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4028 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4029 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4031 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4032 (ashift:GPR (match_dup 1)
4034 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4036 sl<wd>%I2. %0,%1,%<hH>2
4038 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4040 (ashift:GPR (match_dup 1)
4043 (compare:CC (match_dup 0)
4046 [(set_attr "type" "shift")
4047 (set_attr "maybe_var_shift" "yes")
4048 (set_attr "dot" "yes")
4049 (set_attr "length" "4,8")])
4051 ;; Pretend we have a memory form of extswsli until register allocation is done
4052 ;; so that we use LWZ to load the value from memory, instead of LWA.
4053 (define_insn_and_split "ashdi3_extswsli"
4054 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4056 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4057 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4062 "&& reload_completed && MEM_P (operands[1])"
4066 (ashift:DI (sign_extend:DI (match_dup 3))
4069 operands[3] = gen_lowpart (SImode, operands[0]);
4071 [(set_attr "type" "shift")
4072 (set_attr "maybe_var_shift" "no")])
4075 (define_insn_and_split "ashdi3_extswsli_dot"
4076 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4079 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4080 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4082 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4089 "&& reload_completed
4090 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4091 || memory_operand (operands[1], SImode))"
4094 rtx dest = operands[0];
4095 rtx src = operands[1];
4096 rtx shift = operands[2];
4097 rtx cr = operands[3];
4104 src2 = gen_lowpart (SImode, dest);
4105 emit_move_insn (src2, src);
4108 if (REGNO (cr) == CR0_REGNO)
4110 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4114 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4115 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4118 [(set_attr "type" "shift")
4119 (set_attr "maybe_var_shift" "no")
4120 (set_attr "dot" "yes")
4121 (set_attr "length" "4,8,8,12")])
4123 (define_insn_and_split "ashdi3_extswsli_dot2"
4124 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4127 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4128 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4130 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4131 (ashift:DI (sign_extend:DI (match_dup 1))
4139 "&& reload_completed
4140 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4141 || memory_operand (operands[1], SImode))"
4144 rtx dest = operands[0];
4145 rtx src = operands[1];
4146 rtx shift = operands[2];
4147 rtx cr = operands[3];
4154 src2 = gen_lowpart (SImode, dest);
4155 emit_move_insn (src2, src);
4158 if (REGNO (cr) == CR0_REGNO)
4160 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4164 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4165 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4168 [(set_attr "type" "shift")
4169 (set_attr "maybe_var_shift" "no")
4170 (set_attr "dot" "yes")
4171 (set_attr "length" "4,8,8,12")])
4173 (define_insn "lshr<mode>3"
4174 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4175 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4176 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4178 "sr<wd>%I2 %0,%1,%<hH>2"
4179 [(set_attr "type" "shift")
4180 (set_attr "maybe_var_shift" "yes")])
4182 (define_insn "*lshrsi3_64"
4183 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4185 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4186 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4189 [(set_attr "type" "shift")
4190 (set_attr "maybe_var_shift" "yes")])
4192 (define_insn_and_split "*lshr<mode>3_dot"
4193 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4194 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4195 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4197 (clobber (match_scratch:GPR 0 "=r,r"))]
4198 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4200 sr<wd>%I2. %0,%1,%<hH>2
4202 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4204 (lshiftrt:GPR (match_dup 1)
4207 (compare:CC (match_dup 0)
4210 [(set_attr "type" "shift")
4211 (set_attr "maybe_var_shift" "yes")
4212 (set_attr "dot" "yes")
4213 (set_attr "length" "4,8")])
4215 (define_insn_and_split "*lshr<mode>3_dot2"
4216 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4217 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4218 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4220 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4221 (lshiftrt:GPR (match_dup 1)
4223 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4225 sr<wd>%I2. %0,%1,%<hH>2
4227 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4229 (lshiftrt:GPR (match_dup 1)
4232 (compare:CC (match_dup 0)
4235 [(set_attr "type" "shift")
4236 (set_attr "maybe_var_shift" "yes")
4237 (set_attr "dot" "yes")
4238 (set_attr "length" "4,8")])
4241 (define_insn "ashr<mode>3"
4242 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4243 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4244 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4245 (clobber (reg:GPR CA_REGNO))]
4247 "sra<wd>%I2 %0,%1,%<hH>2"
4248 [(set_attr "type" "shift")
4249 (set_attr "maybe_var_shift" "yes")])
4251 (define_insn "*ashrsi3_64"
4252 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4254 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4255 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4256 (clobber (reg:SI CA_REGNO))]
4259 [(set_attr "type" "shift")
4260 (set_attr "maybe_var_shift" "yes")])
4262 (define_insn_and_split "*ashr<mode>3_dot"
4263 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4264 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4265 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4267 (clobber (match_scratch:GPR 0 "=r,r"))
4268 (clobber (reg:GPR CA_REGNO))]
4269 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4271 sra<wd>%I2. %0,%1,%<hH>2
4273 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4274 [(parallel [(set (match_dup 0)
4275 (ashiftrt:GPR (match_dup 1)
4277 (clobber (reg:GPR CA_REGNO))])
4279 (compare:CC (match_dup 0)
4282 [(set_attr "type" "shift")
4283 (set_attr "maybe_var_shift" "yes")
4284 (set_attr "dot" "yes")
4285 (set_attr "length" "4,8")])
4287 (define_insn_and_split "*ashr<mode>3_dot2"
4288 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4289 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4290 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4292 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4293 (ashiftrt:GPR (match_dup 1)
4295 (clobber (reg:GPR CA_REGNO))]
4296 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4298 sra<wd>%I2. %0,%1,%<hH>2
4300 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4301 [(parallel [(set (match_dup 0)
4302 (ashiftrt:GPR (match_dup 1)
4304 (clobber (reg:GPR CA_REGNO))])
4306 (compare:CC (match_dup 0)
4309 [(set_attr "type" "shift")
4310 (set_attr "maybe_var_shift" "yes")
4311 (set_attr "dot" "yes")
4312 (set_attr "length" "4,8")])
4314 ;; Builtins to replace a division to generate FRE reciprocal estimate
4315 ;; instructions and the necessary fixup instructions
4316 (define_expand "recip<mode>3"
4317 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4318 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4319 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4320 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4322 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4326 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4327 ;; hardware division. This is only done before register allocation and with
4328 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4329 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4330 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4332 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4333 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4334 (match_operand 2 "gpc_reg_operand" "")))]
4335 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4336 && can_create_pseudo_p () && flag_finite_math_only
4337 && !flag_trapping_math && flag_reciprocal_math"
4340 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4344 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4345 ;; appropriate fixup.
4346 (define_expand "rsqrt<mode>2"
4347 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4348 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4349 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4351 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4355 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4356 ;; modes here, and also add in conditional vsx/power8-vector support to access
4357 ;; values in the traditional Altivec registers if the appropriate
4358 ;; -mupper-regs-{df,sf} option is enabled.
4360 (define_expand "abs<mode>2"
4361 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4362 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4363 "TARGET_<MODE>_INSN"
4366 (define_insn "*abs<mode>2_fpr"
4367 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4368 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4373 [(set_attr "type" "fpsimple")
4374 (set_attr "fp_type" "fp_addsub_<Fs>")])
4376 (define_insn "*nabs<mode>2_fpr"
4377 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4380 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4385 [(set_attr "type" "fpsimple")
4386 (set_attr "fp_type" "fp_addsub_<Fs>")])
4388 (define_expand "neg<mode>2"
4389 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4390 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4391 "TARGET_<MODE>_INSN"
4394 (define_insn "*neg<mode>2_fpr"
4395 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4396 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4401 [(set_attr "type" "fpsimple")
4402 (set_attr "fp_type" "fp_addsub_<Fs>")])
4404 (define_expand "add<mode>3"
4405 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4406 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4407 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4408 "TARGET_<MODE>_INSN"
4411 (define_insn "*add<mode>3_fpr"
4412 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4413 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4414 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4417 fadd<Ftrad> %0,%1,%2
4418 xsadd<Fvsx> %x0,%x1,%x2"
4419 [(set_attr "type" "fp")
4420 (set_attr "fp_type" "fp_addsub_<Fs>")])
4422 (define_expand "sub<mode>3"
4423 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4424 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4425 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4426 "TARGET_<MODE>_INSN"
4429 (define_insn "*sub<mode>3_fpr"
4430 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4431 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4432 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4435 fsub<Ftrad> %0,%1,%2
4436 xssub<Fvsx> %x0,%x1,%x2"
4437 [(set_attr "type" "fp")
4438 (set_attr "fp_type" "fp_addsub_<Fs>")])
4440 (define_expand "mul<mode>3"
4441 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4442 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4443 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4444 "TARGET_<MODE>_INSN"
4447 (define_insn "*mul<mode>3_fpr"
4448 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4449 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4450 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4453 fmul<Ftrad> %0,%1,%2
4454 xsmul<Fvsx> %x0,%x1,%x2"
4455 [(set_attr "type" "dmul")
4456 (set_attr "fp_type" "fp_mul_<Fs>")])
4458 (define_expand "div<mode>3"
4459 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4460 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4461 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4462 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4465 (define_insn "*div<mode>3_fpr"
4466 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4467 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4468 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4469 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4471 fdiv<Ftrad> %0,%1,%2
4472 xsdiv<Fvsx> %x0,%x1,%x2"
4473 [(set_attr "type" "<Fs>div")
4474 (set_attr "fp_type" "fp_div_<Fs>")])
4476 (define_insn "*sqrt<mode>2_internal"
4477 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4478 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4479 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4480 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4483 xssqrt<Fvsx> %x0,%x1"
4484 [(set_attr "type" "<Fs>sqrt")
4485 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4487 (define_expand "sqrt<mode>2"
4488 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4489 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4490 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4491 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4493 if (<MODE>mode == SFmode
4494 && TARGET_RECIP_PRECISION
4495 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4496 && !optimize_function_for_size_p (cfun)
4497 && flag_finite_math_only && !flag_trapping_math
4498 && flag_unsafe_math_optimizations)
4500 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4505 ;; Floating point reciprocal approximation
4506 (define_insn "fre<Fs>"
4507 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4508 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4514 [(set_attr "type" "fp")])
4516 (define_insn "*rsqrt<mode>2"
4517 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4518 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4520 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4522 frsqrte<Ftrad> %0,%1
4523 xsrsqrte<Fvsx> %x0,%x1"
4524 [(set_attr "type" "fp")])
4526 ;; Floating point comparisons
4527 (define_insn "*cmp<mode>_fpr"
4528 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4529 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4530 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4534 xscmpudp %0,%x1,%x2"
4535 [(set_attr "type" "fpcompare")])
4537 ;; Floating point conversions
4538 (define_expand "extendsfdf2"
4539 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4540 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4541 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4544 (define_insn_and_split "*extendsfdf2_fpr"
4545 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4546 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4547 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4553 xscpsgndp %x0,%x1,%x1
4556 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4559 emit_note (NOTE_INSN_DELETED);
4562 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4564 (define_expand "truncdfsf2"
4565 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4566 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4567 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4570 (define_insn "*truncdfsf2_fpr"
4571 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4572 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4573 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4577 [(set_attr "type" "fp")])
4579 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4580 ;; builtins.c and optabs.c that are not correct for IBM long double
4581 ;; when little-endian.
4582 (define_expand "signbit<mode>2"
4584 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4586 (subreg:DI (match_dup 2) 0))
4589 (set (match_operand:SI 0 "gpc_reg_operand" "")
4592 && (TARGET_FPRS || TARGET_E500_DOUBLE)
4593 && (!FLOAT128_IEEE_P (<MODE>mode)
4594 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4596 if (FLOAT128_IEEE_P (<MODE>mode))
4598 if (<MODE>mode == KFmode)
4599 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4600 else if (<MODE>mode == TFmode)
4601 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4606 operands[2] = gen_reg_rtx (DFmode);
4607 operands[3] = gen_reg_rtx (DImode);
4608 if (TARGET_POWERPC64)
4610 operands[4] = gen_reg_rtx (DImode);
4611 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4612 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4613 WORDS_BIG_ENDIAN ? 4 : 0);
4617 operands[4] = gen_reg_rtx (SImode);
4618 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4619 WORDS_BIG_ENDIAN ? 0 : 4);
4620 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4624 (define_expand "copysign<mode>3"
4626 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4628 (neg:SFDF (abs:SFDF (match_dup 1))))
4629 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4630 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4634 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4635 && ((TARGET_PPC_GFXOPT
4636 && !HONOR_NANS (<MODE>mode)
4637 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4639 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4641 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4643 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4648 operands[3] = gen_reg_rtx (<MODE>mode);
4649 operands[4] = gen_reg_rtx (<MODE>mode);
4650 operands[5] = CONST0_RTX (<MODE>mode);
4653 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4655 (define_insn_and_split "signbit<mode>2_dm"
4656 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4658 [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,m,r")]
4660 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4662 "&& reload_completed"
4665 rs6000_split_signbit (operands[0], operands[1]);
4668 [(set_attr "length" "8,8,12")
4669 (set_attr "type" "mftgpr,load,integer")])
4671 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4672 ;; point types, which makes normal SUBREG's problematical. Instead use a
4673 ;; special pattern to avoid using a normal movdi.
4674 (define_insn "signbit<mode>2_dm2"
4675 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4676 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
4679 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4681 [(set_attr "type" "mftgpr")])
4684 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4685 ;; compiler from optimizing -0.0
4686 (define_insn "copysign<mode>3_fcpsgn"
4687 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4688 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4689 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4691 "TARGET_<MODE>_FPR && TARGET_CMPB"
4694 xscpsgndp %x0,%x2,%x1"
4695 [(set_attr "type" "fpsimple")])
4697 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4698 ;; fsel instruction and some auxiliary computations. Then we just have a
4699 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4701 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4702 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4703 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4704 ;; define_splits to make them if made by combine. On VSX machines we have the
4705 ;; min/max instructions.
4707 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4708 ;; to allow either DF/SF to use only traditional registers.
4710 (define_expand "s<minmax><mode>3"
4711 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4712 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4713 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4714 "TARGET_MINMAX_<MODE>"
4716 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4720 (define_insn "*s<minmax><mode>3_vsx"
4721 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4722 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4723 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4724 "TARGET_VSX && TARGET_<MODE>_FPR"
4726 return (TARGET_P9_MINMAX
4727 ? "xs<minmax>cdp %x0,%x1,%x2"
4728 : "xs<minmax>dp %x0,%x1,%x2");
4730 [(set_attr "type" "fp")])
4732 ;; The conditional move instructions allow us to perform max and min operations
4733 ;; even when we don't have the appropriate max/min instruction using the FSEL
4736 (define_insn_and_split "*s<minmax><mode>3_fpr"
4737 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4738 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4739 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4740 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4745 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4749 (define_expand "mov<mode>cc"
4750 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4751 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4752 (match_operand:GPR 2 "gpc_reg_operand" "")
4753 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4757 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4763 ;; We use the BASE_REGS for the isel input operands because, if rA is
4764 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4765 ;; because we may switch the operands and rB may end up being rA.
4767 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4768 ;; leave out the mode in operand 4 and use one pattern, but reload can
4769 ;; change the mode underneath our feet and then gets confused trying
4770 ;; to reload the value.
4771 (define_insn "isel_signed_<mode>"
4772 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4774 (match_operator 1 "scc_comparison_operator"
4775 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4777 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4778 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4781 { return output_isel (operands); }"
4782 [(set_attr "type" "isel")
4783 (set_attr "length" "4")])
4785 (define_insn "isel_unsigned_<mode>"
4786 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4788 (match_operator 1 "scc_comparison_operator"
4789 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4791 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4792 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4795 { return output_isel (operands); }"
4796 [(set_attr "type" "isel")
4797 (set_attr "length" "4")])
4799 ;; These patterns can be useful for combine; they let combine know that
4800 ;; isel can handle reversed comparisons so long as the operands are
4803 (define_insn "*isel_reversed_signed_<mode>"
4804 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4806 (match_operator 1 "scc_rev_comparison_operator"
4807 [(match_operand:CC 4 "cc_reg_operand" "y")
4809 (match_operand:GPR 2 "gpc_reg_operand" "b")
4810 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4813 { return output_isel (operands); }"
4814 [(set_attr "type" "isel")
4815 (set_attr "length" "4")])
4817 (define_insn "*isel_reversed_unsigned_<mode>"
4818 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4820 (match_operator 1 "scc_rev_comparison_operator"
4821 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4823 (match_operand:GPR 2 "gpc_reg_operand" "b")
4824 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4827 { return output_isel (operands); }"
4828 [(set_attr "type" "isel")
4829 (set_attr "length" "4")])
4831 ;; Floating point conditional move
4832 (define_expand "mov<mode>cc"
4833 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4834 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4835 (match_operand:SFDF 2 "gpc_reg_operand" "")
4836 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4837 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4840 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4846 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4847 [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4849 (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4850 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4851 (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4852 (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4853 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4855 [(set_attr "type" "fp")])
4857 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4858 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4860 (match_operator:CCFP 1 "fpmask_comparison_operator"
4861 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4862 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4863 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4864 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4865 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4870 (if_then_else:V2DI (match_dup 1)
4874 (if_then_else:SFDF (ne (match_dup 6)
4879 if (GET_CODE (operands[6]) == SCRATCH)
4880 operands[6] = gen_reg_rtx (V2DImode);
4882 operands[7] = CONSTM1_RTX (V2DImode);
4883 operands[8] = CONST0_RTX (V2DImode);
4885 [(set_attr "length" "8")
4886 (set_attr "type" "vecperm")])
4888 ;; Handle inverting the fpmask comparisons.
4889 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
4890 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4892 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
4893 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4894 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4895 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4896 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4897 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4902 (if_then_else:V2DI (match_dup 9)
4906 (if_then_else:SFDF (ne (match_dup 6)
4911 rtx op1 = operands[1];
4912 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
4914 if (GET_CODE (operands[6]) == SCRATCH)
4915 operands[6] = gen_reg_rtx (V2DImode);
4917 operands[7] = CONSTM1_RTX (V2DImode);
4918 operands[8] = CONST0_RTX (V2DImode);
4920 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
4922 [(set_attr "length" "8")
4923 (set_attr "type" "vecperm")])
4925 (define_insn "*fpmask<mode>"
4926 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
4928 (match_operator:CCFP 1 "fpmask_comparison_operator"
4929 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
4930 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
4931 (match_operand:V2DI 4 "all_ones_constant" "")
4932 (match_operand:V2DI 5 "zero_constant" "")))]
4934 "xscmp%V1dp %x0,%x2,%x3"
4935 [(set_attr "type" "fpcompare")])
4937 (define_insn "*xxsel<mode>"
4938 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4939 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
4940 (match_operand:V2DI 2 "zero_constant" ""))
4941 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
4942 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
4944 "xxsel %x0,%x4,%x3,%x1"
4945 [(set_attr "type" "vecmove")])
4948 ;; Conversions to and from floating-point.
4950 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4951 ; don't want to support putting SImode in FPR registers.
4952 (define_insn "lfiwax"
4953 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
4954 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
4956 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4962 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
4964 ; This split must be run before register allocation because it allocates the
4965 ; memory slot that is needed to move values to/from the FPR. We don't allocate
4966 ; it earlier to allow for the combiner to merge insns together where it might
4967 ; not be needed and also in case the insns are deleted as dead code.
4969 (define_insn_and_split "floatsi<mode>2_lfiwax"
4970 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4971 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4972 (clobber (match_scratch:DI 2 "=wi"))]
4973 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4974 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4980 rtx dest = operands[0];
4981 rtx src = operands[1];
4984 if (!MEM_P (src) && TARGET_POWERPC64
4985 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4986 tmp = convert_to_mode (DImode, src, false);
4990 if (GET_CODE (tmp) == SCRATCH)
4991 tmp = gen_reg_rtx (DImode);
4994 src = rs6000_address_for_fpconvert (src);
4995 emit_insn (gen_lfiwax (tmp, src));
4999 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5000 emit_move_insn (stack, src);
5001 emit_insn (gen_lfiwax (tmp, stack));
5004 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5007 [(set_attr "length" "12")
5008 (set_attr "type" "fpload")])
5010 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5011 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5014 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5015 (clobber (match_scratch:DI 2 "=wi"))]
5016 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5023 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5024 if (GET_CODE (operands[2]) == SCRATCH)
5025 operands[2] = gen_reg_rtx (DImode);
5026 if (TARGET_VSX_SMALL_INTEGER)
5027 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5029 emit_insn (gen_lfiwax (operands[2], operands[1]));
5030 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5033 [(set_attr "length" "8")
5034 (set_attr "type" "fpload")])
5036 (define_insn "lfiwzx"
5037 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5038 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5040 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5045 xxextractuw %x0,%x1,1"
5046 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5048 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5049 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5050 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5051 (clobber (match_scratch:DI 2 "=wi"))]
5052 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5059 rtx dest = operands[0];
5060 rtx src = operands[1];
5063 if (!MEM_P (src) && TARGET_POWERPC64
5064 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5065 tmp = convert_to_mode (DImode, src, true);
5069 if (GET_CODE (tmp) == SCRATCH)
5070 tmp = gen_reg_rtx (DImode);
5073 src = rs6000_address_for_fpconvert (src);
5074 emit_insn (gen_lfiwzx (tmp, src));
5078 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5079 emit_move_insn (stack, src);
5080 emit_insn (gen_lfiwzx (tmp, stack));
5083 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5086 [(set_attr "length" "12")
5087 (set_attr "type" "fpload")])
5089 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5090 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5091 (unsigned_float:SFDF
5093 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5094 (clobber (match_scratch:DI 2 "=wi"))]
5095 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5102 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5103 if (GET_CODE (operands[2]) == SCRATCH)
5104 operands[2] = gen_reg_rtx (DImode);
5105 if (TARGET_VSX_SMALL_INTEGER)
5106 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5108 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5109 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5112 [(set_attr "length" "8")
5113 (set_attr "type" "fpload")])
5115 ; For each of these conversions, there is a define_expand, a define_insn
5116 ; with a '#' template, and a define_split (with C code). The idea is
5117 ; to allow constant folding with the template of the define_insn,
5118 ; then to have the insns split later (between sched1 and final).
5120 (define_expand "floatsidf2"
5121 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5122 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5125 (clobber (match_dup 4))
5126 (clobber (match_dup 5))
5127 (clobber (match_dup 6))])]
5129 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5132 if (TARGET_E500_DOUBLE)
5134 if (!REG_P (operands[1]))
5135 operands[1] = force_reg (SImode, operands[1]);
5136 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5139 else if (TARGET_LFIWAX && TARGET_FCFID)
5141 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5144 else if (TARGET_FCFID)
5146 rtx dreg = operands[1];
5148 dreg = force_reg (SImode, dreg);
5149 dreg = convert_to_mode (DImode, dreg, false);
5150 emit_insn (gen_floatdidf2 (operands[0], dreg));
5154 if (!REG_P (operands[1]))
5155 operands[1] = force_reg (SImode, operands[1]);
5156 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5157 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5158 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5159 operands[5] = gen_reg_rtx (DFmode);
5160 operands[6] = gen_reg_rtx (SImode);
5163 (define_insn_and_split "*floatsidf2_internal"
5164 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5165 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5166 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5167 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5168 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5169 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5170 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5171 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5177 rtx lowword, highword;
5178 gcc_assert (MEM_P (operands[4]));
5179 highword = adjust_address (operands[4], SImode, 0);
5180 lowword = adjust_address (operands[4], SImode, 4);
5181 if (! WORDS_BIG_ENDIAN)
5182 std::swap (lowword, highword);
5184 emit_insn (gen_xorsi3 (operands[6], operands[1],
5185 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5186 emit_move_insn (lowword, operands[6]);
5187 emit_move_insn (highword, operands[2]);
5188 emit_move_insn (operands[5], operands[4]);
5189 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5192 [(set_attr "length" "24")
5193 (set_attr "type" "fp")])
5195 ;; If we don't have a direct conversion to single precision, don't enable this
5196 ;; conversion for 32-bit without fast math, because we don't have the insn to
5197 ;; generate the fixup swizzle to avoid double rounding problems.
5198 (define_expand "floatunssisf2"
5199 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5200 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5201 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5204 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5205 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5206 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5211 if (!REG_P (operands[1]))
5212 operands[1] = force_reg (SImode, operands[1]);
5214 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5216 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5221 rtx dreg = operands[1];
5223 dreg = force_reg (SImode, dreg);
5224 dreg = convert_to_mode (DImode, dreg, true);
5225 emit_insn (gen_floatdisf2 (operands[0], dreg));
5230 (define_expand "floatunssidf2"
5231 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5232 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5235 (clobber (match_dup 4))
5236 (clobber (match_dup 5))])]
5238 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5241 if (TARGET_E500_DOUBLE)
5243 if (!REG_P (operands[1]))
5244 operands[1] = force_reg (SImode, operands[1]);
5245 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5248 else if (TARGET_LFIWZX && TARGET_FCFID)
5250 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5253 else if (TARGET_FCFID)
5255 rtx dreg = operands[1];
5257 dreg = force_reg (SImode, dreg);
5258 dreg = convert_to_mode (DImode, dreg, true);
5259 emit_insn (gen_floatdidf2 (operands[0], dreg));
5263 if (!REG_P (operands[1]))
5264 operands[1] = force_reg (SImode, operands[1]);
5265 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5266 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5267 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5268 operands[5] = gen_reg_rtx (DFmode);
5271 (define_insn_and_split "*floatunssidf2_internal"
5272 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5273 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5274 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5275 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5276 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5277 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5278 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5279 && !(TARGET_FCFID && TARGET_POWERPC64)"
5285 rtx lowword, highword;
5286 gcc_assert (MEM_P (operands[4]));
5287 highword = adjust_address (operands[4], SImode, 0);
5288 lowword = adjust_address (operands[4], SImode, 4);
5289 if (! WORDS_BIG_ENDIAN)
5290 std::swap (lowword, highword);
5292 emit_move_insn (lowword, operands[1]);
5293 emit_move_insn (highword, operands[2]);
5294 emit_move_insn (operands[5], operands[4]);
5295 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5298 [(set_attr "length" "20")
5299 (set_attr "type" "fp")])
5301 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5302 ;; vector registers. At the moment, QI/HImode are not allowed in floating
5303 ;; point or vector registers, so we use UNSPEC's to use the load byte and
5304 ;; half-word instructions.
5306 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5307 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5309 (match_operand:QHI 1 "input_operand")))
5310 (clobber (match_scratch:DI 2))
5311 (clobber (match_scratch:DI 3))])]
5312 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5314 if (MEM_P (operands[1]))
5315 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5318 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5319 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5321 (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5322 (clobber (match_scratch:DI 2 "=wi,v"))
5323 (clobber (match_scratch:DI 3 "=r,X"))]
5324 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5325 && TARGET_UPPER_REGS_DI"
5327 "&& reload_completed"
5330 rtx result = operands[0];
5331 rtx input = operands[1];
5332 rtx di = operands[2];
5336 rtx tmp = operands[3];
5337 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5338 emit_move_insn (di, tmp);
5345 emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5347 if (<MODE>mode == QImode)
5349 else if (<MODE>mode == HImode)
5354 di_vector = gen_rtx_REG (vmode, REGNO (di));
5355 emit_insn (gen_vsx_sign_extend_<QHI:mode>_di (di, di_vector));
5358 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5362 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5363 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "")
5364 (unsigned_float:FP_ISA3
5365 (match_operand:QHI 1 "input_operand" "")))
5366 (clobber (match_scratch:DI 2 ""))
5367 (clobber (match_scratch:DI 3 ""))])]
5368 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5370 if (MEM_P (operands[1]))
5371 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5374 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5375 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5376 (unsigned_float:FP_ISA3
5377 (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5378 (clobber (match_scratch:DI 2 "=wi,wi"))
5379 (clobber (match_scratch:DI 3 "=r,X"))]
5380 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5382 "&& reload_completed"
5385 rtx result = operands[0];
5386 rtx input = operands[1];
5387 rtx di = operands[2];
5388 rtx tmp = operands[3];
5392 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5393 emit_move_insn (di, tmp);
5396 emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5398 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5402 (define_expand "fix_trunc<mode>si2"
5403 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5404 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5405 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5408 if (!<E500_CONVERT>)
5410 rtx src = force_reg (<MODE>mode, operands[1]);
5413 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5416 rtx tmp = gen_reg_rtx (DImode);
5417 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5418 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5425 ; Like the convert to float patterns, this insn must be split before
5426 ; register allocation so that it can allocate the memory slot if it
5428 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5429 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5430 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5431 (clobber (match_scratch:DI 2 "=d"))]
5432 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5433 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5434 && TARGET_STFIWX && can_create_pseudo_p ()"
5439 rtx dest = operands[0];
5440 rtx src = operands[1];
5441 rtx tmp = operands[2];
5443 if (GET_CODE (tmp) == SCRATCH)
5444 tmp = gen_reg_rtx (DImode);
5446 emit_insn (gen_fctiwz_<mode> (tmp, src));
5449 dest = rs6000_address_for_fpconvert (dest);
5450 emit_insn (gen_stfiwx (dest, tmp));
5453 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5455 dest = gen_lowpart (DImode, dest);
5456 emit_move_insn (dest, tmp);
5461 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5462 emit_insn (gen_stfiwx (stack, tmp));
5463 emit_move_insn (dest, stack);
5467 [(set_attr "length" "12")
5468 (set_attr "type" "fp")])
5470 (define_insn_and_split "fix_trunc<mode>si2_internal"
5471 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5472 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5473 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5474 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5475 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5482 gcc_assert (MEM_P (operands[3]));
5483 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5485 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5486 emit_move_insn (operands[3], operands[2]);
5487 emit_move_insn (operands[0], lowword);
5490 [(set_attr "length" "16")
5491 (set_attr "type" "fp")])
5493 (define_expand "fix_trunc<mode>di2"
5494 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5495 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5496 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5500 (define_insn "*fix_trunc<mode>di2_fctidz"
5501 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5502 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5503 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5508 [(set_attr "type" "fp")])
5510 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5511 [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5512 (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5513 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5515 rtx op0 = operands[0];
5516 rtx op1 = operands[1];
5517 rtx di_tmp = gen_reg_rtx (DImode);
5520 op0 = rs6000_address_for_fpconvert (op0);
5522 emit_insn (gen_fctiwz_<SFDF:mode> (di_tmp, op1));
5523 emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5527 (define_expand "fixuns_trunc<mode>si2"
5528 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5529 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5531 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5535 if (!<E500_CONVERT>)
5537 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5542 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5543 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5544 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5545 (clobber (match_scratch:DI 2 "=d"))]
5546 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5547 && TARGET_STFIWX && can_create_pseudo_p ()"
5552 rtx dest = operands[0];
5553 rtx src = operands[1];
5554 rtx tmp = operands[2];
5556 if (GET_CODE (tmp) == SCRATCH)
5557 tmp = gen_reg_rtx (DImode);
5559 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5562 dest = rs6000_address_for_fpconvert (dest);
5563 emit_insn (gen_stfiwx (dest, tmp));
5566 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5568 dest = gen_lowpart (DImode, dest);
5569 emit_move_insn (dest, tmp);
5574 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5575 emit_insn (gen_stfiwx (stack, tmp));
5576 emit_move_insn (dest, stack);
5580 [(set_attr "length" "12")
5581 (set_attr "type" "fp")])
5583 (define_expand "fixuns_trunc<mode>di2"
5584 [(set (match_operand:DI 0 "register_operand" "")
5585 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5586 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5589 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5590 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5591 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5592 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5597 [(set_attr "type" "fp")])
5599 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5600 [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5601 (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5602 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5604 rtx op0 = operands[0];
5605 rtx op1 = operands[1];
5606 rtx di_tmp = gen_reg_rtx (DImode);
5609 op0 = rs6000_address_for_fpconvert (op0);
5611 emit_insn (gen_fctiwuz_<SFDF:mode> (di_tmp, op1));
5612 emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5616 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5617 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5618 ; because the first makes it clear that operand 0 is not live
5619 ; before the instruction.
5620 (define_insn "fctiwz_<mode>"
5621 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5622 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5624 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5628 [(set_attr "type" "fp")])
5630 (define_insn "fctiwuz_<mode>"
5631 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5632 (unspec:DI [(unsigned_fix:SI
5633 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5635 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5639 [(set_attr "type" "fp")])
5641 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5642 ;; since the friz instruction does not truncate the value if the floating
5643 ;; point value is < LONG_MIN or > LONG_MAX.
5644 (define_insn "*friz"
5645 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5646 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5647 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5648 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5652 [(set_attr "type" "fp")])
5654 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5655 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5656 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5657 ;; extend it, store it back on the stack from the GPR, load it back into the
5658 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5659 ;; disable using store and load to sign/zero extend the value.
5660 (define_insn_and_split "*round32<mode>2_fprs"
5661 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5663 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5664 (clobber (match_scratch:DI 2 "=d"))
5665 (clobber (match_scratch:DI 3 "=d"))]
5666 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5667 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5668 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5673 rtx dest = operands[0];
5674 rtx src = operands[1];
5675 rtx tmp1 = operands[2];
5676 rtx tmp2 = operands[3];
5677 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5679 if (GET_CODE (tmp1) == SCRATCH)
5680 tmp1 = gen_reg_rtx (DImode);
5681 if (GET_CODE (tmp2) == SCRATCH)
5682 tmp2 = gen_reg_rtx (DImode);
5684 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5685 emit_insn (gen_stfiwx (stack, tmp1));
5686 emit_insn (gen_lfiwax (tmp2, stack));
5687 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5690 [(set_attr "type" "fpload")
5691 (set_attr "length" "16")])
5693 (define_insn_and_split "*roundu32<mode>2_fprs"
5694 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5695 (unsigned_float:SFDF
5696 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5697 (clobber (match_scratch:DI 2 "=d"))
5698 (clobber (match_scratch:DI 3 "=d"))]
5699 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5700 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5701 && can_create_pseudo_p ()"
5706 rtx dest = operands[0];
5707 rtx src = operands[1];
5708 rtx tmp1 = operands[2];
5709 rtx tmp2 = operands[3];
5710 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5712 if (GET_CODE (tmp1) == SCRATCH)
5713 tmp1 = gen_reg_rtx (DImode);
5714 if (GET_CODE (tmp2) == SCRATCH)
5715 tmp2 = gen_reg_rtx (DImode);
5717 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5718 emit_insn (gen_stfiwx (stack, tmp1));
5719 emit_insn (gen_lfiwzx (tmp2, stack));
5720 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5723 [(set_attr "type" "fpload")
5724 (set_attr "length" "16")])
5726 ;; No VSX equivalent to fctid
5727 (define_insn "lrint<mode>di2"
5728 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5729 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5731 "TARGET_<MODE>_FPR && TARGET_FPRND"
5733 [(set_attr "type" "fp")])
5735 (define_insn "btrunc<mode>2"
5736 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5737 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5739 "TARGET_<MODE>_FPR && TARGET_FPRND"
5743 [(set_attr "type" "fp")
5744 (set_attr "fp_type" "fp_addsub_<Fs>")])
5746 (define_insn "ceil<mode>2"
5747 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5748 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5750 "TARGET_<MODE>_FPR && TARGET_FPRND"
5754 [(set_attr "type" "fp")
5755 (set_attr "fp_type" "fp_addsub_<Fs>")])
5757 (define_insn "floor<mode>2"
5758 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5759 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5761 "TARGET_<MODE>_FPR && TARGET_FPRND"
5765 [(set_attr "type" "fp")
5766 (set_attr "fp_type" "fp_addsub_<Fs>")])
5768 ;; No VSX equivalent to frin
5769 (define_insn "round<mode>2"
5770 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5771 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5773 "TARGET_<MODE>_FPR && TARGET_FPRND"
5775 [(set_attr "type" "fp")
5776 (set_attr "fp_type" "fp_addsub_<Fs>")])
5778 (define_insn "*xsrdpi<mode>2"
5779 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5780 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5782 "TARGET_<MODE>_FPR && TARGET_VSX"
5784 [(set_attr "type" "fp")
5785 (set_attr "fp_type" "fp_addsub_<Fs>")])
5787 (define_expand "lround<mode>di2"
5789 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5791 (set (match_operand:DI 0 "gpc_reg_operand" "")
5792 (unspec:DI [(match_dup 2)]
5794 "TARGET_<MODE>_FPR && TARGET_VSX"
5796 operands[2] = gen_reg_rtx (<MODE>mode);
5799 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5800 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5801 ; is only generated for Power8 or later.
5802 (define_insn "stfiwx"
5803 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5804 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5810 [(set_attr "type" "fpstore")])
5812 ;; If we don't have a direct conversion to single precision, don't enable this
5813 ;; conversion for 32-bit without fast math, because we don't have the insn to
5814 ;; generate the fixup swizzle to avoid double rounding problems.
5815 (define_expand "floatsisf2"
5816 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5817 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5818 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5821 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5822 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5823 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5828 if (!REG_P (operands[1]))
5829 operands[1] = force_reg (SImode, operands[1]);
5831 else if (TARGET_FCFIDS && TARGET_LFIWAX)
5833 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5836 else if (TARGET_FCFID && TARGET_LFIWAX)
5838 rtx dfreg = gen_reg_rtx (DFmode);
5839 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5840 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5845 rtx dreg = operands[1];
5847 dreg = force_reg (SImode, dreg);
5848 dreg = convert_to_mode (DImode, dreg, false);
5849 emit_insn (gen_floatdisf2 (operands[0], dreg));
5854 (define_expand "floatdidf2"
5855 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5856 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5857 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5860 (define_insn "*floatdidf2_fpr"
5861 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5862 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5863 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5867 [(set_attr "type" "fp")])
5869 ; Allow the combiner to merge source memory operands to the conversion so that
5870 ; the optimizer/register allocator doesn't try to load the value too early in a
5871 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5872 ; hit. We will split after reload to avoid the trip through the GPRs
5874 (define_insn_and_split "*floatdidf2_mem"
5875 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5876 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5877 (clobber (match_scratch:DI 2 "=d,wi"))]
5878 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5880 "&& reload_completed"
5881 [(set (match_dup 2) (match_dup 1))
5882 (set (match_dup 0) (float:DF (match_dup 2)))]
5884 [(set_attr "length" "8")
5885 (set_attr "type" "fpload")])
5887 (define_expand "floatunsdidf2"
5888 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5890 (match_operand:DI 1 "gpc_reg_operand" "")))]
5891 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5894 (define_insn "*floatunsdidf2_fcfidu"
5895 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5896 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5897 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5901 [(set_attr "type" "fp")
5902 (set_attr "length" "4")])
5904 (define_insn_and_split "*floatunsdidf2_mem"
5905 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5906 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5907 (clobber (match_scratch:DI 2 "=d,wi"))]
5908 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5910 "&& reload_completed"
5911 [(set (match_dup 2) (match_dup 1))
5912 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5914 [(set_attr "length" "8")
5915 (set_attr "type" "fpload")])
5917 (define_expand "floatdisf2"
5918 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5919 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5920 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5921 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5926 rtx val = operands[1];
5927 if (!flag_unsafe_math_optimizations)
5929 rtx label = gen_label_rtx ();
5930 val = gen_reg_rtx (DImode);
5931 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5934 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5939 (define_insn "floatdisf2_fcfids"
5940 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5941 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5942 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5943 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5947 [(set_attr "type" "fp")])
5949 (define_insn_and_split "*floatdisf2_mem"
5950 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5951 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5952 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5953 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5954 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5956 "&& reload_completed"
5960 emit_move_insn (operands[2], operands[1]);
5961 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5964 [(set_attr "length" "8")])
5966 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5967 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5968 ;; from double rounding.
5969 ;; Instead of creating a new cpu type for two FP operations, just use fp
5970 (define_insn_and_split "floatdisf2_internal1"
5971 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5972 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5973 (clobber (match_scratch:DF 2 "=d"))]
5974 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5977 "&& reload_completed"
5979 (float:DF (match_dup 1)))
5981 (float_truncate:SF (match_dup 2)))]
5983 [(set_attr "length" "8")
5984 (set_attr "type" "fp")])
5986 ;; Twiddles bits to avoid double rounding.
5987 ;; Bits that might be truncated when converting to DFmode are replaced
5988 ;; by a bit that won't be lost at that stage, but is below the SFmode
5989 ;; rounding position.
5990 (define_expand "floatdisf2_internal2"
5991 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5993 (clobber (reg:DI CA_REGNO))])
5994 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5996 (set (match_dup 3) (plus:DI (match_dup 3)
5998 (set (match_dup 0) (plus:DI (match_dup 0)
6000 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6002 (set (match_dup 0) (ior:DI (match_dup 0)
6004 (set (match_dup 0) (and:DI (match_dup 0)
6006 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6007 (label_ref (match_operand:DI 2 "" ""))
6009 (set (match_dup 0) (match_dup 1))]
6010 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6014 operands[3] = gen_reg_rtx (DImode);
6015 operands[4] = gen_reg_rtx (CCUNSmode);
6018 (define_expand "floatunsdisf2"
6019 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6020 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6021 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6022 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6025 (define_insn "floatunsdisf2_fcfidus"
6026 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6027 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6028 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6029 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6033 [(set_attr "type" "fp")])
6035 (define_insn_and_split "*floatunsdisf2_mem"
6036 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6037 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6038 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6039 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6040 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6042 "&& reload_completed"
6046 emit_move_insn (operands[2], operands[1]);
6047 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6050 [(set_attr "length" "8")
6051 (set_attr "type" "fpload")])
6053 ;; Define the TImode operations that can be done in a small number
6054 ;; of instructions. The & constraints are to prevent the register
6055 ;; allocator from allocating registers that overlap with the inputs
6056 ;; (for example, having an input in 7,8 and an output in 6,7). We
6057 ;; also allow for the output being the same as one of the inputs.
6059 (define_expand "addti3"
6060 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6061 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6062 (match_operand:TI 2 "reg_or_short_operand" "")))]
6065 rtx lo0 = gen_lowpart (DImode, operands[0]);
6066 rtx lo1 = gen_lowpart (DImode, operands[1]);
6067 rtx lo2 = gen_lowpart (DImode, operands[2]);
6068 rtx hi0 = gen_highpart (DImode, operands[0]);
6069 rtx hi1 = gen_highpart (DImode, operands[1]);
6070 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6072 if (!reg_or_short_operand (lo2, DImode))
6073 lo2 = force_reg (DImode, lo2);
6074 if (!adde_operand (hi2, DImode))
6075 hi2 = force_reg (DImode, hi2);
6077 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6078 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6082 (define_expand "subti3"
6083 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6084 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6085 (match_operand:TI 2 "gpc_reg_operand" "")))]
6088 rtx lo0 = gen_lowpart (DImode, operands[0]);
6089 rtx lo1 = gen_lowpart (DImode, operands[1]);
6090 rtx lo2 = gen_lowpart (DImode, operands[2]);
6091 rtx hi0 = gen_highpart (DImode, operands[0]);
6092 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6093 rtx hi2 = gen_highpart (DImode, operands[2]);
6095 if (!reg_or_short_operand (lo1, DImode))
6096 lo1 = force_reg (DImode, lo1);
6097 if (!adde_operand (hi1, DImode))
6098 hi1 = force_reg (DImode, hi1);
6100 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6101 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6105 ;; 128-bit logical operations expanders
6107 (define_expand "and<mode>3"
6108 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6109 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6110 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6114 (define_expand "ior<mode>3"
6115 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6116 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6117 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6121 (define_expand "xor<mode>3"
6122 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6123 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6124 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6128 (define_expand "one_cmpl<mode>2"
6129 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6130 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6134 (define_expand "nor<mode>3"
6135 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6137 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6138 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6142 (define_expand "andc<mode>3"
6143 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6145 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6146 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6150 ;; Power8 vector logical instructions.
6151 (define_expand "eqv<mode>3"
6152 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6154 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6155 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6156 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6159 ;; Rewrite nand into canonical form
6160 (define_expand "nand<mode>3"
6161 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6163 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6164 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6165 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6168 ;; The canonical form is to have the negated element first, so we need to
6169 ;; reverse arguments.
6170 (define_expand "orc<mode>3"
6171 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6173 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6174 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6175 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6178 ;; 128-bit logical operations insns and split operations
6179 (define_insn_and_split "*and<mode>3_internal"
6180 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6182 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6183 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6186 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6187 return "xxland %x0,%x1,%x2";
6189 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6190 return "vand %0,%1,%2";
6194 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6197 rs6000_split_logical (operands, AND, false, false, false);
6202 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6203 (const_string "veclogical")
6204 (const_string "integer")))
6205 (set (attr "length")
6207 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6210 (match_test "TARGET_POWERPC64")
6212 (const_string "16"))))])
6215 (define_insn_and_split "*bool<mode>3_internal"
6216 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6217 (match_operator:BOOL_128 3 "boolean_or_operator"
6218 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6219 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6222 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6223 return "xxl%q3 %x0,%x1,%x2";
6225 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6226 return "v%q3 %0,%1,%2";
6230 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6233 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6238 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6239 (const_string "veclogical")
6240 (const_string "integer")))
6241 (set (attr "length")
6243 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6246 (match_test "TARGET_POWERPC64")
6248 (const_string "16"))))])
6251 (define_insn_and_split "*boolc<mode>3_internal1"
6252 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6253 (match_operator:BOOL_128 3 "boolean_operator"
6255 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6256 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6257 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6259 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6260 return "xxl%q3 %x0,%x1,%x2";
6262 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6263 return "v%q3 %0,%1,%2";
6267 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6268 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6271 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6276 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6277 (const_string "veclogical")
6278 (const_string "integer")))
6279 (set (attr "length")
6281 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6284 (match_test "TARGET_POWERPC64")
6286 (const_string "16"))))])
6288 (define_insn_and_split "*boolc<mode>3_internal2"
6289 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6290 (match_operator:TI2 3 "boolean_operator"
6292 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6293 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6294 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6296 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6299 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6302 [(set_attr "type" "integer")
6303 (set (attr "length")
6305 (match_test "TARGET_POWERPC64")
6307 (const_string "16")))])
6310 (define_insn_and_split "*boolcc<mode>3_internal1"
6311 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6312 (match_operator:BOOL_128 3 "boolean_operator"
6314 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6316 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6317 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6319 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6320 return "xxl%q3 %x0,%x1,%x2";
6322 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6323 return "v%q3 %0,%1,%2";
6327 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6328 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6331 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6336 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6337 (const_string "veclogical")
6338 (const_string "integer")))
6339 (set (attr "length")
6341 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6344 (match_test "TARGET_POWERPC64")
6346 (const_string "16"))))])
6348 (define_insn_and_split "*boolcc<mode>3_internal2"
6349 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6350 (match_operator:TI2 3 "boolean_operator"
6352 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6354 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6355 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6357 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6360 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6363 [(set_attr "type" "integer")
6364 (set (attr "length")
6366 (match_test "TARGET_POWERPC64")
6368 (const_string "16")))])
6372 (define_insn_and_split "*eqv<mode>3_internal1"
6373 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6376 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6377 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6380 if (vsx_register_operand (operands[0], <MODE>mode))
6381 return "xxleqv %x0,%x1,%x2";
6385 "TARGET_P8_VECTOR && reload_completed
6386 && int_reg_operand (operands[0], <MODE>mode)"
6389 rs6000_split_logical (operands, XOR, true, false, false);
6394 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6395 (const_string "veclogical")
6396 (const_string "integer")))
6397 (set (attr "length")
6399 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6402 (match_test "TARGET_POWERPC64")
6404 (const_string "16"))))])
6406 (define_insn_and_split "*eqv<mode>3_internal2"
6407 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6410 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6411 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6414 "reload_completed && !TARGET_P8_VECTOR"
6417 rs6000_split_logical (operands, XOR, true, false, false);
6420 [(set_attr "type" "integer")
6421 (set (attr "length")
6423 (match_test "TARGET_POWERPC64")
6425 (const_string "16")))])
6427 ;; 128-bit one's complement
6428 (define_insn_and_split "*one_cmpl<mode>3_internal"
6429 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6431 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6434 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6435 return "xxlnor %x0,%x1,%x1";
6437 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6438 return "vnor %0,%1,%1";
6442 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6445 rs6000_split_logical (operands, NOT, false, false, false);
6450 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6451 (const_string "veclogical")
6452 (const_string "integer")))
6453 (set (attr "length")
6455 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6458 (match_test "TARGET_POWERPC64")
6460 (const_string "16"))))])
6463 ;; Now define ways of moving data around.
6465 ;; Set up a register with a value from the GOT table
6467 (define_expand "movsi_got"
6468 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6469 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6470 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6471 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6474 if (GET_CODE (operands[1]) == CONST)
6476 rtx offset = const0_rtx;
6477 HOST_WIDE_INT value;
6479 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6480 value = INTVAL (offset);
6483 rtx tmp = (!can_create_pseudo_p ()
6485 : gen_reg_rtx (Pmode));
6486 emit_insn (gen_movsi_got (tmp, operands[1]));
6487 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6492 operands[2] = rs6000_got_register (operands[1]);
6495 (define_insn "*movsi_got_internal"
6496 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6497 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6498 (match_operand:SI 2 "gpc_reg_operand" "b")]
6500 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6501 "lwz %0,%a1@got(%2)"
6502 [(set_attr "type" "load")])
6504 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6505 ;; didn't get allocated to a hard register.
6507 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6508 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6509 (match_operand:SI 2 "memory_operand" "")]
6511 "DEFAULT_ABI == ABI_V4
6513 && (reload_in_progress || reload_completed)"
6514 [(set (match_dup 0) (match_dup 2))
6515 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6519 ;; For SI, we special-case integers that can't be loaded in one insn. We
6520 ;; do the load 16-bits at a time. We could do this by loading from memory,
6521 ;; and this is even supposed to be faster, but it is simpler not to get
6522 ;; integers in the TOC.
6523 (define_insn "movsi_low"
6524 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6525 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6526 (match_operand 2 "" ""))))]
6527 "TARGET_MACHO && ! TARGET_64BIT"
6528 "lwz %0,lo16(%2)(%1)"
6529 [(set_attr "type" "load")
6530 (set_attr "length" "4")])
6532 ;; MR LA LWZ LFIWZX LXSIWZX
6533 ;; STW STFIWX STXSIWX LI LIS
6534 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6535 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6536 ;; MF%1 MT%0 MT%0 NOP
6537 (define_insn "*movsi_internal1"
6538 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6539 "=r, r, r, ?*wI, ?*wH,
6541 r, ?*wIwH, ?*wJwK, ?*wK, ?*wJwK,
6542 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6545 (match_operand:SI 1 "input_operand"
6552 "!TARGET_SINGLE_FPU &&
6553 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6580 "*, *, load, fpload, fpload,
6581 store, fpstore, fpstore, *, *,
6582 *, veclogical, vecsimple, vecsimple, vecsimple,
6583 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6593 (define_insn "*movsi_internal1_single"
6594 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6595 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6596 "TARGET_SINGLE_FPU &&
6597 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6612 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6613 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6615 ;; Split a load of a large constant into the appropriate two-insn
6619 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6620 (match_operand:SI 1 "const_int_operand" ""))]
6621 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6622 && (INTVAL (operands[1]) & 0xffff) != 0"
6626 (ior:SI (match_dup 0)
6630 if (rs6000_emit_set_const (operands[0], operands[1]))
6636 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6638 [(set (match_operand:DI 0 "altivec_register_operand" "")
6639 (match_operand:DI 1 "xxspltib_constant_split" ""))]
6640 "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
6643 rtx op0 = operands[0];
6644 rtx op1 = operands[1];
6645 int r = REGNO (op0);
6646 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6648 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6649 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6653 (define_insn "*mov<mode>_internal2"
6654 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6655 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6657 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6663 [(set_attr "type" "cmp,logical,cmp")
6664 (set_attr "dot" "yes")
6665 (set_attr "length" "4,4,8")])
6668 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6669 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6671 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6673 [(set (match_dup 0) (match_dup 1))
6675 (compare:CC (match_dup 0)
6679 (define_insn "*movhi_internal"
6680 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6681 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6682 "gpc_reg_operand (operands[0], HImode)
6683 || gpc_reg_operand (operands[1], HImode)"
6692 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6694 (define_expand "mov<mode>"
6695 [(set (match_operand:INT 0 "general_operand" "")
6696 (match_operand:INT 1 "any_operand" ""))]
6698 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6700 (define_insn "*movqi_internal"
6701 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6702 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6703 "gpc_reg_operand (operands[0], QImode)
6704 || gpc_reg_operand (operands[1], QImode)"
6713 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6715 ;; Here is how to move condition codes around. When we store CC data in
6716 ;; an integer register or memory, we store just the high-order 4 bits.
6717 ;; This lets us not shift in the most common case of CR0.
6718 (define_expand "movcc"
6719 [(set (match_operand:CC 0 "nonimmediate_operand" "")
6720 (match_operand:CC 1 "nonimmediate_operand" ""))]
6724 (define_insn "*movcc_internal1"
6725 [(set (match_operand:CC 0 "nonimmediate_operand"
6726 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
6727 (match_operand:CC 1 "general_operand"
6728 " y,r, r,O,x,y,r,I,h, r,m,r"))]
6729 "register_operand (operands[0], CCmode)
6730 || register_operand (operands[1], CCmode)"
6734 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6737 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6745 (cond [(eq_attr "alternative" "0,3")
6746 (const_string "cr_logical")
6747 (eq_attr "alternative" "1,2")
6748 (const_string "mtcr")
6749 (eq_attr "alternative" "6,7")
6750 (const_string "integer")
6751 (eq_attr "alternative" "8")
6752 (const_string "mfjmpr")
6753 (eq_attr "alternative" "9")
6754 (const_string "mtjmpr")
6755 (eq_attr "alternative" "10")
6756 (const_string "load")
6757 (eq_attr "alternative" "11")
6758 (const_string "store")
6759 (match_test "TARGET_MFCRF")
6760 (const_string "mfcrf")
6762 (const_string "mfcr")))
6763 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6765 ;; For floating-point, we normally deal with the floating-point registers
6766 ;; unless -msoft-float is used. The sole exception is that parameter passing
6767 ;; can produce floating-point values in fixed-point registers. Unless the
6768 ;; value is a simple constant or already in memory, we deal with this by
6769 ;; allocating memory and copying the value explicitly via that memory location.
6771 ;; Move 32-bit binary/decimal floating point
6772 (define_expand "mov<mode>"
6773 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6774 (match_operand:FMOVE32 1 "any_operand" ""))]
6776 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6779 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6780 (match_operand:FMOVE32 1 "const_double_operand" ""))]
6782 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6783 || (GET_CODE (operands[0]) == SUBREG
6784 && GET_CODE (SUBREG_REG (operands[0])) == REG
6785 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6786 [(set (match_dup 2) (match_dup 3))]
6791 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6793 if (! TARGET_POWERPC64)
6794 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6796 operands[2] = gen_lowpart (SImode, operands[0]);
6798 operands[3] = gen_int_mode (l, SImode);
6801 (define_insn "mov<mode>_hardfloat"
6802 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
6803 "=!r, <f32_lr>, <f32_lr2>, <f32_av>, m, <f32_sm>,
6804 <f32_sm2>, Z, <f32_vsx>, !r, ?<f32_dm>, ?r,
6805 f, <f32_vsx>, !r, *c*l, !r, *h")
6806 (match_operand:FMOVE32 1 "input_operand"
6807 "m, <f32_lm>, <f32_lm2>, Z, r, <f32_sr>,
6808 <f32_sr2>, <f32_av>, <zero_fp>, <zero_fp>, r, <f32_dm>,
6809 f, <f32_vsx>, r, r, *h, 0"))]
6810 "(gpc_reg_operand (operands[0], <MODE>mode)
6811 || gpc_reg_operand (operands[1], <MODE>mode))
6812 && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6827 xscpsgndp %x0,%x1,%x1
6832 [(set_attr "type" "load,fpload,fpload,fpload,store,fpstore,fpstore,fpstore,veclogical,integer,mffgpr,mftgpr,fpsimple,fpsimple,*,mtjmpr,mfjmpr,*")])
6834 (define_insn "*mov<mode>_softfloat"
6835 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6836 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6837 "(gpc_reg_operand (operands[0], <MODE>mode)
6838 || gpc_reg_operand (operands[1], <MODE>mode))
6839 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6851 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6852 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6855 ;; Move 64-bit binary/decimal floating point
6856 (define_expand "mov<mode>"
6857 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6858 (match_operand:FMOVE64 1 "any_operand" ""))]
6860 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6863 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6864 (match_operand:FMOVE64 1 "const_int_operand" ""))]
6865 "! TARGET_POWERPC64 && reload_completed
6866 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6867 || (GET_CODE (operands[0]) == SUBREG
6868 && GET_CODE (SUBREG_REG (operands[0])) == REG
6869 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6870 [(set (match_dup 2) (match_dup 4))
6871 (set (match_dup 3) (match_dup 1))]
6874 int endian = (WORDS_BIG_ENDIAN == 0);
6875 HOST_WIDE_INT value = INTVAL (operands[1]);
6877 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6878 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6879 operands[4] = GEN_INT (value >> 32);
6880 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6884 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6885 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6886 "! TARGET_POWERPC64 && reload_completed
6887 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6888 || (GET_CODE (operands[0]) == SUBREG
6889 && GET_CODE (SUBREG_REG (operands[0])) == REG
6890 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6891 [(set (match_dup 2) (match_dup 4))
6892 (set (match_dup 3) (match_dup 5))]
6895 int endian = (WORDS_BIG_ENDIAN == 0);
6898 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6900 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6901 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6902 operands[4] = gen_int_mode (l[endian], SImode);
6903 operands[5] = gen_int_mode (l[1 - endian], SImode);
6907 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6908 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6909 "TARGET_POWERPC64 && reload_completed
6910 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6911 || (GET_CODE (operands[0]) == SUBREG
6912 && GET_CODE (SUBREG_REG (operands[0])) == REG
6913 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6914 [(set (match_dup 2) (match_dup 3))]
6917 int endian = (WORDS_BIG_ENDIAN == 0);
6921 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6923 operands[2] = gen_lowpart (DImode, operands[0]);
6924 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
6925 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6926 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6928 operands[3] = gen_int_mode (val, DImode);
6931 ;; Don't have reload use general registers to load a constant. It is
6932 ;; less efficient than loading the constant into an FP register, since
6933 ;; it will probably be used there.
6935 ;; The move constraints are ordered to prefer floating point registers before
6936 ;; general purpose registers to avoid doing a store and a load to get the value
6937 ;; into a floating point register when it is needed for a floating point
6938 ;; operation. Prefer traditional floating point registers over VSX registers,
6939 ;; since the D-form version of the memory instructions does not need a GPR for
6940 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6943 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6944 ;; except for 0.0 which can be created on VSX with an xor instruction.
6946 (define_insn "*mov<mode>_hardfloat32"
6947 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6948 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
6949 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6950 && (gpc_reg_operand (operands[0], <MODE>mode)
6951 || gpc_reg_operand (operands[1], <MODE>mode))"
6966 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
6967 (set_attr "size" "64")
6968 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6970 (define_insn "*mov<mode>_softfloat32"
6971 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6972 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6974 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
6975 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6976 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6977 && (gpc_reg_operand (operands[0], <MODE>mode)
6978 || gpc_reg_operand (operands[1], <MODE>mode))"
6980 [(set_attr "type" "store,load,two,*,*,*")
6981 (set_attr "length" "8,8,8,8,12,16")])
6983 ; ld/std require word-aligned displacements -> 'Y' constraint.
6984 ; List Y->r and r->Y before r->r for reload.
6985 (define_insn "*mov<mode>_hardfloat64"
6986 [(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>")
6987 (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"))]
6988 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6989 && (gpc_reg_operand (operands[0], <MODE>mode)
6990 || gpc_reg_operand (operands[1], <MODE>mode))"
7012 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7013 (set_attr "size" "64")
7014 (set_attr "length" "4")])
7016 (define_insn "*mov<mode>_softfloat64"
7017 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7018 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7019 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7020 && (gpc_reg_operand (operands[0], <MODE>mode)
7021 || gpc_reg_operand (operands[1], <MODE>mode))"
7032 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7033 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7035 (define_expand "mov<mode>"
7036 [(set (match_operand:FMOVE128 0 "general_operand" "")
7037 (match_operand:FMOVE128 1 "any_operand" ""))]
7039 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7041 ;; It's important to list Y->r and r->Y before r->r because otherwise
7042 ;; reload, given m->r, will try to pick r->r and reload it, which
7043 ;; doesn't make progress.
7045 ;; We can't split little endian direct moves of TDmode, because the words are
7046 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7047 ;; problematical. Don't allow direct move for this case.
7049 (define_insn_and_split "*mov<mode>_64bit_dm"
7050 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7051 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7052 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7053 && FLOAT128_2REG_P (<MODE>mode)
7054 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7055 && (gpc_reg_operand (operands[0], <MODE>mode)
7056 || gpc_reg_operand (operands[1], <MODE>mode))"
7058 "&& reload_completed"
7060 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7061 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7063 (define_insn_and_split "*movtd_64bit_nodm"
7064 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7065 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7066 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7067 && (gpc_reg_operand (operands[0], TDmode)
7068 || gpc_reg_operand (operands[1], TDmode))"
7070 "&& reload_completed"
7072 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7073 [(set_attr "length" "8,8,8,12,12,8")])
7075 (define_insn_and_split "*mov<mode>_32bit"
7076 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7077 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7078 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7079 && (FLOAT128_2REG_P (<MODE>mode)
7080 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7081 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7082 && (gpc_reg_operand (operands[0], <MODE>mode)
7083 || gpc_reg_operand (operands[1], <MODE>mode))"
7085 "&& reload_completed"
7087 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7088 [(set_attr "length" "8,8,8,8,20,20,16")])
7090 (define_insn_and_split "*mov<mode>_softfloat"
7091 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7092 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7093 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7094 && (gpc_reg_operand (operands[0], <MODE>mode)
7095 || gpc_reg_operand (operands[1], <MODE>mode))"
7097 "&& reload_completed"
7099 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7100 [(set_attr "length" "20,20,16")])
7102 (define_expand "extenddf<mode>2"
7103 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7104 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7105 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7106 && TARGET_LONG_DOUBLE_128"
7108 if (FLOAT128_IEEE_P (<MODE>mode))
7109 rs6000_expand_float128_convert (operands[0], operands[1], false);
7110 else if (TARGET_E500_DOUBLE)
7112 gcc_assert (<MODE>mode == TFmode);
7113 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7115 else if (TARGET_VSX)
7117 if (<MODE>mode == TFmode)
7118 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7119 else if (<MODE>mode == IFmode)
7120 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7126 rtx zero = gen_reg_rtx (DFmode);
7127 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7129 if (<MODE>mode == TFmode)
7130 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7131 else if (<MODE>mode == IFmode)
7132 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7139 ;; Allow memory operands for the source to be created by the combiner.
7140 (define_insn_and_split "extenddf<mode>2_fprs"
7141 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7142 (float_extend:IBM128
7143 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7144 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7145 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7146 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7148 "&& reload_completed"
7149 [(set (match_dup 3) (match_dup 1))
7150 (set (match_dup 4) (match_dup 2))]
7152 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7153 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7155 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7156 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7159 (define_insn_and_split "extenddf<mode>2_vsx"
7160 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7161 (float_extend:IBM128
7162 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7163 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7165 "&& reload_completed"
7166 [(set (match_dup 2) (match_dup 1))
7167 (set (match_dup 3) (match_dup 4))]
7169 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7170 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7172 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7173 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7174 operands[4] = CONST0_RTX (DFmode);
7177 (define_expand "extendsf<mode>2"
7178 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7179 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7181 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7182 && TARGET_LONG_DOUBLE_128"
7184 if (FLOAT128_IEEE_P (<MODE>mode))
7185 rs6000_expand_float128_convert (operands[0], operands[1], false);
7188 rtx tmp = gen_reg_rtx (DFmode);
7189 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7190 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7195 (define_expand "trunc<mode>df2"
7196 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7197 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7199 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7200 && TARGET_LONG_DOUBLE_128"
7202 if (FLOAT128_IEEE_P (<MODE>mode))
7204 rs6000_expand_float128_convert (operands[0], operands[1], false);
7209 (define_insn_and_split "trunc<mode>df2_internal1"
7210 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7212 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7213 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7214 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7218 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7221 emit_note (NOTE_INSN_DELETED);
7224 [(set_attr "type" "fpsimple")])
7226 (define_insn "trunc<mode>df2_internal2"
7227 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7228 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7229 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7230 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7232 [(set_attr "type" "fp")
7233 (set_attr "fp_type" "fp_addsub_d")])
7235 (define_expand "trunc<mode>sf2"
7236 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7237 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7239 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7240 && TARGET_LONG_DOUBLE_128"
7242 if (FLOAT128_IEEE_P (<MODE>mode))
7243 rs6000_expand_float128_convert (operands[0], operands[1], false);
7244 else if (TARGET_E500_DOUBLE)
7246 gcc_assert (<MODE>mode == TFmode);
7247 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7249 else if (<MODE>mode == TFmode)
7250 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7251 else if (<MODE>mode == IFmode)
7252 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7258 (define_insn_and_split "trunc<mode>sf2_fprs"
7259 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7260 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7261 (clobber (match_scratch:DF 2 "=d"))]
7262 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7263 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7265 "&& reload_completed"
7267 (float_truncate:DF (match_dup 1)))
7269 (float_truncate:SF (match_dup 2)))]
7272 (define_expand "floatsi<mode>2"
7273 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7274 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7276 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7277 && TARGET_LONG_DOUBLE_128"
7279 if (FLOAT128_IEEE_P (<MODE>mode))
7280 rs6000_expand_float128_convert (operands[0], operands[1], false);
7283 rtx tmp = gen_reg_rtx (DFmode);
7284 expand_float (tmp, operands[1], false);
7285 if (<MODE>mode == TFmode)
7286 emit_insn (gen_extenddftf2 (operands[0], tmp));
7287 else if (<MODE>mode == IFmode)
7288 emit_insn (gen_extenddfif2 (operands[0], tmp));
7295 ; fadd, but rounding towards zero.
7296 ; This is probably not the optimal code sequence.
7297 (define_insn "fix_trunc_helper<mode>"
7298 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7299 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7300 UNSPEC_FIX_TRUNC_TF))
7301 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7302 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7303 && FLOAT128_IBM_P (<MODE>mode)"
7304 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7305 [(set_attr "type" "fp")
7306 (set_attr "length" "20")])
7308 (define_expand "fix_trunc<mode>si2"
7309 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7310 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7312 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7314 if (FLOAT128_IEEE_P (<MODE>mode))
7315 rs6000_expand_float128_convert (operands[0], operands[1], false);
7316 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7317 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7318 else if (<MODE>mode == TFmode)
7319 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7320 else if (<MODE>mode == IFmode)
7321 emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7327 (define_expand "fix_trunc<mode>si2_fprs"
7328 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7329 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7330 (clobber (match_dup 2))
7331 (clobber (match_dup 3))
7332 (clobber (match_dup 4))
7333 (clobber (match_dup 5))])]
7334 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7336 operands[2] = gen_reg_rtx (DFmode);
7337 operands[3] = gen_reg_rtx (DFmode);
7338 operands[4] = gen_reg_rtx (DImode);
7339 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7342 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7343 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7344 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7345 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7346 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7347 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7348 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7349 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7355 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7358 gcc_assert (MEM_P (operands[5]));
7359 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7361 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7362 emit_move_insn (operands[5], operands[4]);
7363 emit_move_insn (operands[0], lowword);
7367 (define_expand "fix_trunc<mode>di2"
7368 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7369 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7370 "TARGET_FLOAT128_TYPE"
7372 rs6000_expand_float128_convert (operands[0], operands[1], false);
7376 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7377 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7378 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7379 "TARGET_FLOAT128_TYPE"
7381 rs6000_expand_float128_convert (operands[0], operands[1], true);
7385 (define_expand "floatdi<mode>2"
7386 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7387 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7388 "TARGET_FLOAT128_TYPE"
7390 rs6000_expand_float128_convert (operands[0], operands[1], false);
7394 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7395 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7396 (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7397 "TARGET_FLOAT128_TYPE"
7399 rs6000_expand_float128_convert (operands[0], operands[1], true);
7403 (define_expand "neg<mode>2"
7404 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7405 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7406 "FLOAT128_IEEE_P (<MODE>mode)
7407 || (FLOAT128_IBM_P (<MODE>mode)
7408 && TARGET_HARD_FLOAT
7409 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7412 if (FLOAT128_IEEE_P (<MODE>mode))
7414 if (TARGET_FLOAT128_HW)
7416 if (<MODE>mode == TFmode)
7417 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7418 else if (<MODE>mode == KFmode)
7419 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7423 else if (TARGET_FLOAT128_TYPE)
7425 if (<MODE>mode == TFmode)
7426 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7427 else if (<MODE>mode == KFmode)
7428 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7434 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7435 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7437 operands[1], <MODE>mode);
7439 if (target && !rtx_equal_p (target, operands[0]))
7440 emit_move_insn (operands[0], target);
7446 (define_insn "neg<mode>2_internal"
7447 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7448 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7449 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7452 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7453 return \"fneg %L0,%L1\;fneg %0,%1\";
7455 return \"fneg %0,%1\;fneg %L0,%L1\";
7457 [(set_attr "type" "fpsimple")
7458 (set_attr "length" "8")])
7460 (define_expand "abs<mode>2"
7461 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7462 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7463 "FLOAT128_IEEE_P (<MODE>mode)
7464 || (FLOAT128_IBM_P (<MODE>mode)
7465 && TARGET_HARD_FLOAT
7466 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7471 if (FLOAT128_IEEE_P (<MODE>mode))
7473 if (TARGET_FLOAT128_HW)
7475 if (<MODE>mode == TFmode)
7476 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7477 else if (<MODE>mode == KFmode)
7478 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7483 else if (TARGET_FLOAT128_TYPE)
7485 if (<MODE>mode == TFmode)
7486 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7487 else if (<MODE>mode == KFmode)
7488 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7497 label = gen_label_rtx ();
7498 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7500 if (flag_finite_math_only && !flag_trapping_math)
7501 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7503 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7505 else if (<MODE>mode == TFmode)
7506 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7507 else if (<MODE>mode == TFmode)
7508 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7515 (define_expand "abs<mode>2_internal"
7516 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7517 (match_operand:IBM128 1 "gpc_reg_operand" ""))
7518 (set (match_dup 3) (match_dup 5))
7519 (set (match_dup 5) (abs:DF (match_dup 5)))
7520 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7521 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7522 (label_ref (match_operand 2 "" ""))
7524 (set (match_dup 6) (neg:DF (match_dup 6)))]
7525 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7526 && TARGET_LONG_DOUBLE_128"
7529 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7530 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7531 operands[3] = gen_reg_rtx (DFmode);
7532 operands[4] = gen_reg_rtx (CCFPmode);
7533 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7534 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7538 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7541 (define_expand "ieee_128bit_negative_zero"
7542 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7543 "TARGET_FLOAT128_TYPE"
7545 rtvec v = rtvec_alloc (16);
7548 for (i = 0; i < 16; i++)
7549 RTVEC_ELT (v, i) = const0_rtx;
7551 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7552 RTVEC_ELT (v, high) = GEN_INT (0x80);
7554 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7558 ;; IEEE 128-bit negate
7560 ;; We have 2 insns here for negate and absolute value. The first uses
7561 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7562 ;; insns, and second insn after the first split pass loads up the bit to
7563 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
7564 ;; neg/abs to create the constant just once.
7566 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7567 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7568 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7569 (clobber (match_scratch:V16QI 2 "=v"))]
7570 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7573 [(parallel [(set (match_dup 0)
7574 (neg:IEEE128 (match_dup 1)))
7575 (use (match_dup 2))])]
7577 if (GET_CODE (operands[2]) == SCRATCH)
7578 operands[2] = gen_reg_rtx (V16QImode);
7580 operands[3] = gen_reg_rtx (V16QImode);
7581 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7583 [(set_attr "length" "8")
7584 (set_attr "type" "vecsimple")])
7586 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7587 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7588 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7589 (use (match_operand:V16QI 2 "register_operand" "v"))]
7590 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7591 "xxlxor %x0,%x1,%x2"
7592 [(set_attr "type" "veclogical")])
7594 ;; IEEE 128-bit absolute value
7595 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7596 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7597 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7598 (clobber (match_scratch:V16QI 2 "=v"))]
7599 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7602 [(parallel [(set (match_dup 0)
7603 (abs:IEEE128 (match_dup 1)))
7604 (use (match_dup 2))])]
7606 if (GET_CODE (operands[2]) == SCRATCH)
7607 operands[2] = gen_reg_rtx (V16QImode);
7609 operands[3] = gen_reg_rtx (V16QImode);
7610 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7612 [(set_attr "length" "8")
7613 (set_attr "type" "vecsimple")])
7615 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7616 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7617 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7618 (use (match_operand:V16QI 2 "register_operand" "v"))]
7619 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7620 "xxlandc %x0,%x1,%x2"
7621 [(set_attr "type" "veclogical")])
7623 ;; IEEE 128-bit negative absolute value
7624 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7625 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7628 (match_operand:IEEE128 1 "register_operand" "wa"))))
7629 (clobber (match_scratch:V16QI 2 "=v"))]
7630 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
7631 && FLOAT128_IEEE_P (<MODE>mode)"
7634 [(parallel [(set (match_dup 0)
7635 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7636 (use (match_dup 2))])]
7638 if (GET_CODE (operands[2]) == SCRATCH)
7639 operands[2] = gen_reg_rtx (V16QImode);
7641 operands[3] = gen_reg_rtx (V16QImode);
7642 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7644 [(set_attr "length" "8")
7645 (set_attr "type" "vecsimple")])
7647 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7648 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7651 (match_operand:IEEE128 1 "register_operand" "wa"))))
7652 (use (match_operand:V16QI 2 "register_operand" "v"))]
7653 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7655 [(set_attr "type" "veclogical")])
7657 ;; Float128 conversion functions. These expand to library function calls.
7658 ;; We use expand to convert from IBM double double to IEEE 128-bit
7659 ;; and trunc for the opposite.
7660 (define_expand "extendiftf2"
7661 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7662 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7663 "TARGET_FLOAT128_TYPE"
7665 rs6000_expand_float128_convert (operands[0], operands[1], false);
7669 (define_expand "extendifkf2"
7670 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7671 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7672 "TARGET_FLOAT128_TYPE"
7674 rs6000_expand_float128_convert (operands[0], operands[1], false);
7678 (define_expand "extendtfkf2"
7679 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7680 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7681 "TARGET_FLOAT128_TYPE"
7683 rs6000_expand_float128_convert (operands[0], operands[1], false);
7687 (define_expand "trunciftf2"
7688 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7689 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7690 "TARGET_FLOAT128_TYPE"
7692 rs6000_expand_float128_convert (operands[0], operands[1], false);
7696 (define_expand "truncifkf2"
7697 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7698 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7699 "TARGET_FLOAT128_TYPE"
7701 rs6000_expand_float128_convert (operands[0], operands[1], false);
7705 (define_expand "trunckftf2"
7706 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7707 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7708 "TARGET_FLOAT128_TYPE"
7710 rs6000_expand_float128_convert (operands[0], operands[1], false);
7714 (define_expand "trunctfif2"
7715 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7716 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7717 "TARGET_FLOAT128_TYPE"
7719 rs6000_expand_float128_convert (operands[0], operands[1], false);
7724 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
7725 ;; must have 3 arguments, and scratch register constraint must be a single
7728 ;; Reload patterns to support gpr load/store with misaligned mem.
7729 ;; and multiple gpr load/store at offset >= 0xfffc
7730 (define_expand "reload_<mode>_store"
7731 [(parallel [(match_operand 0 "memory_operand" "=m")
7732 (match_operand 1 "gpc_reg_operand" "r")
7733 (match_operand:GPR 2 "register_operand" "=&b")])]
7736 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7740 (define_expand "reload_<mode>_load"
7741 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7742 (match_operand 1 "memory_operand" "m")
7743 (match_operand:GPR 2 "register_operand" "=b")])]
7746 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7751 ;; Reload patterns for various types using the vector registers. We may need
7752 ;; an additional base register to convert the reg+offset addressing to reg+reg
7753 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7754 ;; index register for gpr registers.
7755 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7756 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7757 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7758 (match_operand:P 2 "register_operand" "=b")])]
7761 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7765 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7766 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7767 (match_operand:RELOAD 1 "memory_operand" "m")
7768 (match_operand:P 2 "register_operand" "=b")])]
7771 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7776 ;; Reload sometimes tries to move the address to a GPR, and can generate
7777 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
7778 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7780 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7781 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7782 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7783 (match_operand:P 2 "reg_or_cint_operand" "rI"))
7785 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7787 "&& reload_completed"
7789 (plus:P (match_dup 1)
7792 (and:P (match_dup 0)
7795 ;; Power8 merge instructions to allow direct move to/from floating point
7796 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
7797 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
7798 ;; value, since it is allocated in reload and not all of the flow information
7799 ;; is setup for it. We have two patterns to do the two moves between gprs and
7800 ;; fprs. There isn't a dependancy between the two, but we could potentially
7801 ;; schedule other instructions between the two instructions.
7803 (define_insn "p8_fmrgow_<mode>"
7804 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7806 (match_operand:DF 1 "register_operand" "d")
7807 (match_operand:DF 2 "register_operand" "d")]
7808 UNSPEC_P8V_FMRGOW))]
7809 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7811 [(set_attr "type" "fpsimple")])
7813 (define_insn "p8_mtvsrwz"
7814 [(set (match_operand:DF 0 "register_operand" "=d")
7815 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7816 UNSPEC_P8V_MTVSRWZ))]
7817 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7819 [(set_attr "type" "mftgpr")])
7821 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7822 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7823 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7824 UNSPEC_P8V_RELOAD_FROM_GPR))
7825 (clobber (match_operand:IF 2 "register_operand" "=d"))]
7826 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7828 "&& reload_completed"
7831 rtx dest = operands[0];
7832 rtx src = operands[1];
7833 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7834 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7835 rtx gpr_hi_reg = gen_highpart (SImode, src);
7836 rtx gpr_lo_reg = gen_lowpart (SImode, src);
7838 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7839 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7840 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7843 [(set_attr "length" "12")
7844 (set_attr "type" "three")])
7846 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7847 (define_insn "p8_mtvsrd_df"
7848 [(set (match_operand:DF 0 "register_operand" "=wa")
7849 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7850 UNSPEC_P8V_MTVSRD))]
7851 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7853 [(set_attr "type" "mftgpr")])
7855 (define_insn "p8_xxpermdi_<mode>"
7856 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7857 (unspec:FMOVE128_GPR [
7858 (match_operand:DF 1 "register_operand" "wa")
7859 (match_operand:DF 2 "register_operand" "wa")]
7860 UNSPEC_P8V_XXPERMDI))]
7861 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7862 "xxpermdi %x0,%x1,%x2,0"
7863 [(set_attr "type" "vecperm")])
7865 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7866 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7867 (unspec:FMOVE128_GPR
7868 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7869 UNSPEC_P8V_RELOAD_FROM_GPR))
7870 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
7871 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7873 "&& reload_completed"
7876 rtx dest = operands[0];
7877 rtx src = operands[1];
7878 /* You might think that we could use op0 as one temp and a DF clobber
7879 as op2, but you'd be wrong. Secondary reload move patterns don't
7880 check for overlap of the clobber and the destination. */
7881 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7882 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7883 rtx gpr_hi_reg = gen_highpart (DImode, src);
7884 rtx gpr_lo_reg = gen_lowpart (DImode, src);
7886 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
7887 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
7888 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
7891 [(set_attr "length" "12")
7892 (set_attr "type" "three")])
7895 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7896 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7898 && (int_reg_operand (operands[0], <MODE>mode)
7899 || int_reg_operand (operands[1], <MODE>mode))
7900 && (!TARGET_DIRECT_MOVE_128
7901 || (!vsx_register_operand (operands[0], <MODE>mode)
7902 && !vsx_register_operand (operands[1], <MODE>mode)))"
7904 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7906 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
7907 ;; type is stored internally as double precision in the VSX registers, we have
7908 ;; to convert it from the vector format.
7909 (define_insn "p8_mtvsrd_sf"
7910 [(set (match_operand:SF 0 "register_operand" "=wa")
7911 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
7912 UNSPEC_P8V_MTVSRD))]
7913 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7915 [(set_attr "type" "mftgpr")])
7917 (define_insn_and_split "reload_vsx_from_gprsf"
7918 [(set (match_operand:SF 0 "register_operand" "=wa")
7919 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7920 UNSPEC_P8V_RELOAD_FROM_GPR))
7921 (clobber (match_operand:DI 2 "register_operand" "=r"))]
7922 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7924 "&& reload_completed"
7927 rtx op0 = operands[0];
7928 rtx op1 = operands[1];
7929 rtx op2 = operands[2];
7930 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7932 /* Move SF value to upper 32-bits for xscvspdpn. */
7933 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7934 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7935 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7938 [(set_attr "length" "8")
7939 (set_attr "type" "two")])
7941 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7942 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7943 ;; and then doing a move of that.
7944 (define_insn "p8_mfvsrd_3_<mode>"
7945 [(set (match_operand:DF 0 "register_operand" "=r")
7946 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7947 UNSPEC_P8V_RELOAD_FROM_VSX))]
7948 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7950 [(set_attr "type" "mftgpr")])
7952 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7953 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7954 (unspec:FMOVE128_GPR
7955 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7956 UNSPEC_P8V_RELOAD_FROM_VSX))
7957 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7958 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7960 "&& reload_completed"
7963 rtx dest = operands[0];
7964 rtx src = operands[1];
7965 rtx tmp = operands[2];
7966 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7967 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7969 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7970 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7971 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7974 [(set_attr "length" "12")
7975 (set_attr "type" "three")])
7977 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
7978 ;; type is stored internally as double precision, we have to convert it to the
7981 (define_insn_and_split "reload_gpr_from_vsxsf"
7982 [(set (match_operand:SF 0 "register_operand" "=r")
7983 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7984 UNSPEC_P8V_RELOAD_FROM_VSX))
7985 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7986 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7988 "&& reload_completed"
7991 rtx op0 = operands[0];
7992 rtx op1 = operands[1];
7993 rtx op2 = operands[2];
7994 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7996 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7997 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7998 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8001 [(set_attr "length" "12")
8002 (set_attr "type" "three")])
8004 (define_insn "p8_mfvsrd_4_disf"
8005 [(set (match_operand:DI 0 "register_operand" "=r")
8006 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8007 UNSPEC_P8V_RELOAD_FROM_VSX))]
8008 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8010 [(set_attr "type" "mftgpr")])
8013 ;; Next come the multi-word integer load and store and the load and store
8016 ;; List r->r after r->Y, otherwise reload will try to reload a
8017 ;; non-offsettable address by using r->r which won't make progress.
8018 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8019 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8021 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8022 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8023 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8026 (define_insn "*movdi_internal32"
8027 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8028 "=Y, r, r, ?m, ?*d, ?*d,
8029 r, ?wY, ?Z, ?*wb, ?*wv, ?wi,
8030 ?wo, ?wo, ?wv, ?wi, ?wi, ?wv,
8033 (match_operand:DI 1 "input_operand"
8035 IJKnGHF, wb, wv, wY, Z, wi,
8036 Oj, wM, OjwM, Oj, wM, wS,
8040 && (gpc_reg_operand (operands[0], DImode)
8041 || gpc_reg_operand (operands[1], DImode))"
8063 "store, load, *, fpstore, fpload, fpsimple,
8064 *, fpstore, fpstore, fpload, fpload, veclogical,
8065 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8067 (set_attr "size" "64")])
8070 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8071 (match_operand:DI 1 "const_int_operand" ""))]
8072 "! TARGET_POWERPC64 && reload_completed
8073 && gpr_or_gpr_p (operands[0], operands[1])
8074 && !direct_move_p (operands[0], operands[1])"
8075 [(set (match_dup 2) (match_dup 4))
8076 (set (match_dup 3) (match_dup 1))]
8079 HOST_WIDE_INT value = INTVAL (operands[1]);
8080 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8082 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8084 operands[4] = GEN_INT (value >> 32);
8085 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8089 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8090 (match_operand:DIFD 1 "input_operand" ""))]
8091 "reload_completed && !TARGET_POWERPC64
8092 && gpr_or_gpr_p (operands[0], operands[1])
8093 && !direct_move_p (operands[0], operands[1])"
8095 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8097 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8098 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8099 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8100 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8101 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8102 (define_insn "*movdi_internal64"
8103 [(set (match_operand:DI 0 "nonimmediate_operand"
8105 ?m, ?*d, ?*d, ?wY, ?Z, ?*wb,
8106 ?*wv, ?wi, ?wo, ?wo, ?wv, ?wi,
8107 ?wi, ?wv, ?wv, r, *h, *h,
8108 ?*r, ?*wg, ?*r, ?*wj")
8110 (match_operand:DI 1 "input_operand"
8112 d, m, d, wb, wv, wY,
8113 Z, wi, Oj, wM, OjwM, Oj,
8114 wM, wS, wB, *h, r, 0,
8118 && (gpc_reg_operand (operands[0], DImode)
8119 || gpc_reg_operand (operands[1], DImode))"
8150 "store, load, *, *, *, *,
8151 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8152 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8153 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8154 mftgpr, mffgpr, mftgpr, mffgpr")
8156 (set_attr "size" "64")
8164 ; Some DImode loads are best done as a load of -1 followed by a mask
8167 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8168 (match_operand:DI 1 "const_int_operand"))]
8170 && num_insns_constant (operands[1], DImode) > 1
8171 && rs6000_is_valid_and_mask (operands[1], DImode)"
8175 (and:DI (match_dup 0)
8179 ;; Split a load of a large constant into the appropriate five-instruction
8180 ;; sequence. Handle anything in a constant number of insns.
8181 ;; When non-easy constants can go in the TOC, this should use
8182 ;; easy_fp_constant predicate.
8184 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8185 (match_operand:DI 1 "const_int_operand" ""))]
8186 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8187 [(set (match_dup 0) (match_dup 2))
8188 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8191 if (rs6000_emit_set_const (operands[0], operands[1]))
8198 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8199 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8200 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8201 [(set (match_dup 0) (match_dup 2))
8202 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8205 if (rs6000_emit_set_const (operands[0], operands[1]))
8212 [(set (match_operand:DI 0 "altivec_register_operand" "")
8213 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8214 "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8217 rtx op0 = operands[0];
8218 rtx op1 = operands[1];
8219 int r = REGNO (op0);
8220 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8222 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8223 if (op1 != const0_rtx && op1 != constm1_rtx)
8225 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8226 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8232 [(set (match_operand:DI 0 "altivec_register_operand" "")
8233 (match_operand:DI 1 "xxspltib_constant_split" ""))]
8234 "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8237 rtx op0 = operands[0];
8238 rtx op1 = operands[1];
8239 int r = REGNO (op0);
8240 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8242 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8243 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8248 ;; TImode/PTImode is similar, except that we usually want to compute the
8249 ;; address into a register and use lsi/stsi (the exception is during reload).
8251 (define_insn "*mov<mode>_string"
8252 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8253 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8255 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8256 && (gpc_reg_operand (operands[0], <MODE>mode)
8257 || gpc_reg_operand (operands[1], <MODE>mode))"
8260 switch (which_alternative)
8266 return \"stswi %1,%P0,16\";
8271 /* If the address is not used in the output, we can use lsi. Otherwise,
8272 fall through to generating four loads. */
8274 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8275 return \"lswi %0,%P1,16\";
8283 [(set_attr "type" "store,store,load,load,*,*")
8284 (set_attr "update" "yes")
8285 (set_attr "indexed" "yes")
8286 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8287 (const_string "always")
8288 (const_string "conditional")))])
8290 (define_insn "*mov<mode>_ppc64"
8291 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8292 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8293 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8294 && (gpc_reg_operand (operands[0], <MODE>mode)
8295 || gpc_reg_operand (operands[1], <MODE>mode)))"
8297 return rs6000_output_move_128bit (operands);
8299 [(set_attr "type" "store,store,load,load,*,*")
8300 (set_attr "length" "8")])
8303 [(set (match_operand:TI2 0 "int_reg_operand" "")
8304 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8306 && (VECTOR_MEM_NONE_P (<MODE>mode)
8307 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8308 [(set (match_dup 2) (match_dup 4))
8309 (set (match_dup 3) (match_dup 5))]
8312 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8314 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8316 if (CONST_WIDE_INT_P (operands[1]))
8318 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8319 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8321 else if (CONST_INT_P (operands[1]))
8323 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8324 operands[5] = operands[1];
8331 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8332 (match_operand:TI2 1 "input_operand" ""))]
8334 && gpr_or_gpr_p (operands[0], operands[1])
8335 && !direct_move_p (operands[0], operands[1])
8336 && !quad_load_store_p (operands[0], operands[1])"
8338 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8340 (define_expand "load_multiple"
8341 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8342 (match_operand:SI 1 "" ""))
8343 (use (match_operand:SI 2 "" ""))])]
8344 "TARGET_STRING && !TARGET_POWERPC64"
8352 /* Support only loading a constant number of fixed-point registers from
8353 memory and only bother with this if more than two; the machine
8354 doesn't support more than eight. */
8355 if (GET_CODE (operands[2]) != CONST_INT
8356 || INTVAL (operands[2]) <= 2
8357 || INTVAL (operands[2]) > 8
8358 || GET_CODE (operands[1]) != MEM
8359 || GET_CODE (operands[0]) != REG
8360 || REGNO (operands[0]) >= 32)
8363 count = INTVAL (operands[2]);
8364 regno = REGNO (operands[0]);
8366 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8367 op1 = replace_equiv_address (operands[1],
8368 force_reg (SImode, XEXP (operands[1], 0)));
8370 for (i = 0; i < count; i++)
8371 XVECEXP (operands[3], 0, i)
8372 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8373 adjust_address_nv (op1, SImode, i * 4));
8376 (define_insn "*ldmsi8"
8377 [(match_parallel 0 "load_multiple_operation"
8378 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8379 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8380 (set (match_operand:SI 3 "gpc_reg_operand" "")
8381 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8382 (set (match_operand:SI 4 "gpc_reg_operand" "")
8383 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8384 (set (match_operand:SI 5 "gpc_reg_operand" "")
8385 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8386 (set (match_operand:SI 6 "gpc_reg_operand" "")
8387 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8388 (set (match_operand:SI 7 "gpc_reg_operand" "")
8389 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8390 (set (match_operand:SI 8 "gpc_reg_operand" "")
8391 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8392 (set (match_operand:SI 9 "gpc_reg_operand" "")
8393 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8394 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8396 { return rs6000_output_load_multiple (operands); }"
8397 [(set_attr "type" "load")
8398 (set_attr "update" "yes")
8399 (set_attr "indexed" "yes")
8400 (set_attr "length" "32")])
8402 (define_insn "*ldmsi7"
8403 [(match_parallel 0 "load_multiple_operation"
8404 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8405 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8406 (set (match_operand:SI 3 "gpc_reg_operand" "")
8407 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8408 (set (match_operand:SI 4 "gpc_reg_operand" "")
8409 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8410 (set (match_operand:SI 5 "gpc_reg_operand" "")
8411 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8412 (set (match_operand:SI 6 "gpc_reg_operand" "")
8413 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8414 (set (match_operand:SI 7 "gpc_reg_operand" "")
8415 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8416 (set (match_operand:SI 8 "gpc_reg_operand" "")
8417 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8418 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8420 { return rs6000_output_load_multiple (operands); }"
8421 [(set_attr "type" "load")
8422 (set_attr "update" "yes")
8423 (set_attr "indexed" "yes")
8424 (set_attr "length" "32")])
8426 (define_insn "*ldmsi6"
8427 [(match_parallel 0 "load_multiple_operation"
8428 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8429 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8430 (set (match_operand:SI 3 "gpc_reg_operand" "")
8431 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8432 (set (match_operand:SI 4 "gpc_reg_operand" "")
8433 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8434 (set (match_operand:SI 5 "gpc_reg_operand" "")
8435 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8436 (set (match_operand:SI 6 "gpc_reg_operand" "")
8437 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8438 (set (match_operand:SI 7 "gpc_reg_operand" "")
8439 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8440 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8442 { return rs6000_output_load_multiple (operands); }"
8443 [(set_attr "type" "load")
8444 (set_attr "update" "yes")
8445 (set_attr "indexed" "yes")
8446 (set_attr "length" "32")])
8448 (define_insn "*ldmsi5"
8449 [(match_parallel 0 "load_multiple_operation"
8450 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8451 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8452 (set (match_operand:SI 3 "gpc_reg_operand" "")
8453 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8454 (set (match_operand:SI 4 "gpc_reg_operand" "")
8455 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8456 (set (match_operand:SI 5 "gpc_reg_operand" "")
8457 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8458 (set (match_operand:SI 6 "gpc_reg_operand" "")
8459 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8460 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8462 { return rs6000_output_load_multiple (operands); }"
8463 [(set_attr "type" "load")
8464 (set_attr "update" "yes")
8465 (set_attr "indexed" "yes")
8466 (set_attr "length" "32")])
8468 (define_insn "*ldmsi4"
8469 [(match_parallel 0 "load_multiple_operation"
8470 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8471 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8472 (set (match_operand:SI 3 "gpc_reg_operand" "")
8473 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8474 (set (match_operand:SI 4 "gpc_reg_operand" "")
8475 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8476 (set (match_operand:SI 5 "gpc_reg_operand" "")
8477 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8478 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8480 { return rs6000_output_load_multiple (operands); }"
8481 [(set_attr "type" "load")
8482 (set_attr "update" "yes")
8483 (set_attr "indexed" "yes")
8484 (set_attr "length" "32")])
8486 (define_insn "*ldmsi3"
8487 [(match_parallel 0 "load_multiple_operation"
8488 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8489 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8490 (set (match_operand:SI 3 "gpc_reg_operand" "")
8491 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8492 (set (match_operand:SI 4 "gpc_reg_operand" "")
8493 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8494 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8496 { return rs6000_output_load_multiple (operands); }"
8497 [(set_attr "type" "load")
8498 (set_attr "update" "yes")
8499 (set_attr "indexed" "yes")
8500 (set_attr "length" "32")])
8502 (define_expand "store_multiple"
8503 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8504 (match_operand:SI 1 "" ""))
8505 (clobber (scratch:SI))
8506 (use (match_operand:SI 2 "" ""))])]
8507 "TARGET_STRING && !TARGET_POWERPC64"
8516 /* Support only storing a constant number of fixed-point registers to
8517 memory and only bother with this if more than two; the machine
8518 doesn't support more than eight. */
8519 if (GET_CODE (operands[2]) != CONST_INT
8520 || INTVAL (operands[2]) <= 2
8521 || INTVAL (operands[2]) > 8
8522 || GET_CODE (operands[0]) != MEM
8523 || GET_CODE (operands[1]) != REG
8524 || REGNO (operands[1]) >= 32)
8527 count = INTVAL (operands[2]);
8528 regno = REGNO (operands[1]);
8530 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8531 to = force_reg (SImode, XEXP (operands[0], 0));
8532 op0 = replace_equiv_address (operands[0], to);
8534 XVECEXP (operands[3], 0, 0)
8535 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8536 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8537 gen_rtx_SCRATCH (SImode));
8539 for (i = 1; i < count; i++)
8540 XVECEXP (operands[3], 0, i + 1)
8541 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8542 gen_rtx_REG (SImode, regno + i));
8545 (define_insn "*stmsi8"
8546 [(match_parallel 0 "store_multiple_operation"
8547 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8548 (match_operand:SI 2 "gpc_reg_operand" "r"))
8549 (clobber (match_scratch:SI 3 "=X"))
8550 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8551 (match_operand:SI 4 "gpc_reg_operand" "r"))
8552 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8553 (match_operand:SI 5 "gpc_reg_operand" "r"))
8554 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8555 (match_operand:SI 6 "gpc_reg_operand" "r"))
8556 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8557 (match_operand:SI 7 "gpc_reg_operand" "r"))
8558 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8559 (match_operand:SI 8 "gpc_reg_operand" "r"))
8560 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8561 (match_operand:SI 9 "gpc_reg_operand" "r"))
8562 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8563 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8564 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8566 [(set_attr "type" "store")
8567 (set_attr "update" "yes")
8568 (set_attr "indexed" "yes")
8569 (set_attr "cell_micro" "always")])
8571 (define_insn "*stmsi7"
8572 [(match_parallel 0 "store_multiple_operation"
8573 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8574 (match_operand:SI 2 "gpc_reg_operand" "r"))
8575 (clobber (match_scratch:SI 3 "=X"))
8576 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8577 (match_operand:SI 4 "gpc_reg_operand" "r"))
8578 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8579 (match_operand:SI 5 "gpc_reg_operand" "r"))
8580 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8581 (match_operand:SI 6 "gpc_reg_operand" "r"))
8582 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8583 (match_operand:SI 7 "gpc_reg_operand" "r"))
8584 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8585 (match_operand:SI 8 "gpc_reg_operand" "r"))
8586 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8587 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8588 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8590 [(set_attr "type" "store")
8591 (set_attr "update" "yes")
8592 (set_attr "indexed" "yes")
8593 (set_attr "cell_micro" "always")])
8595 (define_insn "*stmsi6"
8596 [(match_parallel 0 "store_multiple_operation"
8597 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8598 (match_operand:SI 2 "gpc_reg_operand" "r"))
8599 (clobber (match_scratch:SI 3 "=X"))
8600 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8601 (match_operand:SI 4 "gpc_reg_operand" "r"))
8602 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8603 (match_operand:SI 5 "gpc_reg_operand" "r"))
8604 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8605 (match_operand:SI 6 "gpc_reg_operand" "r"))
8606 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8607 (match_operand:SI 7 "gpc_reg_operand" "r"))
8608 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8609 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8610 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8612 [(set_attr "type" "store")
8613 (set_attr "update" "yes")
8614 (set_attr "indexed" "yes")
8615 (set_attr "cell_micro" "always")])
8617 (define_insn "*stmsi5"
8618 [(match_parallel 0 "store_multiple_operation"
8619 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8620 (match_operand:SI 2 "gpc_reg_operand" "r"))
8621 (clobber (match_scratch:SI 3 "=X"))
8622 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8623 (match_operand:SI 4 "gpc_reg_operand" "r"))
8624 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8625 (match_operand:SI 5 "gpc_reg_operand" "r"))
8626 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8627 (match_operand:SI 6 "gpc_reg_operand" "r"))
8628 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8629 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8630 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8632 [(set_attr "type" "store")
8633 (set_attr "update" "yes")
8634 (set_attr "indexed" "yes")
8635 (set_attr "cell_micro" "always")])
8637 (define_insn "*stmsi4"
8638 [(match_parallel 0 "store_multiple_operation"
8639 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8640 (match_operand:SI 2 "gpc_reg_operand" "r"))
8641 (clobber (match_scratch:SI 3 "=X"))
8642 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8643 (match_operand:SI 4 "gpc_reg_operand" "r"))
8644 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8645 (match_operand:SI 5 "gpc_reg_operand" "r"))
8646 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8647 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8648 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8650 [(set_attr "type" "store")
8651 (set_attr "update" "yes")
8652 (set_attr "indexed" "yes")
8653 (set_attr "cell_micro" "always")])
8655 (define_insn "*stmsi3"
8656 [(match_parallel 0 "store_multiple_operation"
8657 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8658 (match_operand:SI 2 "gpc_reg_operand" "r"))
8659 (clobber (match_scratch:SI 3 "=X"))
8660 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8661 (match_operand:SI 4 "gpc_reg_operand" "r"))
8662 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8663 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8664 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8666 [(set_attr "type" "store")
8667 (set_attr "update" "yes")
8668 (set_attr "indexed" "yes")
8669 (set_attr "cell_micro" "always")])
8671 (define_expand "setmemsi"
8672 [(parallel [(set (match_operand:BLK 0 "" "")
8673 (match_operand 2 "const_int_operand" ""))
8674 (use (match_operand:SI 1 "" ""))
8675 (use (match_operand:SI 3 "" ""))])]
8679 /* If value to set is not zero, use the library routine. */
8680 if (operands[2] != const0_rtx)
8683 if (expand_block_clear (operands))
8689 ;; String/block compare insn.
8690 ;; Argument 0 is the target (result)
8691 ;; Argument 1 is the destination
8692 ;; Argument 2 is the source
8693 ;; Argument 3 is the length
8694 ;; Argument 4 is the alignment
8696 (define_expand "cmpmemsi"
8697 [(parallel [(set (match_operand:SI 0)
8698 (compare:SI (match_operand:BLK 1)
8699 (match_operand:BLK 2)))
8700 (use (match_operand:SI 3))
8701 (use (match_operand:SI 4))])]
8704 if (expand_block_compare (operands))
8710 ;; String/block move insn.
8711 ;; Argument 0 is the destination
8712 ;; Argument 1 is the source
8713 ;; Argument 2 is the length
8714 ;; Argument 3 is the alignment
8716 (define_expand "movmemsi"
8717 [(parallel [(set (match_operand:BLK 0 "" "")
8718 (match_operand:BLK 1 "" ""))
8719 (use (match_operand:SI 2 "" ""))
8720 (use (match_operand:SI 3 "" ""))])]
8724 if (expand_block_move (operands))
8730 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
8731 ;; register allocator doesn't have a clue about allocating 8 word registers.
8732 ;; rD/rS = r5 is preferred, efficient form.
8733 (define_expand "movmemsi_8reg"
8734 [(parallel [(set (match_operand 0 "" "")
8735 (match_operand 1 "" ""))
8736 (use (match_operand 2 "" ""))
8737 (use (match_operand 3 "" ""))
8738 (clobber (reg:SI 5))
8739 (clobber (reg:SI 6))
8740 (clobber (reg:SI 7))
8741 (clobber (reg:SI 8))
8742 (clobber (reg:SI 9))
8743 (clobber (reg:SI 10))
8744 (clobber (reg:SI 11))
8745 (clobber (reg:SI 12))
8746 (clobber (match_scratch:SI 4 ""))])]
8751 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8752 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8753 (use (match_operand:SI 2 "immediate_operand" "i"))
8754 (use (match_operand:SI 3 "immediate_operand" "i"))
8755 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8756 (clobber (reg:SI 6))
8757 (clobber (reg:SI 7))
8758 (clobber (reg:SI 8))
8759 (clobber (reg:SI 9))
8760 (clobber (reg:SI 10))
8761 (clobber (reg:SI 11))
8762 (clobber (reg:SI 12))
8763 (clobber (match_scratch:SI 5 "=X"))]
8765 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8766 || INTVAL (operands[2]) == 0)
8767 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8768 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8769 && REGNO (operands[4]) == 5"
8770 "lswi %4,%1,%2\;stswi %4,%0,%2"
8771 [(set_attr "type" "store")
8772 (set_attr "update" "yes")
8773 (set_attr "indexed" "yes")
8774 (set_attr "cell_micro" "always")
8775 (set_attr "length" "8")])
8777 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
8778 ;; register allocator doesn't have a clue about allocating 6 word registers.
8779 ;; rD/rS = r5 is preferred, efficient form.
8780 (define_expand "movmemsi_6reg"
8781 [(parallel [(set (match_operand 0 "" "")
8782 (match_operand 1 "" ""))
8783 (use (match_operand 2 "" ""))
8784 (use (match_operand 3 "" ""))
8785 (clobber (reg:SI 5))
8786 (clobber (reg:SI 6))
8787 (clobber (reg:SI 7))
8788 (clobber (reg:SI 8))
8789 (clobber (reg:SI 9))
8790 (clobber (reg:SI 10))
8791 (clobber (match_scratch:SI 4 ""))])]
8796 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8797 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8798 (use (match_operand:SI 2 "immediate_operand" "i"))
8799 (use (match_operand:SI 3 "immediate_operand" "i"))
8800 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8801 (clobber (reg:SI 6))
8802 (clobber (reg:SI 7))
8803 (clobber (reg:SI 8))
8804 (clobber (reg:SI 9))
8805 (clobber (reg:SI 10))
8806 (clobber (match_scratch:SI 5 "=X"))]
8808 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8809 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8810 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8811 && REGNO (operands[4]) == 5"
8812 "lswi %4,%1,%2\;stswi %4,%0,%2"
8813 [(set_attr "type" "store")
8814 (set_attr "update" "yes")
8815 (set_attr "indexed" "yes")
8816 (set_attr "cell_micro" "always")
8817 (set_attr "length" "8")])
8819 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8820 ;; problems with TImode.
8821 ;; rD/rS = r5 is preferred, efficient form.
8822 (define_expand "movmemsi_4reg"
8823 [(parallel [(set (match_operand 0 "" "")
8824 (match_operand 1 "" ""))
8825 (use (match_operand 2 "" ""))
8826 (use (match_operand 3 "" ""))
8827 (clobber (reg:SI 5))
8828 (clobber (reg:SI 6))
8829 (clobber (reg:SI 7))
8830 (clobber (reg:SI 8))
8831 (clobber (match_scratch:SI 4 ""))])]
8836 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8837 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8838 (use (match_operand:SI 2 "immediate_operand" "i"))
8839 (use (match_operand:SI 3 "immediate_operand" "i"))
8840 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8841 (clobber (reg:SI 6))
8842 (clobber (reg:SI 7))
8843 (clobber (reg:SI 8))
8844 (clobber (match_scratch:SI 5 "=X"))]
8846 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8847 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8848 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8849 && REGNO (operands[4]) == 5"
8850 "lswi %4,%1,%2\;stswi %4,%0,%2"
8851 [(set_attr "type" "store")
8852 (set_attr "update" "yes")
8853 (set_attr "indexed" "yes")
8854 (set_attr "cell_micro" "always")
8855 (set_attr "length" "8")])
8857 ;; Move up to 8 bytes at a time.
8858 (define_expand "movmemsi_2reg"
8859 [(parallel [(set (match_operand 0 "" "")
8860 (match_operand 1 "" ""))
8861 (use (match_operand 2 "" ""))
8862 (use (match_operand 3 "" ""))
8863 (clobber (match_scratch:DI 4 ""))
8864 (clobber (match_scratch:SI 5 ""))])]
8865 "TARGET_STRING && ! TARGET_POWERPC64"
8869 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8870 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8871 (use (match_operand:SI 2 "immediate_operand" "i"))
8872 (use (match_operand:SI 3 "immediate_operand" "i"))
8873 (clobber (match_scratch:DI 4 "=&r"))
8874 (clobber (match_scratch:SI 5 "=X"))]
8875 "TARGET_STRING && ! TARGET_POWERPC64
8876 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8877 "lswi %4,%1,%2\;stswi %4,%0,%2"
8878 [(set_attr "type" "store")
8879 (set_attr "update" "yes")
8880 (set_attr "indexed" "yes")
8881 (set_attr "cell_micro" "always")
8882 (set_attr "length" "8")])
8884 ;; Move up to 4 bytes at a time.
8885 (define_expand "movmemsi_1reg"
8886 [(parallel [(set (match_operand 0 "" "")
8887 (match_operand 1 "" ""))
8888 (use (match_operand 2 "" ""))
8889 (use (match_operand 3 "" ""))
8890 (clobber (match_scratch:SI 4 ""))
8891 (clobber (match_scratch:SI 5 ""))])]
8896 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8897 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8898 (use (match_operand:SI 2 "immediate_operand" "i"))
8899 (use (match_operand:SI 3 "immediate_operand" "i"))
8900 (clobber (match_scratch:SI 4 "=&r"))
8901 (clobber (match_scratch:SI 5 "=X"))]
8902 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8903 "lswi %4,%1,%2\;stswi %4,%0,%2"
8904 [(set_attr "type" "store")
8905 (set_attr "update" "yes")
8906 (set_attr "indexed" "yes")
8907 (set_attr "cell_micro" "always")
8908 (set_attr "length" "8")])
8910 ;; Define insns that do load or store with update. Some of these we can
8911 ;; get by using pre-decrement or pre-increment, but the hardware can also
8912 ;; do cases where the increment is not the size of the object.
8914 ;; In all these cases, we use operands 0 and 1 for the register being
8915 ;; incremented because those are the operands that local-alloc will
8916 ;; tie and these are the pair most likely to be tieable (and the ones
8917 ;; that will benefit the most).
8919 (define_insn "*movdi_update1"
8920 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8921 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8922 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8923 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8924 (plus:DI (match_dup 1) (match_dup 2)))]
8925 "TARGET_POWERPC64 && TARGET_UPDATE
8926 && (!avoiding_indexed_address_p (DImode)
8927 || !gpc_reg_operand (operands[2], DImode))"
8931 [(set_attr "type" "load")
8932 (set_attr "update" "yes")
8933 (set_attr "indexed" "yes,no")])
8935 (define_insn "movdi_<mode>_update"
8936 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8937 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8938 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8939 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8940 (plus:P (match_dup 1) (match_dup 2)))]
8941 "TARGET_POWERPC64 && TARGET_UPDATE
8942 && (!avoiding_indexed_address_p (Pmode)
8943 || !gpc_reg_operand (operands[2], Pmode)
8944 || (REG_P (operands[0])
8945 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8949 [(set_attr "type" "store")
8950 (set_attr "update" "yes")
8951 (set_attr "indexed" "yes,no")])
8953 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8954 ;; needed for stack allocation, even if the user passes -mno-update.
8955 (define_insn "movdi_<mode>_update_stack"
8956 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8957 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8958 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8959 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8960 (plus:P (match_dup 1) (match_dup 2)))]
8965 [(set_attr "type" "store")
8966 (set_attr "update" "yes")
8967 (set_attr "indexed" "yes,no")])
8969 (define_insn "*movsi_update1"
8970 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8971 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8972 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8973 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8974 (plus:SI (match_dup 1) (match_dup 2)))]
8976 && (!avoiding_indexed_address_p (SImode)
8977 || !gpc_reg_operand (operands[2], SImode))"
8981 [(set_attr "type" "load")
8982 (set_attr "update" "yes")
8983 (set_attr "indexed" "yes,no")])
8985 (define_insn "*movsi_update2"
8986 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8988 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8989 (match_operand:DI 2 "gpc_reg_operand" "r")))))
8990 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8991 (plus:DI (match_dup 1) (match_dup 2)))]
8992 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8993 && !avoiding_indexed_address_p (DImode)"
8995 [(set_attr "type" "load")
8996 (set_attr "sign_extend" "yes")
8997 (set_attr "update" "yes")
8998 (set_attr "indexed" "yes")])
9000 (define_insn "movsi_update"
9001 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9002 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9003 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9004 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9005 (plus:SI (match_dup 1) (match_dup 2)))]
9007 && (!avoiding_indexed_address_p (SImode)
9008 || !gpc_reg_operand (operands[2], SImode)
9009 || (REG_P (operands[0])
9010 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9014 [(set_attr "type" "store")
9015 (set_attr "update" "yes")
9016 (set_attr "indexed" "yes,no")])
9018 ;; This is an unconditional pattern; needed for stack allocation, even
9019 ;; if the user passes -mno-update.
9020 (define_insn "movsi_update_stack"
9021 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9022 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9023 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9024 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9025 (plus:SI (match_dup 1) (match_dup 2)))]
9030 [(set_attr "type" "store")
9031 (set_attr "update" "yes")
9032 (set_attr "indexed" "yes,no")])
9034 (define_insn "*movhi_update1"
9035 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9036 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9037 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9038 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9039 (plus:SI (match_dup 1) (match_dup 2)))]
9041 && (!avoiding_indexed_address_p (SImode)
9042 || !gpc_reg_operand (operands[2], SImode))"
9046 [(set_attr "type" "load")
9047 (set_attr "update" "yes")
9048 (set_attr "indexed" "yes,no")])
9050 (define_insn "*movhi_update2"
9051 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9053 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9054 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9055 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9056 (plus:SI (match_dup 1) (match_dup 2)))]
9058 && (!avoiding_indexed_address_p (SImode)
9059 || !gpc_reg_operand (operands[2], SImode))"
9063 [(set_attr "type" "load")
9064 (set_attr "update" "yes")
9065 (set_attr "indexed" "yes,no")])
9067 (define_insn "*movhi_update3"
9068 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9070 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9071 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9072 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9073 (plus:SI (match_dup 1) (match_dup 2)))]
9074 "TARGET_UPDATE && rs6000_gen_cell_microcode
9075 && (!avoiding_indexed_address_p (SImode)
9076 || !gpc_reg_operand (operands[2], SImode))"
9080 [(set_attr "type" "load")
9081 (set_attr "sign_extend" "yes")
9082 (set_attr "update" "yes")
9083 (set_attr "indexed" "yes,no")])
9085 (define_insn "*movhi_update4"
9086 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9087 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9088 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9089 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9090 (plus:SI (match_dup 1) (match_dup 2)))]
9092 && (!avoiding_indexed_address_p (SImode)
9093 || !gpc_reg_operand (operands[2], SImode))"
9097 [(set_attr "type" "store")
9098 (set_attr "update" "yes")
9099 (set_attr "indexed" "yes,no")])
9101 (define_insn "*movqi_update1"
9102 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9103 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9104 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9105 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9106 (plus:SI (match_dup 1) (match_dup 2)))]
9108 && (!avoiding_indexed_address_p (SImode)
9109 || !gpc_reg_operand (operands[2], SImode))"
9113 [(set_attr "type" "load")
9114 (set_attr "update" "yes")
9115 (set_attr "indexed" "yes,no")])
9117 (define_insn "*movqi_update2"
9118 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9120 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9121 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9122 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9123 (plus:SI (match_dup 1) (match_dup 2)))]
9125 && (!avoiding_indexed_address_p (SImode)
9126 || !gpc_reg_operand (operands[2], SImode))"
9130 [(set_attr "type" "load")
9131 (set_attr "update" "yes")
9132 (set_attr "indexed" "yes,no")])
9134 (define_insn "*movqi_update3"
9135 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9136 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9137 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9138 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9139 (plus:SI (match_dup 1) (match_dup 2)))]
9141 && (!avoiding_indexed_address_p (SImode)
9142 || !gpc_reg_operand (operands[2], SImode))"
9146 [(set_attr "type" "store")
9147 (set_attr "update" "yes")
9148 (set_attr "indexed" "yes,no")])
9150 (define_insn "*movsf_update1"
9151 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9152 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9153 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9154 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9155 (plus:SI (match_dup 1) (match_dup 2)))]
9156 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9157 && (!avoiding_indexed_address_p (SImode)
9158 || !gpc_reg_operand (operands[2], SImode))"
9162 [(set_attr "type" "fpload")
9163 (set_attr "update" "yes")
9164 (set_attr "indexed" "yes,no")])
9166 (define_insn "*movsf_update2"
9167 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9168 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9169 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9170 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9171 (plus:SI (match_dup 1) (match_dup 2)))]
9172 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9173 && (!avoiding_indexed_address_p (SImode)
9174 || !gpc_reg_operand (operands[2], SImode))"
9178 [(set_attr "type" "fpstore")
9179 (set_attr "update" "yes")
9180 (set_attr "indexed" "yes,no")])
9182 (define_insn "*movsf_update3"
9183 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9184 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9185 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9186 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9187 (plus:SI (match_dup 1) (match_dup 2)))]
9188 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9189 && (!avoiding_indexed_address_p (SImode)
9190 || !gpc_reg_operand (operands[2], SImode))"
9194 [(set_attr "type" "load")
9195 (set_attr "update" "yes")
9196 (set_attr "indexed" "yes,no")])
9198 (define_insn "*movsf_update4"
9199 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9200 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9201 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9202 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9203 (plus:SI (match_dup 1) (match_dup 2)))]
9204 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9205 && (!avoiding_indexed_address_p (SImode)
9206 || !gpc_reg_operand (operands[2], SImode))"
9210 [(set_attr "type" "store")
9211 (set_attr "update" "yes")
9212 (set_attr "indexed" "yes,no")])
9214 (define_insn "*movdf_update1"
9215 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9216 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9217 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9218 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9219 (plus:SI (match_dup 1) (match_dup 2)))]
9220 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9221 && (!avoiding_indexed_address_p (SImode)
9222 || !gpc_reg_operand (operands[2], SImode))"
9226 [(set_attr "type" "fpload")
9227 (set_attr "update" "yes")
9228 (set_attr "indexed" "yes,no")
9229 (set_attr "size" "64")])
9231 (define_insn "*movdf_update2"
9232 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9233 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9234 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9235 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9236 (plus:SI (match_dup 1) (match_dup 2)))]
9237 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9238 && (!avoiding_indexed_address_p (SImode)
9239 || !gpc_reg_operand (operands[2], SImode))"
9243 [(set_attr "type" "fpstore")
9244 (set_attr "update" "yes")
9245 (set_attr "indexed" "yes,no")])
9248 ;; After inserting conditional returns we can sometimes have
9249 ;; unnecessary register moves. Unfortunately we cannot have a
9250 ;; modeless peephole here, because some single SImode sets have early
9251 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9252 ;; sequences, using get_attr_length here will smash the operands
9253 ;; array. Neither is there an early_cobbler_p predicate.
9254 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9255 ;; Also this optimization interferes with scalars going into
9256 ;; altivec registers (the code does reloading through the FPRs).
9258 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9259 (match_operand:DF 1 "any_operand" ""))
9260 (set (match_operand:DF 2 "gpc_reg_operand" "")
9262 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9263 && !TARGET_UPPER_REGS_DF
9264 && peep2_reg_dead_p (2, operands[0])"
9265 [(set (match_dup 2) (match_dup 1))])
9268 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9269 (match_operand:SF 1 "any_operand" ""))
9270 (set (match_operand:SF 2 "gpc_reg_operand" "")
9272 "!TARGET_UPPER_REGS_SF
9273 && peep2_reg_dead_p (2, operands[0])"
9274 [(set (match_dup 2) (match_dup 1))])
9279 ;; Mode attributes for different ABIs.
9280 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9281 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9282 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9283 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9285 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9286 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9287 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9288 (match_operand 4 "" "g")))
9289 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9290 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9292 (clobber (reg:SI LR_REGNO))]
9293 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9295 if (TARGET_CMODEL != CMODEL_SMALL)
9296 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9299 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9301 "&& TARGET_TLS_MARKERS"
9303 (unspec:TLSmode [(match_dup 1)
9306 (parallel [(set (match_dup 0)
9307 (call (mem:TLSmode (match_dup 3))
9309 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9310 (clobber (reg:SI LR_REGNO))])]
9312 [(set_attr "type" "two")
9313 (set (attr "length")
9314 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9318 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9319 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9320 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9321 (match_operand 4 "" "g")))
9322 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9323 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9325 (clobber (reg:SI LR_REGNO))]
9326 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9330 if (TARGET_SECURE_PLT && flag_pic == 2)
9331 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9333 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9336 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9338 "&& TARGET_TLS_MARKERS"
9340 (unspec:TLSmode [(match_dup 1)
9343 (parallel [(set (match_dup 0)
9344 (call (mem:TLSmode (match_dup 3))
9346 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9347 (clobber (reg:SI LR_REGNO))])]
9349 [(set_attr "type" "two")
9350 (set_attr "length" "8")])
9352 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9353 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9354 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9355 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9357 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9358 "addi %0,%1,%2@got@tlsgd"
9359 "&& TARGET_CMODEL != CMODEL_SMALL"
9362 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9364 (lo_sum:TLSmode (match_dup 3)
9365 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9368 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9370 [(set (attr "length")
9371 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9375 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9376 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9378 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9379 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9381 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9382 "addis %0,%1,%2@got@tlsgd@ha"
9383 [(set_attr "length" "4")])
9385 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9386 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9387 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9388 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9389 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9391 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9392 "addi %0,%1,%2@got@tlsgd@l"
9393 [(set_attr "length" "4")])
9395 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9396 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9397 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9398 (match_operand 2 "" "g")))
9399 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9401 (clobber (reg:SI LR_REGNO))]
9402 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9403 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9404 "bl %z1(%3@tlsgd)\;nop"
9405 [(set_attr "type" "branch")
9406 (set_attr "length" "8")])
9408 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9409 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9410 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9411 (match_operand 2 "" "g")))
9412 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9414 (clobber (reg:SI LR_REGNO))]
9415 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9419 if (TARGET_SECURE_PLT && flag_pic == 2)
9420 return "bl %z1+32768(%3@tlsgd)@plt";
9421 return "bl %z1(%3@tlsgd)@plt";
9423 return "bl %z1(%3@tlsgd)";
9425 [(set_attr "type" "branch")
9426 (set_attr "length" "4")])
9428 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9429 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9430 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9431 (match_operand 3 "" "g")))
9432 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9434 (clobber (reg:SI LR_REGNO))]
9435 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9437 if (TARGET_CMODEL != CMODEL_SMALL)
9438 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9441 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9443 "&& TARGET_TLS_MARKERS"
9445 (unspec:TLSmode [(match_dup 1)]
9447 (parallel [(set (match_dup 0)
9448 (call (mem:TLSmode (match_dup 2))
9450 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9451 (clobber (reg:SI LR_REGNO))])]
9453 [(set_attr "type" "two")
9454 (set (attr "length")
9455 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9459 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9460 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9461 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9462 (match_operand 3 "" "g")))
9463 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9465 (clobber (reg:SI LR_REGNO))]
9466 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9470 if (TARGET_SECURE_PLT && flag_pic == 2)
9471 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9473 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9476 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9478 "&& TARGET_TLS_MARKERS"
9480 (unspec:TLSmode [(match_dup 1)]
9482 (parallel [(set (match_dup 0)
9483 (call (mem:TLSmode (match_dup 2))
9485 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9486 (clobber (reg:SI LR_REGNO))])]
9488 [(set_attr "length" "8")])
9490 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9491 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9492 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9494 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9495 "addi %0,%1,%&@got@tlsld"
9496 "&& TARGET_CMODEL != CMODEL_SMALL"
9499 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9501 (lo_sum:TLSmode (match_dup 2)
9502 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9505 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9507 [(set (attr "length")
9508 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9512 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9513 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9515 (unspec:TLSmode [(const_int 0)
9516 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9518 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9519 "addis %0,%1,%&@got@tlsld@ha"
9520 [(set_attr "length" "4")])
9522 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9523 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9524 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9525 (unspec:TLSmode [(const_int 0)
9526 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9528 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9529 "addi %0,%1,%&@got@tlsld@l"
9530 [(set_attr "length" "4")])
9532 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9533 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9534 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9535 (match_operand 2 "" "g")))
9536 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9537 (clobber (reg:SI LR_REGNO))]
9538 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9539 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9540 "bl %z1(%&@tlsld)\;nop"
9541 [(set_attr "type" "branch")
9542 (set_attr "length" "8")])
9544 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9545 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9546 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9547 (match_operand 2 "" "g")))
9548 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9549 (clobber (reg:SI LR_REGNO))]
9550 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9554 if (TARGET_SECURE_PLT && flag_pic == 2)
9555 return "bl %z1+32768(%&@tlsld)@plt";
9556 return "bl %z1(%&@tlsld)@plt";
9558 return "bl %z1(%&@tlsld)";
9560 [(set_attr "type" "branch")
9561 (set_attr "length" "4")])
9563 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9564 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9565 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9566 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9569 "addi %0,%1,%2@dtprel")
9571 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9572 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9573 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9574 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9575 UNSPEC_TLSDTPRELHA))]
9577 "addis %0,%1,%2@dtprel@ha")
9579 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9580 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9581 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9582 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9583 UNSPEC_TLSDTPRELLO))]
9585 "addi %0,%1,%2@dtprel@l")
9587 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9588 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9589 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9590 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9591 UNSPEC_TLSGOTDTPREL))]
9593 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9594 "&& TARGET_CMODEL != CMODEL_SMALL"
9597 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9599 (lo_sum:TLSmode (match_dup 3)
9600 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9603 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9605 [(set (attr "length")
9606 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9610 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9611 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9613 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9614 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9615 UNSPEC_TLSGOTDTPREL)))]
9616 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9617 "addis %0,%1,%2@got@dtprel@ha"
9618 [(set_attr "length" "4")])
9620 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9621 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9622 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9623 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9624 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9625 UNSPEC_TLSGOTDTPREL)))]
9626 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9627 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9628 [(set_attr "length" "4")])
9630 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9631 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9632 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9633 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9636 "addi %0,%1,%2@tprel")
9638 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9639 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9640 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9641 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9642 UNSPEC_TLSTPRELHA))]
9644 "addis %0,%1,%2@tprel@ha")
9646 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9647 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9648 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9649 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9650 UNSPEC_TLSTPRELLO))]
9652 "addi %0,%1,%2@tprel@l")
9654 ;; "b" output constraint here and on tls_tls input to support linker tls
9655 ;; optimization. The linker may edit the instructions emitted by a
9656 ;; tls_got_tprel/tls_tls pair to addis,addi.
9657 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9658 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9659 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9660 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9661 UNSPEC_TLSGOTTPREL))]
9663 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9664 "&& TARGET_CMODEL != CMODEL_SMALL"
9667 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9669 (lo_sum:TLSmode (match_dup 3)
9670 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9673 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9675 [(set (attr "length")
9676 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9680 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9681 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9683 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9684 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9685 UNSPEC_TLSGOTTPREL)))]
9686 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9687 "addis %0,%1,%2@got@tprel@ha"
9688 [(set_attr "length" "4")])
9690 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9691 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9692 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9693 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9694 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9695 UNSPEC_TLSGOTTPREL)))]
9696 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9697 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9698 [(set_attr "length" "4")])
9700 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9701 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9702 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9703 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9705 "TARGET_ELF && HAVE_AS_TLS"
9708 (define_expand "tls_get_tpointer"
9709 [(set (match_operand:SI 0 "gpc_reg_operand" "")
9710 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9711 "TARGET_XCOFF && HAVE_AS_TLS"
9714 emit_insn (gen_tls_get_tpointer_internal ());
9715 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9719 (define_insn "tls_get_tpointer_internal"
9721 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9722 (clobber (reg:SI LR_REGNO))]
9723 "TARGET_XCOFF && HAVE_AS_TLS"
9724 "bla __get_tpointer")
9726 (define_expand "tls_get_addr<mode>"
9727 [(set (match_operand:P 0 "gpc_reg_operand" "")
9728 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9729 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9730 "TARGET_XCOFF && HAVE_AS_TLS"
9733 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9734 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9735 emit_insn (gen_tls_get_addr_internal<mode> ());
9736 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9740 (define_insn "tls_get_addr_internal<mode>"
9742 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9746 (clobber (reg:P 11))
9747 (clobber (reg:CC CR0_REGNO))
9748 (clobber (reg:P LR_REGNO))]
9749 "TARGET_XCOFF && HAVE_AS_TLS"
9750 "bla __tls_get_addr")
9752 ;; Next come insns related to the calling sequence.
9754 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9755 ;; We move the back-chain and decrement the stack pointer.
9757 (define_expand "allocate_stack"
9758 [(set (match_operand 0 "gpc_reg_operand" "")
9759 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9761 (minus (reg 1) (match_dup 1)))]
9764 { rtx chain = gen_reg_rtx (Pmode);
9765 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9767 rtx insn, par, set, mem;
9769 emit_move_insn (chain, stack_bot);
9771 /* Check stack bounds if necessary. */
9772 if (crtl->limit_stack)
9775 available = expand_binop (Pmode, sub_optab,
9776 stack_pointer_rtx, stack_limit_rtx,
9777 NULL_RTX, 1, OPTAB_WIDEN);
9778 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9781 if (GET_CODE (operands[1]) != CONST_INT
9782 || INTVAL (operands[1]) < -32767
9783 || INTVAL (operands[1]) > 32768)
9785 neg_op0 = gen_reg_rtx (Pmode);
9787 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9789 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9792 neg_op0 = GEN_INT (- INTVAL (operands[1]));
9794 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9795 : gen_movdi_di_update_stack))
9796 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9798 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9799 it now and set the alias set/attributes. The above gen_*_update
9800 calls will generate a PARALLEL with the MEM set being the first
9802 par = PATTERN (insn);
9803 gcc_assert (GET_CODE (par) == PARALLEL);
9804 set = XVECEXP (par, 0, 0);
9805 gcc_assert (GET_CODE (set) == SET);
9806 mem = SET_DEST (set);
9807 gcc_assert (MEM_P (mem));
9808 MEM_NOTRAP_P (mem) = 1;
9809 set_mem_alias_set (mem, get_frame_alias_set ());
9811 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9815 ;; These patterns say how to save and restore the stack pointer. We need not
9816 ;; save the stack pointer at function level since we are careful to
9817 ;; preserve the backchain. At block level, we have to restore the backchain
9818 ;; when we restore the stack pointer.
9820 ;; For nonlocal gotos, we must save both the stack pointer and its
9821 ;; backchain and restore both. Note that in the nonlocal case, the
9822 ;; save area is a memory location.
9824 (define_expand "save_stack_function"
9825 [(match_operand 0 "any_operand" "")
9826 (match_operand 1 "any_operand" "")]
9830 (define_expand "restore_stack_function"
9831 [(match_operand 0 "any_operand" "")
9832 (match_operand 1 "any_operand" "")]
9836 ;; Adjust stack pointer (op0) to a new value (op1).
9837 ;; First copy old stack backchain to new location, and ensure that the
9838 ;; scheduler won't reorder the sp assignment before the backchain write.
9839 (define_expand "restore_stack_block"
9840 [(set (match_dup 2) (match_dup 3))
9841 (set (match_dup 4) (match_dup 2))
9843 (set (match_operand 0 "register_operand" "")
9844 (match_operand 1 "register_operand" ""))]
9850 operands[1] = force_reg (Pmode, operands[1]);
9851 operands[2] = gen_reg_rtx (Pmode);
9852 operands[3] = gen_frame_mem (Pmode, operands[0]);
9853 operands[4] = gen_frame_mem (Pmode, operands[1]);
9854 p = rtvec_alloc (1);
9855 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9857 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9860 (define_expand "save_stack_nonlocal"
9861 [(set (match_dup 3) (match_dup 4))
9862 (set (match_operand 0 "memory_operand" "") (match_dup 3))
9863 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9867 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9869 /* Copy the backchain to the first word, sp to the second. */
9870 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9871 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9872 operands[3] = gen_reg_rtx (Pmode);
9873 operands[4] = gen_frame_mem (Pmode, operands[1]);
9876 (define_expand "restore_stack_nonlocal"
9877 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9878 (set (match_dup 3) (match_dup 4))
9879 (set (match_dup 5) (match_dup 2))
9881 (set (match_operand 0 "register_operand" "") (match_dup 3))]
9885 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9888 /* Restore the backchain from the first word, sp from the second. */
9889 operands[2] = gen_reg_rtx (Pmode);
9890 operands[3] = gen_reg_rtx (Pmode);
9891 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9892 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9893 operands[5] = gen_frame_mem (Pmode, operands[3]);
9894 p = rtvec_alloc (1);
9895 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9897 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9900 ;; TOC register handling.
9902 ;; Code to initialize the TOC register...
9904 (define_insn "load_toc_aix_si"
9905 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9906 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9908 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9912 extern int need_toc_init;
9914 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9915 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9916 operands[2] = gen_rtx_REG (Pmode, 2);
9917 return \"lwz %0,%1(%2)\";
9919 [(set_attr "type" "load")
9920 (set_attr "update" "no")
9921 (set_attr "indexed" "no")])
9923 (define_insn "load_toc_aix_di"
9924 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9925 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9927 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9931 extern int need_toc_init;
9933 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9934 !TARGET_ELF || !TARGET_MINIMAL_TOC);
9936 strcat (buf, \"@toc\");
9937 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9938 operands[2] = gen_rtx_REG (Pmode, 2);
9939 return \"ld %0,%1(%2)\";
9941 [(set_attr "type" "load")
9942 (set_attr "update" "no")
9943 (set_attr "indexed" "no")])
9945 (define_insn "load_toc_v4_pic_si"
9946 [(set (reg:SI LR_REGNO)
9947 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9948 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9949 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9950 [(set_attr "type" "branch")
9951 (set_attr "length" "4")])
9953 (define_expand "load_toc_v4_PIC_1"
9954 [(parallel [(set (reg:SI LR_REGNO)
9955 (match_operand:SI 0 "immediate_operand" "s"))
9956 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9957 "TARGET_ELF && DEFAULT_ABI == ABI_V4
9958 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9961 (define_insn "load_toc_v4_PIC_1_normal"
9962 [(set (reg:SI LR_REGNO)
9963 (match_operand:SI 0 "immediate_operand" "s"))
9964 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9965 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9966 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9967 "bcl 20,31,%0\\n%0:"
9968 [(set_attr "type" "branch")
9969 (set_attr "length" "4")
9970 (set_attr "cannot_copy" "yes")])
9972 (define_insn "load_toc_v4_PIC_1_476"
9973 [(set (reg:SI LR_REGNO)
9974 (match_operand:SI 0 "immediate_operand" "s"))
9975 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9976 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9977 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9981 static char templ[32];
9983 get_ppc476_thunk_name (name);
9984 sprintf (templ, \"bl %s\\n%%0:\", name);
9987 [(set_attr "type" "branch")
9988 (set_attr "length" "4")
9989 (set_attr "cannot_copy" "yes")])
9991 (define_expand "load_toc_v4_PIC_1b"
9992 [(parallel [(set (reg:SI LR_REGNO)
9993 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9994 (label_ref (match_operand 1 "" ""))]
9997 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10000 (define_insn "load_toc_v4_PIC_1b_normal"
10001 [(set (reg:SI LR_REGNO)
10002 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10003 (label_ref (match_operand 1 "" ""))]
10006 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10007 "bcl 20,31,$+8\;.long %0-$"
10008 [(set_attr "type" "branch")
10009 (set_attr "length" "8")])
10011 (define_insn "load_toc_v4_PIC_1b_476"
10012 [(set (reg:SI LR_REGNO)
10013 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10014 (label_ref (match_operand 1 "" ""))]
10017 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10021 static char templ[32];
10023 get_ppc476_thunk_name (name);
10024 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10027 [(set_attr "type" "branch")
10028 (set_attr "length" "16")])
10030 (define_insn "load_toc_v4_PIC_2"
10031 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10032 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10033 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10034 (match_operand:SI 3 "immediate_operand" "s")))))]
10035 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10037 [(set_attr "type" "load")])
10039 (define_insn "load_toc_v4_PIC_3b"
10040 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10041 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10043 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10044 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10045 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10046 "addis %0,%1,%2-%3@ha")
10048 (define_insn "load_toc_v4_PIC_3c"
10049 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10050 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10051 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10052 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10053 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10054 "addi %0,%1,%2-%3@l")
10056 ;; If the TOC is shared over a translation unit, as happens with all
10057 ;; the kinds of PIC that we support, we need to restore the TOC
10058 ;; pointer only when jumping over units of translation.
10059 ;; On Darwin, we need to reload the picbase.
10061 (define_expand "builtin_setjmp_receiver"
10062 [(use (label_ref (match_operand 0 "" "")))]
10063 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10064 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10065 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10069 if (DEFAULT_ABI == ABI_DARWIN)
10071 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10072 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10076 crtl->uses_pic_offset_table = 1;
10077 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10078 CODE_LABEL_NUMBER (operands[0]));
10079 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10081 emit_insn (gen_load_macho_picbase (tmplabrtx));
10082 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10083 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10087 rs6000_emit_load_toc_table (FALSE);
10091 ;; Largetoc support
10092 (define_insn "*largetoc_high"
10093 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10095 (unspec [(match_operand:DI 1 "" "")
10096 (match_operand:DI 2 "gpc_reg_operand" "b")]
10098 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10099 "addis %0,%2,%1@toc@ha")
10101 (define_insn "*largetoc_high_aix<mode>"
10102 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10104 (unspec [(match_operand:P 1 "" "")
10105 (match_operand:P 2 "gpc_reg_operand" "b")]
10107 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10108 "addis %0,%1@u(%2)")
10110 (define_insn "*largetoc_high_plus"
10111 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10114 (unspec [(match_operand:DI 1 "" "")
10115 (match_operand:DI 2 "gpc_reg_operand" "b")]
10117 (match_operand:DI 3 "add_cint_operand" "n"))))]
10118 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10119 "addis %0,%2,%1+%3@toc@ha")
10121 (define_insn "*largetoc_high_plus_aix<mode>"
10122 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10125 (unspec [(match_operand:P 1 "" "")
10126 (match_operand:P 2 "gpc_reg_operand" "b")]
10128 (match_operand:P 3 "add_cint_operand" "n"))))]
10129 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10130 "addis %0,%1+%3@u(%2)")
10132 (define_insn "*largetoc_low"
10133 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10134 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10135 (match_operand:DI 2 "" "")))]
10136 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10139 (define_insn "*largetoc_low_aix<mode>"
10140 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10141 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10142 (match_operand:P 2 "" "")))]
10143 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10146 (define_insn_and_split "*tocref<mode>"
10147 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10148 (match_operand:P 1 "small_toc_ref" "R"))]
10151 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10152 [(set (match_dup 0) (high:P (match_dup 1)))
10153 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10155 ;; Elf specific ways of loading addresses for non-PIC code.
10156 ;; The output of this could be r0, but we make a very strong
10157 ;; preference for a base register because it will usually
10158 ;; be needed there.
10159 (define_insn "elf_high"
10160 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10161 (high:SI (match_operand 1 "" "")))]
10162 "TARGET_ELF && ! TARGET_64BIT"
10165 (define_insn "elf_low"
10166 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10167 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10168 (match_operand 2 "" "")))]
10169 "TARGET_ELF && ! TARGET_64BIT"
10172 ;; Call and call_value insns
10173 (define_expand "call"
10174 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10175 (match_operand 1 "" ""))
10176 (use (match_operand 2 "" ""))
10177 (clobber (reg:SI LR_REGNO))])]
10182 if (MACHOPIC_INDIRECT)
10183 operands[0] = machopic_indirect_call_target (operands[0]);
10186 gcc_assert (GET_CODE (operands[0]) == MEM);
10187 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10189 operands[0] = XEXP (operands[0], 0);
10191 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10193 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10197 if (GET_CODE (operands[0]) != SYMBOL_REF
10198 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10200 if (INTVAL (operands[2]) & CALL_LONG)
10201 operands[0] = rs6000_longcall_ref (operands[0]);
10203 switch (DEFAULT_ABI)
10207 operands[0] = force_reg (Pmode, operands[0]);
10211 gcc_unreachable ();
10216 (define_expand "call_value"
10217 [(parallel [(set (match_operand 0 "" "")
10218 (call (mem:SI (match_operand 1 "address_operand" ""))
10219 (match_operand 2 "" "")))
10220 (use (match_operand 3 "" ""))
10221 (clobber (reg:SI LR_REGNO))])]
10226 if (MACHOPIC_INDIRECT)
10227 operands[1] = machopic_indirect_call_target (operands[1]);
10230 gcc_assert (GET_CODE (operands[1]) == MEM);
10231 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10233 operands[1] = XEXP (operands[1], 0);
10235 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10237 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10241 if (GET_CODE (operands[1]) != SYMBOL_REF
10242 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10244 if (INTVAL (operands[3]) & CALL_LONG)
10245 operands[1] = rs6000_longcall_ref (operands[1]);
10247 switch (DEFAULT_ABI)
10251 operands[1] = force_reg (Pmode, operands[1]);
10255 gcc_unreachable ();
10260 ;; Call to function in current module. No TOC pointer reload needed.
10261 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10262 ;; either the function was not prototyped, or it was prototyped as a
10263 ;; variable argument function. It is > 0 if FP registers were passed
10264 ;; and < 0 if they were not.
10266 (define_insn "*call_local32"
10267 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10268 (match_operand 1 "" "g,g"))
10269 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10270 (clobber (reg:SI LR_REGNO))]
10271 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10274 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10275 output_asm_insn (\"crxor 6,6,6\", operands);
10277 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10278 output_asm_insn (\"creqv 6,6,6\", operands);
10280 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10282 [(set_attr "type" "branch")
10283 (set_attr "length" "4,8")])
10285 (define_insn "*call_local64"
10286 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10287 (match_operand 1 "" "g,g"))
10288 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10289 (clobber (reg:SI LR_REGNO))]
10290 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10293 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10294 output_asm_insn (\"crxor 6,6,6\", operands);
10296 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10297 output_asm_insn (\"creqv 6,6,6\", operands);
10299 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10301 [(set_attr "type" "branch")
10302 (set_attr "length" "4,8")])
10304 (define_insn "*call_value_local32"
10305 [(set (match_operand 0 "" "")
10306 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10307 (match_operand 2 "" "g,g")))
10308 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10309 (clobber (reg:SI LR_REGNO))]
10310 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10313 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10314 output_asm_insn (\"crxor 6,6,6\", operands);
10316 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10317 output_asm_insn (\"creqv 6,6,6\", operands);
10319 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10321 [(set_attr "type" "branch")
10322 (set_attr "length" "4,8")])
10325 (define_insn "*call_value_local64"
10326 [(set (match_operand 0 "" "")
10327 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10328 (match_operand 2 "" "g,g")))
10329 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10330 (clobber (reg:SI LR_REGNO))]
10331 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10334 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10335 output_asm_insn (\"crxor 6,6,6\", operands);
10337 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10338 output_asm_insn (\"creqv 6,6,6\", operands);
10340 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10342 [(set_attr "type" "branch")
10343 (set_attr "length" "4,8")])
10346 ;; A function pointer under System V is just a normal pointer
10347 ;; operands[0] is the function pointer
10348 ;; operands[1] is the stack size to clean up
10349 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10350 ;; which indicates how to set cr1
10352 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10353 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10354 (match_operand 1 "" "g,g,g,g"))
10355 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10356 (clobber (reg:SI LR_REGNO))]
10357 "DEFAULT_ABI == ABI_V4
10358 || DEFAULT_ABI == ABI_DARWIN"
10360 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10361 output_asm_insn ("crxor 6,6,6", operands);
10363 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10364 output_asm_insn ("creqv 6,6,6", operands);
10368 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10369 (set_attr "length" "4,4,8,8")])
10371 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10372 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10373 (match_operand 1 "" "g,g"))
10374 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10375 (clobber (reg:SI LR_REGNO))]
10376 "(DEFAULT_ABI == ABI_DARWIN
10377 || (DEFAULT_ABI == ABI_V4
10378 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10380 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10381 output_asm_insn ("crxor 6,6,6", operands);
10383 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10384 output_asm_insn ("creqv 6,6,6", operands);
10387 return output_call(insn, operands, 0, 2);
10389 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10391 gcc_assert (!TARGET_SECURE_PLT);
10392 return "bl %z0@plt";
10398 "DEFAULT_ABI == ABI_V4
10399 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10400 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10401 [(parallel [(call (mem:SI (match_dup 0))
10403 (use (match_dup 2))
10404 (use (match_dup 3))
10405 (clobber (reg:SI LR_REGNO))])]
10407 operands[3] = pic_offset_table_rtx;
10409 [(set_attr "type" "branch,branch")
10410 (set_attr "length" "4,8")])
10412 (define_insn "*call_nonlocal_sysv_secure<mode>"
10413 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10414 (match_operand 1 "" "g,g"))
10415 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10416 (use (match_operand:SI 3 "register_operand" "r,r"))
10417 (clobber (reg:SI LR_REGNO))]
10418 "(DEFAULT_ABI == ABI_V4
10419 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10420 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10422 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10423 output_asm_insn ("crxor 6,6,6", operands);
10425 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10426 output_asm_insn ("creqv 6,6,6", operands);
10429 /* The magic 32768 offset here and in the other sysv call insns
10430 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10431 See sysv4.h:toc_section. */
10432 return "bl %z0+32768@plt";
10434 return "bl %z0@plt";
10436 [(set_attr "type" "branch,branch")
10437 (set_attr "length" "4,8")])
10439 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10440 [(set (match_operand 0 "" "")
10441 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10442 (match_operand 2 "" "g,g,g,g")))
10443 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10444 (clobber (reg:SI LR_REGNO))]
10445 "DEFAULT_ABI == ABI_V4
10446 || DEFAULT_ABI == ABI_DARWIN"
10448 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10449 output_asm_insn ("crxor 6,6,6", operands);
10451 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10452 output_asm_insn ("creqv 6,6,6", operands);
10456 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10457 (set_attr "length" "4,4,8,8")])
10459 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10460 [(set (match_operand 0 "" "")
10461 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10462 (match_operand 2 "" "g,g")))
10463 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10464 (clobber (reg:SI LR_REGNO))]
10465 "(DEFAULT_ABI == ABI_DARWIN
10466 || (DEFAULT_ABI == ABI_V4
10467 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10469 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10470 output_asm_insn ("crxor 6,6,6", operands);
10472 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10473 output_asm_insn ("creqv 6,6,6", operands);
10476 return output_call(insn, operands, 1, 3);
10478 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10480 gcc_assert (!TARGET_SECURE_PLT);
10481 return "bl %z1@plt";
10487 "DEFAULT_ABI == ABI_V4
10488 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10489 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10490 [(parallel [(set (match_dup 0)
10491 (call (mem:SI (match_dup 1))
10493 (use (match_dup 3))
10494 (use (match_dup 4))
10495 (clobber (reg:SI LR_REGNO))])]
10497 operands[4] = pic_offset_table_rtx;
10499 [(set_attr "type" "branch,branch")
10500 (set_attr "length" "4,8")])
10502 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10503 [(set (match_operand 0 "" "")
10504 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10505 (match_operand 2 "" "g,g")))
10506 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10507 (use (match_operand:SI 4 "register_operand" "r,r"))
10508 (clobber (reg:SI LR_REGNO))]
10509 "(DEFAULT_ABI == ABI_V4
10510 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10511 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10513 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10514 output_asm_insn ("crxor 6,6,6", operands);
10516 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10517 output_asm_insn ("creqv 6,6,6", operands);
10520 return "bl %z1+32768@plt";
10522 return "bl %z1@plt";
10524 [(set_attr "type" "branch,branch")
10525 (set_attr "length" "4,8")])
10528 ;; Call to AIX abi function in the same module.
10530 (define_insn "*call_local_aix<mode>"
10531 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10532 (match_operand 1 "" "g"))
10533 (clobber (reg:P LR_REGNO))]
10534 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10536 [(set_attr "type" "branch")
10537 (set_attr "length" "4")])
10539 (define_insn "*call_value_local_aix<mode>"
10540 [(set (match_operand 0 "" "")
10541 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10542 (match_operand 2 "" "g")))
10543 (clobber (reg:P LR_REGNO))]
10544 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10546 [(set_attr "type" "branch")
10547 (set_attr "length" "4")])
10549 ;; Call to AIX abi function which may be in another module.
10550 ;; Restore the TOC pointer (r2) after the call.
10552 (define_insn "*call_nonlocal_aix<mode>"
10553 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10554 (match_operand 1 "" "g"))
10555 (clobber (reg:P LR_REGNO))]
10556 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10558 [(set_attr "type" "branch")
10559 (set_attr "length" "8")])
10561 (define_insn "*call_value_nonlocal_aix<mode>"
10562 [(set (match_operand 0 "" "")
10563 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10564 (match_operand 2 "" "g")))
10565 (clobber (reg:P LR_REGNO))]
10566 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10568 [(set_attr "type" "branch")
10569 (set_attr "length" "8")])
10571 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10572 ;; Operand0 is the addresss of the function to call
10573 ;; Operand2 is the location in the function descriptor to load r2 from
10574 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10576 (define_insn "*call_indirect_aix<mode>"
10577 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10578 (match_operand 1 "" "g,g"))
10579 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10580 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10581 (clobber (reg:P LR_REGNO))]
10582 "DEFAULT_ABI == ABI_AIX"
10583 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10584 [(set_attr "type" "jmpreg")
10585 (set_attr "length" "12")])
10587 (define_insn "*call_value_indirect_aix<mode>"
10588 [(set (match_operand 0 "" "")
10589 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10590 (match_operand 2 "" "g,g")))
10591 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10592 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10593 (clobber (reg:P LR_REGNO))]
10594 "DEFAULT_ABI == ABI_AIX"
10595 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10596 [(set_attr "type" "jmpreg")
10597 (set_attr "length" "12")])
10599 ;; Call to indirect functions with the ELFv2 ABI.
10600 ;; Operand0 is the addresss of the function to call
10601 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10603 (define_insn "*call_indirect_elfv2<mode>"
10604 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10605 (match_operand 1 "" "g,g"))
10606 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10607 (clobber (reg:P LR_REGNO))]
10608 "DEFAULT_ABI == ABI_ELFv2"
10609 "b%T0l\;<ptrload> 2,%2(1)"
10610 [(set_attr "type" "jmpreg")
10611 (set_attr "length" "8")])
10613 (define_insn "*call_value_indirect_elfv2<mode>"
10614 [(set (match_operand 0 "" "")
10615 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10616 (match_operand 2 "" "g,g")))
10617 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10618 (clobber (reg:P LR_REGNO))]
10619 "DEFAULT_ABI == ABI_ELFv2"
10620 "b%T1l\;<ptrload> 2,%3(1)"
10621 [(set_attr "type" "jmpreg")
10622 (set_attr "length" "8")])
10625 ;; Call subroutine returning any type.
10626 (define_expand "untyped_call"
10627 [(parallel [(call (match_operand 0 "" "")
10629 (match_operand 1 "" "")
10630 (match_operand 2 "" "")])]
10636 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10638 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10640 rtx set = XVECEXP (operands[2], 0, i);
10641 emit_move_insn (SET_DEST (set), SET_SRC (set));
10644 /* The optimizer does not know that the call sets the function value
10645 registers we stored in the result block. We avoid problems by
10646 claiming that all hard registers are used and clobbered at this
10648 emit_insn (gen_blockage ());
10653 ;; sibling call patterns
10654 (define_expand "sibcall"
10655 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10656 (match_operand 1 "" ""))
10657 (use (match_operand 2 "" ""))
10663 if (MACHOPIC_INDIRECT)
10664 operands[0] = machopic_indirect_call_target (operands[0]);
10667 gcc_assert (GET_CODE (operands[0]) == MEM);
10668 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10670 operands[0] = XEXP (operands[0], 0);
10672 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10674 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10679 (define_expand "sibcall_value"
10680 [(parallel [(set (match_operand 0 "register_operand" "")
10681 (call (mem:SI (match_operand 1 "address_operand" ""))
10682 (match_operand 2 "" "")))
10683 (use (match_operand 3 "" ""))
10689 if (MACHOPIC_INDIRECT)
10690 operands[1] = machopic_indirect_call_target (operands[1]);
10693 gcc_assert (GET_CODE (operands[1]) == MEM);
10694 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10696 operands[1] = XEXP (operands[1], 0);
10698 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10700 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10705 (define_insn "*sibcall_local32"
10706 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10707 (match_operand 1 "" "g,g"))
10708 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10710 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10713 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10714 output_asm_insn (\"crxor 6,6,6\", operands);
10716 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10717 output_asm_insn (\"creqv 6,6,6\", operands);
10719 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10721 [(set_attr "type" "branch")
10722 (set_attr "length" "4,8")])
10724 (define_insn "*sibcall_local64"
10725 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10726 (match_operand 1 "" "g,g"))
10727 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10729 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10732 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10733 output_asm_insn (\"crxor 6,6,6\", operands);
10735 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10736 output_asm_insn (\"creqv 6,6,6\", operands);
10738 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10740 [(set_attr "type" "branch")
10741 (set_attr "length" "4,8")])
10743 (define_insn "*sibcall_value_local32"
10744 [(set (match_operand 0 "" "")
10745 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10746 (match_operand 2 "" "g,g")))
10747 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10749 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10752 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10753 output_asm_insn (\"crxor 6,6,6\", operands);
10755 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10756 output_asm_insn (\"creqv 6,6,6\", operands);
10758 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10760 [(set_attr "type" "branch")
10761 (set_attr "length" "4,8")])
10763 (define_insn "*sibcall_value_local64"
10764 [(set (match_operand 0 "" "")
10765 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10766 (match_operand 2 "" "g,g")))
10767 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10769 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10772 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10773 output_asm_insn (\"crxor 6,6,6\", operands);
10775 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10776 output_asm_insn (\"creqv 6,6,6\", operands);
10778 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10780 [(set_attr "type" "branch")
10781 (set_attr "length" "4,8")])
10783 (define_insn "*sibcall_nonlocal_sysv<mode>"
10784 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10785 (match_operand 1 "" ""))
10786 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10788 "(DEFAULT_ABI == ABI_DARWIN
10789 || DEFAULT_ABI == ABI_V4)
10790 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10793 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10794 output_asm_insn (\"crxor 6,6,6\", operands);
10796 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10797 output_asm_insn (\"creqv 6,6,6\", operands);
10799 if (which_alternative >= 2)
10801 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10803 gcc_assert (!TARGET_SECURE_PLT);
10804 return \"b %z0@plt\";
10809 [(set_attr "type" "branch")
10810 (set_attr "length" "4,8,4,8")])
10812 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10813 [(set (match_operand 0 "" "")
10814 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10815 (match_operand 2 "" "")))
10816 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10818 "(DEFAULT_ABI == ABI_DARWIN
10819 || DEFAULT_ABI == ABI_V4)
10820 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10823 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10824 output_asm_insn (\"crxor 6,6,6\", operands);
10826 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10827 output_asm_insn (\"creqv 6,6,6\", operands);
10829 if (which_alternative >= 2)
10831 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10833 gcc_assert (!TARGET_SECURE_PLT);
10834 return \"b %z1@plt\";
10839 [(set_attr "type" "branch")
10840 (set_attr "length" "4,8,4,8")])
10842 ;; AIX ABI sibling call patterns.
10844 (define_insn "*sibcall_aix<mode>"
10845 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10846 (match_operand 1 "" "g,g"))
10848 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10852 [(set_attr "type" "branch")
10853 (set_attr "length" "4")])
10855 (define_insn "*sibcall_value_aix<mode>"
10856 [(set (match_operand 0 "" "")
10857 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10858 (match_operand 2 "" "g,g")))
10860 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10864 [(set_attr "type" "branch")
10865 (set_attr "length" "4")])
10867 (define_expand "sibcall_epilogue"
10868 [(use (const_int 0))]
10871 if (!TARGET_SCHED_PROLOG)
10872 emit_insn (gen_blockage ());
10873 rs6000_emit_epilogue (TRUE);
10877 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10878 ;; all of memory. This blocks insns from being moved across this point.
10880 (define_insn "blockage"
10881 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10885 (define_expand "probe_stack_address"
10886 [(use (match_operand 0 "address_operand"))]
10889 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10890 MEM_VOLATILE_P (operands[0]) = 1;
10893 emit_insn (gen_probe_stack_di (operands[0]));
10895 emit_insn (gen_probe_stack_si (operands[0]));
10899 (define_insn "probe_stack_<mode>"
10900 [(set (match_operand:P 0 "memory_operand" "=m")
10901 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10904 operands[1] = gen_rtx_REG (Pmode, 0);
10905 return "st<wd>%U0%X0 %1,%0";
10907 [(set_attr "type" "store")
10908 (set (attr "update")
10909 (if_then_else (match_operand 0 "update_address_mem")
10910 (const_string "yes")
10911 (const_string "no")))
10912 (set (attr "indexed")
10913 (if_then_else (match_operand 0 "indexed_address_mem")
10914 (const_string "yes")
10915 (const_string "no")))
10916 (set_attr "length" "4")])
10918 (define_insn "probe_stack_range<P:mode>"
10919 [(set (match_operand:P 0 "register_operand" "=r")
10920 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10921 (match_operand:P 2 "register_operand" "r")]
10922 UNSPECV_PROBE_STACK_RANGE))]
10924 "* return output_probe_stack_range (operands[0], operands[2]);"
10925 [(set_attr "type" "three")])
10927 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
10928 ;; signed & unsigned, and one type of branch.
10930 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10931 ;; insns, and branches.
10933 (define_expand "cbranch<mode>4"
10934 [(use (match_operator 0 "rs6000_cbranch_operator"
10935 [(match_operand:GPR 1 "gpc_reg_operand" "")
10936 (match_operand:GPR 2 "reg_or_short_operand" "")]))
10937 (use (match_operand 3 ""))]
10941 /* Take care of the possibility that operands[2] might be negative but
10942 this might be a logical operation. That insn doesn't exist. */
10943 if (GET_CODE (operands[2]) == CONST_INT
10944 && INTVAL (operands[2]) < 0)
10946 operands[2] = force_reg (<MODE>mode, operands[2]);
10947 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10948 GET_MODE (operands[0]),
10949 operands[1], operands[2]);
10952 rs6000_emit_cbranch (<MODE>mode, operands);
10956 (define_expand "cbranch<mode>4"
10957 [(use (match_operator 0 "rs6000_cbranch_operator"
10958 [(match_operand:FP 1 "gpc_reg_operand" "")
10959 (match_operand:FP 2 "gpc_reg_operand" "")]))
10960 (use (match_operand 3 ""))]
10964 rs6000_emit_cbranch (<MODE>mode, operands);
10968 (define_expand "cstore<mode>4_signed"
10969 [(use (match_operator 1 "signed_comparison_operator"
10970 [(match_operand:P 2 "gpc_reg_operand")
10971 (match_operand:P 3 "gpc_reg_operand")]))
10972 (clobber (match_operand:P 0 "gpc_reg_operand"))]
10975 enum rtx_code cond_code = GET_CODE (operands[1]);
10977 rtx op0 = operands[0];
10978 rtx op1 = operands[2];
10979 rtx op2 = operands[3];
10981 if (cond_code == GE || cond_code == LT)
10983 cond_code = swap_condition (cond_code);
10984 std::swap (op1, op2);
10987 rtx tmp1 = gen_reg_rtx (<MODE>mode);
10988 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10989 rtx tmp3 = gen_reg_rtx (<MODE>mode);
10991 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10992 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10993 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10995 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10997 if (cond_code == LE)
10998 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11001 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11002 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11003 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11009 (define_expand "cstore<mode>4_unsigned"
11010 [(use (match_operator 1 "unsigned_comparison_operator"
11011 [(match_operand:P 2 "gpc_reg_operand")
11012 (match_operand:P 3 "reg_or_short_operand")]))
11013 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11016 enum rtx_code cond_code = GET_CODE (operands[1]);
11018 rtx op0 = operands[0];
11019 rtx op1 = operands[2];
11020 rtx op2 = operands[3];
11022 if (cond_code == GEU || cond_code == LTU)
11024 cond_code = swap_condition (cond_code);
11025 std::swap (op1, op2);
11028 if (!gpc_reg_operand (op1, <MODE>mode))
11029 op1 = force_reg (<MODE>mode, op1);
11030 if (!reg_or_short_operand (op2, <MODE>mode))
11031 op2 = force_reg (<MODE>mode, op2);
11033 rtx tmp = gen_reg_rtx (<MODE>mode);
11034 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11036 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11037 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11039 if (cond_code == LEU)
11040 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11042 emit_insn (gen_neg<mode>2 (op0, tmp2));
11047 (define_expand "cstore_si_as_di"
11048 [(use (match_operator 1 "unsigned_comparison_operator"
11049 [(match_operand:SI 2 "gpc_reg_operand")
11050 (match_operand:SI 3 "reg_or_short_operand")]))
11051 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11054 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11055 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11057 operands[2] = force_reg (SImode, operands[2]);
11058 operands[3] = force_reg (SImode, operands[3]);
11059 rtx op1 = gen_reg_rtx (DImode);
11060 rtx op2 = gen_reg_rtx (DImode);
11061 convert_move (op1, operands[2], uns_flag);
11062 convert_move (op2, operands[3], uns_flag);
11064 if (cond_code == GT || cond_code == LE)
11066 cond_code = swap_condition (cond_code);
11067 std::swap (op1, op2);
11070 rtx tmp = gen_reg_rtx (DImode);
11071 rtx tmp2 = gen_reg_rtx (DImode);
11072 emit_insn (gen_subdi3 (tmp, op1, op2));
11073 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11079 gcc_unreachable ();
11084 tmp3 = gen_reg_rtx (DImode);
11085 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11089 convert_move (operands[0], tmp3, 1);
11094 (define_expand "cstore<mode>4_signed_imm"
11095 [(use (match_operator 1 "signed_comparison_operator"
11096 [(match_operand:GPR 2 "gpc_reg_operand")
11097 (match_operand:GPR 3 "immediate_operand")]))
11098 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11101 bool invert = false;
11103 enum rtx_code cond_code = GET_CODE (operands[1]);
11105 rtx op0 = operands[0];
11106 rtx op1 = operands[2];
11107 HOST_WIDE_INT val = INTVAL (operands[3]);
11109 if (cond_code == GE || cond_code == GT)
11111 cond_code = reverse_condition (cond_code);
11115 if (cond_code == LE)
11118 rtx tmp = gen_reg_rtx (<MODE>mode);
11119 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11120 rtx x = gen_reg_rtx (<MODE>mode);
11122 emit_insn (gen_and<mode>3 (x, op1, tmp));
11124 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11128 rtx tmp = gen_reg_rtx (<MODE>mode);
11129 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11133 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11134 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11139 (define_expand "cstore<mode>4_unsigned_imm"
11140 [(use (match_operator 1 "unsigned_comparison_operator"
11141 [(match_operand:GPR 2 "gpc_reg_operand")
11142 (match_operand:GPR 3 "immediate_operand")]))
11143 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11146 bool invert = false;
11148 enum rtx_code cond_code = GET_CODE (operands[1]);
11150 rtx op0 = operands[0];
11151 rtx op1 = operands[2];
11152 HOST_WIDE_INT val = INTVAL (operands[3]);
11154 if (cond_code == GEU || cond_code == GTU)
11156 cond_code = reverse_condition (cond_code);
11160 if (cond_code == LEU)
11163 rtx tmp = gen_reg_rtx (<MODE>mode);
11164 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11165 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11166 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11167 rtx x = gen_reg_rtx (<MODE>mode);
11169 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11171 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11175 rtx tmp = gen_reg_rtx (<MODE>mode);
11176 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11180 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11181 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11186 (define_expand "cstore<mode>4"
11187 [(use (match_operator 1 "rs6000_cbranch_operator"
11188 [(match_operand:GPR 2 "gpc_reg_operand")
11189 (match_operand:GPR 3 "reg_or_short_operand")]))
11190 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11193 /* Use ISEL if the user asked for it. */
11195 rs6000_emit_sISEL (<MODE>mode, operands);
11197 /* Expanding EQ and NE directly to some machine instructions does not help
11198 but does hurt combine. So don't. */
11199 else if (GET_CODE (operands[1]) == EQ)
11200 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11201 else if (<MODE>mode == Pmode
11202 && GET_CODE (operands[1]) == NE)
11203 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11204 else if (GET_CODE (operands[1]) == NE)
11206 rtx tmp = gen_reg_rtx (<MODE>mode);
11207 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11208 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11211 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11212 etc. combinations magically work out just right. */
11213 else if (<MODE>mode == Pmode
11214 && unsigned_comparison_operator (operands[1], VOIDmode))
11215 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11216 operands[2], operands[3]));
11218 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11219 else if (<MODE>mode == SImode && Pmode == DImode)
11220 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11221 operands[2], operands[3]));
11223 /* For signed comparisons against a constant, we can do some simple
11225 else if (signed_comparison_operator (operands[1], VOIDmode)
11226 && CONST_INT_P (operands[3]))
11227 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11228 operands[2], operands[3]));
11230 /* And similarly for unsigned comparisons. */
11231 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11232 && CONST_INT_P (operands[3]))
11233 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11234 operands[2], operands[3]));
11236 /* We also do not want to use mfcr for signed comparisons. */
11237 else if (<MODE>mode == Pmode
11238 && signed_comparison_operator (operands[1], VOIDmode))
11239 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11240 operands[2], operands[3]));
11242 /* Everything else, use the mfcr brute force. */
11244 rs6000_emit_sCOND (<MODE>mode, operands);
11249 (define_expand "cstore<mode>4"
11250 [(use (match_operator 1 "rs6000_cbranch_operator"
11251 [(match_operand:FP 2 "gpc_reg_operand")
11252 (match_operand:FP 3 "gpc_reg_operand")]))
11253 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11256 rs6000_emit_sCOND (<MODE>mode, operands);
11261 (define_expand "stack_protect_set"
11262 [(match_operand 0 "memory_operand" "")
11263 (match_operand 1 "memory_operand" "")]
11266 #ifdef TARGET_THREAD_SSP_OFFSET
11267 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11268 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11269 operands[1] = gen_rtx_MEM (Pmode, addr);
11272 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11274 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11278 (define_insn "stack_protect_setsi"
11279 [(set (match_operand:SI 0 "memory_operand" "=m")
11280 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11281 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11283 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11284 [(set_attr "type" "three")
11285 (set_attr "length" "12")])
11287 (define_insn "stack_protect_setdi"
11288 [(set (match_operand:DI 0 "memory_operand" "=Y")
11289 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11290 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11292 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11293 [(set_attr "type" "three")
11294 (set_attr "length" "12")])
11296 (define_expand "stack_protect_test"
11297 [(match_operand 0 "memory_operand" "")
11298 (match_operand 1 "memory_operand" "")
11299 (match_operand 2 "" "")]
11302 rtx test, op0, op1;
11303 #ifdef TARGET_THREAD_SSP_OFFSET
11304 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11305 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11306 operands[1] = gen_rtx_MEM (Pmode, addr);
11309 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11310 test = gen_rtx_EQ (VOIDmode, op0, op1);
11311 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11315 (define_insn "stack_protect_testsi"
11316 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11317 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11318 (match_operand:SI 2 "memory_operand" "m,m")]
11320 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11321 (clobber (match_scratch:SI 3 "=&r,&r"))]
11324 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11325 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11326 [(set_attr "length" "16,20")])
11328 (define_insn "stack_protect_testdi"
11329 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11330 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11331 (match_operand:DI 2 "memory_operand" "Y,Y")]
11333 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11334 (clobber (match_scratch:DI 3 "=&r,&r"))]
11337 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11338 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11339 [(set_attr "length" "16,20")])
11342 ;; Here are the actual compare insns.
11343 (define_insn "*cmp<mode>_signed"
11344 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11345 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11346 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11348 "cmp<wd>%I2 %0,%1,%2"
11349 [(set_attr "type" "cmp")])
11351 (define_insn "*cmp<mode>_unsigned"
11352 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11353 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11354 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11356 "cmpl<wd>%I2 %0,%1,%2"
11357 [(set_attr "type" "cmp")])
11359 ;; If we are comparing a register for equality with a large constant,
11360 ;; we can do this with an XOR followed by a compare. But this is profitable
11361 ;; only if the large constant is only used for the comparison (and in this
11362 ;; case we already have a register to reuse as scratch).
11364 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11365 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11368 [(set (match_operand:SI 0 "register_operand")
11369 (match_operand:SI 1 "logical_const_operand" ""))
11370 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11372 (match_operand:SI 2 "logical_const_operand" "")]))
11373 (set (match_operand:CC 4 "cc_reg_operand" "")
11374 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11377 (if_then_else (match_operator 6 "equality_operator"
11378 [(match_dup 4) (const_int 0)])
11379 (match_operand 7 "" "")
11380 (match_operand 8 "" "")))]
11381 "peep2_reg_dead_p (3, operands[0])
11382 && peep2_reg_dead_p (4, operands[4])
11383 && REGNO (operands[0]) != REGNO (operands[5])"
11384 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11385 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11386 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11389 /* Get the constant we are comparing against, and see what it looks like
11390 when sign-extended from 16 to 32 bits. Then see what constant we could
11391 XOR with SEXTC to get the sign-extended value. */
11392 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11394 operands[1], operands[2]);
11395 HOST_WIDE_INT c = INTVAL (cnst);
11396 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11397 HOST_WIDE_INT xorv = c ^ sextc;
11399 operands[9] = GEN_INT (xorv);
11400 operands[10] = GEN_INT (sextc);
11403 ;; The following two insns don't exist as single insns, but if we provide
11404 ;; them, we can swap an add and compare, which will enable us to overlap more
11405 ;; of the required delay between a compare and branch. We generate code for
11406 ;; them by splitting.
11409 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11410 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11411 (match_operand:SI 2 "short_cint_operand" "i")))
11412 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11413 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11416 [(set_attr "length" "8")])
11419 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11420 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11421 (match_operand:SI 2 "u_short_cint_operand" "i")))
11422 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11423 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11426 [(set_attr "length" "8")])
11429 [(set (match_operand:CC 3 "cc_reg_operand" "")
11430 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11431 (match_operand:SI 2 "short_cint_operand" "")))
11432 (set (match_operand:SI 0 "gpc_reg_operand" "")
11433 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11435 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11436 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11439 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11440 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11441 (match_operand:SI 2 "u_short_cint_operand" "")))
11442 (set (match_operand:SI 0 "gpc_reg_operand" "")
11443 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11445 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11446 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11448 ;; Only need to compare second words if first words equal
11449 (define_insn "*cmp<mode>_internal1"
11450 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11451 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11452 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11453 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11454 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11455 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11456 [(set_attr "type" "fpcompare")
11457 (set_attr "length" "12")])
11459 (define_insn_and_split "*cmp<mode>_internal2"
11460 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11461 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11462 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11463 (clobber (match_scratch:DF 3 "=d"))
11464 (clobber (match_scratch:DF 4 "=d"))
11465 (clobber (match_scratch:DF 5 "=d"))
11466 (clobber (match_scratch:DF 6 "=d"))
11467 (clobber (match_scratch:DF 7 "=d"))
11468 (clobber (match_scratch:DF 8 "=d"))
11469 (clobber (match_scratch:DF 9 "=d"))
11470 (clobber (match_scratch:DF 10 "=d"))
11471 (clobber (match_scratch:GPR 11 "=b"))]
11472 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11473 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11475 "&& reload_completed"
11476 [(set (match_dup 3) (match_dup 14))
11477 (set (match_dup 4) (match_dup 15))
11478 (set (match_dup 9) (abs:DF (match_dup 5)))
11479 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11480 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11481 (label_ref (match_dup 12))
11483 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11484 (set (pc) (label_ref (match_dup 13)))
11486 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11487 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11488 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11489 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11492 REAL_VALUE_TYPE rv;
11493 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11494 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11496 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11497 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11498 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11499 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11500 operands[12] = gen_label_rtx ();
11501 operands[13] = gen_label_rtx ();
11503 operands[14] = force_const_mem (DFmode,
11504 const_double_from_real_value (rv, DFmode));
11505 operands[15] = force_const_mem (DFmode,
11506 const_double_from_real_value (dconst0,
11511 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11512 operands[14] = gen_const_mem (DFmode, tocref);
11513 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11514 operands[15] = gen_const_mem (DFmode, tocref);
11515 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11516 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11520 ;; Now we have the scc insns. We can do some combinations because of the
11521 ;; way the machine works.
11523 ;; Note that this is probably faster if we can put an insn between the
11524 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11525 ;; cases the insns below which don't use an intermediate CR field will
11526 ;; be used instead.
11528 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11529 (match_operator:SI 1 "scc_comparison_operator"
11530 [(match_operand 2 "cc_reg_operand" "y")
11533 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11534 [(set (attr "type")
11535 (cond [(match_test "TARGET_MFCRF")
11536 (const_string "mfcrf")
11538 (const_string "mfcr")))
11539 (set_attr "length" "8")])
11541 ;; Same as above, but get the GT bit.
11542 (define_insn "move_from_CR_gt_bit"
11543 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11544 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11545 "TARGET_HARD_FLOAT && !TARGET_FPRS"
11546 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11547 [(set_attr "type" "mfcr")
11548 (set_attr "length" "8")])
11550 ;; Same as above, but get the OV/ORDERED bit.
11551 (define_insn "move_from_CR_ov_bit"
11552 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11553 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11556 "mfcr %0\;rlwinm %0,%0,%t1,1"
11557 [(set_attr "type" "mfcr")
11558 (set_attr "length" "8")])
11561 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11562 (match_operator:DI 1 "scc_comparison_operator"
11563 [(match_operand 2 "cc_reg_operand" "y")
11566 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11567 [(set (attr "type")
11568 (cond [(match_test "TARGET_MFCRF")
11569 (const_string "mfcrf")
11571 (const_string "mfcr")))
11572 (set_attr "length" "8")])
11575 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11576 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11577 [(match_operand 2 "cc_reg_operand" "y,y")
11580 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11581 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11584 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11586 [(set_attr "type" "shift")
11587 (set_attr "dot" "yes")
11588 (set_attr "length" "8,16")])
11591 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11592 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11593 [(match_operand 2 "cc_reg_operand" "")
11596 (set (match_operand:SI 3 "gpc_reg_operand" "")
11597 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11598 "TARGET_32BIT && reload_completed"
11599 [(set (match_dup 3)
11600 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11602 (compare:CC (match_dup 3)
11607 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11608 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11609 [(match_operand 2 "cc_reg_operand" "y")
11611 (match_operand:SI 3 "const_int_operand" "n")))]
11615 int is_bit = ccr_bit (operands[1], 1);
11616 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11619 if (is_bit >= put_bit)
11620 count = is_bit - put_bit;
11622 count = 32 - (put_bit - is_bit);
11624 operands[4] = GEN_INT (count);
11625 operands[5] = GEN_INT (put_bit);
11627 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11629 [(set (attr "type")
11630 (cond [(match_test "TARGET_MFCRF")
11631 (const_string "mfcrf")
11633 (const_string "mfcr")))
11634 (set_attr "length" "8")])
11637 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11639 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11640 [(match_operand 2 "cc_reg_operand" "y,y")
11642 (match_operand:SI 3 "const_int_operand" "n,n"))
11644 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11645 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11650 int is_bit = ccr_bit (operands[1], 1);
11651 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11654 /* Force split for non-cc0 compare. */
11655 if (which_alternative == 1)
11658 if (is_bit >= put_bit)
11659 count = is_bit - put_bit;
11661 count = 32 - (put_bit - is_bit);
11663 operands[5] = GEN_INT (count);
11664 operands[6] = GEN_INT (put_bit);
11666 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11668 [(set_attr "type" "shift")
11669 (set_attr "dot" "yes")
11670 (set_attr "length" "8,16")])
11673 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11675 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11676 [(match_operand 2 "cc_reg_operand" "")
11678 (match_operand:SI 3 "const_int_operand" ""))
11680 (set (match_operand:SI 4 "gpc_reg_operand" "")
11681 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11684 [(set (match_dup 4)
11685 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11688 (compare:CC (match_dup 4)
11693 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11696 (define_insn_and_split "eq<mode>3"
11697 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11698 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11699 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11700 (clobber (match_scratch:GPR 3 "=r"))
11701 (clobber (match_scratch:GPR 4 "=r"))]
11705 [(set (match_dup 4)
11706 (clz:GPR (match_dup 3)))
11708 (lshiftrt:GPR (match_dup 4)
11711 operands[3] = rs6000_emit_eqne (<MODE>mode,
11712 operands[1], operands[2], operands[3]);
11714 if (GET_CODE (operands[4]) == SCRATCH)
11715 operands[4] = gen_reg_rtx (<MODE>mode);
11717 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11719 [(set (attr "length")
11720 (if_then_else (match_test "operands[2] == const0_rtx")
11722 (const_string "12")))])
11724 (define_insn_and_split "ne<mode>3"
11725 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11726 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11727 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11728 (clobber (match_scratch:P 3 "=r"))
11729 (clobber (match_scratch:P 4 "=r"))
11730 (clobber (reg:P CA_REGNO))]
11734 [(parallel [(set (match_dup 4)
11735 (plus:P (match_dup 3)
11737 (set (reg:P CA_REGNO)
11738 (ne:P (match_dup 3)
11740 (parallel [(set (match_dup 0)
11741 (plus:P (plus:P (not:P (match_dup 4))
11744 (clobber (reg:P CA_REGNO))])]
11746 operands[3] = rs6000_emit_eqne (<MODE>mode,
11747 operands[1], operands[2], operands[3]);
11749 if (GET_CODE (operands[4]) == SCRATCH)
11750 operands[4] = gen_reg_rtx (<MODE>mode);
11752 [(set (attr "length")
11753 (if_then_else (match_test "operands[2] == const0_rtx")
11755 (const_string "12")))])
11757 (define_insn_and_split "*neg_eq_<mode>"
11758 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11759 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11760 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11761 (clobber (match_scratch:P 3 "=r"))
11762 (clobber (match_scratch:P 4 "=r"))
11763 (clobber (reg:P CA_REGNO))]
11767 [(parallel [(set (match_dup 4)
11768 (plus:P (match_dup 3)
11770 (set (reg:P CA_REGNO)
11771 (ne:P (match_dup 3)
11773 (parallel [(set (match_dup 0)
11774 (plus:P (reg:P CA_REGNO)
11776 (clobber (reg:P CA_REGNO))])]
11778 operands[3] = rs6000_emit_eqne (<MODE>mode,
11779 operands[1], operands[2], operands[3]);
11781 if (GET_CODE (operands[4]) == SCRATCH)
11782 operands[4] = gen_reg_rtx (<MODE>mode);
11784 [(set (attr "length")
11785 (if_then_else (match_test "operands[2] == const0_rtx")
11787 (const_string "12")))])
11789 (define_insn_and_split "*neg_ne_<mode>"
11790 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11791 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11792 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11793 (clobber (match_scratch:P 3 "=r"))
11794 (clobber (match_scratch:P 4 "=r"))
11795 (clobber (reg:P CA_REGNO))]
11799 [(parallel [(set (match_dup 4)
11800 (neg:P (match_dup 3)))
11801 (set (reg:P CA_REGNO)
11802 (eq:P (match_dup 3)
11804 (parallel [(set (match_dup 0)
11805 (plus:P (reg:P CA_REGNO)
11807 (clobber (reg:P CA_REGNO))])]
11809 operands[3] = rs6000_emit_eqne (<MODE>mode,
11810 operands[1], operands[2], operands[3]);
11812 if (GET_CODE (operands[4]) == SCRATCH)
11813 operands[4] = gen_reg_rtx (<MODE>mode);
11815 [(set (attr "length")
11816 (if_then_else (match_test "operands[2] == const0_rtx")
11818 (const_string "12")))])
11820 (define_insn_and_split "*plus_eq_<mode>"
11821 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11822 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11823 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11824 (match_operand:P 3 "gpc_reg_operand" "r")))
11825 (clobber (match_scratch:P 4 "=r"))
11826 (clobber (match_scratch:P 5 "=r"))
11827 (clobber (reg:P CA_REGNO))]
11831 [(parallel [(set (match_dup 5)
11832 (neg:P (match_dup 4)))
11833 (set (reg:P CA_REGNO)
11834 (eq:P (match_dup 4)
11836 (parallel [(set (match_dup 0)
11837 (plus:P (match_dup 3)
11839 (clobber (reg:P CA_REGNO))])]
11841 operands[4] = rs6000_emit_eqne (<MODE>mode,
11842 operands[1], operands[2], operands[4]);
11844 if (GET_CODE (operands[5]) == SCRATCH)
11845 operands[5] = gen_reg_rtx (<MODE>mode);
11847 [(set (attr "length")
11848 (if_then_else (match_test "operands[2] == const0_rtx")
11850 (const_string "12")))])
11852 (define_insn_and_split "*plus_ne_<mode>"
11853 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11854 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11855 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11856 (match_operand:P 3 "gpc_reg_operand" "r")))
11857 (clobber (match_scratch:P 4 "=r"))
11858 (clobber (match_scratch:P 5 "=r"))
11859 (clobber (reg:P CA_REGNO))]
11863 [(parallel [(set (match_dup 5)
11864 (plus:P (match_dup 4)
11866 (set (reg:P CA_REGNO)
11867 (ne:P (match_dup 4)
11869 (parallel [(set (match_dup 0)
11870 (plus:P (match_dup 3)
11872 (clobber (reg:P CA_REGNO))])]
11874 operands[4] = rs6000_emit_eqne (<MODE>mode,
11875 operands[1], operands[2], operands[4]);
11877 if (GET_CODE (operands[5]) == SCRATCH)
11878 operands[5] = gen_reg_rtx (<MODE>mode);
11880 [(set (attr "length")
11881 (if_then_else (match_test "operands[2] == const0_rtx")
11883 (const_string "12")))])
11885 (define_insn_and_split "*minus_eq_<mode>"
11886 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11887 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11888 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11889 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11890 (clobber (match_scratch:P 4 "=r"))
11891 (clobber (match_scratch:P 5 "=r"))
11892 (clobber (reg:P CA_REGNO))]
11896 [(parallel [(set (match_dup 5)
11897 (plus:P (match_dup 4)
11899 (set (reg:P CA_REGNO)
11900 (ne:P (match_dup 4)
11902 (parallel [(set (match_dup 0)
11903 (plus:P (plus:P (match_dup 3)
11906 (clobber (reg:P CA_REGNO))])]
11908 operands[4] = rs6000_emit_eqne (<MODE>mode,
11909 operands[1], operands[2], operands[4]);
11911 if (GET_CODE (operands[5]) == SCRATCH)
11912 operands[5] = gen_reg_rtx (<MODE>mode);
11914 [(set (attr "length")
11915 (if_then_else (match_test "operands[2] == const0_rtx")
11917 (const_string "12")))])
11919 (define_insn_and_split "*minus_ne_<mode>"
11920 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11921 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11922 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11923 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11924 (clobber (match_scratch:P 4 "=r"))
11925 (clobber (match_scratch:P 5 "=r"))
11926 (clobber (reg:P CA_REGNO))]
11930 [(parallel [(set (match_dup 5)
11931 (neg:P (match_dup 4)))
11932 (set (reg:P CA_REGNO)
11933 (eq:P (match_dup 4)
11935 (parallel [(set (match_dup 0)
11936 (plus:P (plus:P (match_dup 3)
11939 (clobber (reg:P CA_REGNO))])]
11941 operands[4] = rs6000_emit_eqne (<MODE>mode,
11942 operands[1], operands[2], operands[4]);
11944 if (GET_CODE (operands[5]) == SCRATCH)
11945 operands[5] = gen_reg_rtx (<MODE>mode);
11947 [(set (attr "length")
11948 (if_then_else (match_test "operands[2] == const0_rtx")
11950 (const_string "12")))])
11952 (define_insn_and_split "*eqsi3_ext<mode>"
11953 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11954 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11955 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11956 (clobber (match_scratch:SI 3 "=r"))
11957 (clobber (match_scratch:SI 4 "=r"))]
11961 [(set (match_dup 4)
11962 (clz:SI (match_dup 3)))
11965 (lshiftrt:SI (match_dup 4)
11968 operands[3] = rs6000_emit_eqne (SImode,
11969 operands[1], operands[2], operands[3]);
11971 if (GET_CODE (operands[4]) == SCRATCH)
11972 operands[4] = gen_reg_rtx (SImode);
11974 [(set (attr "length")
11975 (if_then_else (match_test "operands[2] == const0_rtx")
11977 (const_string "12")))])
11979 (define_insn_and_split "*nesi3_ext<mode>"
11980 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11981 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11982 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11983 (clobber (match_scratch:SI 3 "=r"))
11984 (clobber (match_scratch:SI 4 "=r"))
11985 (clobber (match_scratch:EXTSI 5 "=r"))]
11989 [(set (match_dup 4)
11990 (clz:SI (match_dup 3)))
11993 (lshiftrt:SI (match_dup 4)
11996 (xor:EXTSI (match_dup 5)
11999 operands[3] = rs6000_emit_eqne (SImode,
12000 operands[1], operands[2], operands[3]);
12002 if (GET_CODE (operands[4]) == SCRATCH)
12003 operands[4] = gen_reg_rtx (SImode);
12004 if (GET_CODE (operands[5]) == SCRATCH)
12005 operands[5] = gen_reg_rtx (<MODE>mode);
12007 [(set (attr "length")
12008 (if_then_else (match_test "operands[2] == const0_rtx")
12009 (const_string "12")
12010 (const_string "16")))])
12012 ;; Define both directions of branch and return. If we need a reload
12013 ;; register, we'd rather use CR0 since it is much easier to copy a
12014 ;; register CC value to there.
12018 (if_then_else (match_operator 1 "branch_comparison_operator"
12020 "cc_reg_operand" "y")
12022 (label_ref (match_operand 0 "" ""))
12027 return output_cbranch (operands[1], \"%l0\", 0, insn);
12029 [(set_attr "type" "branch")])
12033 (if_then_else (match_operator 0 "branch_comparison_operator"
12035 "cc_reg_operand" "y")
12042 return output_cbranch (operands[0], NULL, 0, insn);
12044 [(set_attr "type" "jmpreg")
12045 (set_attr "length" "4")])
12049 (if_then_else (match_operator 1 "branch_comparison_operator"
12051 "cc_reg_operand" "y")
12054 (label_ref (match_operand 0 "" ""))))]
12058 return output_cbranch (operands[1], \"%l0\", 1, insn);
12060 [(set_attr "type" "branch")])
12064 (if_then_else (match_operator 0 "branch_comparison_operator"
12066 "cc_reg_operand" "y")
12073 return output_cbranch (operands[0], NULL, 1, insn);
12075 [(set_attr "type" "jmpreg")
12076 (set_attr "length" "4")])
12078 ;; Logic on condition register values.
12080 ; This pattern matches things like
12081 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12082 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12084 ; which are generated by the branch logic.
12085 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12087 (define_insn "*cceq_ior_compare"
12088 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12089 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12090 [(match_operator:SI 2
12091 "branch_positive_comparison_operator"
12093 "cc_reg_operand" "y,y")
12095 (match_operator:SI 4
12096 "branch_positive_comparison_operator"
12098 "cc_reg_operand" "0,y")
12102 "cr%q1 %E0,%j2,%j4"
12103 [(set_attr "type" "cr_logical,delayed_cr")])
12105 ; Why is the constant -1 here, but 1 in the previous pattern?
12106 ; Because ~1 has all but the low bit set.
12108 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12109 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12110 [(not:SI (match_operator:SI 2
12111 "branch_positive_comparison_operator"
12113 "cc_reg_operand" "y,y")
12115 (match_operator:SI 4
12116 "branch_positive_comparison_operator"
12118 "cc_reg_operand" "0,y")
12122 "cr%q1 %E0,%j2,%j4"
12123 [(set_attr "type" "cr_logical,delayed_cr")])
12125 (define_insn "*cceq_rev_compare"
12126 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12127 (compare:CCEQ (match_operator:SI 1
12128 "branch_positive_comparison_operator"
12130 "cc_reg_operand" "0,y")
12135 [(set_attr "type" "cr_logical,delayed_cr")])
12137 ;; If we are comparing the result of two comparisons, this can be done
12138 ;; using creqv or crxor.
12140 (define_insn_and_split ""
12141 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12142 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12143 [(match_operand 2 "cc_reg_operand" "y")
12145 (match_operator 3 "branch_comparison_operator"
12146 [(match_operand 4 "cc_reg_operand" "y")
12151 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12155 int positive_1, positive_2;
12157 positive_1 = branch_positive_comparison_operator (operands[1],
12158 GET_MODE (operands[1]));
12159 positive_2 = branch_positive_comparison_operator (operands[3],
12160 GET_MODE (operands[3]));
12163 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12164 GET_CODE (operands[1])),
12166 operands[2], const0_rtx);
12167 else if (GET_MODE (operands[1]) != SImode)
12168 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12169 operands[2], const0_rtx);
12172 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12173 GET_CODE (operands[3])),
12175 operands[4], const0_rtx);
12176 else if (GET_MODE (operands[3]) != SImode)
12177 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12178 operands[4], const0_rtx);
12180 if (positive_1 == positive_2)
12182 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12183 operands[5] = constm1_rtx;
12187 operands[5] = const1_rtx;
12191 ;; Unconditional branch and return.
12193 (define_insn "jump"
12195 (label_ref (match_operand 0 "" "")))]
12198 [(set_attr "type" "branch")])
12200 (define_insn "<return_str>return"
12204 [(set_attr "type" "jmpreg")])
12206 (define_expand "indirect_jump"
12207 [(set (pc) (match_operand 0 "register_operand" ""))])
12209 (define_insn "*indirect_jump<mode>"
12210 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12215 [(set_attr "type" "jmpreg")])
12217 ;; Table jump for switch statements:
12218 (define_expand "tablejump"
12219 [(use (match_operand 0 "" ""))
12220 (use (label_ref (match_operand 1 "" "")))]
12225 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12227 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12231 (define_expand "tablejumpsi"
12232 [(set (match_dup 3)
12233 (plus:SI (match_operand:SI 0 "" "")
12235 (parallel [(set (pc) (match_dup 3))
12236 (use (label_ref (match_operand 1 "" "")))])]
12239 { operands[0] = force_reg (SImode, operands[0]);
12240 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12241 operands[3] = gen_reg_rtx (SImode);
12244 (define_expand "tablejumpdi"
12245 [(set (match_dup 4)
12246 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12248 (plus:DI (match_dup 4)
12250 (parallel [(set (pc) (match_dup 3))
12251 (use (label_ref (match_operand 1 "" "")))])]
12254 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12255 operands[3] = gen_reg_rtx (DImode);
12256 operands[4] = gen_reg_rtx (DImode);
12259 (define_insn "*tablejump<mode>_internal1"
12261 (match_operand:P 0 "register_operand" "c,*l"))
12262 (use (label_ref (match_operand 1 "" "")))]
12267 [(set_attr "type" "jmpreg")])
12270 [(unspec [(const_int 0)] UNSPEC_NOP)]
12274 (define_insn "group_ending_nop"
12275 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12279 if (rs6000_cpu_attr == CPU_POWER6)
12280 return \"ori 1,1,0\";
12281 return \"ori 2,2,0\";
12284 ;; Define the subtract-one-and-jump insns, starting with the template
12285 ;; so loop.c knows what to generate.
12287 (define_expand "doloop_end"
12288 [(use (match_operand 0 "" "")) ; loop pseudo
12289 (use (match_operand 1 "" ""))] ; label
12295 if (GET_MODE (operands[0]) != DImode)
12297 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12301 if (GET_MODE (operands[0]) != SImode)
12303 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12308 (define_expand "ctr<mode>"
12309 [(parallel [(set (pc)
12310 (if_then_else (ne (match_operand:P 0 "register_operand" "")
12312 (label_ref (match_operand 1 "" ""))
12315 (plus:P (match_dup 0)
12317 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12318 (clobber (match_scratch:CC 2 ""))
12319 (clobber (match_scratch:P 3 ""))])]
12323 ;; We need to be able to do this for any operand, including MEM, or we
12324 ;; will cause reload to blow up since we don't allow output reloads on
12326 ;; For the length attribute to be calculated correctly, the
12327 ;; label MUST be operand 0.
12328 ;; The UNSPEC is present to prevent combine creating this pattern.
12330 (define_insn "*ctr<mode>_internal1"
12332 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12334 (label_ref (match_operand 0 "" ""))
12336 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12337 (plus:P (match_dup 1)
12339 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12340 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12341 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12345 if (which_alternative != 0)
12347 else if (get_attr_length (insn) == 4)
12348 return \"bdnz %l0\";
12350 return \"bdz $+8\;b %l0\";
12352 [(set_attr "type" "branch")
12353 (set_attr "length" "*,16,20,20")])
12355 (define_insn "*ctr<mode>_internal2"
12357 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12360 (label_ref (match_operand 0 "" ""))))
12361 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12362 (plus:P (match_dup 1)
12364 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12365 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12366 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12370 if (which_alternative != 0)
12372 else if (get_attr_length (insn) == 4)
12373 return \"bdz %l0\";
12375 return \"bdnz $+8\;b %l0\";
12377 [(set_attr "type" "branch")
12378 (set_attr "length" "*,16,20,20")])
12380 ;; Similar but use EQ
12382 (define_insn "*ctr<mode>_internal5"
12384 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12386 (label_ref (match_operand 0 "" ""))
12388 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12389 (plus:P (match_dup 1)
12391 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12392 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12393 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12397 if (which_alternative != 0)
12399 else if (get_attr_length (insn) == 4)
12400 return \"bdz %l0\";
12402 return \"bdnz $+8\;b %l0\";
12404 [(set_attr "type" "branch")
12405 (set_attr "length" "*,16,20,20")])
12407 (define_insn "*ctr<mode>_internal6"
12409 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12412 (label_ref (match_operand 0 "" ""))))
12413 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12414 (plus:P (match_dup 1)
12416 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12417 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12418 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12422 if (which_alternative != 0)
12424 else if (get_attr_length (insn) == 4)
12425 return \"bdnz %l0\";
12427 return \"bdz $+8\;b %l0\";
12429 [(set_attr "type" "branch")
12430 (set_attr "length" "*,16,20,20")])
12432 ;; Now the splitters if we could not allocate the CTR register
12436 (if_then_else (match_operator 2 "comparison_operator"
12437 [(match_operand:P 1 "gpc_reg_operand" "")
12439 (match_operand 5 "" "")
12440 (match_operand 6 "" "")))
12441 (set (match_operand:P 0 "int_reg_operand" "")
12442 (plus:P (match_dup 1) (const_int -1)))
12443 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12444 (clobber (match_scratch:CC 3 ""))
12445 (clobber (match_scratch:P 4 ""))]
12447 [(set (match_dup 3)
12448 (compare:CC (match_dup 1)
12451 (plus:P (match_dup 1)
12453 (set (pc) (if_then_else (match_dup 7)
12457 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12458 operands[3], const0_rtx); }")
12462 (if_then_else (match_operator 2 "comparison_operator"
12463 [(match_operand:P 1 "gpc_reg_operand" "")
12465 (match_operand 5 "" "")
12466 (match_operand 6 "" "")))
12467 (set (match_operand:P 0 "nonimmediate_operand" "")
12468 (plus:P (match_dup 1) (const_int -1)))
12469 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12470 (clobber (match_scratch:CC 3 ""))
12471 (clobber (match_scratch:P 4 ""))]
12472 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12473 [(set (match_dup 3)
12474 (compare:CC (match_dup 1)
12477 (plus:P (match_dup 1)
12481 (set (pc) (if_then_else (match_dup 7)
12485 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12486 operands[3], const0_rtx); }")
12488 (define_insn "trap"
12489 [(trap_if (const_int 1) (const_int 0))]
12492 [(set_attr "type" "trap")])
12494 (define_expand "ctrap<mode>4"
12495 [(trap_if (match_operator 0 "ordered_comparison_operator"
12496 [(match_operand:GPR 1 "register_operand")
12497 (match_operand:GPR 2 "reg_or_short_operand")])
12498 (match_operand 3 "zero_constant" ""))]
12503 [(trap_if (match_operator 0 "ordered_comparison_operator"
12504 [(match_operand:GPR 1 "register_operand" "r")
12505 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12508 "t<wd>%V0%I2 %1,%2"
12509 [(set_attr "type" "trap")])
12511 ;; Insns related to generating the function prologue and epilogue.
12513 (define_expand "prologue"
12514 [(use (const_int 0))]
12517 rs6000_emit_prologue ();
12518 if (!TARGET_SCHED_PROLOG)
12519 emit_insn (gen_blockage ());
12523 (define_insn "*movesi_from_cr_one"
12524 [(match_parallel 0 "mfcr_operation"
12525 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12526 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12527 (match_operand 3 "immediate_operand" "n")]
12528 UNSPEC_MOVESI_FROM_CR))])]
12534 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12536 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12537 operands[4] = GEN_INT (mask);
12538 output_asm_insn (\"mfcr %1,%4\", operands);
12542 [(set_attr "type" "mfcrf")])
12544 (define_insn "movesi_from_cr"
12545 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12546 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12547 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12548 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12549 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12550 UNSPEC_MOVESI_FROM_CR))]
12553 [(set_attr "type" "mfcr")])
12555 (define_insn "*crsave"
12556 [(match_parallel 0 "crsave_operation"
12557 [(set (match_operand:SI 1 "memory_operand" "=m")
12558 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12561 [(set_attr "type" "store")])
12563 (define_insn "*stmw"
12564 [(match_parallel 0 "stmw_operation"
12565 [(set (match_operand:SI 1 "memory_operand" "=m")
12566 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12569 [(set_attr "type" "store")
12570 (set_attr "update" "yes")
12571 (set_attr "indexed" "yes")])
12573 ; The following comment applies to:
12577 ; return_and_restore_gpregs*
12578 ; return_and_restore_fpregs*
12579 ; return_and_restore_fpregs_aix*
12581 ; The out-of-line save / restore functions expects one input argument.
12582 ; Since those are not standard call_insn's, we must avoid using
12583 ; MATCH_OPERAND for that argument. That way the register rename
12584 ; optimization will not try to rename this register.
12585 ; Each pattern is repeated for each possible register number used in
12586 ; various ABIs (r11, r1, and for some functions r12)
12588 (define_insn "*save_gpregs_<mode>_r11"
12589 [(match_parallel 0 "any_parallel_operand"
12590 [(clobber (reg:P LR_REGNO))
12591 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12593 (set (match_operand:P 2 "memory_operand" "=m")
12594 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12597 [(set_attr "type" "branch")
12598 (set_attr "length" "4")])
12600 (define_insn "*save_gpregs_<mode>_r12"
12601 [(match_parallel 0 "any_parallel_operand"
12602 [(clobber (reg:P LR_REGNO))
12603 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12605 (set (match_operand:P 2 "memory_operand" "=m")
12606 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12609 [(set_attr "type" "branch")
12610 (set_attr "length" "4")])
12612 (define_insn "*save_gpregs_<mode>_r1"
12613 [(match_parallel 0 "any_parallel_operand"
12614 [(clobber (reg:P LR_REGNO))
12615 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12617 (set (match_operand:P 2 "memory_operand" "=m")
12618 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12621 [(set_attr "type" "branch")
12622 (set_attr "length" "4")])
12624 (define_insn "*save_fpregs_<mode>_r11"
12625 [(match_parallel 0 "any_parallel_operand"
12626 [(clobber (reg:P LR_REGNO))
12627 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12629 (set (match_operand:DF 2 "memory_operand" "=m")
12630 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12633 [(set_attr "type" "branch")
12634 (set_attr "length" "4")])
12636 (define_insn "*save_fpregs_<mode>_r12"
12637 [(match_parallel 0 "any_parallel_operand"
12638 [(clobber (reg:P LR_REGNO))
12639 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12641 (set (match_operand:DF 2 "memory_operand" "=m")
12642 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12645 [(set_attr "type" "branch")
12646 (set_attr "length" "4")])
12648 (define_insn "*save_fpregs_<mode>_r1"
12649 [(match_parallel 0 "any_parallel_operand"
12650 [(clobber (reg:P LR_REGNO))
12651 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12653 (set (match_operand:DF 2 "memory_operand" "=m")
12654 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12657 [(set_attr "type" "branch")
12658 (set_attr "length" "4")])
12660 ; This is to explain that changes to the stack pointer should
12661 ; not be moved over loads from or stores to stack memory.
12662 (define_insn "stack_tie"
12663 [(match_parallel 0 "tie_operand"
12664 [(set (mem:BLK (reg 1)) (const_int 0))])]
12667 [(set_attr "length" "0")])
12669 (define_expand "epilogue"
12670 [(use (const_int 0))]
12673 if (!TARGET_SCHED_PROLOG)
12674 emit_insn (gen_blockage ());
12675 rs6000_emit_epilogue (FALSE);
12679 ; On some processors, doing the mtcrf one CC register at a time is
12680 ; faster (like on the 604e). On others, doing them all at once is
12681 ; faster; for instance, on the 601 and 750.
12683 (define_expand "movsi_to_cr_one"
12684 [(set (match_operand:CC 0 "cc_reg_operand" "")
12685 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12686 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12688 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12690 (define_insn "*movsi_to_cr"
12691 [(match_parallel 0 "mtcrf_operation"
12692 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12693 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12694 (match_operand 3 "immediate_operand" "n")]
12695 UNSPEC_MOVESI_TO_CR))])]
12701 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12702 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12703 operands[4] = GEN_INT (mask);
12704 return \"mtcrf %4,%2\";
12706 [(set_attr "type" "mtcr")])
12708 (define_insn "*mtcrfsi"
12709 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12710 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12711 (match_operand 2 "immediate_operand" "n")]
12712 UNSPEC_MOVESI_TO_CR))]
12713 "GET_CODE (operands[0]) == REG
12714 && CR_REGNO_P (REGNO (operands[0]))
12715 && GET_CODE (operands[2]) == CONST_INT
12716 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12718 [(set_attr "type" "mtcr")])
12720 ; The load-multiple instructions have similar properties.
12721 ; Note that "load_multiple" is a name known to the machine-independent
12722 ; code that actually corresponds to the PowerPC load-string.
12724 (define_insn "*lmw"
12725 [(match_parallel 0 "lmw_operation"
12726 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12727 (match_operand:SI 2 "memory_operand" "m"))])]
12730 [(set_attr "type" "load")
12731 (set_attr "update" "yes")
12732 (set_attr "indexed" "yes")
12733 (set_attr "cell_micro" "always")])
12735 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12736 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
12738 ; The following comment applies to:
12742 ; return_and_restore_gpregs*
12743 ; return_and_restore_fpregs*
12744 ; return_and_restore_fpregs_aix*
12746 ; The out-of-line save / restore functions expects one input argument.
12747 ; Since those are not standard call_insn's, we must avoid using
12748 ; MATCH_OPERAND for that argument. That way the register rename
12749 ; optimization will not try to rename this register.
12750 ; Each pattern is repeated for each possible register number used in
12751 ; various ABIs (r11, r1, and for some functions r12)
12753 (define_insn "*restore_gpregs_<mode>_r11"
12754 [(match_parallel 0 "any_parallel_operand"
12755 [(clobber (reg:P LR_REGNO))
12756 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12758 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12759 (match_operand:P 3 "memory_operand" "m"))])]
12762 [(set_attr "type" "branch")
12763 (set_attr "length" "4")])
12765 (define_insn "*restore_gpregs_<mode>_r12"
12766 [(match_parallel 0 "any_parallel_operand"
12767 [(clobber (reg:P LR_REGNO))
12768 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12770 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12771 (match_operand:P 3 "memory_operand" "m"))])]
12774 [(set_attr "type" "branch")
12775 (set_attr "length" "4")])
12777 (define_insn "*restore_gpregs_<mode>_r1"
12778 [(match_parallel 0 "any_parallel_operand"
12779 [(clobber (reg:P LR_REGNO))
12780 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12782 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12783 (match_operand:P 3 "memory_operand" "m"))])]
12786 [(set_attr "type" "branch")
12787 (set_attr "length" "4")])
12789 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12790 [(match_parallel 0 "any_parallel_operand"
12792 (clobber (reg:P LR_REGNO))
12793 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12795 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12796 (match_operand:P 3 "memory_operand" "m"))])]
12799 [(set_attr "type" "branch")
12800 (set_attr "length" "4")])
12802 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12803 [(match_parallel 0 "any_parallel_operand"
12805 (clobber (reg:P LR_REGNO))
12806 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12808 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12809 (match_operand:P 3 "memory_operand" "m"))])]
12812 [(set_attr "type" "branch")
12813 (set_attr "length" "4")])
12815 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12816 [(match_parallel 0 "any_parallel_operand"
12818 (clobber (reg:P LR_REGNO))
12819 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12821 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12822 (match_operand:P 3 "memory_operand" "m"))])]
12825 [(set_attr "type" "branch")
12826 (set_attr "length" "4")])
12828 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12829 [(match_parallel 0 "any_parallel_operand"
12831 (clobber (reg:P LR_REGNO))
12832 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12834 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12835 (match_operand:DF 3 "memory_operand" "m"))])]
12838 [(set_attr "type" "branch")
12839 (set_attr "length" "4")])
12841 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12842 [(match_parallel 0 "any_parallel_operand"
12844 (clobber (reg:P LR_REGNO))
12845 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12847 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12848 (match_operand:DF 3 "memory_operand" "m"))])]
12851 [(set_attr "type" "branch")
12852 (set_attr "length" "4")])
12854 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12855 [(match_parallel 0 "any_parallel_operand"
12857 (clobber (reg:P LR_REGNO))
12858 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12860 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12861 (match_operand:DF 3 "memory_operand" "m"))])]
12864 [(set_attr "type" "branch")
12865 (set_attr "length" "4")])
12867 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12868 [(match_parallel 0 "any_parallel_operand"
12870 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12872 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12873 (match_operand:DF 3 "memory_operand" "m"))])]
12876 [(set_attr "type" "branch")
12877 (set_attr "length" "4")])
12879 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12880 [(match_parallel 0 "any_parallel_operand"
12882 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12884 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12885 (match_operand:DF 3 "memory_operand" "m"))])]
12888 [(set_attr "type" "branch")
12889 (set_attr "length" "4")])
12891 ; This is used in compiling the unwind routines.
12892 (define_expand "eh_return"
12893 [(use (match_operand 0 "general_operand" ""))]
12898 emit_insn (gen_eh_set_lr_si (operands[0]));
12900 emit_insn (gen_eh_set_lr_di (operands[0]));
12904 ; We can't expand this before we know where the link register is stored.
12905 (define_insn "eh_set_lr_<mode>"
12906 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12908 (clobber (match_scratch:P 1 "=&b"))]
12913 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12914 (clobber (match_scratch 1 ""))]
12919 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12923 (define_insn "prefetch"
12924 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12925 (match_operand:SI 1 "const_int_operand" "n")
12926 (match_operand:SI 2 "const_int_operand" "n"))]
12930 if (GET_CODE (operands[0]) == REG)
12931 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12932 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12934 [(set_attr "type" "load")])
12936 ;; Handle -fsplit-stack.
12938 (define_expand "split_stack_prologue"
12942 rs6000_expand_split_stack_prologue ();
12946 (define_expand "load_split_stack_limit"
12947 [(set (match_operand 0)
12948 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12951 emit_insn (gen_rtx_SET (operands[0],
12952 gen_rtx_UNSPEC (Pmode,
12953 gen_rtvec (1, const0_rtx),
12954 UNSPEC_STACK_CHECK)));
12958 (define_insn "load_split_stack_limit_di"
12959 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12960 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12962 "ld %0,-0x7040(13)"
12963 [(set_attr "type" "load")
12964 (set_attr "update" "no")
12965 (set_attr "indexed" "no")])
12967 (define_insn "load_split_stack_limit_si"
12968 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12969 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12971 "lwz %0,-0x7020(2)"
12972 [(set_attr "type" "load")
12973 (set_attr "update" "no")
12974 (set_attr "indexed" "no")])
12976 ;; A return instruction which the middle-end doesn't see.
12977 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
12978 ;; after the call to __morestack.
12979 (define_insn "split_stack_return"
12980 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
12983 [(set_attr "type" "jmpreg")])
12985 ;; If there are operand 0 bytes available on the stack, jump to
12987 (define_expand "split_stack_space_check"
12988 [(set (match_dup 2)
12989 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12991 (minus (reg STACK_POINTER_REGNUM)
12992 (match_operand 0)))
12993 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12994 (set (pc) (if_then_else
12995 (geu (match_dup 4) (const_int 0))
12996 (label_ref (match_operand 1))
13000 rs6000_split_stack_space_check (operands[0], operands[1]);
13004 (define_insn "bpermd_<mode>"
13005 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13006 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13007 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13010 [(set_attr "type" "popcnt")])
13013 ;; Builtin fma support. Handle
13014 ;; Note that the conditions for expansion are in the FMA_F iterator.
13016 (define_expand "fma<mode>4"
13017 [(set (match_operand:FMA_F 0 "register_operand" "")
13019 (match_operand:FMA_F 1 "register_operand" "")
13020 (match_operand:FMA_F 2 "register_operand" "")
13021 (match_operand:FMA_F 3 "register_operand" "")))]
13025 (define_insn "*fma<mode>4_fpr"
13026 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13028 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13029 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13030 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13031 "TARGET_<MODE>_FPR"
13033 fmadd<Ftrad> %0,%1,%2,%3
13034 xsmadda<Fvsx> %x0,%x1,%x2
13035 xsmaddm<Fvsx> %x0,%x1,%x3"
13036 [(set_attr "type" "fp")
13037 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13039 ; Altivec only has fma and nfms.
13040 (define_expand "fms<mode>4"
13041 [(set (match_operand:FMA_F 0 "register_operand" "")
13043 (match_operand:FMA_F 1 "register_operand" "")
13044 (match_operand:FMA_F 2 "register_operand" "")
13045 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
13046 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13049 (define_insn "*fms<mode>4_fpr"
13050 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13052 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13053 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13054 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13055 "TARGET_<MODE>_FPR"
13057 fmsub<Ftrad> %0,%1,%2,%3
13058 xsmsuba<Fvsx> %x0,%x1,%x2
13059 xsmsubm<Fvsx> %x0,%x1,%x3"
13060 [(set_attr "type" "fp")
13061 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13063 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13064 (define_expand "fnma<mode>4"
13065 [(set (match_operand:FMA_F 0 "register_operand" "")
13068 (match_operand:FMA_F 1 "register_operand" "")
13069 (match_operand:FMA_F 2 "register_operand" "")
13070 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13071 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13074 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13075 (define_expand "fnms<mode>4"
13076 [(set (match_operand:FMA_F 0 "register_operand" "")
13079 (match_operand:FMA_F 1 "register_operand" "")
13080 (match_operand:FMA_F 2 "register_operand" "")
13081 (match_operand:FMA_F 3 "register_operand" ""))))]
13082 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13085 ; Not an official optab name, but used from builtins.
13086 (define_expand "nfma<mode>4"
13087 [(set (match_operand:FMA_F 0 "register_operand" "")
13090 (match_operand:FMA_F 1 "register_operand" "")
13091 (match_operand:FMA_F 2 "register_operand" "")
13092 (match_operand:FMA_F 3 "register_operand" ""))))]
13093 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13096 (define_insn "*nfma<mode>4_fpr"
13097 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13100 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13101 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13102 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13103 "TARGET_<MODE>_FPR"
13105 fnmadd<Ftrad> %0,%1,%2,%3
13106 xsnmadda<Fvsx> %x0,%x1,%x2
13107 xsnmaddm<Fvsx> %x0,%x1,%x3"
13108 [(set_attr "type" "fp")
13109 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13111 ; Not an official optab name, but used from builtins.
13112 (define_expand "nfms<mode>4"
13113 [(set (match_operand:FMA_F 0 "register_operand" "")
13116 (match_operand:FMA_F 1 "register_operand" "")
13117 (match_operand:FMA_F 2 "register_operand" "")
13118 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13122 (define_insn "*nfmssf4_fpr"
13123 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13126 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13127 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13129 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13130 "TARGET_<MODE>_FPR"
13132 fnmsub<Ftrad> %0,%1,%2,%3
13133 xsnmsuba<Fvsx> %x0,%x1,%x2
13134 xsnmsubm<Fvsx> %x0,%x1,%x3"
13135 [(set_attr "type" "fp")
13136 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13139 (define_expand "rs6000_get_timebase"
13140 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13143 if (TARGET_POWERPC64)
13144 emit_insn (gen_rs6000_mftb_di (operands[0]));
13146 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13150 (define_insn "rs6000_get_timebase_ppc32"
13151 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13152 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13153 (clobber (match_scratch:SI 1 "=r"))
13154 (clobber (match_scratch:CC 2 "=y"))]
13155 "!TARGET_POWERPC64"
13157 if (WORDS_BIG_ENDIAN)
13160 return "mfspr %0,269\;"
13168 return "mftbu %0\;"
13177 return "mfspr %L0,269\;"
13185 return "mftbu %L0\;"
13192 [(set_attr "length" "20")])
13194 (define_insn "rs6000_mftb_<mode>"
13195 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13196 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13200 return "mfspr %0,268";
13206 (define_insn "rs6000_mffs"
13207 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13208 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13209 "TARGET_HARD_FLOAT && TARGET_FPRS"
13212 (define_insn "rs6000_mtfsf"
13213 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13214 (match_operand:DF 1 "gpc_reg_operand" "d")]
13216 "TARGET_HARD_FLOAT && TARGET_FPRS"
13220 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13221 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13222 ;; register that is being loaded. The fused ops must be physically adjacent.
13224 ;; There are two parts to addis fusion. The support for fused TOCs occur
13225 ;; before register allocation, and is meant to reduce the lifetime for the
13226 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13227 ;; to use the register that is being load. The peephole2 then gathers any
13228 ;; other fused possibilities that it can find after register allocation. If
13229 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13231 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13232 ;; before register allocation, so that we can avoid allocating a temporary base
13233 ;; register that won't be used, and that we try to load into base registers,
13234 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13235 ;; (addis followed by load) even on power8.
13238 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13239 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13240 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13241 [(parallel [(set (match_dup 0) (match_dup 2))
13242 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13243 (use (match_dup 3))
13244 (clobber (scratch:DI))])]
13246 operands[2] = fusion_wrap_memory_address (operands[1]);
13247 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13250 (define_insn "*toc_fusionload_<mode>"
13251 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13252 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13253 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13254 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13255 (clobber (match_scratch:DI 3 "=X,&b"))]
13256 "TARGET_TOC_FUSION_INT"
13258 if (base_reg_operand (operands[0], <MODE>mode))
13259 return emit_fusion_gpr_load (operands[0], operands[1]);
13261 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13263 [(set_attr "type" "load")
13264 (set_attr "length" "8")])
13266 (define_insn "*toc_fusionload_di"
13267 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13268 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13269 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13270 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13271 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13272 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13273 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13275 if (base_reg_operand (operands[0], DImode))
13276 return emit_fusion_gpr_load (operands[0], operands[1]);
13278 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13280 [(set_attr "type" "load")
13281 (set_attr "length" "8")])
13284 ;; Find cases where the addis that feeds into a load instruction is either used
13285 ;; once or is the same as the target register, and replace it with the fusion
13289 [(set (match_operand:P 0 "base_reg_operand" "")
13290 (match_operand:P 1 "fusion_gpr_addis" ""))
13291 (set (match_operand:INT1 2 "base_reg_operand" "")
13292 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13294 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13298 expand_fusion_gpr_load (operands);
13302 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13305 (define_insn "fusion_gpr_load_<mode>"
13306 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13307 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13308 UNSPEC_FUSION_GPR))]
13311 return emit_fusion_gpr_load (operands[0], operands[1]);
13313 [(set_attr "type" "load")
13314 (set_attr "length" "8")])
13317 ;; ISA 3.0 (power9) fusion support
13318 ;; Merge addis with floating load/store to FPRs (or GPRs).
13320 [(set (match_operand:P 0 "base_reg_operand" "")
13321 (match_operand:P 1 "fusion_gpr_addis" ""))
13322 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13323 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13324 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13325 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13328 expand_fusion_p9_load (operands);
13333 [(set (match_operand:P 0 "base_reg_operand" "")
13334 (match_operand:P 1 "fusion_gpr_addis" ""))
13335 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13336 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13337 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13338 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13341 expand_fusion_p9_store (operands);
13346 [(set (match_operand:SDI 0 "int_reg_operand" "")
13347 (match_operand:SDI 1 "upper16_cint_operand" ""))
13349 (ior:SDI (match_dup 0)
13350 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13352 [(set (match_dup 0)
13353 (unspec:SDI [(match_dup 1)
13354 (match_dup 2)] UNSPEC_FUSION_P9))])
13357 [(set (match_operand:SDI 0 "int_reg_operand" "")
13358 (match_operand:SDI 1 "upper16_cint_operand" ""))
13359 (set (match_operand:SDI 2 "int_reg_operand" "")
13360 (ior:SDI (match_dup 0)
13361 (match_operand:SDI 3 "u_short_cint_operand" "")))]
13363 && !rtx_equal_p (operands[0], operands[2])
13364 && peep2_reg_dead_p (2, operands[0])"
13365 [(set (match_dup 2)
13366 (unspec:SDI [(match_dup 1)
13367 (match_dup 3)] UNSPEC_FUSION_P9))])
13369 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13370 ;; reload). Because we want to eventually have secondary_reload generate
13371 ;; these, they have to have a single alternative that gives the register
13372 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13373 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13374 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13376 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13378 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13381 /* This insn is a secondary reload insn, which cannot have alternatives.
13382 If we are not loading up register 0, use the power8 fusion instead. */
13383 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13384 return emit_fusion_gpr_load (operands[0], operands[1]);
13386 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13388 [(set_attr "type" "load")
13389 (set_attr "length" "8")])
13391 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13392 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13394 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13396 (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
13399 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13401 [(set_attr "type" "store")
13402 (set_attr "length" "8")])
13404 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
13405 [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
13407 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13409 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13412 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13414 [(set_attr "type" "fpload")
13415 (set_attr "length" "8")])
13417 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
13418 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13420 [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
13422 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13425 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13427 [(set_attr "type" "fpstore")
13428 (set_attr "length" "8")])
13430 (define_insn "*fusion_p9_<mode>_constant"
13431 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13432 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13433 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13434 UNSPEC_FUSION_P9))]
13437 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13438 return "ori %0,%0,%2";
13440 [(set_attr "type" "two")
13441 (set_attr "length" "8")])
13444 ;; Miscellaneous ISA 2.06 (power7) instructions
13445 (define_insn "addg6s"
13446 [(set (match_operand:SI 0 "register_operand" "=r")
13447 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13448 (match_operand:SI 2 "register_operand" "r")]
13452 [(set_attr "type" "integer")
13453 (set_attr "length" "4")])
13455 (define_insn "cdtbcd"
13456 [(set (match_operand:SI 0 "register_operand" "=r")
13457 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13461 [(set_attr "type" "integer")
13462 (set_attr "length" "4")])
13464 (define_insn "cbcdtd"
13465 [(set (match_operand:SI 0 "register_operand" "=r")
13466 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13470 [(set_attr "type" "integer")
13471 (set_attr "length" "4")])
13473 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13478 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13479 (UNSPEC_DIVEO "eo")
13480 (UNSPEC_DIVEU "eu")
13481 (UNSPEC_DIVEUO "euo")])
13483 (define_insn "div<div_extend>_<mode>"
13484 [(set (match_operand:GPR 0 "register_operand" "=r")
13485 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13486 (match_operand:GPR 2 "register_operand" "r")]
13487 UNSPEC_DIV_EXTEND))]
13489 "div<wd><div_extend> %0,%1,%2"
13490 [(set_attr "type" "div")
13491 (set_attr "size" "<bits>")])
13494 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13496 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13497 (define_mode_attr FP128_64 [(TF "DF")
13502 (define_expand "unpack<mode>"
13503 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13505 [(match_operand:FMOVE128 1 "register_operand" "")
13506 (match_operand:QI 2 "const_0_to_1_operand" "")]
13507 UNSPEC_UNPACK_128BIT))]
13508 "FLOAT128_2REG_P (<MODE>mode)"
13511 (define_insn_and_split "unpack<mode>_dm"
13512 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13514 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13515 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13516 UNSPEC_UNPACK_128BIT))]
13517 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13519 "&& reload_completed"
13520 [(set (match_dup 0) (match_dup 3))]
13522 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13524 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13526 emit_note (NOTE_INSN_DELETED);
13530 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13532 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13533 (set_attr "length" "4")])
13535 (define_insn_and_split "unpack<mode>_nodm"
13536 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13538 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13539 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13540 UNSPEC_UNPACK_128BIT))]
13541 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13543 "&& reload_completed"
13544 [(set (match_dup 0) (match_dup 3))]
13546 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13548 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13550 emit_note (NOTE_INSN_DELETED);
13554 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13556 [(set_attr "type" "fp,fpstore")
13557 (set_attr "length" "4")])
13559 (define_insn_and_split "pack<mode>"
13560 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13562 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13563 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13564 UNSPEC_PACK_128BIT))]
13565 "FLOAT128_2REG_P (<MODE>mode)"
13569 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13570 [(set (match_dup 3) (match_dup 1))
13571 (set (match_dup 4) (match_dup 2))]
13573 unsigned dest_hi = REGNO (operands[0]);
13574 unsigned dest_lo = dest_hi + 1;
13576 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13577 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13579 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13580 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13582 [(set_attr "type" "fpsimple,fp")
13583 (set_attr "length" "4,8")])
13585 (define_insn "unpack<mode>"
13586 [(set (match_operand:DI 0 "register_operand" "=d,d")
13587 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13588 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13589 UNSPEC_UNPACK_128BIT))]
13590 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13592 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13593 return ASM_COMMENT_START " xxpermdi to same register";
13595 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13596 return "xxpermdi %x0,%x1,%x1,%3";
13598 [(set_attr "type" "vecperm")])
13600 (define_insn "pack<mode>"
13601 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13602 (unspec:FMOVE128_VSX
13603 [(match_operand:DI 1 "register_operand" "d")
13604 (match_operand:DI 2 "register_operand" "d")]
13605 UNSPEC_PACK_128BIT))]
13607 "xxpermdi %x0,%x1,%x2,0"
13608 [(set_attr "type" "vecperm")])
13612 ;; ISA 2.08 IEEE 128-bit floating point support.
13614 (define_insn "add<mode>3"
13615 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13617 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13618 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13619 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13621 [(set_attr "type" "vecfloat")
13622 (set_attr "size" "128")])
13624 (define_insn "sub<mode>3"
13625 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13627 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13628 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13629 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13631 [(set_attr "type" "vecfloat")
13632 (set_attr "size" "128")])
13634 (define_insn "mul<mode>3"
13635 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13637 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13638 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13639 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13641 [(set_attr "type" "vecfloat")
13642 (set_attr "size" "128")])
13644 (define_insn "div<mode>3"
13645 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13647 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13648 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13649 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13651 [(set_attr "type" "vecdiv")
13652 (set_attr "size" "128")])
13654 (define_insn "sqrt<mode>2"
13655 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13657 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13658 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13660 [(set_attr "type" "vecdiv")
13661 (set_attr "size" "128")])
13663 (define_expand "copysign<mode>3"
13664 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13665 (use (match_operand:IEEE128 1 "altivec_register_operand"))
13666 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13667 "FLOAT128_IEEE_P (<MODE>mode)"
13669 if (TARGET_FLOAT128_HW)
13670 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13674 rtx tmp = gen_reg_rtx (<MODE>mode);
13675 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13676 operands[2], tmp));
13681 (define_insn "copysign<mode>3_hard"
13682 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13684 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13685 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13687 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13688 "xscpsgnqp %0,%2,%1"
13689 [(set_attr "type" "vecmove")
13690 (set_attr "size" "128")])
13692 (define_insn "copysign<mode>3_soft"
13693 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13695 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13696 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13697 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
13699 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13700 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13701 [(set_attr "type" "veccomplex")
13702 (set_attr "length" "8")])
13704 (define_insn "neg<mode>2_hw"
13705 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13707 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13708 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13710 [(set_attr "type" "vecmove")
13711 (set_attr "size" "128")])
13714 (define_insn "abs<mode>2_hw"
13715 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13717 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13718 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13720 [(set_attr "type" "vecmove")
13721 (set_attr "size" "128")])
13724 (define_insn "*nabs<mode>2_hw"
13725 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13728 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13729 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13731 [(set_attr "type" "vecmove")
13732 (set_attr "size" "128")])
13734 ;; Initially don't worry about doing fusion
13735 (define_insn "*fma<mode>4_hw"
13736 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13738 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13739 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13740 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13741 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13742 "xsmaddqp %0,%1,%2"
13743 [(set_attr "type" "vecfloat")
13744 (set_attr "size" "128")])
13746 (define_insn "*fms<mode>4_hw"
13747 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13749 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13750 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13752 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13753 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13754 "xsmsubqp %0,%1,%2"
13755 [(set_attr "type" "vecfloat")
13756 (set_attr "size" "128")])
13758 (define_insn "*nfma<mode>4_hw"
13759 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13762 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13763 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13764 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13765 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13766 "xsnmaddqp %0,%1,%2"
13767 [(set_attr "type" "vecfloat")
13768 (set_attr "size" "128")])
13770 (define_insn "*nfms<mode>4_hw"
13771 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13774 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13775 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13777 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13778 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13779 "xsnmsubqp %0,%1,%2"
13780 [(set_attr "type" "vecfloat")
13781 (set_attr "size" "128")])
13783 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13784 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13785 (float_extend:IEEE128
13786 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13787 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13789 [(set_attr "type" "vecfloat")
13790 (set_attr "size" "128")])
13792 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13793 ;; point is a simple copy.
13794 (define_insn_and_split "extendkftf2"
13795 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13796 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13797 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13801 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13804 emit_note (NOTE_INSN_DELETED);
13807 [(set_attr "type" "*,veclogical")
13808 (set_attr "length" "0,4")])
13810 (define_insn_and_split "trunctfkf2"
13811 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13812 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13813 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13817 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13820 emit_note (NOTE_INSN_DELETED);
13823 [(set_attr "type" "*,veclogical")
13824 (set_attr "length" "0,4")])
13826 (define_insn "trunc<mode>df2_hw"
13827 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13829 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13830 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13832 [(set_attr "type" "vecfloat")
13833 (set_attr "size" "128")])
13835 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13836 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13838 (define_insn_and_split "trunc<mode>sf2_hw"
13839 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13841 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13842 (clobber (match_scratch:DF 2 "=v"))]
13843 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13846 [(set (match_dup 2)
13847 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13849 (float_truncate:SF (match_dup 2)))]
13851 if (GET_CODE (operands[2]) == SCRATCH)
13852 operands[2] = gen_reg_rtx (DFmode);
13854 [(set_attr "type" "vecfloat")
13855 (set_attr "length" "8")])
13857 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13858 ;; allowed in the traditional floating point registers. Use V2DImode so that
13859 ;; we can get a value in an Altivec register.
13861 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13862 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13863 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13864 (clobber (match_scratch:V2DI 2 "=v,v"))]
13865 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13870 convert_float128_to_int (operands, <CODE>);
13873 [(set_attr "length" "8")
13874 (set_attr "type" "mftgpr,fpstore")])
13876 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13877 [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13878 (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13879 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13880 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13885 convert_float128_to_int (operands, <CODE>);
13888 [(set_attr "length" "8")
13889 (set_attr "type" "mftgpr,vecsimple,fpstore")])
13891 (define_insn_and_split "float<uns>_<mode>si2_hw"
13892 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13893 (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13894 (clobber (match_scratch:V2DI 2 "=v,v"))]
13895 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13900 convert_int_to_float128 (operands, <CODE>);
13903 [(set_attr "length" "8")
13904 (set_attr "type" "vecfloat")])
13906 (define_insn_and_split "float<uns>_<mode>di2_hw"
13907 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13908 (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13909 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13910 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13915 convert_int_to_float128 (operands, <CODE>);
13918 [(set_attr "length" "8")
13919 (set_attr "type" "vecfloat")])
13921 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13922 (define_insn "*xscvqp<su>wz_<mode>"
13923 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13926 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13927 UNSPEC_IEEE128_CONVERT))]
13928 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13929 "xscvqp<su>wz %0,%1"
13930 [(set_attr "type" "vecfloat")
13931 (set_attr "size" "128")])
13933 (define_insn "*xscvqp<su>dz_<mode>"
13934 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13937 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13938 UNSPEC_IEEE128_CONVERT))]
13939 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13940 "xscvqp<su>dz %0,%1"
13941 [(set_attr "type" "vecfloat")
13942 (set_attr "size" "128")])
13944 (define_insn "*xscv<su>dqp_<mode>"
13945 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13947 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13948 UNSPEC_IEEE128_CONVERT)))]
13949 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13950 "xscv<su>dqp %0,%1"
13951 [(set_attr "type" "vecfloat")
13952 (set_attr "size" "128")])
13954 (define_insn "*ieee128_mfvsrd_64bit"
13955 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13956 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13957 UNSPEC_IEEE128_MOVE))]
13958 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13963 [(set_attr "type" "mftgpr,fpstore,veclogical")])
13966 (define_insn "*ieee128_mfvsrd_32bit"
13967 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13968 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13969 UNSPEC_IEEE128_MOVE))]
13970 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13974 [(set_attr "type" "fpstore,veclogical")])
13976 (define_insn "*ieee128_mfvsrwz"
13977 [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13978 (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13979 UNSPEC_IEEE128_MOVE))]
13980 "TARGET_FLOAT128_HW"
13984 [(set_attr "type" "mftgpr,fpstore")])
13986 ;; 0 says do sign-extension, 1 says zero-extension
13987 (define_insn "*ieee128_mtvsrw"
13988 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13989 (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13990 (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13991 UNSPEC_IEEE128_MOVE))]
13992 "TARGET_FLOAT128_HW"
13998 [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
14001 (define_insn "*ieee128_mtvsrd_64bit"
14002 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
14003 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
14004 UNSPEC_IEEE128_MOVE))]
14005 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
14010 [(set_attr "type" "mffgpr,fpload,veclogical")])
14012 (define_insn "*ieee128_mtvsrd_32bit"
14013 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
14014 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
14015 UNSPEC_IEEE128_MOVE))]
14016 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
14020 [(set_attr "type" "fpload,veclogical")])
14022 ;; IEEE 128-bit instructions with round to odd semantics
14023 (define_insn "*trunc<mode>df2_odd"
14024 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14025 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14026 UNSPEC_ROUND_TO_ODD))]
14027 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14029 [(set_attr "type" "vecfloat")
14030 (set_attr "size" "128")])
14032 ;; IEEE 128-bit comparisons
14033 (define_insn "*cmp<mode>_hw"
14034 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14035 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14036 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14037 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14038 "xscmpuqp %0,%1,%2"
14039 [(set_attr "type" "veccmp")
14040 (set_attr "size" "128")])
14044 (include "sync.md")
14045 (include "vector.md")
14047 (include "altivec.md")
14050 (include "paired.md")
14051 (include "crypto.md")