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_FLOAT128")
380 (KF "TARGET_FLOAT128")
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 "o") (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 "o") (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 "stxsiwzx %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")
510 (IF "TARGET_FLOAT128")
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,??wj,!wz,!wu")
841 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
849 [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
851 (define_insn_and_split "*zero_extendsi<mode>2_dot"
852 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
853 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
855 (clobber (match_scratch:EXTSI 0 "=r,r"))]
856 "rs6000_gen_cell_microcode"
860 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
862 (zero_extend:DI (match_dup 1)))
864 (compare:CC (match_dup 0)
867 [(set_attr "type" "shift")
868 (set_attr "dot" "yes")
869 (set_attr "length" "4,8")])
871 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
872 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
873 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
875 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
876 (zero_extend:EXTSI (match_dup 1)))]
877 "rs6000_gen_cell_microcode"
881 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
883 (zero_extend:EXTSI (match_dup 1)))
885 (compare:CC (match_dup 0)
888 [(set_attr "type" "shift")
889 (set_attr "dot" "yes")
890 (set_attr "length" "4,8")])
893 (define_insn "extendqi<mode>2"
894 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
895 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
898 [(set_attr "type" "exts")])
900 (define_insn_and_split "*extendqi<mode>2_dot"
901 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
902 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
904 (clobber (match_scratch:EXTQI 0 "=r,r"))]
905 "rs6000_gen_cell_microcode"
909 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
911 (sign_extend:EXTQI (match_dup 1)))
913 (compare:CC (match_dup 0)
916 [(set_attr "type" "exts")
917 (set_attr "dot" "yes")
918 (set_attr "length" "4,8")])
920 (define_insn_and_split "*extendqi<mode>2_dot2"
921 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
922 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
924 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
925 (sign_extend:EXTQI (match_dup 1)))]
926 "rs6000_gen_cell_microcode"
930 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
932 (sign_extend:EXTQI (match_dup 1)))
934 (compare:CC (match_dup 0)
937 [(set_attr "type" "exts")
938 (set_attr "dot" "yes")
939 (set_attr "length" "4,8")])
942 (define_expand "extendhi<mode>2"
943 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
944 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
948 (define_insn "*extendhi<mode>2"
949 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
950 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
951 "rs6000_gen_cell_microcode"
955 [(set_attr "type" "load,exts")
956 (set_attr "sign_extend" "yes")])
958 (define_insn "*extendhi<mode>2_noload"
959 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
960 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
961 "!rs6000_gen_cell_microcode"
963 [(set_attr "type" "exts")])
965 (define_insn_and_split "*extendhi<mode>2_dot"
966 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
967 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
969 (clobber (match_scratch:EXTHI 0 "=r,r"))]
970 "rs6000_gen_cell_microcode"
974 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
976 (sign_extend:EXTHI (match_dup 1)))
978 (compare:CC (match_dup 0)
981 [(set_attr "type" "exts")
982 (set_attr "dot" "yes")
983 (set_attr "length" "4,8")])
985 (define_insn_and_split "*extendhi<mode>2_dot2"
986 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
987 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
989 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
990 (sign_extend:EXTHI (match_dup 1)))]
991 "rs6000_gen_cell_microcode"
995 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
997 (sign_extend:EXTHI (match_dup 1)))
999 (compare:CC (match_dup 0)
1002 [(set_attr "type" "exts")
1003 (set_attr "dot" "yes")
1004 (set_attr "length" "4,8")])
1007 (define_insn "extendsi<mode>2"
1008 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
1009 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
1017 [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
1018 (set_attr "sign_extend" "yes")])
1020 (define_insn_and_split "*extendsi<mode>2_dot"
1021 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1022 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1024 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1025 "rs6000_gen_cell_microcode"
1029 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1031 (sign_extend:EXTSI (match_dup 1)))
1033 (compare:CC (match_dup 0)
1036 [(set_attr "type" "exts")
1037 (set_attr "dot" "yes")
1038 (set_attr "length" "4,8")])
1040 (define_insn_and_split "*extendsi<mode>2_dot2"
1041 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1042 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1044 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1045 (sign_extend:EXTSI (match_dup 1)))]
1046 "rs6000_gen_cell_microcode"
1050 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1052 (sign_extend:EXTSI (match_dup 1)))
1054 (compare:CC (match_dup 0)
1057 [(set_attr "type" "exts")
1058 (set_attr "dot" "yes")
1059 (set_attr "length" "4,8")])
1061 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1063 (define_insn "*macchwc"
1064 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1065 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1066 (match_operand:SI 2 "gpc_reg_operand" "r")
1069 (match_operand:HI 1 "gpc_reg_operand" "r")))
1070 (match_operand:SI 4 "gpc_reg_operand" "0"))
1072 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1073 (plus:SI (mult:SI (ashiftrt:SI
1081 [(set_attr "type" "halfmul")])
1083 (define_insn "*macchw"
1084 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1085 (plus:SI (mult:SI (ashiftrt:SI
1086 (match_operand:SI 2 "gpc_reg_operand" "r")
1089 (match_operand:HI 1 "gpc_reg_operand" "r")))
1090 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1093 [(set_attr "type" "halfmul")])
1095 (define_insn "*macchwuc"
1096 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1097 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1098 (match_operand:SI 2 "gpc_reg_operand" "r")
1101 (match_operand:HI 1 "gpc_reg_operand" "r")))
1102 (match_operand:SI 4 "gpc_reg_operand" "0"))
1104 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1105 (plus:SI (mult:SI (lshiftrt:SI
1113 [(set_attr "type" "halfmul")])
1115 (define_insn "*macchwu"
1116 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1117 (plus:SI (mult:SI (lshiftrt:SI
1118 (match_operand:SI 2 "gpc_reg_operand" "r")
1121 (match_operand:HI 1 "gpc_reg_operand" "r")))
1122 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1125 [(set_attr "type" "halfmul")])
1127 (define_insn "*machhwc"
1128 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1129 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1130 (match_operand:SI 1 "gpc_reg_operand" "%r")
1133 (match_operand:SI 2 "gpc_reg_operand" "r")
1135 (match_operand:SI 4 "gpc_reg_operand" "0"))
1137 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1138 (plus:SI (mult:SI (ashiftrt:SI
1147 [(set_attr "type" "halfmul")])
1149 (define_insn "*machhw"
1150 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1151 (plus:SI (mult:SI (ashiftrt:SI
1152 (match_operand:SI 1 "gpc_reg_operand" "%r")
1155 (match_operand:SI 2 "gpc_reg_operand" "r")
1157 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1160 [(set_attr "type" "halfmul")])
1162 (define_insn "*machhwuc"
1163 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1164 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1165 (match_operand:SI 1 "gpc_reg_operand" "%r")
1168 (match_operand:SI 2 "gpc_reg_operand" "r")
1170 (match_operand:SI 4 "gpc_reg_operand" "0"))
1172 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1173 (plus:SI (mult:SI (lshiftrt:SI
1182 [(set_attr "type" "halfmul")])
1184 (define_insn "*machhwu"
1185 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1186 (plus:SI (mult:SI (lshiftrt:SI
1187 (match_operand:SI 1 "gpc_reg_operand" "%r")
1190 (match_operand:SI 2 "gpc_reg_operand" "r")
1192 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1195 [(set_attr "type" "halfmul")])
1197 (define_insn "*maclhwc"
1198 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1199 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1200 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1202 (match_operand:HI 2 "gpc_reg_operand" "r")))
1203 (match_operand:SI 4 "gpc_reg_operand" "0"))
1205 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1206 (plus:SI (mult:SI (sign_extend:SI
1213 [(set_attr "type" "halfmul")])
1215 (define_insn "*maclhw"
1216 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1217 (plus:SI (mult:SI (sign_extend:SI
1218 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1220 (match_operand:HI 2 "gpc_reg_operand" "r")))
1221 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1224 [(set_attr "type" "halfmul")])
1226 (define_insn "*maclhwuc"
1227 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1228 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1229 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1231 (match_operand:HI 2 "gpc_reg_operand" "r")))
1232 (match_operand:SI 4 "gpc_reg_operand" "0"))
1234 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1235 (plus:SI (mult:SI (zero_extend:SI
1242 [(set_attr "type" "halfmul")])
1244 (define_insn "*maclhwu"
1245 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1246 (plus:SI (mult:SI (zero_extend:SI
1247 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1249 (match_operand:HI 2 "gpc_reg_operand" "r")))
1250 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1253 [(set_attr "type" "halfmul")])
1255 (define_insn "*nmacchwc"
1256 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1257 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1258 (mult:SI (ashiftrt:SI
1259 (match_operand:SI 2 "gpc_reg_operand" "r")
1262 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1264 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1265 (minus:SI (match_dup 4)
1266 (mult:SI (ashiftrt:SI
1273 [(set_attr "type" "halfmul")])
1275 (define_insn "*nmacchw"
1276 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1277 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1278 (mult:SI (ashiftrt:SI
1279 (match_operand:SI 2 "gpc_reg_operand" "r")
1282 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1285 [(set_attr "type" "halfmul")])
1287 (define_insn "*nmachhwc"
1288 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1289 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1290 (mult:SI (ashiftrt:SI
1291 (match_operand:SI 1 "gpc_reg_operand" "%r")
1294 (match_operand:SI 2 "gpc_reg_operand" "r")
1297 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1298 (minus:SI (match_dup 4)
1299 (mult:SI (ashiftrt:SI
1307 [(set_attr "type" "halfmul")])
1309 (define_insn "*nmachhw"
1310 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1311 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1312 (mult:SI (ashiftrt:SI
1313 (match_operand:SI 1 "gpc_reg_operand" "%r")
1316 (match_operand:SI 2 "gpc_reg_operand" "r")
1320 [(set_attr "type" "halfmul")])
1322 (define_insn "*nmaclhwc"
1323 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1324 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1325 (mult:SI (sign_extend:SI
1326 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1328 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1330 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1331 (minus:SI (match_dup 4)
1332 (mult:SI (sign_extend:SI
1338 [(set_attr "type" "halfmul")])
1340 (define_insn "*nmaclhw"
1341 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1342 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1343 (mult:SI (sign_extend:SI
1344 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1346 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1349 [(set_attr "type" "halfmul")])
1351 (define_insn "*mulchwc"
1352 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1353 (compare:CC (mult:SI (ashiftrt:SI
1354 (match_operand:SI 2 "gpc_reg_operand" "r")
1357 (match_operand:HI 1 "gpc_reg_operand" "r")))
1359 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1360 (mult:SI (ashiftrt:SI
1367 [(set_attr "type" "halfmul")])
1369 (define_insn "*mulchw"
1370 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1371 (mult:SI (ashiftrt:SI
1372 (match_operand:SI 2 "gpc_reg_operand" "r")
1375 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1378 [(set_attr "type" "halfmul")])
1380 (define_insn "*mulchwuc"
1381 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1382 (compare:CC (mult:SI (lshiftrt:SI
1383 (match_operand:SI 2 "gpc_reg_operand" "r")
1386 (match_operand:HI 1 "gpc_reg_operand" "r")))
1388 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1389 (mult:SI (lshiftrt:SI
1396 [(set_attr "type" "halfmul")])
1398 (define_insn "*mulchwu"
1399 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1400 (mult:SI (lshiftrt:SI
1401 (match_operand:SI 2 "gpc_reg_operand" "r")
1404 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1407 [(set_attr "type" "halfmul")])
1409 (define_insn "*mulhhwc"
1410 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1411 (compare:CC (mult:SI (ashiftrt:SI
1412 (match_operand:SI 1 "gpc_reg_operand" "%r")
1415 (match_operand:SI 2 "gpc_reg_operand" "r")
1418 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1419 (mult:SI (ashiftrt:SI
1427 [(set_attr "type" "halfmul")])
1429 (define_insn "*mulhhw"
1430 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1431 (mult:SI (ashiftrt:SI
1432 (match_operand:SI 1 "gpc_reg_operand" "%r")
1435 (match_operand:SI 2 "gpc_reg_operand" "r")
1439 [(set_attr "type" "halfmul")])
1441 (define_insn "*mulhhwuc"
1442 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1443 (compare:CC (mult:SI (lshiftrt:SI
1444 (match_operand:SI 1 "gpc_reg_operand" "%r")
1447 (match_operand:SI 2 "gpc_reg_operand" "r")
1450 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1451 (mult:SI (lshiftrt:SI
1459 [(set_attr "type" "halfmul")])
1461 (define_insn "*mulhhwu"
1462 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1463 (mult:SI (lshiftrt:SI
1464 (match_operand:SI 1 "gpc_reg_operand" "%r")
1467 (match_operand:SI 2 "gpc_reg_operand" "r")
1471 [(set_attr "type" "halfmul")])
1473 (define_insn "*mullhwc"
1474 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1475 (compare:CC (mult:SI (sign_extend:SI
1476 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1478 (match_operand:HI 2 "gpc_reg_operand" "r")))
1480 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1481 (mult:SI (sign_extend:SI
1487 [(set_attr "type" "halfmul")])
1489 (define_insn "*mullhw"
1490 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1491 (mult:SI (sign_extend:SI
1492 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1494 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1497 [(set_attr "type" "halfmul")])
1499 (define_insn "*mullhwuc"
1500 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1501 (compare:CC (mult:SI (zero_extend:SI
1502 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1504 (match_operand:HI 2 "gpc_reg_operand" "r")))
1506 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1507 (mult:SI (zero_extend:SI
1513 [(set_attr "type" "halfmul")])
1515 (define_insn "*mullhwu"
1516 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1517 (mult:SI (zero_extend:SI
1518 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1520 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1523 [(set_attr "type" "halfmul")])
1525 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1526 (define_insn "dlmzb"
1527 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1528 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1529 (match_operand:SI 2 "gpc_reg_operand" "r")]
1531 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1532 (unspec:SI [(match_dup 1)
1538 (define_expand "strlensi"
1539 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1540 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1541 (match_operand:QI 2 "const_int_operand" "")
1542 (match_operand 3 "const_int_operand" "")]
1543 UNSPEC_DLMZB_STRLEN))
1544 (clobber (match_scratch:CC 4 "=x"))]
1545 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1547 rtx result = operands[0];
1548 rtx src = operands[1];
1549 rtx search_char = operands[2];
1550 rtx align = operands[3];
1551 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1552 rtx loop_label, end_label, mem, cr0, cond;
1553 if (search_char != const0_rtx
1554 || GET_CODE (align) != CONST_INT
1555 || INTVAL (align) < 8)
1557 word1 = gen_reg_rtx (SImode);
1558 word2 = gen_reg_rtx (SImode);
1559 scratch_dlmzb = gen_reg_rtx (SImode);
1560 scratch_string = gen_reg_rtx (Pmode);
1561 loop_label = gen_label_rtx ();
1562 end_label = gen_label_rtx ();
1563 addr = force_reg (Pmode, XEXP (src, 0));
1564 emit_move_insn (scratch_string, addr);
1565 emit_label (loop_label);
1566 mem = change_address (src, SImode, scratch_string);
1567 emit_move_insn (word1, mem);
1568 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1569 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1570 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1571 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1572 emit_jump_insn (gen_rtx_SET (pc_rtx,
1573 gen_rtx_IF_THEN_ELSE (VOIDmode,
1579 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1580 emit_jump_insn (gen_rtx_SET (pc_rtx,
1581 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1583 emit_label (end_label);
1584 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1585 emit_insn (gen_subsi3 (result, scratch_string, addr));
1586 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1590 ;; Fixed-point arithmetic insns.
1592 (define_expand "add<mode>3"
1593 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1594 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1595 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1598 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1600 rtx lo0 = gen_lowpart (SImode, operands[0]);
1601 rtx lo1 = gen_lowpart (SImode, operands[1]);
1602 rtx lo2 = gen_lowpart (SImode, operands[2]);
1603 rtx hi0 = gen_highpart (SImode, operands[0]);
1604 rtx hi1 = gen_highpart (SImode, operands[1]);
1605 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1607 if (!reg_or_short_operand (lo2, SImode))
1608 lo2 = force_reg (SImode, lo2);
1609 if (!adde_operand (hi2, SImode))
1610 hi2 = force_reg (SImode, hi2);
1612 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1613 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1617 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1619 rtx tmp = ((!can_create_pseudo_p ()
1620 || rtx_equal_p (operands[0], operands[1]))
1621 ? operands[0] : gen_reg_rtx (<MODE>mode));
1623 HOST_WIDE_INT val = INTVAL (operands[2]);
1624 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1625 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1627 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1630 /* The ordering here is important for the prolog expander.
1631 When space is allocated from the stack, adding 'low' first may
1632 produce a temporary deallocation (which would be bad). */
1633 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1634 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1639 (define_insn "*add<mode>3"
1640 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1641 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1642 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1648 [(set_attr "type" "add")])
1650 (define_insn "addsi3_high"
1651 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1652 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1653 (high:SI (match_operand 2 "" ""))))]
1654 "TARGET_MACHO && !TARGET_64BIT"
1655 "addis %0,%1,ha16(%2)"
1656 [(set_attr "type" "add")])
1658 (define_insn_and_split "*add<mode>3_dot"
1659 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1660 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1661 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1663 (clobber (match_scratch:GPR 0 "=r,r"))]
1664 "<MODE>mode == Pmode"
1668 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1670 (plus:GPR (match_dup 1)
1673 (compare:CC (match_dup 0)
1676 [(set_attr "type" "add")
1677 (set_attr "dot" "yes")
1678 (set_attr "length" "4,8")])
1680 (define_insn_and_split "*add<mode>3_dot2"
1681 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1682 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1683 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1685 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1686 (plus:GPR (match_dup 1)
1688 "<MODE>mode == Pmode"
1692 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1694 (plus:GPR (match_dup 1)
1697 (compare:CC (match_dup 0)
1700 [(set_attr "type" "add")
1701 (set_attr "dot" "yes")
1702 (set_attr "length" "4,8")])
1704 (define_insn_and_split "*add<mode>3_imm_dot"
1705 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1706 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1707 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1709 (clobber (match_scratch:GPR 0 "=r,r"))
1710 (clobber (reg:GPR CA_REGNO))]
1711 "<MODE>mode == Pmode"
1715 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1717 (plus:GPR (match_dup 1)
1720 (compare:CC (match_dup 0)
1723 [(set_attr "type" "add")
1724 (set_attr "dot" "yes")
1725 (set_attr "length" "4,8")])
1727 (define_insn_and_split "*add<mode>3_imm_dot2"
1728 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1729 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1730 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1732 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1733 (plus:GPR (match_dup 1)
1735 (clobber (reg:GPR CA_REGNO))]
1736 "<MODE>mode == Pmode"
1740 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1742 (plus:GPR (match_dup 1)
1745 (compare:CC (match_dup 0)
1748 [(set_attr "type" "add")
1749 (set_attr "dot" "yes")
1750 (set_attr "length" "4,8")])
1752 ;; Split an add that we can't do in one insn into two insns, each of which
1753 ;; does one 16-bit part. This is used by combine. Note that the low-order
1754 ;; add should be last in case the result gets used in an address.
1757 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1758 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1759 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1761 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1762 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1764 HOST_WIDE_INT val = INTVAL (operands[2]);
1765 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1766 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1768 operands[4] = GEN_INT (low);
1769 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1770 operands[3] = GEN_INT (rest);
1771 else if (can_create_pseudo_p ())
1773 operands[3] = gen_reg_rtx (DImode);
1774 emit_move_insn (operands[3], operands[2]);
1775 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1783 (define_insn "add<mode>3_carry"
1784 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1785 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1786 (match_operand:P 2 "reg_or_short_operand" "rI")))
1787 (set (reg:P CA_REGNO)
1788 (ltu:P (plus:P (match_dup 1)
1793 [(set_attr "type" "add")])
1795 (define_insn "*add<mode>3_imm_carry_pos"
1796 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1797 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1798 (match_operand:P 2 "short_cint_operand" "n")))
1799 (set (reg:P CA_REGNO)
1800 (geu:P (match_dup 1)
1801 (match_operand:P 3 "const_int_operand" "n")))]
1802 "INTVAL (operands[2]) > 0
1803 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1805 [(set_attr "type" "add")])
1807 (define_insn "*add<mode>3_imm_carry_0"
1808 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1809 (match_operand:P 1 "gpc_reg_operand" "r"))
1810 (set (reg:P CA_REGNO)
1814 [(set_attr "type" "add")])
1816 (define_insn "*add<mode>3_imm_carry_m1"
1817 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1818 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1820 (set (reg:P CA_REGNO)
1825 [(set_attr "type" "add")])
1827 (define_insn "*add<mode>3_imm_carry_neg"
1828 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1829 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1830 (match_operand:P 2 "short_cint_operand" "n")))
1831 (set (reg:P CA_REGNO)
1832 (gtu:P (match_dup 1)
1833 (match_operand:P 3 "const_int_operand" "n")))]
1834 "INTVAL (operands[2]) < 0
1835 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1837 [(set_attr "type" "add")])
1840 (define_expand "add<mode>3_carry_in"
1842 (set (match_operand:GPR 0 "gpc_reg_operand")
1843 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1844 (match_operand:GPR 2 "adde_operand"))
1845 (reg:GPR CA_REGNO)))
1846 (clobber (reg:GPR CA_REGNO))])]
1849 if (operands[2] == const0_rtx)
1851 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1854 if (operands[2] == constm1_rtx)
1856 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1861 (define_insn "*add<mode>3_carry_in_internal"
1862 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1863 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1864 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1865 (reg:GPR CA_REGNO)))
1866 (clobber (reg:GPR CA_REGNO))]
1869 [(set_attr "type" "add")])
1871 (define_insn "add<mode>3_carry_in_0"
1872 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1873 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1874 (reg:GPR CA_REGNO)))
1875 (clobber (reg:GPR CA_REGNO))]
1878 [(set_attr "type" "add")])
1880 (define_insn "add<mode>3_carry_in_m1"
1881 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1882 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1885 (clobber (reg:GPR CA_REGNO))]
1888 [(set_attr "type" "add")])
1891 (define_expand "one_cmpl<mode>2"
1892 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1893 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1896 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1898 rs6000_split_logical (operands, NOT, false, false, false);
1903 (define_insn "*one_cmpl<mode>2"
1904 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1905 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1909 (define_insn_and_split "*one_cmpl<mode>2_dot"
1910 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1911 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1913 (clobber (match_scratch:GPR 0 "=r,r"))]
1914 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1918 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1920 (not:GPR (match_dup 1)))
1922 (compare:CC (match_dup 0)
1925 [(set_attr "type" "logical")
1926 (set_attr "dot" "yes")
1927 (set_attr "length" "4,8")])
1929 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1930 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1931 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1933 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1934 (not:GPR (match_dup 1)))]
1935 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1939 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1941 (not:GPR (match_dup 1)))
1943 (compare:CC (match_dup 0)
1946 [(set_attr "type" "logical")
1947 (set_attr "dot" "yes")
1948 (set_attr "length" "4,8")])
1951 (define_expand "sub<mode>3"
1952 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1953 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1954 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1957 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1959 rtx lo0 = gen_lowpart (SImode, operands[0]);
1960 rtx lo1 = gen_lowpart (SImode, operands[1]);
1961 rtx lo2 = gen_lowpart (SImode, operands[2]);
1962 rtx hi0 = gen_highpart (SImode, operands[0]);
1963 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1964 rtx hi2 = gen_highpart (SImode, operands[2]);
1966 if (!reg_or_short_operand (lo1, SImode))
1967 lo1 = force_reg (SImode, lo1);
1968 if (!adde_operand (hi1, SImode))
1969 hi1 = force_reg (SImode, hi1);
1971 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1972 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1976 if (short_cint_operand (operands[1], <MODE>mode))
1978 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1983 (define_insn "*subf<mode>3"
1984 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1985 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1986 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1989 [(set_attr "type" "add")])
1991 (define_insn_and_split "*subf<mode>3_dot"
1992 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1993 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1994 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1996 (clobber (match_scratch:GPR 0 "=r,r"))]
1997 "<MODE>mode == Pmode"
2001 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2003 (minus:GPR (match_dup 2)
2006 (compare:CC (match_dup 0)
2009 [(set_attr "type" "add")
2010 (set_attr "dot" "yes")
2011 (set_attr "length" "4,8")])
2013 (define_insn_and_split "*subf<mode>3_dot2"
2014 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2015 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2016 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2018 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2019 (minus:GPR (match_dup 2)
2021 "<MODE>mode == Pmode"
2025 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2027 (minus:GPR (match_dup 2)
2030 (compare:CC (match_dup 0)
2033 [(set_attr "type" "add")
2034 (set_attr "dot" "yes")
2035 (set_attr "length" "4,8")])
2037 (define_insn "subf<mode>3_imm"
2038 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2039 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2040 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2041 (clobber (reg:GPR CA_REGNO))]
2044 [(set_attr "type" "add")])
2047 (define_insn "subf<mode>3_carry"
2048 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2049 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2050 (match_operand:P 1 "gpc_reg_operand" "r")))
2051 (set (reg:P CA_REGNO)
2052 (leu:P (match_dup 1)
2056 [(set_attr "type" "add")])
2058 (define_insn "*subf<mode>3_imm_carry_0"
2059 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2060 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2061 (set (reg:P CA_REGNO)
2066 [(set_attr "type" "add")])
2068 (define_insn "*subf<mode>3_imm_carry_m1"
2069 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2070 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2071 (set (reg:P CA_REGNO)
2075 [(set_attr "type" "add")])
2078 (define_expand "subf<mode>3_carry_in"
2080 (set (match_operand:GPR 0 "gpc_reg_operand")
2081 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2083 (match_operand:GPR 2 "adde_operand")))
2084 (clobber (reg:GPR CA_REGNO))])]
2087 if (operands[2] == const0_rtx)
2089 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2092 if (operands[2] == constm1_rtx)
2094 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2099 (define_insn "*subf<mode>3_carry_in_internal"
2100 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2101 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2103 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2104 (clobber (reg:GPR CA_REGNO))]
2107 [(set_attr "type" "add")])
2109 (define_insn "subf<mode>3_carry_in_0"
2110 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2111 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2112 (reg:GPR CA_REGNO)))
2113 (clobber (reg:GPR CA_REGNO))]
2116 [(set_attr "type" "add")])
2118 (define_insn "subf<mode>3_carry_in_m1"
2119 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2120 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2121 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2123 (clobber (reg:GPR CA_REGNO))]
2126 [(set_attr "type" "add")])
2128 (define_insn "subf<mode>3_carry_in_xx"
2129 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2130 (plus:GPR (reg:GPR CA_REGNO)
2132 (clobber (reg:GPR CA_REGNO))]
2135 [(set_attr "type" "add")])
2138 (define_insn "neg<mode>2"
2139 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2140 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2143 [(set_attr "type" "add")])
2145 (define_insn_and_split "*neg<mode>2_dot"
2146 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2147 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2149 (clobber (match_scratch:GPR 0 "=r,r"))]
2150 "<MODE>mode == Pmode"
2154 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2156 (neg:GPR (match_dup 1)))
2158 (compare:CC (match_dup 0)
2161 [(set_attr "type" "add")
2162 (set_attr "dot" "yes")
2163 (set_attr "length" "4,8")])
2165 (define_insn_and_split "*neg<mode>2_dot2"
2166 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2167 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2169 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2170 (neg:GPR (match_dup 1)))]
2171 "<MODE>mode == Pmode"
2175 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2177 (neg:GPR (match_dup 1)))
2179 (compare:CC (match_dup 0)
2182 [(set_attr "type" "add")
2183 (set_attr "dot" "yes")
2184 (set_attr "length" "4,8")])
2187 (define_insn "clz<mode>2"
2188 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2189 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2192 [(set_attr "type" "cntlz")])
2194 (define_expand "ctz<mode>2"
2196 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2198 (and:GPR (match_dup 1)
2201 (clz:GPR (match_dup 3)))
2202 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2203 (minus:GPR (match_dup 5)
2205 (clobber (reg:GPR CA_REGNO))])]
2210 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2214 operands[2] = gen_reg_rtx (<MODE>mode);
2215 operands[3] = gen_reg_rtx (<MODE>mode);
2216 operands[4] = gen_reg_rtx (<MODE>mode);
2217 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2220 (define_insn "ctz<mode>2_hw"
2221 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2222 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2225 [(set_attr "type" "cntlz")])
2227 (define_expand "ffs<mode>2"
2229 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2231 (and:GPR (match_dup 1)
2234 (clz:GPR (match_dup 3)))
2235 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2236 (minus:GPR (match_dup 5)
2238 (clobber (reg:GPR CA_REGNO))])]
2241 operands[2] = gen_reg_rtx (<MODE>mode);
2242 operands[3] = gen_reg_rtx (<MODE>mode);
2243 operands[4] = gen_reg_rtx (<MODE>mode);
2244 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2248 (define_expand "popcount<mode>2"
2249 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2250 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2251 "TARGET_POPCNTB || TARGET_POPCNTD"
2253 rs6000_emit_popcount (operands[0], operands[1]);
2257 (define_insn "popcntb<mode>2"
2258 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2259 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2263 [(set_attr "type" "popcnt")])
2265 (define_insn "popcntd<mode>2"
2266 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2267 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2270 [(set_attr "type" "popcnt")])
2273 (define_expand "parity<mode>2"
2274 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2275 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2278 rs6000_emit_parity (operands[0], operands[1]);
2282 (define_insn "parity<mode>2_cmpb"
2283 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2284 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2285 "TARGET_CMPB && TARGET_POPCNTB"
2287 [(set_attr "type" "popcnt")])
2290 ;; Since the hardware zeros the upper part of the register, save generating the
2291 ;; AND immediate if we are converting to unsigned
2292 (define_insn "*bswaphi2_extenddi"
2293 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2295 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2298 [(set_attr "length" "4")
2299 (set_attr "type" "load")])
2301 (define_insn "*bswaphi2_extendsi"
2302 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2304 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2307 [(set_attr "length" "4")
2308 (set_attr "type" "load")])
2310 (define_expand "bswaphi2"
2311 [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2313 (match_operand:HI 1 "reg_or_mem_operand" "")))
2314 (clobber (match_scratch:SI 2 ""))])]
2317 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2318 operands[1] = force_reg (HImode, operands[1]);
2321 (define_insn "bswaphi2_internal"
2322 [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2324 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2325 (clobber (match_scratch:SI 2 "=X,X,&r"))]
2331 [(set_attr "length" "4,4,12")
2332 (set_attr "type" "load,store,*")])
2335 [(set (match_operand:HI 0 "gpc_reg_operand" "")
2336 (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2337 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2340 (and:SI (lshiftrt:SI (match_dup 4)
2344 (and:SI (ashift:SI (match_dup 4)
2346 (const_int 65280))) ;; 0xff00
2348 (ior:SI (match_dup 3)
2352 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2353 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2356 (define_insn "*bswapsi2_extenddi"
2357 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2359 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2362 [(set_attr "length" "4")
2363 (set_attr "type" "load")])
2365 (define_expand "bswapsi2"
2366 [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2368 (match_operand:SI 1 "reg_or_mem_operand" "")))]
2371 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2372 operands[1] = force_reg (SImode, operands[1]);
2375 (define_insn "*bswapsi2_internal"
2376 [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2378 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2384 [(set_attr "length" "4,4,12")
2385 (set_attr "type" "load,store,*")])
2387 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2388 ;; zero_extract insns do not change for -mlittle.
2390 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2391 (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2393 [(set (match_dup 0) ; DABC
2394 (rotate:SI (match_dup 1)
2396 (set (match_dup 0) ; DCBC
2397 (ior:SI (and:SI (ashift:SI (match_dup 1)
2399 (const_int 16711680))
2400 (and:SI (match_dup 0)
2401 (const_int -16711681))))
2402 (set (match_dup 0) ; DCBA
2403 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2406 (and:SI (match_dup 0)
2412 (define_expand "bswapdi2"
2413 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2415 (match_operand:DI 1 "reg_or_mem_operand" "")))
2416 (clobber (match_scratch:DI 2 ""))
2417 (clobber (match_scratch:DI 3 ""))])]
2420 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2421 operands[1] = force_reg (DImode, operands[1]);
2423 if (!TARGET_POWERPC64)
2425 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2426 that uses 64-bit registers needs the same scratch registers as 64-bit
2428 emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2433 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2434 (define_insn "*bswapdi2_ldbrx"
2435 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2436 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2437 (clobber (match_scratch:DI 2 "=X,X,&r"))
2438 (clobber (match_scratch:DI 3 "=X,X,&r"))]
2439 "TARGET_POWERPC64 && TARGET_LDBRX
2440 && (REG_P (operands[0]) || REG_P (operands[1]))"
2445 [(set_attr "length" "4,4,36")
2446 (set_attr "type" "load,store,*")])
2448 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2449 (define_insn "*bswapdi2_64bit"
2450 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2451 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2452 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2453 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2454 "TARGET_POWERPC64 && !TARGET_LDBRX
2455 && (REG_P (operands[0]) || REG_P (operands[1]))
2456 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2457 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2459 [(set_attr "length" "16,12,36")])
2462 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2463 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2464 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2465 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2466 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2470 rtx dest = operands[0];
2471 rtx src = operands[1];
2472 rtx op2 = operands[2];
2473 rtx op3 = operands[3];
2474 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2475 BYTES_BIG_ENDIAN ? 4 : 0);
2476 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2477 BYTES_BIG_ENDIAN ? 4 : 0);
2483 addr1 = XEXP (src, 0);
2484 if (GET_CODE (addr1) == PLUS)
2486 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2487 if (TARGET_AVOID_XFORM)
2489 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2493 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2495 else if (TARGET_AVOID_XFORM)
2497 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2502 emit_move_insn (op2, GEN_INT (4));
2503 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2506 word1 = change_address (src, SImode, addr1);
2507 word2 = change_address (src, SImode, addr2);
2509 if (BYTES_BIG_ENDIAN)
2511 emit_insn (gen_bswapsi2 (op3_32, word2));
2512 emit_insn (gen_bswapsi2 (dest_32, word1));
2516 emit_insn (gen_bswapsi2 (op3_32, word1));
2517 emit_insn (gen_bswapsi2 (dest_32, word2));
2520 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2521 emit_insn (gen_iordi3 (dest, dest, op3));
2526 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2527 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2528 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2529 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2530 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2534 rtx dest = operands[0];
2535 rtx src = operands[1];
2536 rtx op2 = operands[2];
2537 rtx op3 = operands[3];
2538 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2539 BYTES_BIG_ENDIAN ? 4 : 0);
2540 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2541 BYTES_BIG_ENDIAN ? 4 : 0);
2547 addr1 = XEXP (dest, 0);
2548 if (GET_CODE (addr1) == PLUS)
2550 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2551 if (TARGET_AVOID_XFORM)
2553 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2557 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2559 else if (TARGET_AVOID_XFORM)
2561 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2566 emit_move_insn (op2, GEN_INT (4));
2567 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2570 word1 = change_address (dest, SImode, addr1);
2571 word2 = change_address (dest, SImode, addr2);
2573 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2575 if (BYTES_BIG_ENDIAN)
2577 emit_insn (gen_bswapsi2 (word1, src_si));
2578 emit_insn (gen_bswapsi2 (word2, op3_si));
2582 emit_insn (gen_bswapsi2 (word2, src_si));
2583 emit_insn (gen_bswapsi2 (word1, op3_si));
2589 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2590 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2591 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2592 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2593 "TARGET_POWERPC64 && reload_completed"
2597 rtx dest = operands[0];
2598 rtx src = operands[1];
2599 rtx op2 = operands[2];
2600 rtx op3 = operands[3];
2601 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2602 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2603 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2604 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2605 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2607 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2608 emit_insn (gen_bswapsi2 (dest_si, src_si));
2609 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2610 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2611 emit_insn (gen_iordi3 (dest, dest, op3));
2615 (define_insn "bswapdi2_32bit"
2616 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2617 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2618 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2619 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2621 [(set_attr "length" "16,12,36")])
2624 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2625 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2626 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2627 "!TARGET_POWERPC64 && reload_completed"
2631 rtx dest = operands[0];
2632 rtx src = operands[1];
2633 rtx op2 = operands[2];
2634 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2635 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2641 addr1 = XEXP (src, 0);
2642 if (GET_CODE (addr1) == PLUS)
2644 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2645 if (TARGET_AVOID_XFORM
2646 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2648 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2652 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2654 else if (TARGET_AVOID_XFORM
2655 || REGNO (addr1) == REGNO (dest2))
2657 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2662 emit_move_insn (op2, GEN_INT (4));
2663 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2666 word1 = change_address (src, SImode, addr1);
2667 word2 = change_address (src, SImode, addr2);
2669 emit_insn (gen_bswapsi2 (dest2, word1));
2670 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2671 thus allowing us to omit an early clobber on the output. */
2672 emit_insn (gen_bswapsi2 (dest1, word2));
2677 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2678 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2679 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2680 "!TARGET_POWERPC64 && reload_completed"
2684 rtx dest = operands[0];
2685 rtx src = operands[1];
2686 rtx op2 = operands[2];
2687 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2688 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2694 addr1 = XEXP (dest, 0);
2695 if (GET_CODE (addr1) == PLUS)
2697 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2698 if (TARGET_AVOID_XFORM)
2700 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2704 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2706 else if (TARGET_AVOID_XFORM)
2708 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2713 emit_move_insn (op2, GEN_INT (4));
2714 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2717 word1 = change_address (dest, SImode, addr1);
2718 word2 = change_address (dest, SImode, addr2);
2720 emit_insn (gen_bswapsi2 (word2, src1));
2721 emit_insn (gen_bswapsi2 (word1, src2));
2726 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2727 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2728 (clobber (match_operand:SI 2 "" ""))]
2729 "!TARGET_POWERPC64 && reload_completed"
2733 rtx dest = operands[0];
2734 rtx src = operands[1];
2735 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2736 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2737 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2738 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2740 emit_insn (gen_bswapsi2 (dest1, src2));
2741 emit_insn (gen_bswapsi2 (dest2, src1));
2746 (define_insn "mul<mode>3"
2747 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2748 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2749 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2754 [(set_attr "type" "mul")
2756 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2758 (match_operand:GPR 2 "short_cint_operand" "")
2759 (const_string "16")]
2760 (const_string "<bits>")))])
2762 (define_insn_and_split "*mul<mode>3_dot"
2763 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2764 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2765 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2767 (clobber (match_scratch:GPR 0 "=r,r"))]
2768 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2772 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2774 (mult:GPR (match_dup 1)
2777 (compare:CC (match_dup 0)
2780 [(set_attr "type" "mul")
2781 (set_attr "size" "<bits>")
2782 (set_attr "dot" "yes")
2783 (set_attr "length" "4,8")])
2785 (define_insn_and_split "*mul<mode>3_dot2"
2786 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2787 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2788 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2790 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2791 (mult:GPR (match_dup 1)
2793 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2797 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2799 (mult:GPR (match_dup 1)
2802 (compare:CC (match_dup 0)
2805 [(set_attr "type" "mul")
2806 (set_attr "size" "<bits>")
2807 (set_attr "dot" "yes")
2808 (set_attr "length" "4,8")])
2811 (define_expand "<su>mul<mode>3_highpart"
2812 [(set (match_operand:GPR 0 "gpc_reg_operand")
2814 (mult:<DMODE> (any_extend:<DMODE>
2815 (match_operand:GPR 1 "gpc_reg_operand"))
2817 (match_operand:GPR 2 "gpc_reg_operand")))
2821 if (<MODE>mode == SImode && TARGET_POWERPC64)
2823 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2828 if (!WORDS_BIG_ENDIAN)
2830 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2836 (define_insn "*<su>mul<mode>3_highpart"
2837 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2839 (mult:<DMODE> (any_extend:<DMODE>
2840 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2842 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2844 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2845 "mulh<wd><u> %0,%1,%2"
2846 [(set_attr "type" "mul")
2847 (set_attr "size" "<bits>")])
2849 (define_insn "<su>mulsi3_highpart_le"
2850 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2852 (mult:DI (any_extend:DI
2853 (match_operand:SI 1 "gpc_reg_operand" "r"))
2855 (match_operand:SI 2 "gpc_reg_operand" "r")))
2857 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2859 [(set_attr "type" "mul")])
2861 (define_insn "<su>muldi3_highpart_le"
2862 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2864 (mult:TI (any_extend:TI
2865 (match_operand:DI 1 "gpc_reg_operand" "r"))
2867 (match_operand:DI 2 "gpc_reg_operand" "r")))
2869 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2871 [(set_attr "type" "mul")
2872 (set_attr "size" "64")])
2874 (define_insn "<su>mulsi3_highpart_64"
2875 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2878 (mult:DI (any_extend:DI
2879 (match_operand:SI 1 "gpc_reg_operand" "r"))
2881 (match_operand:SI 2 "gpc_reg_operand" "r")))
2885 [(set_attr "type" "mul")])
2887 (define_expand "<u>mul<mode><dmode>3"
2888 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2889 (mult:<DMODE> (any_extend:<DMODE>
2890 (match_operand:GPR 1 "gpc_reg_operand"))
2892 (match_operand:GPR 2 "gpc_reg_operand"))))]
2893 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2895 rtx l = gen_reg_rtx (<MODE>mode);
2896 rtx h = gen_reg_rtx (<MODE>mode);
2897 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2898 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2899 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2900 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2904 (define_insn "*maddld4"
2905 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2906 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2907 (match_operand:DI 2 "gpc_reg_operand" "r"))
2908 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2910 "maddld %0,%1,%2,%3"
2911 [(set_attr "type" "mul")])
2913 (define_insn "udiv<mode>3"
2914 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2915 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2916 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2919 [(set_attr "type" "div")
2920 (set_attr "size" "<bits>")])
2923 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2924 ;; modulus. If it isn't a power of two, force operands into register and do
2926 (define_expand "div<mode>3"
2927 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2928 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2929 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2932 if (CONST_INT_P (operands[2])
2933 && INTVAL (operands[2]) > 0
2934 && exact_log2 (INTVAL (operands[2])) >= 0)
2936 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2940 operands[2] = force_reg (<MODE>mode, operands[2]);
2943 (define_insn "*div<mode>3"
2944 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2945 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2946 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2949 [(set_attr "type" "div")
2950 (set_attr "size" "<bits>")])
2952 (define_insn "div<mode>3_sra"
2953 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2954 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2955 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2956 (clobber (reg:GPR CA_REGNO))]
2958 "sra<wd>i %0,%1,%p2\;addze %0,%0"
2959 [(set_attr "type" "two")
2960 (set_attr "length" "8")])
2962 (define_insn_and_split "*div<mode>3_sra_dot"
2963 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2964 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2965 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2967 (clobber (match_scratch:GPR 0 "=r,r"))
2968 (clobber (reg:GPR CA_REGNO))]
2969 "<MODE>mode == Pmode"
2971 sra<wd>i %0,%1,%p2\;addze. %0,%0
2973 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2974 [(parallel [(set (match_dup 0)
2975 (div:GPR (match_dup 1)
2977 (clobber (reg:GPR CA_REGNO))])
2979 (compare:CC (match_dup 0)
2982 [(set_attr "type" "two")
2983 (set_attr "length" "8,12")
2984 (set_attr "cell_micro" "not")])
2986 (define_insn_and_split "*div<mode>3_sra_dot2"
2987 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2988 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2989 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2991 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2992 (div:GPR (match_dup 1)
2994 (clobber (reg:GPR CA_REGNO))]
2995 "<MODE>mode == Pmode"
2997 sra<wd>i %0,%1,%p2\;addze. %0,%0
2999 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3000 [(parallel [(set (match_dup 0)
3001 (div:GPR (match_dup 1)
3003 (clobber (reg:GPR CA_REGNO))])
3005 (compare:CC (match_dup 0)
3008 [(set_attr "type" "two")
3009 (set_attr "length" "8,12")
3010 (set_attr "cell_micro" "not")])
3012 (define_expand "mod<mode>3"
3013 [(set (match_operand:GPR 0 "gpc_reg_operand")
3014 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3015 (match_operand:GPR 2 "reg_or_cint_operand")))]
3022 if (GET_CODE (operands[2]) != CONST_INT
3023 || INTVAL (operands[2]) <= 0
3024 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3029 operands[2] = force_reg (<MODE>mode, operands[2]);
3033 temp1 = gen_reg_rtx (<MODE>mode);
3034 temp2 = gen_reg_rtx (<MODE>mode);
3036 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3037 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3038 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3043 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3044 ;; mod, prefer putting the result of mod into a different register
3045 (define_insn "*mod<mode>3"
3046 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3047 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3048 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3051 [(set_attr "type" "div")
3052 (set_attr "size" "<bits>")])
3055 (define_insn "umod<mode>3"
3056 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3057 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3058 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3061 [(set_attr "type" "div")
3062 (set_attr "size" "<bits>")])
3064 ;; On machines with modulo support, do a combined div/mod the old fashioned
3065 ;; method, since the multiply/subtract is faster than doing the mod instruction
3069 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3070 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3071 (match_operand:GPR 2 "gpc_reg_operand" "")))
3072 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3073 (mod:GPR (match_dup 1)
3076 && ! reg_mentioned_p (operands[0], operands[1])
3077 && ! reg_mentioned_p (operands[0], operands[2])
3078 && ! reg_mentioned_p (operands[3], operands[1])
3079 && ! reg_mentioned_p (operands[3], operands[2])"
3081 (div:GPR (match_dup 1)
3084 (mult:GPR (match_dup 0)
3087 (minus:GPR (match_dup 1)
3091 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3092 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3093 (match_operand:GPR 2 "gpc_reg_operand" "")))
3094 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3095 (umod:GPR (match_dup 1)
3098 && ! reg_mentioned_p (operands[0], operands[1])
3099 && ! reg_mentioned_p (operands[0], operands[2])
3100 && ! reg_mentioned_p (operands[3], operands[1])
3101 && ! reg_mentioned_p (operands[3], operands[2])"
3103 (div:GPR (match_dup 1)
3106 (mult:GPR (match_dup 0)
3109 (minus:GPR (match_dup 1)
3113 ;; Logical instructions
3114 ;; The logical instructions are mostly combined by using match_operator,
3115 ;; but the plain AND insns are somewhat different because there is no
3116 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3117 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3119 (define_expand "and<mode>3"
3120 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3121 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3122 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3125 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3127 rs6000_split_logical (operands, AND, false, false, false);
3131 if (CONST_INT_P (operands[2]))
3133 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3135 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3139 if (logical_const_operand (operands[2], <MODE>mode)
3140 && rs6000_gen_cell_microcode)
3142 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3146 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3148 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3152 operands[2] = force_reg (<MODE>mode, operands[2]);
3157 (define_insn "and<mode>3_imm"
3158 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3159 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3160 (match_operand:GPR 2 "logical_const_operand" "n")))
3161 (clobber (match_scratch:CC 3 "=x"))]
3162 "rs6000_gen_cell_microcode
3163 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3164 "andi%e2. %0,%1,%u2"
3165 [(set_attr "type" "logical")
3166 (set_attr "dot" "yes")])
3168 (define_insn_and_split "*and<mode>3_imm_dot"
3169 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3170 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3171 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3173 (clobber (match_scratch:GPR 0 "=r,r"))
3174 (clobber (match_scratch:CC 4 "=X,x"))]
3175 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3176 && rs6000_gen_cell_microcode
3177 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3181 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3182 [(parallel [(set (match_dup 0)
3183 (and:GPR (match_dup 1)
3185 (clobber (match_dup 4))])
3187 (compare:CC (match_dup 0)
3190 [(set_attr "type" "logical")
3191 (set_attr "dot" "yes")
3192 (set_attr "length" "4,8")])
3194 (define_insn_and_split "*and<mode>3_imm_dot2"
3195 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3196 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3197 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3199 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3200 (and:GPR (match_dup 1)
3202 (clobber (match_scratch:CC 4 "=X,x"))]
3203 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3204 && rs6000_gen_cell_microcode
3205 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3209 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3210 [(parallel [(set (match_dup 0)
3211 (and:GPR (match_dup 1)
3213 (clobber (match_dup 4))])
3215 (compare:CC (match_dup 0)
3218 [(set_attr "type" "logical")
3219 (set_attr "dot" "yes")
3220 (set_attr "length" "4,8")])
3222 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3223 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3224 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3225 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3227 (clobber (match_scratch:GPR 0 "=r,r"))]
3228 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3229 && rs6000_gen_cell_microcode"
3233 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3235 (and:GPR (match_dup 1)
3238 (compare:CC (match_dup 0)
3241 [(set_attr "type" "logical")
3242 (set_attr "dot" "yes")
3243 (set_attr "length" "4,8")])
3245 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3246 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3247 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3248 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3250 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3251 (and:GPR (match_dup 1)
3253 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3254 && rs6000_gen_cell_microcode"
3258 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3260 (and:GPR (match_dup 1)
3263 (compare:CC (match_dup 0)
3266 [(set_attr "type" "logical")
3267 (set_attr "dot" "yes")
3268 (set_attr "length" "4,8")])
3270 (define_insn "*and<mode>3_imm_dot_shifted"
3271 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3274 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3275 (match_operand:SI 4 "const_int_operand" "n"))
3276 (match_operand:GPR 2 "const_int_operand" "n"))
3278 (clobber (match_scratch:GPR 0 "=r"))]
3279 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3280 << INTVAL (operands[4])),
3282 && (<MODE>mode == Pmode
3283 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3284 && rs6000_gen_cell_microcode"
3286 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3287 return "andi%e2. %0,%1,%u2";
3289 [(set_attr "type" "logical")
3290 (set_attr "dot" "yes")])
3293 (define_insn "and<mode>3_mask"
3294 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3295 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3296 (match_operand:GPR 2 "const_int_operand" "n")))]
3297 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3299 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3301 [(set_attr "type" "shift")])
3303 (define_insn_and_split "*and<mode>3_mask_dot"
3304 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3305 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3306 (match_operand:GPR 2 "const_int_operand" "n,n"))
3308 (clobber (match_scratch:GPR 0 "=r,r"))]
3309 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3310 && rs6000_gen_cell_microcode
3311 && !logical_const_operand (operands[2], <MODE>mode)
3312 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3314 if (which_alternative == 0)
3315 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3319 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3321 (and:GPR (match_dup 1)
3324 (compare:CC (match_dup 0)
3327 [(set_attr "type" "shift")
3328 (set_attr "dot" "yes")
3329 (set_attr "length" "4,8")])
3331 (define_insn_and_split "*and<mode>3_mask_dot2"
3332 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3333 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3334 (match_operand:GPR 2 "const_int_operand" "n,n"))
3336 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3337 (and:GPR (match_dup 1)
3339 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3340 && rs6000_gen_cell_microcode
3341 && !logical_const_operand (operands[2], <MODE>mode)
3342 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3344 if (which_alternative == 0)
3345 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3349 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3351 (and:GPR (match_dup 1)
3354 (compare:CC (match_dup 0)
3357 [(set_attr "type" "shift")
3358 (set_attr "dot" "yes")
3359 (set_attr "length" "4,8")])
3362 (define_insn_and_split "*and<mode>3_2insn"
3363 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3364 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3365 (match_operand:GPR 2 "const_int_operand" "n")))]
3366 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3367 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3368 || (logical_const_operand (operands[2], <MODE>mode)
3369 && rs6000_gen_cell_microcode))"
3374 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3377 [(set_attr "type" "shift")
3378 (set_attr "length" "8")])
3380 (define_insn_and_split "*and<mode>3_2insn_dot"
3381 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3382 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3383 (match_operand:GPR 2 "const_int_operand" "n,n"))
3385 (clobber (match_scratch:GPR 0 "=r,r"))]
3386 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3387 && rs6000_gen_cell_microcode
3388 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3389 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3390 || (logical_const_operand (operands[2], <MODE>mode)
3391 && rs6000_gen_cell_microcode))"
3393 "&& reload_completed"
3396 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3399 [(set_attr "type" "shift")
3400 (set_attr "dot" "yes")
3401 (set_attr "length" "8,12")])
3403 (define_insn_and_split "*and<mode>3_2insn_dot2"
3404 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3405 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3406 (match_operand:GPR 2 "const_int_operand" "n,n"))
3408 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3409 (and:GPR (match_dup 1)
3411 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3412 && rs6000_gen_cell_microcode
3413 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3414 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3415 || (logical_const_operand (operands[2], <MODE>mode)
3416 && rs6000_gen_cell_microcode))"
3418 "&& reload_completed"
3421 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3424 [(set_attr "type" "shift")
3425 (set_attr "dot" "yes")
3426 (set_attr "length" "8,12")])
3429 (define_expand "<code><mode>3"
3430 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3431 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3432 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3435 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3437 rs6000_split_logical (operands, <CODE>, false, false, false);
3441 if (non_logical_cint_operand (operands[2], <MODE>mode))
3443 rtx tmp = ((!can_create_pseudo_p ()
3444 || rtx_equal_p (operands[0], operands[1]))
3445 ? operands[0] : gen_reg_rtx (<MODE>mode));
3447 HOST_WIDE_INT value = INTVAL (operands[2]);
3448 HOST_WIDE_INT lo = value & 0xffff;
3449 HOST_WIDE_INT hi = value - lo;
3451 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3452 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3456 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3457 operands[2] = force_reg (<MODE>mode, operands[2]);
3461 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3462 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3463 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3466 (iorxor:GPR (match_dup 1)
3469 (iorxor:GPR (match_dup 3)
3472 operands[3] = ((!can_create_pseudo_p ()
3473 || rtx_equal_p (operands[0], operands[1]))
3474 ? operands[0] : gen_reg_rtx (<MODE>mode));
3476 HOST_WIDE_INT value = INTVAL (operands[2]);
3477 HOST_WIDE_INT lo = value & 0xffff;
3478 HOST_WIDE_INT hi = value - lo;
3480 operands[4] = GEN_INT (hi);
3481 operands[5] = GEN_INT (lo);
3484 (define_insn "*bool<mode>3_imm"
3485 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3486 (match_operator:GPR 3 "boolean_or_operator"
3487 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3488 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3491 [(set_attr "type" "logical")])
3493 (define_insn "*bool<mode>3"
3494 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3495 (match_operator:GPR 3 "boolean_operator"
3496 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3497 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3500 [(set_attr "type" "logical")])
3502 (define_insn_and_split "*bool<mode>3_dot"
3503 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3504 (compare:CC (match_operator:GPR 3 "boolean_operator"
3505 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3506 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3508 (clobber (match_scratch:GPR 0 "=r,r"))]
3509 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3513 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3517 (compare:CC (match_dup 0)
3520 [(set_attr "type" "logical")
3521 (set_attr "dot" "yes")
3522 (set_attr "length" "4,8")])
3524 (define_insn_and_split "*bool<mode>3_dot2"
3525 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3526 (compare:CC (match_operator:GPR 3 "boolean_operator"
3527 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3528 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3530 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3532 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3536 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3540 (compare:CC (match_dup 0)
3543 [(set_attr "type" "logical")
3544 (set_attr "dot" "yes")
3545 (set_attr "length" "4,8")])
3548 (define_insn "*boolc<mode>3"
3549 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3550 (match_operator:GPR 3 "boolean_operator"
3551 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3552 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3555 [(set_attr "type" "logical")])
3557 (define_insn_and_split "*boolc<mode>3_dot"
3558 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3559 (compare:CC (match_operator:GPR 3 "boolean_operator"
3560 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3561 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3563 (clobber (match_scratch:GPR 0 "=r,r"))]
3564 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3568 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3572 (compare:CC (match_dup 0)
3575 [(set_attr "type" "logical")
3576 (set_attr "dot" "yes")
3577 (set_attr "length" "4,8")])
3579 (define_insn_and_split "*boolc<mode>3_dot2"
3580 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3581 (compare:CC (match_operator:GPR 3 "boolean_operator"
3582 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3583 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3585 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3587 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3591 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3595 (compare:CC (match_dup 0)
3598 [(set_attr "type" "logical")
3599 (set_attr "dot" "yes")
3600 (set_attr "length" "4,8")])
3603 (define_insn "*boolcc<mode>3"
3604 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3605 (match_operator:GPR 3 "boolean_operator"
3606 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3607 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3610 [(set_attr "type" "logical")])
3612 (define_insn_and_split "*boolcc<mode>3_dot"
3613 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3614 (compare:CC (match_operator:GPR 3 "boolean_operator"
3615 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3616 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3618 (clobber (match_scratch:GPR 0 "=r,r"))]
3619 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3623 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3627 (compare:CC (match_dup 0)
3630 [(set_attr "type" "logical")
3631 (set_attr "dot" "yes")
3632 (set_attr "length" "4,8")])
3634 (define_insn_and_split "*boolcc<mode>3_dot2"
3635 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3636 (compare:CC (match_operator:GPR 3 "boolean_operator"
3637 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3638 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3640 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3642 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3646 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3650 (compare:CC (match_dup 0)
3653 [(set_attr "type" "logical")
3654 (set_attr "dot" "yes")
3655 (set_attr "length" "4,8")])
3658 ;; TODO: Should have dots of this as well.
3659 (define_insn "*eqv<mode>3"
3660 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3661 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3662 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3665 [(set_attr "type" "logical")])
3667 ;; Rotate-and-mask and insert.
3669 (define_insn "*rotl<mode>3_mask"
3670 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3671 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3672 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3673 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3674 (match_operand:GPR 3 "const_int_operand" "n")))]
3675 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3677 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3679 [(set_attr "type" "shift")
3680 (set_attr "maybe_var_shift" "yes")])
3682 (define_insn_and_split "*rotl<mode>3_mask_dot"
3683 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3685 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3686 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3687 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3688 (match_operand:GPR 3 "const_int_operand" "n,n"))
3690 (clobber (match_scratch:GPR 0 "=r,r"))]
3691 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3692 && rs6000_gen_cell_microcode
3693 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3695 if (which_alternative == 0)
3696 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3700 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3702 (and:GPR (match_dup 4)
3705 (compare:CC (match_dup 0)
3708 [(set_attr "type" "shift")
3709 (set_attr "maybe_var_shift" "yes")
3710 (set_attr "dot" "yes")
3711 (set_attr "length" "4,8")])
3713 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3714 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3716 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3717 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3718 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3719 (match_operand:GPR 3 "const_int_operand" "n,n"))
3721 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3722 (and:GPR (match_dup 4)
3724 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3725 && rs6000_gen_cell_microcode
3726 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3728 if (which_alternative == 0)
3729 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3733 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3735 (and:GPR (match_dup 4)
3738 (compare:CC (match_dup 0)
3741 [(set_attr "type" "shift")
3742 (set_attr "maybe_var_shift" "yes")
3743 (set_attr "dot" "yes")
3744 (set_attr "length" "4,8")])
3746 ; Special case for less-than-0. We can do it with just one machine
3747 ; instruction, but the generic optimizers do not realise it is cheap.
3748 (define_insn "*lt0_disi"
3749 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3750 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3753 "rlwinm %0,%1,1,31,31"
3754 [(set_attr "type" "shift")])
3758 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3759 ; both are an AND so are the same precedence).
3760 (define_insn "*rotl<mode>3_insert"
3761 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3762 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3763 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3764 (match_operand:SI 2 "const_int_operand" "n")])
3765 (match_operand:GPR 3 "const_int_operand" "n"))
3766 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3767 (match_operand:GPR 6 "const_int_operand" "n"))))]
3768 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3769 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3771 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3773 [(set_attr "type" "insert")])
3774 ; FIXME: this needs an attr "size", so that the scheduler can see the
3775 ; difference between rlwimi and rldimi. We also might want dot forms,
3776 ; but not for rlwimi on POWER4 and similar processors.
3778 (define_insn "*rotl<mode>3_insert_2"
3779 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3780 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3781 (match_operand:GPR 6 "const_int_operand" "n"))
3782 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3783 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3784 (match_operand:SI 2 "const_int_operand" "n")])
3785 (match_operand:GPR 3 "const_int_operand" "n"))))]
3786 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3787 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3789 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3791 [(set_attr "type" "insert")])
3793 ; There are also some forms without one of the ANDs.
3794 (define_insn "*rotl<mode>3_insert_3"
3795 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3796 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3797 (match_operand:GPR 4 "const_int_operand" "n"))
3798 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3799 (match_operand:SI 2 "const_int_operand" "n"))))]
3800 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3802 if (<MODE>mode == SImode)
3803 return "rlwimi %0,%1,%h2,0,31-%h2";
3805 return "rldimi %0,%1,%H2,0";
3807 [(set_attr "type" "insert")])
3809 (define_insn "*rotl<mode>3_insert_4"
3810 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3811 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3812 (match_operand:GPR 4 "const_int_operand" "n"))
3813 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3814 (match_operand:SI 2 "const_int_operand" "n"))))]
3815 "<MODE>mode == SImode &&
3816 GET_MODE_PRECISION (<MODE>mode)
3817 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3819 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3820 - INTVAL (operands[2]));
3821 if (<MODE>mode == SImode)
3822 return "rlwimi %0,%1,%h2,32-%h2,31";
3824 return "rldimi %0,%1,%H2,64-%H2";
3826 [(set_attr "type" "insert")])
3829 ; This handles the important case of multiple-precision shifts. There is
3830 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3832 [(set (match_operand:GPR 0 "gpc_reg_operand")
3833 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3834 (match_operand:SI 3 "const_int_operand"))
3835 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3836 (match_operand:SI 4 "const_int_operand"))))]
3837 "can_create_pseudo_p ()
3838 && INTVAL (operands[3]) + INTVAL (operands[4])
3839 >= GET_MODE_PRECISION (<MODE>mode)"
3841 (lshiftrt:GPR (match_dup 2)
3844 (ior:GPR (and:GPR (match_dup 5)
3846 (ashift:GPR (match_dup 1)
3849 unsigned HOST_WIDE_INT mask = 1;
3850 mask = (mask << INTVAL (operands[3])) - 1;
3851 operands[5] = gen_reg_rtx (<MODE>mode);
3852 operands[6] = GEN_INT (mask);
3856 [(set (match_operand:GPR 0 "gpc_reg_operand")
3857 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3858 (match_operand:SI 4 "const_int_operand"))
3859 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3860 (match_operand:SI 3 "const_int_operand"))))]
3861 "can_create_pseudo_p ()
3862 && INTVAL (operands[3]) + INTVAL (operands[4])
3863 >= GET_MODE_PRECISION (<MODE>mode)"
3865 (lshiftrt:GPR (match_dup 2)
3868 (ior:GPR (and:GPR (match_dup 5)
3870 (ashift:GPR (match_dup 1)
3873 unsigned HOST_WIDE_INT mask = 1;
3874 mask = (mask << INTVAL (operands[3])) - 1;
3875 operands[5] = gen_reg_rtx (<MODE>mode);
3876 operands[6] = GEN_INT (mask);
3880 ; Another important case is setting some bits to 1; we can do that with
3881 ; an insert instruction, in many cases.
3882 (define_insn_and_split "*ior<mode>_mask"
3883 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3884 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3885 (match_operand:GPR 2 "const_int_operand" "n")))
3886 (clobber (match_scratch:GPR 3 "=r"))]
3887 "!logical_const_operand (operands[2], <MODE>mode)
3888 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3894 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3897 (and:GPR (match_dup 1)
3901 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3902 if (GET_CODE (operands[3]) == SCRATCH)
3903 operands[3] = gen_reg_rtx (<MODE>mode);
3904 operands[4] = GEN_INT (ne);
3905 operands[5] = GEN_INT (~UINTVAL (operands[2]));
3907 [(set_attr "type" "two")
3908 (set_attr "length" "8")])
3911 ;; Now the simple shifts.
3913 (define_insn "rotl<mode>3"
3914 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3915 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3916 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3918 "rotl<wd>%I2 %0,%1,%<hH>2"
3919 [(set_attr "type" "shift")
3920 (set_attr "maybe_var_shift" "yes")])
3922 (define_insn "*rotlsi3_64"
3923 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3925 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3926 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3928 "rotlw%I2 %0,%1,%h2"
3929 [(set_attr "type" "shift")
3930 (set_attr "maybe_var_shift" "yes")])
3932 (define_insn_and_split "*rotl<mode>3_dot"
3933 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3934 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3935 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3937 (clobber (match_scratch:GPR 0 "=r,r"))]
3938 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3940 rotl<wd>%I2. %0,%1,%<hH>2
3942 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3944 (rotate:GPR (match_dup 1)
3947 (compare:CC (match_dup 0)
3950 [(set_attr "type" "shift")
3951 (set_attr "maybe_var_shift" "yes")
3952 (set_attr "dot" "yes")
3953 (set_attr "length" "4,8")])
3955 (define_insn_and_split "*rotl<mode>3_dot2"
3956 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3957 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3958 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3960 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3961 (rotate:GPR (match_dup 1)
3963 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3965 rotl<wd>%I2. %0,%1,%<hH>2
3967 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3969 (rotate:GPR (match_dup 1)
3972 (compare:CC (match_dup 0)
3975 [(set_attr "type" "shift")
3976 (set_attr "maybe_var_shift" "yes")
3977 (set_attr "dot" "yes")
3978 (set_attr "length" "4,8")])
3981 (define_insn "ashl<mode>3"
3982 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3983 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3984 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3986 "sl<wd>%I2 %0,%1,%<hH>2"
3987 [(set_attr "type" "shift")
3988 (set_attr "maybe_var_shift" "yes")])
3990 (define_insn "*ashlsi3_64"
3991 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3993 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3994 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3997 [(set_attr "type" "shift")
3998 (set_attr "maybe_var_shift" "yes")])
4000 (define_insn_and_split "*ashl<mode>3_dot"
4001 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4002 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4003 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4005 (clobber (match_scratch:GPR 0 "=r,r"))]
4006 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4008 sl<wd>%I2. %0,%1,%<hH>2
4010 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4012 (ashift:GPR (match_dup 1)
4015 (compare:CC (match_dup 0)
4018 [(set_attr "type" "shift")
4019 (set_attr "maybe_var_shift" "yes")
4020 (set_attr "dot" "yes")
4021 (set_attr "length" "4,8")])
4023 (define_insn_and_split "*ashl<mode>3_dot2"
4024 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4025 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4026 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4028 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4029 (ashift:GPR (match_dup 1)
4031 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4033 sl<wd>%I2. %0,%1,%<hH>2
4035 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4037 (ashift:GPR (match_dup 1)
4040 (compare:CC (match_dup 0)
4043 [(set_attr "type" "shift")
4044 (set_attr "maybe_var_shift" "yes")
4045 (set_attr "dot" "yes")
4046 (set_attr "length" "4,8")])
4048 ;; Pretend we have a memory form of extswsli until register allocation is done
4049 ;; so that we use LWZ to load the value from memory, instead of LWA.
4050 (define_insn_and_split "ashdi3_extswsli"
4051 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4053 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4054 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4059 "&& reload_completed && MEM_P (operands[1])"
4063 (ashift:DI (sign_extend:DI (match_dup 3))
4066 operands[3] = gen_lowpart (SImode, operands[0]);
4068 [(set_attr "type" "shift")
4069 (set_attr "maybe_var_shift" "no")])
4072 (define_insn_and_split "ashdi3_extswsli_dot"
4073 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4076 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4077 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4079 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4086 "&& reload_completed
4087 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4088 || memory_operand (operands[1], SImode))"
4091 rtx dest = operands[0];
4092 rtx src = operands[1];
4093 rtx shift = operands[2];
4094 rtx cr = operands[3];
4101 src2 = gen_lowpart (SImode, dest);
4102 emit_move_insn (src2, src);
4105 if (REGNO (cr) == CR0_REGNO)
4107 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4111 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4112 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4115 [(set_attr "type" "shift")
4116 (set_attr "maybe_var_shift" "no")
4117 (set_attr "dot" "yes")
4118 (set_attr "length" "4,8,8,12")])
4120 (define_insn_and_split "ashdi3_extswsli_dot2"
4121 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4124 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4125 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4127 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4128 (ashift:DI (sign_extend:DI (match_dup 1))
4136 "&& reload_completed
4137 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4138 || memory_operand (operands[1], SImode))"
4141 rtx dest = operands[0];
4142 rtx src = operands[1];
4143 rtx shift = operands[2];
4144 rtx cr = operands[3];
4151 src2 = gen_lowpart (SImode, dest);
4152 emit_move_insn (src2, src);
4155 if (REGNO (cr) == CR0_REGNO)
4157 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4161 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4162 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4165 [(set_attr "type" "shift")
4166 (set_attr "maybe_var_shift" "no")
4167 (set_attr "dot" "yes")
4168 (set_attr "length" "4,8,8,12")])
4170 (define_insn "lshr<mode>3"
4171 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4172 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4173 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4175 "sr<wd>%I2 %0,%1,%<hH>2"
4176 [(set_attr "type" "shift")
4177 (set_attr "maybe_var_shift" "yes")])
4179 (define_insn "*lshrsi3_64"
4180 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4182 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4183 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4186 [(set_attr "type" "shift")
4187 (set_attr "maybe_var_shift" "yes")])
4189 (define_insn_and_split "*lshr<mode>3_dot"
4190 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4191 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4192 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4194 (clobber (match_scratch:GPR 0 "=r,r"))]
4195 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4197 sr<wd>%I2. %0,%1,%<hH>2
4199 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4201 (lshiftrt:GPR (match_dup 1)
4204 (compare:CC (match_dup 0)
4207 [(set_attr "type" "shift")
4208 (set_attr "maybe_var_shift" "yes")
4209 (set_attr "dot" "yes")
4210 (set_attr "length" "4,8")])
4212 (define_insn_and_split "*lshr<mode>3_dot2"
4213 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4214 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4215 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4217 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4218 (lshiftrt:GPR (match_dup 1)
4220 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4222 sr<wd>%I2. %0,%1,%<hH>2
4224 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4226 (lshiftrt:GPR (match_dup 1)
4229 (compare:CC (match_dup 0)
4232 [(set_attr "type" "shift")
4233 (set_attr "maybe_var_shift" "yes")
4234 (set_attr "dot" "yes")
4235 (set_attr "length" "4,8")])
4238 (define_insn "ashr<mode>3"
4239 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4240 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4241 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4242 (clobber (reg:GPR CA_REGNO))]
4244 "sra<wd>%I2 %0,%1,%<hH>2"
4245 [(set_attr "type" "shift")
4246 (set_attr "maybe_var_shift" "yes")])
4248 (define_insn "*ashrsi3_64"
4249 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4251 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4252 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4253 (clobber (reg:SI CA_REGNO))]
4256 [(set_attr "type" "shift")
4257 (set_attr "maybe_var_shift" "yes")])
4259 (define_insn_and_split "*ashr<mode>3_dot"
4260 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4261 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4262 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4264 (clobber (match_scratch:GPR 0 "=r,r"))
4265 (clobber (reg:GPR CA_REGNO))]
4266 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4268 sra<wd>%I2. %0,%1,%<hH>2
4270 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4271 [(parallel [(set (match_dup 0)
4272 (ashiftrt:GPR (match_dup 1)
4274 (clobber (reg:GPR CA_REGNO))])
4276 (compare:CC (match_dup 0)
4279 [(set_attr "type" "shift")
4280 (set_attr "maybe_var_shift" "yes")
4281 (set_attr "dot" "yes")
4282 (set_attr "length" "4,8")])
4284 (define_insn_and_split "*ashr<mode>3_dot2"
4285 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4286 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4287 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4289 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4290 (ashiftrt:GPR (match_dup 1)
4292 (clobber (reg:GPR CA_REGNO))]
4293 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4295 sra<wd>%I2. %0,%1,%<hH>2
4297 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4298 [(parallel [(set (match_dup 0)
4299 (ashiftrt:GPR (match_dup 1)
4301 (clobber (reg:GPR CA_REGNO))])
4303 (compare:CC (match_dup 0)
4306 [(set_attr "type" "shift")
4307 (set_attr "maybe_var_shift" "yes")
4308 (set_attr "dot" "yes")
4309 (set_attr "length" "4,8")])
4311 ;; Builtins to replace a division to generate FRE reciprocal estimate
4312 ;; instructions and the necessary fixup instructions
4313 (define_expand "recip<mode>3"
4314 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4315 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4316 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4317 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4319 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4323 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4324 ;; hardware division. This is only done before register allocation and with
4325 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4327 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4328 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4329 (match_operand 2 "gpc_reg_operand" "")))]
4330 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4331 && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4332 && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4335 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4339 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4340 ;; appropriate fixup.
4341 (define_expand "rsqrt<mode>2"
4342 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4343 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4344 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4346 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4350 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4351 ;; modes here, and also add in conditional vsx/power8-vector support to access
4352 ;; values in the traditional Altivec registers if the appropriate
4353 ;; -mupper-regs-{df,sf} option is enabled.
4355 (define_expand "abs<mode>2"
4356 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4357 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4358 "TARGET_<MODE>_INSN"
4361 (define_insn "*abs<mode>2_fpr"
4362 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4363 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4368 [(set_attr "type" "fpsimple")
4369 (set_attr "fp_type" "fp_addsub_<Fs>")])
4371 (define_insn "*nabs<mode>2_fpr"
4372 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4375 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4380 [(set_attr "type" "fpsimple")
4381 (set_attr "fp_type" "fp_addsub_<Fs>")])
4383 (define_expand "neg<mode>2"
4384 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4385 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4386 "TARGET_<MODE>_INSN"
4389 (define_insn "*neg<mode>2_fpr"
4390 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4391 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4396 [(set_attr "type" "fpsimple")
4397 (set_attr "fp_type" "fp_addsub_<Fs>")])
4399 (define_expand "add<mode>3"
4400 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4401 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4402 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4403 "TARGET_<MODE>_INSN"
4406 (define_insn "*add<mode>3_fpr"
4407 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4408 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4409 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4412 fadd<Ftrad> %0,%1,%2
4413 xsadd<Fvsx> %x0,%x1,%x2"
4414 [(set_attr "type" "fp")
4415 (set_attr "fp_type" "fp_addsub_<Fs>")])
4417 (define_expand "sub<mode>3"
4418 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4419 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4420 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4421 "TARGET_<MODE>_INSN"
4424 (define_insn "*sub<mode>3_fpr"
4425 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4426 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4427 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4430 fsub<Ftrad> %0,%1,%2
4431 xssub<Fvsx> %x0,%x1,%x2"
4432 [(set_attr "type" "fp")
4433 (set_attr "fp_type" "fp_addsub_<Fs>")])
4435 (define_expand "mul<mode>3"
4436 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4437 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4438 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4439 "TARGET_<MODE>_INSN"
4442 (define_insn "*mul<mode>3_fpr"
4443 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4444 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4445 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4448 fmul<Ftrad> %0,%1,%2
4449 xsmul<Fvsx> %x0,%x1,%x2"
4450 [(set_attr "type" "dmul")
4451 (set_attr "fp_type" "fp_mul_<Fs>")])
4453 (define_expand "div<mode>3"
4454 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4455 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4456 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4457 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4460 (define_insn "*div<mode>3_fpr"
4461 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4462 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4463 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4464 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4466 fdiv<Ftrad> %0,%1,%2
4467 xsdiv<Fvsx> %x0,%x1,%x2"
4468 [(set_attr "type" "<Fs>div")
4469 (set_attr "fp_type" "fp_div_<Fs>")])
4471 (define_insn "*sqrt<mode>2_internal"
4472 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4473 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4474 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4475 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4478 xssqrt<Fvsx> %x0,%x1"
4479 [(set_attr "type" "<Fs>sqrt")
4480 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4482 (define_expand "sqrt<mode>2"
4483 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4484 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4485 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4486 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4488 if (<MODE>mode == SFmode
4489 && TARGET_RECIP_PRECISION
4490 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4491 && !optimize_function_for_size_p (cfun)
4492 && flag_finite_math_only && !flag_trapping_math
4493 && flag_unsafe_math_optimizations)
4495 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4500 ;; Floating point reciprocal approximation
4501 (define_insn "fre<Fs>"
4502 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4503 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4509 [(set_attr "type" "fp")])
4511 (define_insn "*rsqrt<mode>2"
4512 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4513 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4515 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4517 frsqrte<Ftrad> %0,%1
4518 xsrsqrte<Fvsx> %x0,%x1"
4519 [(set_attr "type" "fp")])
4521 ;; Floating point comparisons
4522 (define_insn "*cmp<mode>_fpr"
4523 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4524 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4525 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4529 xscmpudp %0,%x1,%x2"
4530 [(set_attr "type" "fpcompare")])
4532 ;; Floating point conversions
4533 (define_expand "extendsfdf2"
4534 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4535 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4536 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4539 (define_insn_and_split "*extendsfdf2_fpr"
4540 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4541 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))]
4542 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4548 xscpsgndp %x0,%x1,%x1
4551 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4554 emit_note (NOTE_INSN_DELETED);
4557 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4559 (define_expand "truncdfsf2"
4560 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4561 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4562 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4565 (define_insn "*truncdfsf2_fpr"
4566 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4567 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4568 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4572 [(set_attr "type" "fp")])
4574 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4575 ;; builtins.c and optabs.c that are not correct for IBM long double
4576 ;; when little-endian.
4577 (define_expand "signbit<mode>2"
4579 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4581 (subreg:DI (match_dup 2) 0))
4584 (set (match_operand:SI 0 "gpc_reg_operand" "")
4587 && (TARGET_FPRS || TARGET_E500_DOUBLE)
4588 && (!FLOAT128_IEEE_P (<MODE>mode)
4589 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4591 if (FLOAT128_IEEE_P (<MODE>mode))
4593 if (<MODE>mode == KFmode)
4594 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4595 else if (<MODE>mode == TFmode)
4596 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4601 operands[2] = gen_reg_rtx (DFmode);
4602 operands[3] = gen_reg_rtx (DImode);
4603 if (TARGET_POWERPC64)
4605 operands[4] = gen_reg_rtx (DImode);
4606 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4607 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4608 WORDS_BIG_ENDIAN ? 4 : 0);
4612 operands[4] = gen_reg_rtx (SImode);
4613 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4614 WORDS_BIG_ENDIAN ? 0 : 4);
4615 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4619 (define_expand "copysign<mode>3"
4621 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4623 (neg:SFDF (abs:SFDF (match_dup 1))))
4624 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4625 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4629 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4630 && ((TARGET_PPC_GFXOPT
4631 && !HONOR_NANS (<MODE>mode)
4632 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4634 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4636 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4638 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4643 operands[3] = gen_reg_rtx (<MODE>mode);
4644 operands[4] = gen_reg_rtx (<MODE>mode);
4645 operands[5] = CONST0_RTX (<MODE>mode);
4648 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4650 (define_insn_and_split "signbit<mode>2_dm"
4651 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4653 [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,m,r")]
4655 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4657 "&& reload_completed"
4660 rs6000_split_signbit (operands[0], operands[1]);
4663 [(set_attr "length" "8,8,12")
4664 (set_attr "type" "mftgpr,load,integer")])
4666 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4667 ;; point types, which makes normal SUBREG's problematical. Instead use a
4668 ;; special pattern to avoid using a normal movdi.
4669 (define_insn "signbit<mode>2_dm2"
4670 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4671 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
4674 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4676 [(set_attr "type" "mftgpr")])
4679 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4680 ;; compiler from optimizing -0.0
4681 (define_insn "copysign<mode>3_fcpsgn"
4682 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4683 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4684 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4686 "TARGET_<MODE>_FPR && TARGET_CMPB"
4689 xscpsgndp %x0,%x2,%x1"
4690 [(set_attr "type" "fpsimple")])
4692 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4693 ;; fsel instruction and some auxiliary computations. Then we just have a
4694 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4696 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4697 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4698 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4699 ;; define_splits to make them if made by combine. On VSX machines we have the
4700 ;; min/max instructions.
4702 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4703 ;; to allow either DF/SF to use only traditional registers.
4705 (define_expand "s<minmax><mode>3"
4706 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4707 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4708 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4709 "TARGET_MINMAX_<MODE>"
4711 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4715 (define_insn "*s<minmax><mode>3_vsx"
4716 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4717 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4718 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4719 "TARGET_VSX && TARGET_<MODE>_FPR"
4721 return (TARGET_P9_MINMAX
4722 ? "xs<minmax>cdp %x0,%x1,%x2"
4723 : "xs<minmax>dp %x0,%x1,%x2");
4725 [(set_attr "type" "fp")])
4727 ;; The conditional move instructions allow us to perform max and min operations
4728 ;; even when we don't have the appropriate max/min instruction using the FSEL
4731 (define_insn_and_split "*s<minmax><mode>3_fpr"
4732 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4733 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4734 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4735 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4740 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4744 (define_expand "mov<mode>cc"
4745 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4746 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4747 (match_operand:GPR 2 "gpc_reg_operand" "")
4748 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4752 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4758 ;; We use the BASE_REGS for the isel input operands because, if rA is
4759 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4760 ;; because we may switch the operands and rB may end up being rA.
4762 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4763 ;; leave out the mode in operand 4 and use one pattern, but reload can
4764 ;; change the mode underneath our feet and then gets confused trying
4765 ;; to reload the value.
4766 (define_insn "isel_signed_<mode>"
4767 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4769 (match_operator 1 "scc_comparison_operator"
4770 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4772 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4773 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4776 { return output_isel (operands); }"
4777 [(set_attr "type" "isel")
4778 (set_attr "length" "4")])
4780 (define_insn "isel_unsigned_<mode>"
4781 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4783 (match_operator 1 "scc_comparison_operator"
4784 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4786 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4787 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4790 { return output_isel (operands); }"
4791 [(set_attr "type" "isel")
4792 (set_attr "length" "4")])
4794 ;; These patterns can be useful for combine; they let combine know that
4795 ;; isel can handle reversed comparisons so long as the operands are
4798 (define_insn "*isel_reversed_signed_<mode>"
4799 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4801 (match_operator 1 "scc_rev_comparison_operator"
4802 [(match_operand:CC 4 "cc_reg_operand" "y")
4804 (match_operand:GPR 2 "gpc_reg_operand" "b")
4805 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4808 { return output_isel (operands); }"
4809 [(set_attr "type" "isel")
4810 (set_attr "length" "4")])
4812 (define_insn "*isel_reversed_unsigned_<mode>"
4813 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4815 (match_operator 1 "scc_rev_comparison_operator"
4816 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4818 (match_operand:GPR 2 "gpc_reg_operand" "b")
4819 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4822 { return output_isel (operands); }"
4823 [(set_attr "type" "isel")
4824 (set_attr "length" "4")])
4826 ;; Floating point conditional move
4827 (define_expand "mov<mode>cc"
4828 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4829 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4830 (match_operand:SFDF 2 "gpc_reg_operand" "")
4831 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4832 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4835 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4841 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4842 [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4844 (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4845 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4846 (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4847 (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4848 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4850 [(set_attr "type" "fp")])
4852 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4853 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4855 (match_operator:CCFP 1 "fpmask_comparison_operator"
4856 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4857 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4858 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4859 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4860 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4865 (if_then_else:V2DI (match_dup 1)
4869 (if_then_else:SFDF (ne (match_dup 6)
4874 if (GET_CODE (operands[6]) == SCRATCH)
4875 operands[6] = gen_reg_rtx (V2DImode);
4877 operands[7] = CONSTM1_RTX (V2DImode);
4878 operands[8] = CONST0_RTX (V2DImode);
4880 [(set_attr "length" "8")
4881 (set_attr "type" "vecperm")])
4883 (define_insn "*fpmask<mode>"
4884 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
4886 (match_operator:CCFP 1 "fpmask_comparison_operator"
4887 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
4888 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
4889 (match_operand:V2DI 4 "all_ones_constant" "")
4890 (match_operand:V2DI 5 "zero_constant" "")))]
4892 "xscmp%V1dp %x0,%x2,%x3"
4893 [(set_attr "type" "fpcompare")])
4895 (define_insn "*xxsel<mode>"
4896 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4897 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
4898 (match_operand:V2DI 2 "zero_constant" ""))
4899 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
4900 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
4902 "xxsel %x0,%x1,%x3,%x4"
4903 [(set_attr "type" "vecmove")])
4906 ;; Conversions to and from floating-point.
4908 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4909 ; don't want to support putting SImode in FPR registers.
4910 (define_insn "lfiwax"
4911 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4912 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4914 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4919 [(set_attr "type" "fpload,fpload,mffgpr")])
4921 ; This split must be run before register allocation because it allocates the
4922 ; memory slot that is needed to move values to/from the FPR. We don't allocate
4923 ; it earlier to allow for the combiner to merge insns together where it might
4924 ; not be needed and also in case the insns are deleted as dead code.
4926 (define_insn_and_split "floatsi<mode>2_lfiwax"
4927 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4928 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4929 (clobber (match_scratch:DI 2 "=wi"))]
4930 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4931 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4937 rtx dest = operands[0];
4938 rtx src = operands[1];
4941 if (!MEM_P (src) && TARGET_POWERPC64
4942 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4943 tmp = convert_to_mode (DImode, src, false);
4947 if (GET_CODE (tmp) == SCRATCH)
4948 tmp = gen_reg_rtx (DImode);
4951 src = rs6000_address_for_fpconvert (src);
4952 emit_insn (gen_lfiwax (tmp, src));
4956 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4957 emit_move_insn (stack, src);
4958 emit_insn (gen_lfiwax (tmp, stack));
4961 emit_insn (gen_floatdi<mode>2 (dest, tmp));
4964 [(set_attr "length" "12")
4965 (set_attr "type" "fpload")])
4967 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
4968 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4971 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
4972 (clobber (match_scratch:DI 2 "=wi"))]
4973 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4980 operands[1] = rs6000_address_for_fpconvert (operands[1]);
4981 if (GET_CODE (operands[2]) == SCRATCH)
4982 operands[2] = gen_reg_rtx (DImode);
4983 emit_insn (gen_lfiwax (operands[2], operands[1]));
4984 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4987 [(set_attr "length" "8")
4988 (set_attr "type" "fpload")])
4990 (define_insn "lfiwzx"
4991 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4992 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4994 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
4999 [(set_attr "type" "fpload,fpload,mftgpr")])
5001 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5002 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5003 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5004 (clobber (match_scratch:DI 2 "=wi"))]
5005 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5012 rtx dest = operands[0];
5013 rtx src = operands[1];
5016 if (!MEM_P (src) && TARGET_POWERPC64
5017 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5018 tmp = convert_to_mode (DImode, src, true);
5022 if (GET_CODE (tmp) == SCRATCH)
5023 tmp = gen_reg_rtx (DImode);
5026 src = rs6000_address_for_fpconvert (src);
5027 emit_insn (gen_lfiwzx (tmp, src));
5031 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5032 emit_move_insn (stack, src);
5033 emit_insn (gen_lfiwzx (tmp, stack));
5036 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5039 [(set_attr "length" "12")
5040 (set_attr "type" "fpload")])
5042 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5043 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5044 (unsigned_float:SFDF
5046 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5047 (clobber (match_scratch:DI 2 "=wi"))]
5048 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5055 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5056 if (GET_CODE (operands[2]) == SCRATCH)
5057 operands[2] = gen_reg_rtx (DImode);
5058 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5059 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5062 [(set_attr "length" "8")
5063 (set_attr "type" "fpload")])
5065 ; For each of these conversions, there is a define_expand, a define_insn
5066 ; with a '#' template, and a define_split (with C code). The idea is
5067 ; to allow constant folding with the template of the define_insn,
5068 ; then to have the insns split later (between sched1 and final).
5070 (define_expand "floatsidf2"
5071 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5072 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5075 (clobber (match_dup 4))
5076 (clobber (match_dup 5))
5077 (clobber (match_dup 6))])]
5079 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5082 if (TARGET_E500_DOUBLE)
5084 if (!REG_P (operands[1]))
5085 operands[1] = force_reg (SImode, operands[1]);
5086 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5089 else if (TARGET_LFIWAX && TARGET_FCFID)
5091 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5094 else if (TARGET_FCFID)
5096 rtx dreg = operands[1];
5098 dreg = force_reg (SImode, dreg);
5099 dreg = convert_to_mode (DImode, dreg, false);
5100 emit_insn (gen_floatdidf2 (operands[0], dreg));
5104 if (!REG_P (operands[1]))
5105 operands[1] = force_reg (SImode, operands[1]);
5106 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5107 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5108 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5109 operands[5] = gen_reg_rtx (DFmode);
5110 operands[6] = gen_reg_rtx (SImode);
5113 (define_insn_and_split "*floatsidf2_internal"
5114 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5115 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5116 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5117 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5118 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5119 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5120 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5121 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5127 rtx lowword, highword;
5128 gcc_assert (MEM_P (operands[4]));
5129 highword = adjust_address (operands[4], SImode, 0);
5130 lowword = adjust_address (operands[4], SImode, 4);
5131 if (! WORDS_BIG_ENDIAN)
5132 std::swap (lowword, highword);
5134 emit_insn (gen_xorsi3 (operands[6], operands[1],
5135 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5136 emit_move_insn (lowword, operands[6]);
5137 emit_move_insn (highword, operands[2]);
5138 emit_move_insn (operands[5], operands[4]);
5139 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5142 [(set_attr "length" "24")
5143 (set_attr "type" "fp")])
5145 ;; If we don't have a direct conversion to single precision, don't enable this
5146 ;; conversion for 32-bit without fast math, because we don't have the insn to
5147 ;; generate the fixup swizzle to avoid double rounding problems.
5148 (define_expand "floatunssisf2"
5149 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5150 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5151 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5154 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5155 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5156 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5161 if (!REG_P (operands[1]))
5162 operands[1] = force_reg (SImode, operands[1]);
5164 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5166 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5171 rtx dreg = operands[1];
5173 dreg = force_reg (SImode, dreg);
5174 dreg = convert_to_mode (DImode, dreg, true);
5175 emit_insn (gen_floatdisf2 (operands[0], dreg));
5180 (define_expand "floatunssidf2"
5181 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5182 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5185 (clobber (match_dup 4))
5186 (clobber (match_dup 5))])]
5188 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5191 if (TARGET_E500_DOUBLE)
5193 if (!REG_P (operands[1]))
5194 operands[1] = force_reg (SImode, operands[1]);
5195 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5198 else if (TARGET_LFIWZX && TARGET_FCFID)
5200 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5203 else if (TARGET_FCFID)
5205 rtx dreg = operands[1];
5207 dreg = force_reg (SImode, dreg);
5208 dreg = convert_to_mode (DImode, dreg, true);
5209 emit_insn (gen_floatdidf2 (operands[0], dreg));
5213 if (!REG_P (operands[1]))
5214 operands[1] = force_reg (SImode, operands[1]);
5215 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5216 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5217 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5218 operands[5] = gen_reg_rtx (DFmode);
5221 (define_insn_and_split "*floatunssidf2_internal"
5222 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5223 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5224 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5225 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5226 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5227 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5228 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5229 && !(TARGET_FCFID && TARGET_POWERPC64)"
5235 rtx lowword, highword;
5236 gcc_assert (MEM_P (operands[4]));
5237 highword = adjust_address (operands[4], SImode, 0);
5238 lowword = adjust_address (operands[4], SImode, 4);
5239 if (! WORDS_BIG_ENDIAN)
5240 std::swap (lowword, highword);
5242 emit_move_insn (lowword, operands[1]);
5243 emit_move_insn (highword, operands[2]);
5244 emit_move_insn (operands[5], operands[4]);
5245 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5248 [(set_attr "length" "20")
5249 (set_attr "type" "fp")])
5251 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5252 ;; vector registers. At the moment, QI/HImode are not allowed in floating
5253 ;; point or vector registers, so we use UNSPEC's to use the load byte and
5254 ;; half-word instructions.
5256 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5257 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5259 (match_operand:QHI 1 "input_operand")))
5260 (clobber (match_scratch:DI 2))
5261 (clobber (match_scratch:DI 3))])]
5262 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5264 if (MEM_P (operands[1]))
5265 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5268 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5269 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5271 (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5272 (clobber (match_scratch:DI 2 "=wi,v"))
5273 (clobber (match_scratch:DI 3 "=r,X"))]
5274 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5275 && TARGET_UPPER_REGS_DI"
5277 "&& reload_completed"
5280 rtx result = operands[0];
5281 rtx input = operands[1];
5282 rtx di = operands[2];
5286 rtx tmp = operands[3];
5287 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5288 emit_move_insn (di, tmp);
5295 emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5297 if (<MODE>mode == QImode)
5299 else if (<MODE>mode == HImode)
5304 di_vector = gen_rtx_REG (vmode, REGNO (di));
5305 emit_insn (gen_vsx_sign_extend_<QHI:mode>_di (di, di_vector));
5308 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5312 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5313 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "")
5314 (unsigned_float:FP_ISA3
5315 (match_operand:QHI 1 "input_operand" "")))
5316 (clobber (match_scratch:DI 2 ""))
5317 (clobber (match_scratch:DI 3 ""))])]
5318 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5320 if (MEM_P (operands[1]))
5321 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5324 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5325 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5326 (unsigned_float:FP_ISA3
5327 (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5328 (clobber (match_scratch:DI 2 "=wi,wi"))
5329 (clobber (match_scratch:DI 3 "=r,X"))]
5330 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5332 "&& reload_completed"
5335 rtx result = operands[0];
5336 rtx input = operands[1];
5337 rtx di = operands[2];
5338 rtx tmp = operands[3];
5342 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5343 emit_move_insn (di, tmp);
5346 emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5348 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5352 (define_expand "fix_trunc<mode>si2"
5353 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5354 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5355 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5358 if (!<E500_CONVERT>)
5360 rtx src = force_reg (SFmode, operands[1]);
5363 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5366 rtx tmp = gen_reg_rtx (DImode);
5367 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5368 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5375 ; Like the convert to float patterns, this insn must be split before
5376 ; register allocation so that it can allocate the memory slot if it
5378 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5379 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5380 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5381 (clobber (match_scratch:DI 2 "=d"))]
5382 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5383 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5384 && TARGET_STFIWX && can_create_pseudo_p ()"
5389 rtx dest = operands[0];
5390 rtx src = operands[1];
5391 rtx tmp = operands[2];
5393 if (GET_CODE (tmp) == SCRATCH)
5394 tmp = gen_reg_rtx (DImode);
5396 emit_insn (gen_fctiwz_<mode> (tmp, src));
5399 dest = rs6000_address_for_fpconvert (dest);
5400 emit_insn (gen_stfiwx (dest, tmp));
5403 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5405 dest = gen_lowpart (DImode, dest);
5406 emit_move_insn (dest, tmp);
5411 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5412 emit_insn (gen_stfiwx (stack, tmp));
5413 emit_move_insn (dest, stack);
5417 [(set_attr "length" "12")
5418 (set_attr "type" "fp")])
5420 (define_insn_and_split "fix_trunc<mode>si2_internal"
5421 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5422 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5423 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5424 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5425 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5432 gcc_assert (MEM_P (operands[3]));
5433 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5435 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5436 emit_move_insn (operands[3], operands[2]);
5437 emit_move_insn (operands[0], lowword);
5440 [(set_attr "length" "16")
5441 (set_attr "type" "fp")])
5443 (define_expand "fix_trunc<mode>di2"
5444 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5445 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5446 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5450 (define_insn "*fix_trunc<mode>di2_fctidz"
5451 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5452 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5453 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5458 [(set_attr "type" "fp")])
5460 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5461 [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5462 (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5463 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5465 rtx op0 = operands[0];
5466 rtx op1 = operands[1];
5467 rtx di_tmp = gen_reg_rtx (DImode);
5470 op0 = rs6000_address_for_fpconvert (op0);
5472 emit_insn (gen_fctiwz_<SFDF:mode> (di_tmp, op1));
5473 emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5477 (define_expand "fixuns_trunc<mode>si2"
5478 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5479 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5481 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5485 if (!<E500_CONVERT>)
5487 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5492 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5493 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5494 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5495 (clobber (match_scratch:DI 2 "=d"))]
5496 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5497 && TARGET_STFIWX && can_create_pseudo_p ()"
5502 rtx dest = operands[0];
5503 rtx src = operands[1];
5504 rtx tmp = operands[2];
5506 if (GET_CODE (tmp) == SCRATCH)
5507 tmp = gen_reg_rtx (DImode);
5509 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5512 dest = rs6000_address_for_fpconvert (dest);
5513 emit_insn (gen_stfiwx (dest, tmp));
5516 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5518 dest = gen_lowpart (DImode, dest);
5519 emit_move_insn (dest, tmp);
5524 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5525 emit_insn (gen_stfiwx (stack, tmp));
5526 emit_move_insn (dest, stack);
5530 [(set_attr "length" "12")
5531 (set_attr "type" "fp")])
5533 (define_expand "fixuns_trunc<mode>di2"
5534 [(set (match_operand:DI 0 "register_operand" "")
5535 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5536 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5539 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5540 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5541 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5542 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5547 [(set_attr "type" "fp")])
5549 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5550 [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5551 (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5552 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5554 rtx op0 = operands[0];
5555 rtx op1 = operands[1];
5556 rtx di_tmp = gen_reg_rtx (DImode);
5559 op0 = rs6000_address_for_fpconvert (op0);
5561 emit_insn (gen_fctiwuz_<SFDF:mode> (di_tmp, op1));
5562 emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5566 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5567 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5568 ; because the first makes it clear that operand 0 is not live
5569 ; before the instruction.
5570 (define_insn "fctiwz_<mode>"
5571 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5572 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5574 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5578 [(set_attr "type" "fp")])
5580 (define_insn "fctiwuz_<mode>"
5581 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5582 (unspec:DI [(unsigned_fix:SI
5583 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5585 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5589 [(set_attr "type" "fp")])
5591 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5592 ;; since the friz instruction does not truncate the value if the floating
5593 ;; point value is < LONG_MIN or > LONG_MAX.
5594 (define_insn "*friz"
5595 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5596 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5597 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5598 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5602 [(set_attr "type" "fp")])
5604 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5605 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5606 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5607 ;; extend it, store it back on the stack from the GPR, load it back into the
5608 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5609 ;; disable using store and load to sign/zero extend the value.
5610 (define_insn_and_split "*round32<mode>2_fprs"
5611 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5613 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5614 (clobber (match_scratch:DI 2 "=d"))
5615 (clobber (match_scratch:DI 3 "=d"))]
5616 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5617 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5618 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5623 rtx dest = operands[0];
5624 rtx src = operands[1];
5625 rtx tmp1 = operands[2];
5626 rtx tmp2 = operands[3];
5627 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5629 if (GET_CODE (tmp1) == SCRATCH)
5630 tmp1 = gen_reg_rtx (DImode);
5631 if (GET_CODE (tmp2) == SCRATCH)
5632 tmp2 = gen_reg_rtx (DImode);
5634 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5635 emit_insn (gen_stfiwx (stack, tmp1));
5636 emit_insn (gen_lfiwax (tmp2, stack));
5637 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5640 [(set_attr "type" "fpload")
5641 (set_attr "length" "16")])
5643 (define_insn_and_split "*roundu32<mode>2_fprs"
5644 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5645 (unsigned_float:SFDF
5646 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5647 (clobber (match_scratch:DI 2 "=d"))
5648 (clobber (match_scratch:DI 3 "=d"))]
5649 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5650 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5651 && can_create_pseudo_p ()"
5656 rtx dest = operands[0];
5657 rtx src = operands[1];
5658 rtx tmp1 = operands[2];
5659 rtx tmp2 = operands[3];
5660 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5662 if (GET_CODE (tmp1) == SCRATCH)
5663 tmp1 = gen_reg_rtx (DImode);
5664 if (GET_CODE (tmp2) == SCRATCH)
5665 tmp2 = gen_reg_rtx (DImode);
5667 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5668 emit_insn (gen_stfiwx (stack, tmp1));
5669 emit_insn (gen_lfiwzx (tmp2, stack));
5670 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5673 [(set_attr "type" "fpload")
5674 (set_attr "length" "16")])
5676 ;; No VSX equivalent to fctid
5677 (define_insn "lrint<mode>di2"
5678 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5679 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5681 "TARGET_<MODE>_FPR && TARGET_FPRND"
5683 [(set_attr "type" "fp")])
5685 (define_insn "btrunc<mode>2"
5686 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5687 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5689 "TARGET_<MODE>_FPR && TARGET_FPRND"
5693 [(set_attr "type" "fp")
5694 (set_attr "fp_type" "fp_addsub_<Fs>")])
5696 (define_insn "ceil<mode>2"
5697 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5698 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5700 "TARGET_<MODE>_FPR && TARGET_FPRND"
5704 [(set_attr "type" "fp")
5705 (set_attr "fp_type" "fp_addsub_<Fs>")])
5707 (define_insn "floor<mode>2"
5708 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5709 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5711 "TARGET_<MODE>_FPR && TARGET_FPRND"
5715 [(set_attr "type" "fp")
5716 (set_attr "fp_type" "fp_addsub_<Fs>")])
5718 ;; No VSX equivalent to frin
5719 (define_insn "round<mode>2"
5720 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5721 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5723 "TARGET_<MODE>_FPR && TARGET_FPRND"
5725 [(set_attr "type" "fp")
5726 (set_attr "fp_type" "fp_addsub_<Fs>")])
5728 (define_insn "*xsrdpi<mode>2"
5729 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5730 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5732 "TARGET_<MODE>_FPR && TARGET_VSX"
5734 [(set_attr "type" "fp")
5735 (set_attr "fp_type" "fp_addsub_<Fs>")])
5737 (define_expand "lround<mode>di2"
5739 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5741 (set (match_operand:DI 0 "gpc_reg_operand" "")
5742 (unspec:DI [(match_dup 2)]
5744 "TARGET_<MODE>_FPR && TARGET_VSX"
5746 operands[2] = gen_reg_rtx (<MODE>mode);
5749 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5750 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5751 ; is only generated for Power8 or later.
5752 (define_insn "stfiwx"
5753 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5754 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5760 [(set_attr "type" "fpstore")])
5762 ;; If we don't have a direct conversion to single precision, don't enable this
5763 ;; conversion for 32-bit without fast math, because we don't have the insn to
5764 ;; generate the fixup swizzle to avoid double rounding problems.
5765 (define_expand "floatsisf2"
5766 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5767 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5768 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5771 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5772 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5773 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5778 if (!REG_P (operands[1]))
5779 operands[1] = force_reg (SImode, operands[1]);
5781 else if (TARGET_FCFIDS && TARGET_LFIWAX)
5783 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5786 else if (TARGET_FCFID && TARGET_LFIWAX)
5788 rtx dfreg = gen_reg_rtx (DFmode);
5789 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5790 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5795 rtx dreg = operands[1];
5797 dreg = force_reg (SImode, dreg);
5798 dreg = convert_to_mode (DImode, dreg, false);
5799 emit_insn (gen_floatdisf2 (operands[0], dreg));
5804 (define_expand "floatdidf2"
5805 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5806 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5807 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5810 (define_insn "*floatdidf2_fpr"
5811 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5812 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5813 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5817 [(set_attr "type" "fp")])
5819 ; Allow the combiner to merge source memory operands to the conversion so that
5820 ; the optimizer/register allocator doesn't try to load the value too early in a
5821 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5822 ; hit. We will split after reload to avoid the trip through the GPRs
5824 (define_insn_and_split "*floatdidf2_mem"
5825 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5826 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5827 (clobber (match_scratch:DI 2 "=d,wi"))]
5828 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5830 "&& reload_completed"
5831 [(set (match_dup 2) (match_dup 1))
5832 (set (match_dup 0) (float:DF (match_dup 2)))]
5834 [(set_attr "length" "8")
5835 (set_attr "type" "fpload")])
5837 (define_expand "floatunsdidf2"
5838 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5840 (match_operand:DI 1 "gpc_reg_operand" "")))]
5841 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5844 (define_insn "*floatunsdidf2_fcfidu"
5845 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5846 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5847 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5851 [(set_attr "type" "fp")
5852 (set_attr "length" "4")])
5854 (define_insn_and_split "*floatunsdidf2_mem"
5855 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5856 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5857 (clobber (match_scratch:DI 2 "=d,wi"))]
5858 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5860 "&& reload_completed"
5861 [(set (match_dup 2) (match_dup 1))
5862 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5864 [(set_attr "length" "8")
5865 (set_attr "type" "fpload")])
5867 (define_expand "floatdisf2"
5868 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5869 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5870 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5871 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5876 rtx val = operands[1];
5877 if (!flag_unsafe_math_optimizations)
5879 rtx label = gen_label_rtx ();
5880 val = gen_reg_rtx (DImode);
5881 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5884 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5889 (define_insn "floatdisf2_fcfids"
5890 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5891 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5892 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5893 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5897 [(set_attr "type" "fp")])
5899 (define_insn_and_split "*floatdisf2_mem"
5900 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5901 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5902 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5903 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5904 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5906 "&& reload_completed"
5910 emit_move_insn (operands[2], operands[1]);
5911 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5914 [(set_attr "length" "8")])
5916 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5917 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5918 ;; from double rounding.
5919 ;; Instead of creating a new cpu type for two FP operations, just use fp
5920 (define_insn_and_split "floatdisf2_internal1"
5921 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5922 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5923 (clobber (match_scratch:DF 2 "=d"))]
5924 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5927 "&& reload_completed"
5929 (float:DF (match_dup 1)))
5931 (float_truncate:SF (match_dup 2)))]
5933 [(set_attr "length" "8")
5934 (set_attr "type" "fp")])
5936 ;; Twiddles bits to avoid double rounding.
5937 ;; Bits that might be truncated when converting to DFmode are replaced
5938 ;; by a bit that won't be lost at that stage, but is below the SFmode
5939 ;; rounding position.
5940 (define_expand "floatdisf2_internal2"
5941 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5943 (clobber (reg:DI CA_REGNO))])
5944 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5946 (set (match_dup 3) (plus:DI (match_dup 3)
5948 (set (match_dup 0) (plus:DI (match_dup 0)
5950 (set (match_dup 4) (compare:CCUNS (match_dup 3)
5952 (set (match_dup 0) (ior:DI (match_dup 0)
5954 (set (match_dup 0) (and:DI (match_dup 0)
5956 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5957 (label_ref (match_operand:DI 2 "" ""))
5959 (set (match_dup 0) (match_dup 1))]
5960 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5964 operands[3] = gen_reg_rtx (DImode);
5965 operands[4] = gen_reg_rtx (CCUNSmode);
5968 (define_expand "floatunsdisf2"
5969 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5970 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5971 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5972 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5975 (define_insn "floatunsdisf2_fcfidus"
5976 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5977 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5978 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5979 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5983 [(set_attr "type" "fp")])
5985 (define_insn_and_split "*floatunsdisf2_mem"
5986 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5987 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5988 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5989 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5990 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5992 "&& reload_completed"
5996 emit_move_insn (operands[2], operands[1]);
5997 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6000 [(set_attr "length" "8")
6001 (set_attr "type" "fpload")])
6003 ;; Define the TImode operations that can be done in a small number
6004 ;; of instructions. The & constraints are to prevent the register
6005 ;; allocator from allocating registers that overlap with the inputs
6006 ;; (for example, having an input in 7,8 and an output in 6,7). We
6007 ;; also allow for the output being the same as one of the inputs.
6009 (define_expand "addti3"
6010 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6011 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6012 (match_operand:TI 2 "reg_or_short_operand" "")))]
6015 rtx lo0 = gen_lowpart (DImode, operands[0]);
6016 rtx lo1 = gen_lowpart (DImode, operands[1]);
6017 rtx lo2 = gen_lowpart (DImode, operands[2]);
6018 rtx hi0 = gen_highpart (DImode, operands[0]);
6019 rtx hi1 = gen_highpart (DImode, operands[1]);
6020 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6022 if (!reg_or_short_operand (lo2, DImode))
6023 lo2 = force_reg (DImode, lo2);
6024 if (!adde_operand (hi2, DImode))
6025 hi2 = force_reg (DImode, hi2);
6027 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6028 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6032 (define_expand "subti3"
6033 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6034 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6035 (match_operand:TI 2 "gpc_reg_operand" "")))]
6038 rtx lo0 = gen_lowpart (DImode, operands[0]);
6039 rtx lo1 = gen_lowpart (DImode, operands[1]);
6040 rtx lo2 = gen_lowpart (DImode, operands[2]);
6041 rtx hi0 = gen_highpart (DImode, operands[0]);
6042 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6043 rtx hi2 = gen_highpart (DImode, operands[2]);
6045 if (!reg_or_short_operand (lo1, DImode))
6046 lo1 = force_reg (DImode, lo1);
6047 if (!adde_operand (hi1, DImode))
6048 hi1 = force_reg (DImode, hi1);
6050 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6051 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6055 ;; 128-bit logical operations expanders
6057 (define_expand "and<mode>3"
6058 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6059 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6060 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6064 (define_expand "ior<mode>3"
6065 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6066 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6067 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6071 (define_expand "xor<mode>3"
6072 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6073 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6074 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6078 (define_expand "one_cmpl<mode>2"
6079 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6080 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6084 (define_expand "nor<mode>3"
6085 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6087 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6088 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6092 (define_expand "andc<mode>3"
6093 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6095 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6096 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6100 ;; Power8 vector logical instructions.
6101 (define_expand "eqv<mode>3"
6102 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6104 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6105 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6106 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6109 ;; Rewrite nand into canonical form
6110 (define_expand "nand<mode>3"
6111 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6113 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6114 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6115 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6118 ;; The canonical form is to have the negated element first, so we need to
6119 ;; reverse arguments.
6120 (define_expand "orc<mode>3"
6121 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6123 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6124 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6125 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6128 ;; 128-bit logical operations insns and split operations
6129 (define_insn_and_split "*and<mode>3_internal"
6130 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6132 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6133 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6136 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6137 return "xxland %x0,%x1,%x2";
6139 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6140 return "vand %0,%1,%2";
6144 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6147 rs6000_split_logical (operands, AND, false, false, false);
6152 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6153 (const_string "veclogical")
6154 (const_string "integer")))
6155 (set (attr "length")
6157 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6160 (match_test "TARGET_POWERPC64")
6162 (const_string "16"))))])
6165 (define_insn_and_split "*bool<mode>3_internal"
6166 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6167 (match_operator:BOOL_128 3 "boolean_or_operator"
6168 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6169 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6172 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6173 return "xxl%q3 %x0,%x1,%x2";
6175 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6176 return "v%q3 %0,%1,%2";
6180 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6183 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6188 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6189 (const_string "veclogical")
6190 (const_string "integer")))
6191 (set (attr "length")
6193 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6196 (match_test "TARGET_POWERPC64")
6198 (const_string "16"))))])
6201 (define_insn_and_split "*boolc<mode>3_internal1"
6202 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6203 (match_operator:BOOL_128 3 "boolean_operator"
6205 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6206 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6207 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6209 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6210 return "xxl%q3 %x0,%x1,%x2";
6212 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6213 return "v%q3 %0,%1,%2";
6217 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6218 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6221 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6226 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6227 (const_string "veclogical")
6228 (const_string "integer")))
6229 (set (attr "length")
6231 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6234 (match_test "TARGET_POWERPC64")
6236 (const_string "16"))))])
6238 (define_insn_and_split "*boolc<mode>3_internal2"
6239 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6240 (match_operator:TI2 3 "boolean_operator"
6242 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6243 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6244 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6246 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6249 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6252 [(set_attr "type" "integer")
6253 (set (attr "length")
6255 (match_test "TARGET_POWERPC64")
6257 (const_string "16")))])
6260 (define_insn_and_split "*boolcc<mode>3_internal1"
6261 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6262 (match_operator:BOOL_128 3 "boolean_operator"
6264 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6266 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6267 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6269 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6270 return "xxl%q3 %x0,%x1,%x2";
6272 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6273 return "v%q3 %0,%1,%2";
6277 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6278 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6281 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6286 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6287 (const_string "veclogical")
6288 (const_string "integer")))
6289 (set (attr "length")
6291 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6294 (match_test "TARGET_POWERPC64")
6296 (const_string "16"))))])
6298 (define_insn_and_split "*boolcc<mode>3_internal2"
6299 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6300 (match_operator:TI2 3 "boolean_operator"
6302 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6304 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6305 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6307 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6310 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6313 [(set_attr "type" "integer")
6314 (set (attr "length")
6316 (match_test "TARGET_POWERPC64")
6318 (const_string "16")))])
6322 (define_insn_and_split "*eqv<mode>3_internal1"
6323 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6326 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6327 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6330 if (vsx_register_operand (operands[0], <MODE>mode))
6331 return "xxleqv %x0,%x1,%x2";
6335 "TARGET_P8_VECTOR && reload_completed
6336 && int_reg_operand (operands[0], <MODE>mode)"
6339 rs6000_split_logical (operands, XOR, true, false, false);
6344 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6345 (const_string "veclogical")
6346 (const_string "integer")))
6347 (set (attr "length")
6349 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6352 (match_test "TARGET_POWERPC64")
6354 (const_string "16"))))])
6356 (define_insn_and_split "*eqv<mode>3_internal2"
6357 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6360 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6361 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6364 "reload_completed && !TARGET_P8_VECTOR"
6367 rs6000_split_logical (operands, XOR, true, false, false);
6370 [(set_attr "type" "integer")
6371 (set (attr "length")
6373 (match_test "TARGET_POWERPC64")
6375 (const_string "16")))])
6377 ;; 128-bit one's complement
6378 (define_insn_and_split "*one_cmpl<mode>3_internal"
6379 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6381 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6384 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6385 return "xxlnor %x0,%x1,%x1";
6387 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6388 return "vnor %0,%1,%1";
6392 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6395 rs6000_split_logical (operands, NOT, false, false, false);
6400 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6401 (const_string "veclogical")
6402 (const_string "integer")))
6403 (set (attr "length")
6405 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6408 (match_test "TARGET_POWERPC64")
6410 (const_string "16"))))])
6413 ;; Now define ways of moving data around.
6415 ;; Set up a register with a value from the GOT table
6417 (define_expand "movsi_got"
6418 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6419 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6420 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6421 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6424 if (GET_CODE (operands[1]) == CONST)
6426 rtx offset = const0_rtx;
6427 HOST_WIDE_INT value;
6429 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6430 value = INTVAL (offset);
6433 rtx tmp = (!can_create_pseudo_p ()
6435 : gen_reg_rtx (Pmode));
6436 emit_insn (gen_movsi_got (tmp, operands[1]));
6437 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6442 operands[2] = rs6000_got_register (operands[1]);
6445 (define_insn "*movsi_got_internal"
6446 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6447 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6448 (match_operand:SI 2 "gpc_reg_operand" "b")]
6450 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6451 "lwz %0,%a1@got(%2)"
6452 [(set_attr "type" "load")])
6454 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6455 ;; didn't get allocated to a hard register.
6457 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6458 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6459 (match_operand:SI 2 "memory_operand" "")]
6461 "DEFAULT_ABI == ABI_V4
6463 && (reload_in_progress || reload_completed)"
6464 [(set (match_dup 0) (match_dup 2))
6465 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6469 ;; For SI, we special-case integers that can't be loaded in one insn. We
6470 ;; do the load 16-bits at a time. We could do this by loading from memory,
6471 ;; and this is even supposed to be faster, but it is simpler not to get
6472 ;; integers in the TOC.
6473 (define_insn "movsi_low"
6474 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6475 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6476 (match_operand 2 "" ""))))]
6477 "TARGET_MACHO && ! TARGET_64BIT"
6478 "lwz %0,lo16(%2)(%1)"
6479 [(set_attr "type" "load")
6480 (set_attr "length" "4")])
6482 (define_insn "*movsi_internal1"
6483 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6484 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6485 "!TARGET_SINGLE_FPU &&
6486 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6499 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6500 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6502 (define_insn "*movsi_internal1_single"
6503 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6504 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6505 "TARGET_SINGLE_FPU &&
6506 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6521 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6522 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6524 ;; Split a load of a large constant into the appropriate two-insn
6528 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6529 (match_operand:SI 1 "const_int_operand" ""))]
6530 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6531 && (INTVAL (operands[1]) & 0xffff) != 0"
6535 (ior:SI (match_dup 0)
6539 if (rs6000_emit_set_const (operands[0], operands[1]))
6545 (define_insn "*mov<mode>_internal2"
6546 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6547 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6549 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6555 [(set_attr "type" "cmp,logical,cmp")
6556 (set_attr "dot" "yes")
6557 (set_attr "length" "4,4,8")])
6560 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6561 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6563 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6565 [(set (match_dup 0) (match_dup 1))
6567 (compare:CC (match_dup 0)
6571 (define_insn "*movhi_internal"
6572 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6573 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6574 "gpc_reg_operand (operands[0], HImode)
6575 || gpc_reg_operand (operands[1], HImode)"
6584 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6586 (define_expand "mov<mode>"
6587 [(set (match_operand:INT 0 "general_operand" "")
6588 (match_operand:INT 1 "any_operand" ""))]
6590 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6592 (define_insn "*movqi_internal"
6593 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6594 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6595 "gpc_reg_operand (operands[0], QImode)
6596 || gpc_reg_operand (operands[1], QImode)"
6605 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6607 ;; Here is how to move condition codes around. When we store CC data in
6608 ;; an integer register or memory, we store just the high-order 4 bits.
6609 ;; This lets us not shift in the most common case of CR0.
6610 (define_expand "movcc"
6611 [(set (match_operand:CC 0 "nonimmediate_operand" "")
6612 (match_operand:CC 1 "nonimmediate_operand" ""))]
6616 (define_insn "*movcc_internal1"
6617 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6618 (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6619 "register_operand (operands[0], CCmode)
6620 || register_operand (operands[1], CCmode)"
6624 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6627 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6635 (cond [(eq_attr "alternative" "0,3")
6636 (const_string "cr_logical")
6637 (eq_attr "alternative" "1,2")
6638 (const_string "mtcr")
6639 (eq_attr "alternative" "6,7")
6640 (const_string "integer")
6641 (eq_attr "alternative" "8")
6642 (const_string "mfjmpr")
6643 (eq_attr "alternative" "9")
6644 (const_string "mtjmpr")
6645 (eq_attr "alternative" "10")
6646 (const_string "load")
6647 (eq_attr "alternative" "11")
6648 (const_string "store")
6649 (match_test "TARGET_MFCRF")
6650 (const_string "mfcrf")
6652 (const_string "mfcr")))
6653 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6655 ;; For floating-point, we normally deal with the floating-point registers
6656 ;; unless -msoft-float is used. The sole exception is that parameter passing
6657 ;; can produce floating-point values in fixed-point registers. Unless the
6658 ;; value is a simple constant or already in memory, we deal with this by
6659 ;; allocating memory and copying the value explicitly via that memory location.
6661 ;; Move 32-bit binary/decimal floating point
6662 (define_expand "mov<mode>"
6663 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6664 (match_operand:FMOVE32 1 "any_operand" ""))]
6666 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6669 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6670 (match_operand:FMOVE32 1 "const_double_operand" ""))]
6672 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6673 || (GET_CODE (operands[0]) == SUBREG
6674 && GET_CODE (SUBREG_REG (operands[0])) == REG
6675 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6676 [(set (match_dup 2) (match_dup 3))]
6681 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6683 if (! TARGET_POWERPC64)
6684 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6686 operands[2] = gen_lowpart (SImode, operands[0]);
6688 operands[3] = gen_int_mode (l, SImode);
6691 (define_insn "mov<mode>_hardfloat"
6692 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_lr2>,<f32_sm>,<f32_sm2>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h")
6693 (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,<zero_fp>,<zero_fp>,<f32_lm>,<f32_lm2>,<f32_sr>,<f32_sr2>,Z,<f32_av>,r,<f32_dm>,r,h,0"))]
6694 "(gpc_reg_operand (operands[0], <MODE>mode)
6695 || gpc_reg_operand (operands[1], <MODE>mode))
6696 && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6702 xscpsgndp %x0,%x1,%x1
6716 [(set_attr "type" "*,load,store,fpsimple,fpsimple,veclogical,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mffgpr,mftgpr,mtjmpr,mfjmpr,*")
6717 (set_attr "length" "4")])
6719 (define_insn "*mov<mode>_softfloat"
6720 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6721 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6722 "(gpc_reg_operand (operands[0], <MODE>mode)
6723 || gpc_reg_operand (operands[1], <MODE>mode))
6724 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6736 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6737 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6740 ;; Move 64-bit binary/decimal floating point
6741 (define_expand "mov<mode>"
6742 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6743 (match_operand:FMOVE64 1 "any_operand" ""))]
6745 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6748 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6749 (match_operand:FMOVE64 1 "const_int_operand" ""))]
6750 "! TARGET_POWERPC64 && reload_completed
6751 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6752 || (GET_CODE (operands[0]) == SUBREG
6753 && GET_CODE (SUBREG_REG (operands[0])) == REG
6754 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6755 [(set (match_dup 2) (match_dup 4))
6756 (set (match_dup 3) (match_dup 1))]
6759 int endian = (WORDS_BIG_ENDIAN == 0);
6760 HOST_WIDE_INT value = INTVAL (operands[1]);
6762 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6763 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6764 operands[4] = GEN_INT (value >> 32);
6765 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6769 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6770 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6771 "! TARGET_POWERPC64 && reload_completed
6772 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6773 || (GET_CODE (operands[0]) == SUBREG
6774 && GET_CODE (SUBREG_REG (operands[0])) == REG
6775 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6776 [(set (match_dup 2) (match_dup 4))
6777 (set (match_dup 3) (match_dup 5))]
6780 int endian = (WORDS_BIG_ENDIAN == 0);
6783 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6785 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6786 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6787 operands[4] = gen_int_mode (l[endian], SImode);
6788 operands[5] = gen_int_mode (l[1 - endian], SImode);
6792 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6793 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6794 "TARGET_POWERPC64 && reload_completed
6795 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6796 || (GET_CODE (operands[0]) == SUBREG
6797 && GET_CODE (SUBREG_REG (operands[0])) == REG
6798 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6799 [(set (match_dup 2) (match_dup 3))]
6802 int endian = (WORDS_BIG_ENDIAN == 0);
6806 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6808 operands[2] = gen_lowpart (DImode, operands[0]);
6809 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
6810 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6811 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6813 operands[3] = gen_int_mode (val, DImode);
6816 ;; Don't have reload use general registers to load a constant. It is
6817 ;; less efficient than loading the constant into an FP register, since
6818 ;; it will probably be used there.
6820 ;; The move constraints are ordered to prefer floating point registers before
6821 ;; general purpose registers to avoid doing a store and a load to get the value
6822 ;; into a floating point register when it is needed for a floating point
6823 ;; operation. Prefer traditional floating point registers over VSX registers,
6824 ;; since the D-form version of the memory instructions does not need a GPR for
6825 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6828 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6829 ;; except for 0.0 which can be created on VSX with an xor instruction.
6831 (define_insn "*mov<mode>_hardfloat32"
6832 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6833 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
6834 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6835 && (gpc_reg_operand (operands[0], <MODE>mode)
6836 || gpc_reg_operand (operands[1], <MODE>mode))"
6851 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
6852 (set_attr "size" "64")
6853 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6855 (define_insn "*mov<mode>_softfloat32"
6856 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6857 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6859 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
6860 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6861 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6862 && (gpc_reg_operand (operands[0], <MODE>mode)
6863 || gpc_reg_operand (operands[1], <MODE>mode))"
6865 [(set_attr "type" "store,load,two,*,*,*")
6866 (set_attr "length" "8,8,8,8,12,16")])
6868 ; ld/std require word-aligned displacements -> 'Y' constraint.
6869 ; List Y->r and r->Y before r->r for reload.
6870 (define_insn "*mov<mode>_hardfloat64"
6871 [(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>")
6872 (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"))]
6873 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6874 && (gpc_reg_operand (operands[0], <MODE>mode)
6875 || gpc_reg_operand (operands[1], <MODE>mode))"
6897 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6898 (set_attr "size" "64")
6899 (set_attr "length" "4")])
6901 (define_insn "*mov<mode>_softfloat64"
6902 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6903 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6904 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6905 && (gpc_reg_operand (operands[0], <MODE>mode)
6906 || gpc_reg_operand (operands[1], <MODE>mode))"
6917 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6918 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6920 (define_expand "mov<mode>"
6921 [(set (match_operand:FMOVE128 0 "general_operand" "")
6922 (match_operand:FMOVE128 1 "any_operand" ""))]
6924 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6926 ;; It's important to list Y->r and r->Y before r->r because otherwise
6927 ;; reload, given m->r, will try to pick r->r and reload it, which
6928 ;; doesn't make progress.
6930 ;; We can't split little endian direct moves of TDmode, because the words are
6931 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
6932 ;; problematical. Don't allow direct move for this case.
6934 (define_insn_and_split "*mov<mode>_64bit_dm"
6935 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
6936 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
6937 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6938 && FLOAT128_2REG_P (<MODE>mode)
6939 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6940 && (gpc_reg_operand (operands[0], <MODE>mode)
6941 || gpc_reg_operand (operands[1], <MODE>mode))"
6943 "&& reload_completed"
6945 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6946 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6948 (define_insn_and_split "*movtd_64bit_nodm"
6949 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
6950 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
6951 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6952 && (gpc_reg_operand (operands[0], TDmode)
6953 || gpc_reg_operand (operands[1], TDmode))"
6955 "&& reload_completed"
6957 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6958 [(set_attr "length" "8,8,8,12,12,8")])
6960 (define_insn_and_split "*mov<mode>_32bit"
6961 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
6962 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
6963 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
6964 && (FLOAT128_2REG_P (<MODE>mode)
6965 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
6966 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
6967 && (gpc_reg_operand (operands[0], <MODE>mode)
6968 || gpc_reg_operand (operands[1], <MODE>mode))"
6970 "&& reload_completed"
6972 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6973 [(set_attr "length" "8,8,8,8,20,20,16")])
6975 (define_insn_and_split "*mov<mode>_softfloat"
6976 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
6977 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
6978 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
6979 && (gpc_reg_operand (operands[0], <MODE>mode)
6980 || gpc_reg_operand (operands[1], <MODE>mode))"
6982 "&& reload_completed"
6984 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6985 [(set_attr "length" "20,20,16")])
6987 (define_expand "extenddf<mode>2"
6988 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6989 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
6990 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
6991 && TARGET_LONG_DOUBLE_128"
6993 if (FLOAT128_IEEE_P (<MODE>mode))
6994 rs6000_expand_float128_convert (operands[0], operands[1], false);
6995 else if (TARGET_E500_DOUBLE)
6997 gcc_assert (<MODE>mode == TFmode);
6998 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7000 else if (TARGET_VSX)
7002 if (<MODE>mode == TFmode)
7003 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7004 else if (<MODE>mode == IFmode)
7005 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7011 rtx zero = gen_reg_rtx (DFmode);
7012 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7014 if (<MODE>mode == TFmode)
7015 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7016 else if (<MODE>mode == IFmode)
7017 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7024 ;; Allow memory operands for the source to be created by the combiner.
7025 (define_insn_and_split "extenddf<mode>2_fprs"
7026 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7027 (float_extend:IBM128
7028 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7029 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7030 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7031 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7033 "&& reload_completed"
7034 [(set (match_dup 3) (match_dup 1))
7035 (set (match_dup 4) (match_dup 2))]
7037 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7038 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7040 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7041 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7044 (define_insn_and_split "extenddf<mode>2_vsx"
7045 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7046 (float_extend:IBM128
7047 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7048 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7050 "&& reload_completed"
7051 [(set (match_dup 2) (match_dup 1))
7052 (set (match_dup 3) (match_dup 4))]
7054 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7055 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7057 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7058 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7059 operands[4] = CONST0_RTX (DFmode);
7062 (define_expand "extendsf<mode>2"
7063 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7064 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7066 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7067 && TARGET_LONG_DOUBLE_128"
7069 if (FLOAT128_IEEE_P (<MODE>mode))
7070 rs6000_expand_float128_convert (operands[0], operands[1], false);
7073 rtx tmp = gen_reg_rtx (DFmode);
7074 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7075 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7080 (define_expand "trunc<mode>df2"
7081 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7082 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7084 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7085 && TARGET_LONG_DOUBLE_128"
7087 if (FLOAT128_IEEE_P (<MODE>mode))
7089 rs6000_expand_float128_convert (operands[0], operands[1], false);
7094 (define_insn_and_split "trunc<mode>df2_internal1"
7095 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7097 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7098 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7099 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7103 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7106 emit_note (NOTE_INSN_DELETED);
7109 [(set_attr "type" "fpsimple")])
7111 (define_insn "trunc<mode>df2_internal2"
7112 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7113 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7114 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7115 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7117 [(set_attr "type" "fp")
7118 (set_attr "fp_type" "fp_addsub_d")])
7120 (define_expand "trunc<mode>sf2"
7121 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7122 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7124 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7125 && TARGET_LONG_DOUBLE_128"
7127 if (FLOAT128_IEEE_P (<MODE>mode))
7128 rs6000_expand_float128_convert (operands[0], operands[1], false);
7129 else if (TARGET_E500_DOUBLE)
7131 gcc_assert (<MODE>mode == TFmode);
7132 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7134 else if (<MODE>mode == TFmode)
7135 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7136 else if (<MODE>mode == IFmode)
7137 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7143 (define_insn_and_split "trunc<mode>sf2_fprs"
7144 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7145 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7146 (clobber (match_scratch:DF 2 "=d"))]
7147 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7148 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7150 "&& reload_completed"
7152 (float_truncate:DF (match_dup 1)))
7154 (float_truncate:SF (match_dup 2)))]
7157 (define_expand "floatsi<mode>2"
7158 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7159 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7161 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7162 && TARGET_LONG_DOUBLE_128"
7164 if (FLOAT128_IEEE_P (<MODE>mode))
7165 rs6000_expand_float128_convert (operands[0], operands[1], false);
7168 rtx tmp = gen_reg_rtx (DFmode);
7169 expand_float (tmp, operands[1], false);
7170 if (<MODE>mode == TFmode)
7171 emit_insn (gen_extenddftf2 (operands[0], tmp));
7172 else if (<MODE>mode == IFmode)
7173 emit_insn (gen_extenddfif2 (operands[0], tmp));
7180 ; fadd, but rounding towards zero.
7181 ; This is probably not the optimal code sequence.
7182 (define_insn "fix_trunc_helper<mode>"
7183 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7184 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7185 UNSPEC_FIX_TRUNC_TF))
7186 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7187 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7188 && FLOAT128_IBM_P (<MODE>mode)"
7189 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7190 [(set_attr "type" "fp")
7191 (set_attr "length" "20")])
7193 (define_expand "fix_trunc<mode>si2"
7194 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7195 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7197 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7199 if (FLOAT128_IEEE_P (<MODE>mode))
7200 rs6000_expand_float128_convert (operands[0], operands[1], false);
7201 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7202 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7203 else if (<MODE>mode == TFmode)
7204 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7205 else if (<MODE>mode == IFmode)
7206 emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7212 (define_expand "fix_trunc<mode>si2_fprs"
7213 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7214 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7215 (clobber (match_dup 2))
7216 (clobber (match_dup 3))
7217 (clobber (match_dup 4))
7218 (clobber (match_dup 5))])]
7219 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7221 operands[2] = gen_reg_rtx (DFmode);
7222 operands[3] = gen_reg_rtx (DFmode);
7223 operands[4] = gen_reg_rtx (DImode);
7224 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7227 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7228 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7229 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7230 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7231 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7232 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7233 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7234 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7240 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7243 gcc_assert (MEM_P (operands[5]));
7244 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7246 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7247 emit_move_insn (operands[5], operands[4]);
7248 emit_move_insn (operands[0], lowword);
7252 (define_expand "fix_trunc<mode>di2"
7253 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7254 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7257 rs6000_expand_float128_convert (operands[0], operands[1], false);
7261 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7262 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7263 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7266 rs6000_expand_float128_convert (operands[0], operands[1], true);
7270 (define_expand "floatdi<mode>2"
7271 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7272 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7275 rs6000_expand_float128_convert (operands[0], operands[1], false);
7279 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7280 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7281 (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7284 rs6000_expand_float128_convert (operands[0], operands[1], true);
7288 (define_expand "neg<mode>2"
7289 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7290 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7291 "FLOAT128_IEEE_P (<MODE>mode)
7292 || (FLOAT128_IBM_P (<MODE>mode)
7293 && TARGET_HARD_FLOAT
7294 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7297 if (FLOAT128_IEEE_P (<MODE>mode))
7299 if (TARGET_FLOAT128_HW)
7301 if (<MODE>mode == TFmode)
7302 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7303 else if (<MODE>mode == KFmode)
7304 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7308 else if (TARGET_FLOAT128)
7310 if (<MODE>mode == TFmode)
7311 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7312 else if (<MODE>mode == KFmode)
7313 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7319 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7320 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7322 operands[1], <MODE>mode);
7324 if (target && !rtx_equal_p (target, operands[0]))
7325 emit_move_insn (operands[0], target);
7331 (define_insn "neg<mode>2_internal"
7332 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7333 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7334 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7337 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7338 return \"fneg %L0,%L1\;fneg %0,%1\";
7340 return \"fneg %0,%1\;fneg %L0,%L1\";
7342 [(set_attr "type" "fpsimple")
7343 (set_attr "length" "8")])
7345 (define_expand "abs<mode>2"
7346 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7347 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7348 "FLOAT128_IEEE_P (<MODE>mode)
7349 || (FLOAT128_IBM_P (<MODE>mode)
7350 && TARGET_HARD_FLOAT
7351 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7356 if (FLOAT128_IEEE_P (<MODE>mode))
7358 if (TARGET_FLOAT128_HW)
7360 if (<MODE>mode == TFmode)
7361 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7362 else if (<MODE>mode == KFmode)
7363 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7368 else if (TARGET_FLOAT128)
7370 if (<MODE>mode == TFmode)
7371 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7372 else if (<MODE>mode == KFmode)
7373 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7382 label = gen_label_rtx ();
7383 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7385 if (flag_finite_math_only && !flag_trapping_math)
7386 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7388 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7390 else if (<MODE>mode == TFmode)
7391 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7392 else if (<MODE>mode == TFmode)
7393 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7400 (define_expand "abs<mode>2_internal"
7401 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7402 (match_operand:IBM128 1 "gpc_reg_operand" ""))
7403 (set (match_dup 3) (match_dup 5))
7404 (set (match_dup 5) (abs:DF (match_dup 5)))
7405 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7406 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7407 (label_ref (match_operand 2 "" ""))
7409 (set (match_dup 6) (neg:DF (match_dup 6)))]
7410 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7411 && TARGET_LONG_DOUBLE_128"
7414 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7415 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7416 operands[3] = gen_reg_rtx (DFmode);
7417 operands[4] = gen_reg_rtx (CCFPmode);
7418 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7419 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7423 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7426 (define_expand "ieee_128bit_negative_zero"
7427 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7430 rtvec v = rtvec_alloc (16);
7433 for (i = 0; i < 16; i++)
7434 RTVEC_ELT (v, i) = const0_rtx;
7436 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7437 RTVEC_ELT (v, high) = GEN_INT (0x80);
7439 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7443 ;; IEEE 128-bit negate
7445 ;; We have 2 insns here for negate and absolute value. The first uses
7446 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7447 ;; insns, and second insn after the first split pass loads up the bit to
7448 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
7449 ;; neg/abs to create the constant just once.
7451 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7452 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7453 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7454 (clobber (match_scratch:V16QI 2 "=v"))]
7455 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7458 [(parallel [(set (match_dup 0)
7459 (neg:IEEE128 (match_dup 1)))
7460 (use (match_dup 2))])]
7462 if (GET_CODE (operands[2]) == SCRATCH)
7463 operands[2] = gen_reg_rtx (V16QImode);
7465 operands[3] = gen_reg_rtx (V16QImode);
7466 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7468 [(set_attr "length" "8")
7469 (set_attr "type" "vecsimple")])
7471 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7472 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7473 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7474 (use (match_operand:V16QI 2 "register_operand" "v"))]
7475 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7476 "xxlxor %x0,%x1,%x2"
7477 [(set_attr "type" "veclogical")])
7479 ;; IEEE 128-bit absolute value
7480 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7481 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7482 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7483 (clobber (match_scratch:V16QI 2 "=v"))]
7484 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7487 [(parallel [(set (match_dup 0)
7488 (abs:IEEE128 (match_dup 1)))
7489 (use (match_dup 2))])]
7491 if (GET_CODE (operands[2]) == SCRATCH)
7492 operands[2] = gen_reg_rtx (V16QImode);
7494 operands[3] = gen_reg_rtx (V16QImode);
7495 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7497 [(set_attr "length" "8")
7498 (set_attr "type" "vecsimple")])
7500 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7501 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7502 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7503 (use (match_operand:V16QI 2 "register_operand" "v"))]
7504 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7505 "xxlandc %x0,%x1,%x2"
7506 [(set_attr "type" "veclogical")])
7508 ;; IEEE 128-bit negative absolute value
7509 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7510 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7513 (match_operand:IEEE128 1 "register_operand" "wa"))))
7514 (clobber (match_scratch:V16QI 2 "=v"))]
7515 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7518 [(parallel [(set (match_dup 0)
7519 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7520 (use (match_dup 2))])]
7522 if (GET_CODE (operands[2]) == SCRATCH)
7523 operands[2] = gen_reg_rtx (V16QImode);
7525 operands[3] = gen_reg_rtx (V16QImode);
7526 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7528 [(set_attr "length" "8")
7529 (set_attr "type" "vecsimple")])
7531 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7532 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7535 (match_operand:IEEE128 1 "register_operand" "wa"))))
7536 (use (match_operand:V16QI 2 "register_operand" "v"))]
7537 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7539 [(set_attr "type" "veclogical")])
7541 ;; Float128 conversion functions. These expand to library function calls.
7542 ;; We use expand to convert from IBM double double to IEEE 128-bit
7543 ;; and trunc for the opposite.
7544 (define_expand "extendiftf2"
7545 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7546 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7549 rs6000_expand_float128_convert (operands[0], operands[1], false);
7553 (define_expand "extendifkf2"
7554 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7555 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7558 rs6000_expand_float128_convert (operands[0], operands[1], false);
7562 (define_expand "extendtfkf2"
7563 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7564 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7567 rs6000_expand_float128_convert (operands[0], operands[1], false);
7571 (define_expand "trunciftf2"
7572 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7573 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7576 rs6000_expand_float128_convert (operands[0], operands[1], false);
7580 (define_expand "truncifkf2"
7581 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7582 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7585 rs6000_expand_float128_convert (operands[0], operands[1], false);
7589 (define_expand "trunckftf2"
7590 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7591 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7594 rs6000_expand_float128_convert (operands[0], operands[1], false);
7598 (define_expand "trunctfif2"
7599 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7600 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7603 rs6000_expand_float128_convert (operands[0], operands[1], false);
7608 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
7609 ;; must have 3 arguments, and scratch register constraint must be a single
7612 ;; Reload patterns to support gpr load/store with misaligned mem.
7613 ;; and multiple gpr load/store at offset >= 0xfffc
7614 (define_expand "reload_<mode>_store"
7615 [(parallel [(match_operand 0 "memory_operand" "=m")
7616 (match_operand 1 "gpc_reg_operand" "r")
7617 (match_operand:GPR 2 "register_operand" "=&b")])]
7620 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7624 (define_expand "reload_<mode>_load"
7625 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7626 (match_operand 1 "memory_operand" "m")
7627 (match_operand:GPR 2 "register_operand" "=b")])]
7630 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7635 ;; Reload patterns for various types using the vector registers. We may need
7636 ;; an additional base register to convert the reg+offset addressing to reg+reg
7637 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7638 ;; index register for gpr registers.
7639 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7640 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7641 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7642 (match_operand:P 2 "register_operand" "=b")])]
7645 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7649 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7650 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7651 (match_operand:RELOAD 1 "memory_operand" "m")
7652 (match_operand:P 2 "register_operand" "=b")])]
7655 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7660 ;; Reload sometimes tries to move the address to a GPR, and can generate
7661 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
7662 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7664 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7665 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7666 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7667 (match_operand:P 2 "reg_or_cint_operand" "rI"))
7669 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7671 "&& reload_completed"
7673 (plus:P (match_dup 1)
7676 (and:P (match_dup 0)
7679 ;; Power8 merge instructions to allow direct move to/from floating point
7680 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
7681 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
7682 ;; value, since it is allocated in reload and not all of the flow information
7683 ;; is setup for it. We have two patterns to do the two moves between gprs and
7684 ;; fprs. There isn't a dependancy between the two, but we could potentially
7685 ;; schedule other instructions between the two instructions.
7687 (define_insn "p8_fmrgow_<mode>"
7688 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7690 (match_operand:DF 1 "register_operand" "d")
7691 (match_operand:DF 2 "register_operand" "d")]
7692 UNSPEC_P8V_FMRGOW))]
7693 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7695 [(set_attr "type" "fpsimple")])
7697 (define_insn "p8_mtvsrwz"
7698 [(set (match_operand:DF 0 "register_operand" "=d")
7699 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7700 UNSPEC_P8V_MTVSRWZ))]
7701 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7703 [(set_attr "type" "mftgpr")])
7705 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7706 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7707 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7708 UNSPEC_P8V_RELOAD_FROM_GPR))
7709 (clobber (match_operand:IF 2 "register_operand" "=d"))]
7710 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7712 "&& reload_completed"
7715 rtx dest = operands[0];
7716 rtx src = operands[1];
7717 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7718 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7719 rtx gpr_hi_reg = gen_highpart (SImode, src);
7720 rtx gpr_lo_reg = gen_lowpart (SImode, src);
7722 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7723 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7724 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7727 [(set_attr "length" "12")
7728 (set_attr "type" "three")])
7730 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7731 (define_insn "p8_mtvsrd_df"
7732 [(set (match_operand:DF 0 "register_operand" "=wa")
7733 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7734 UNSPEC_P8V_MTVSRD))]
7735 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7737 [(set_attr "type" "mftgpr")])
7739 (define_insn "p8_xxpermdi_<mode>"
7740 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7741 (unspec:FMOVE128_GPR [
7742 (match_operand:DF 1 "register_operand" "wa")
7743 (match_operand:DF 2 "register_operand" "wa")]
7744 UNSPEC_P8V_XXPERMDI))]
7745 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7746 "xxpermdi %x0,%x1,%x2,0"
7747 [(set_attr "type" "vecperm")])
7749 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7750 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7751 (unspec:FMOVE128_GPR
7752 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7753 UNSPEC_P8V_RELOAD_FROM_GPR))
7754 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
7755 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7757 "&& reload_completed"
7760 rtx dest = operands[0];
7761 rtx src = operands[1];
7762 /* You might think that we could use op0 as one temp and a DF clobber
7763 as op2, but you'd be wrong. Secondary reload move patterns don't
7764 check for overlap of the clobber and the destination. */
7765 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7766 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7767 rtx gpr_hi_reg = gen_highpart (DImode, src);
7768 rtx gpr_lo_reg = gen_lowpart (DImode, src);
7770 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
7771 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
7772 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
7775 [(set_attr "length" "12")
7776 (set_attr "type" "three")])
7779 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7780 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7782 && (int_reg_operand (operands[0], <MODE>mode)
7783 || int_reg_operand (operands[1], <MODE>mode))
7784 && (!TARGET_DIRECT_MOVE_128
7785 || (!vsx_register_operand (operands[0], <MODE>mode)
7786 && !vsx_register_operand (operands[1], <MODE>mode)))"
7788 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7790 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
7791 ;; type is stored internally as double precision in the VSX registers, we have
7792 ;; to convert it from the vector format.
7793 (define_insn "p8_mtvsrd_sf"
7794 [(set (match_operand:SF 0 "register_operand" "=wa")
7795 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
7796 UNSPEC_P8V_MTVSRD))]
7797 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7799 [(set_attr "type" "mftgpr")])
7801 (define_insn_and_split "reload_vsx_from_gprsf"
7802 [(set (match_operand:SF 0 "register_operand" "=wa")
7803 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7804 UNSPEC_P8V_RELOAD_FROM_GPR))
7805 (clobber (match_operand:DI 2 "register_operand" "=r"))]
7806 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7808 "&& reload_completed"
7811 rtx op0 = operands[0];
7812 rtx op1 = operands[1];
7813 rtx op2 = operands[2];
7814 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7816 /* Move SF value to upper 32-bits for xscvspdpn. */
7817 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7818 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7819 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7822 [(set_attr "length" "8")
7823 (set_attr "type" "two")])
7825 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7826 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7827 ;; and then doing a move of that.
7828 (define_insn "p8_mfvsrd_3_<mode>"
7829 [(set (match_operand:DF 0 "register_operand" "=r")
7830 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7831 UNSPEC_P8V_RELOAD_FROM_VSX))]
7832 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7834 [(set_attr "type" "mftgpr")])
7836 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7837 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7838 (unspec:FMOVE128_GPR
7839 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7840 UNSPEC_P8V_RELOAD_FROM_VSX))
7841 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7842 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7844 "&& reload_completed"
7847 rtx dest = operands[0];
7848 rtx src = operands[1];
7849 rtx tmp = operands[2];
7850 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7851 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7853 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7854 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7855 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7858 [(set_attr "length" "12")
7859 (set_attr "type" "three")])
7861 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
7862 ;; type is stored internally as double precision, we have to convert it to the
7865 (define_insn_and_split "reload_gpr_from_vsxsf"
7866 [(set (match_operand:SF 0 "register_operand" "=r")
7867 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7868 UNSPEC_P8V_RELOAD_FROM_VSX))
7869 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7870 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7872 "&& reload_completed"
7875 rtx op0 = operands[0];
7876 rtx op1 = operands[1];
7877 rtx op2 = operands[2];
7878 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7880 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7881 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7882 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7885 [(set_attr "length" "12")
7886 (set_attr "type" "three")])
7888 (define_insn "p8_mfvsrd_4_disf"
7889 [(set (match_operand:DI 0 "register_operand" "=r")
7890 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7891 UNSPEC_P8V_RELOAD_FROM_VSX))]
7892 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7894 [(set_attr "type" "mftgpr")])
7897 ;; Next come the multi-word integer load and store and the load and store
7900 ;; List r->r after r->Y, otherwise reload will try to reload a
7901 ;; non-offsettable address by using r->r which won't make progress.
7902 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7903 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7905 ;; GPR store GPR load GPR move FPR store FPR load FPR move
7906 ;; GPR const AVX store AVX store AVX load AVX load VSX move
7907 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
7910 (define_insn "*movdi_internal32"
7911 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
7912 "=Y, r, r, ?m, ?*d, ?*d,
7913 r, ?wY, ?Z, ?*wb, ?*wv, ?wi,
7914 ?wo, ?wo, ?wv, ?wi, ?wi, ?wv,
7917 (match_operand:DI 1 "input_operand"
7919 IJKnGHF, wb, wv, wY, Z, wi,
7920 Oj, wM, OjwM, Oj, wM, wS,
7924 && (gpc_reg_operand (operands[0], DImode)
7925 || gpc_reg_operand (operands[1], DImode))"
7947 "store, load, *, fpstore, fpload, fpsimple,
7948 *, fpstore, fpstore, fpload, fpload, veclogical,
7949 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
7951 (set_attr "size" "64")])
7954 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7955 (match_operand:DI 1 "const_int_operand" ""))]
7956 "! TARGET_POWERPC64 && reload_completed
7957 && gpr_or_gpr_p (operands[0], operands[1])
7958 && !direct_move_p (operands[0], operands[1])"
7959 [(set (match_dup 2) (match_dup 4))
7960 (set (match_dup 3) (match_dup 1))]
7963 HOST_WIDE_INT value = INTVAL (operands[1]);
7964 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7966 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7968 operands[4] = GEN_INT (value >> 32);
7969 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7973 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7974 (match_operand:DIFD 1 "input_operand" ""))]
7975 "reload_completed && !TARGET_POWERPC64
7976 && gpr_or_gpr_p (operands[0], operands[1])
7977 && !direct_move_p (operands[0], operands[1])"
7979 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7981 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
7982 ;; FPR store FPR load FPR move AVX store AVX store AVX load
7983 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
7984 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
7985 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
7986 (define_insn "*movdi_internal64"
7987 [(set (match_operand:DI 0 "nonimmediate_operand"
7989 ?m, ?*d, ?*d, ?wY, ?Z, ?*wb,
7990 ?*wv, ?wi, ?wo, ?wo, ?wv, ?wi,
7991 ?wi, ?wv, ?wv, r, *h, *h,
7992 ?*r, ?*wg, ?*r, ?*wj")
7994 (match_operand:DI 1 "input_operand"
7996 d, m, d, wb, wv, wY,
7997 Z, wi, Oj, wM, OjwM, Oj,
7998 wM, wS, wB, *h, r, 0,
8002 && (gpc_reg_operand (operands[0], DImode)
8003 || gpc_reg_operand (operands[1], DImode))"
8034 "store, load, *, *, *, *,
8035 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8036 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8037 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8038 mftgpr, mffgpr, mftgpr, mffgpr")
8040 (set_attr "size" "64")
8048 ; Some DImode loads are best done as a load of -1 followed by a mask
8051 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8052 (match_operand:DI 1 "const_int_operand"))]
8054 && num_insns_constant (operands[1], DImode) > 1
8055 && rs6000_is_valid_and_mask (operands[1], DImode)"
8059 (and:DI (match_dup 0)
8063 ;; Split a load of a large constant into the appropriate five-instruction
8064 ;; sequence. Handle anything in a constant number of insns.
8065 ;; When non-easy constants can go in the TOC, this should use
8066 ;; easy_fp_constant predicate.
8068 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8069 (match_operand:DI 1 "const_int_operand" ""))]
8070 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8071 [(set (match_dup 0) (match_dup 2))
8072 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8075 if (rs6000_emit_set_const (operands[0], operands[1]))
8082 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8083 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8084 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8085 [(set (match_dup 0) (match_dup 2))
8086 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8089 if (rs6000_emit_set_const (operands[0], operands[1]))
8096 [(set (match_operand:DI 0 "altivec_register_operand" "")
8097 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8098 "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8101 rtx op0 = operands[0];
8102 rtx op1 = operands[1];
8103 int r = REGNO (op0);
8104 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8106 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8107 if (op1 != const0_rtx && op1 != constm1_rtx)
8109 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8110 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8116 [(set (match_operand:DI 0 "altivec_register_operand" "")
8117 (match_operand:DI 1 "xxspltib_constant_split" ""))]
8118 "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8121 rtx op0 = operands[0];
8122 rtx op1 = operands[1];
8123 int r = REGNO (op0);
8124 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8126 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8127 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8132 ;; TImode/PTImode is similar, except that we usually want to compute the
8133 ;; address into a register and use lsi/stsi (the exception is during reload).
8135 (define_insn "*mov<mode>_string"
8136 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8137 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8139 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8140 && (gpc_reg_operand (operands[0], <MODE>mode)
8141 || gpc_reg_operand (operands[1], <MODE>mode))"
8144 switch (which_alternative)
8150 return \"stswi %1,%P0,16\";
8154 /* If the address is not used in the output, we can use lsi. Otherwise,
8155 fall through to generating four loads. */
8157 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8158 return \"lswi %0,%P1,16\";
8159 /* ... fall through ... */
8166 [(set_attr "type" "store,store,load,load,*,*")
8167 (set_attr "update" "yes")
8168 (set_attr "indexed" "yes")
8169 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8170 (const_string "always")
8171 (const_string "conditional")))])
8173 (define_insn "*mov<mode>_ppc64"
8174 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8175 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8176 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8177 && (gpc_reg_operand (operands[0], <MODE>mode)
8178 || gpc_reg_operand (operands[1], <MODE>mode)))"
8180 return rs6000_output_move_128bit (operands);
8182 [(set_attr "type" "store,store,load,load,*,*")
8183 (set_attr "length" "8")])
8186 [(set (match_operand:TI2 0 "int_reg_operand" "")
8187 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8189 && (VECTOR_MEM_NONE_P (<MODE>mode)
8190 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8191 [(set (match_dup 2) (match_dup 4))
8192 (set (match_dup 3) (match_dup 5))]
8195 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8197 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8199 if (CONST_WIDE_INT_P (operands[1]))
8201 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8202 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8204 else if (CONST_INT_P (operands[1]))
8206 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8207 operands[5] = operands[1];
8214 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8215 (match_operand:TI2 1 "input_operand" ""))]
8217 && gpr_or_gpr_p (operands[0], operands[1])
8218 && !direct_move_p (operands[0], operands[1])
8219 && !quad_load_store_p (operands[0], operands[1])"
8221 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8223 (define_expand "load_multiple"
8224 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8225 (match_operand:SI 1 "" ""))
8226 (use (match_operand:SI 2 "" ""))])]
8227 "TARGET_STRING && !TARGET_POWERPC64"
8235 /* Support only loading a constant number of fixed-point registers from
8236 memory and only bother with this if more than two; the machine
8237 doesn't support more than eight. */
8238 if (GET_CODE (operands[2]) != CONST_INT
8239 || INTVAL (operands[2]) <= 2
8240 || INTVAL (operands[2]) > 8
8241 || GET_CODE (operands[1]) != MEM
8242 || GET_CODE (operands[0]) != REG
8243 || REGNO (operands[0]) >= 32)
8246 count = INTVAL (operands[2]);
8247 regno = REGNO (operands[0]);
8249 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8250 op1 = replace_equiv_address (operands[1],
8251 force_reg (SImode, XEXP (operands[1], 0)));
8253 for (i = 0; i < count; i++)
8254 XVECEXP (operands[3], 0, i)
8255 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8256 adjust_address_nv (op1, SImode, i * 4));
8259 (define_insn "*ldmsi8"
8260 [(match_parallel 0 "load_multiple_operation"
8261 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8262 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8263 (set (match_operand:SI 3 "gpc_reg_operand" "")
8264 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8265 (set (match_operand:SI 4 "gpc_reg_operand" "")
8266 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8267 (set (match_operand:SI 5 "gpc_reg_operand" "")
8268 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8269 (set (match_operand:SI 6 "gpc_reg_operand" "")
8270 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8271 (set (match_operand:SI 7 "gpc_reg_operand" "")
8272 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8273 (set (match_operand:SI 8 "gpc_reg_operand" "")
8274 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8275 (set (match_operand:SI 9 "gpc_reg_operand" "")
8276 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8277 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8279 { return rs6000_output_load_multiple (operands); }"
8280 [(set_attr "type" "load")
8281 (set_attr "update" "yes")
8282 (set_attr "indexed" "yes")
8283 (set_attr "length" "32")])
8285 (define_insn "*ldmsi7"
8286 [(match_parallel 0 "load_multiple_operation"
8287 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8288 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8289 (set (match_operand:SI 3 "gpc_reg_operand" "")
8290 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8291 (set (match_operand:SI 4 "gpc_reg_operand" "")
8292 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8293 (set (match_operand:SI 5 "gpc_reg_operand" "")
8294 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8295 (set (match_operand:SI 6 "gpc_reg_operand" "")
8296 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8297 (set (match_operand:SI 7 "gpc_reg_operand" "")
8298 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8299 (set (match_operand:SI 8 "gpc_reg_operand" "")
8300 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8301 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8303 { return rs6000_output_load_multiple (operands); }"
8304 [(set_attr "type" "load")
8305 (set_attr "update" "yes")
8306 (set_attr "indexed" "yes")
8307 (set_attr "length" "32")])
8309 (define_insn "*ldmsi6"
8310 [(match_parallel 0 "load_multiple_operation"
8311 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8312 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8313 (set (match_operand:SI 3 "gpc_reg_operand" "")
8314 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8315 (set (match_operand:SI 4 "gpc_reg_operand" "")
8316 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8317 (set (match_operand:SI 5 "gpc_reg_operand" "")
8318 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8319 (set (match_operand:SI 6 "gpc_reg_operand" "")
8320 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8321 (set (match_operand:SI 7 "gpc_reg_operand" "")
8322 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8323 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8325 { return rs6000_output_load_multiple (operands); }"
8326 [(set_attr "type" "load")
8327 (set_attr "update" "yes")
8328 (set_attr "indexed" "yes")
8329 (set_attr "length" "32")])
8331 (define_insn "*ldmsi5"
8332 [(match_parallel 0 "load_multiple_operation"
8333 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8334 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8335 (set (match_operand:SI 3 "gpc_reg_operand" "")
8336 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8337 (set (match_operand:SI 4 "gpc_reg_operand" "")
8338 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8339 (set (match_operand:SI 5 "gpc_reg_operand" "")
8340 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8341 (set (match_operand:SI 6 "gpc_reg_operand" "")
8342 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8343 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8345 { return rs6000_output_load_multiple (operands); }"
8346 [(set_attr "type" "load")
8347 (set_attr "update" "yes")
8348 (set_attr "indexed" "yes")
8349 (set_attr "length" "32")])
8351 (define_insn "*ldmsi4"
8352 [(match_parallel 0 "load_multiple_operation"
8353 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8354 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8355 (set (match_operand:SI 3 "gpc_reg_operand" "")
8356 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8357 (set (match_operand:SI 4 "gpc_reg_operand" "")
8358 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8359 (set (match_operand:SI 5 "gpc_reg_operand" "")
8360 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8361 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8363 { return rs6000_output_load_multiple (operands); }"
8364 [(set_attr "type" "load")
8365 (set_attr "update" "yes")
8366 (set_attr "indexed" "yes")
8367 (set_attr "length" "32")])
8369 (define_insn "*ldmsi3"
8370 [(match_parallel 0 "load_multiple_operation"
8371 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8372 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8373 (set (match_operand:SI 3 "gpc_reg_operand" "")
8374 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8375 (set (match_operand:SI 4 "gpc_reg_operand" "")
8376 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8377 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8379 { return rs6000_output_load_multiple (operands); }"
8380 [(set_attr "type" "load")
8381 (set_attr "update" "yes")
8382 (set_attr "indexed" "yes")
8383 (set_attr "length" "32")])
8385 (define_expand "store_multiple"
8386 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8387 (match_operand:SI 1 "" ""))
8388 (clobber (scratch:SI))
8389 (use (match_operand:SI 2 "" ""))])]
8390 "TARGET_STRING && !TARGET_POWERPC64"
8399 /* Support only storing a constant number of fixed-point registers to
8400 memory and only bother with this if more than two; the machine
8401 doesn't support more than eight. */
8402 if (GET_CODE (operands[2]) != CONST_INT
8403 || INTVAL (operands[2]) <= 2
8404 || INTVAL (operands[2]) > 8
8405 || GET_CODE (operands[0]) != MEM
8406 || GET_CODE (operands[1]) != REG
8407 || REGNO (operands[1]) >= 32)
8410 count = INTVAL (operands[2]);
8411 regno = REGNO (operands[1]);
8413 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8414 to = force_reg (SImode, XEXP (operands[0], 0));
8415 op0 = replace_equiv_address (operands[0], to);
8417 XVECEXP (operands[3], 0, 0)
8418 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8419 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8420 gen_rtx_SCRATCH (SImode));
8422 for (i = 1; i < count; i++)
8423 XVECEXP (operands[3], 0, i + 1)
8424 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8425 gen_rtx_REG (SImode, regno + i));
8428 (define_insn "*stmsi8"
8429 [(match_parallel 0 "store_multiple_operation"
8430 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8431 (match_operand:SI 2 "gpc_reg_operand" "r"))
8432 (clobber (match_scratch:SI 3 "=X"))
8433 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8434 (match_operand:SI 4 "gpc_reg_operand" "r"))
8435 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8436 (match_operand:SI 5 "gpc_reg_operand" "r"))
8437 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8438 (match_operand:SI 6 "gpc_reg_operand" "r"))
8439 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8440 (match_operand:SI 7 "gpc_reg_operand" "r"))
8441 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8442 (match_operand:SI 8 "gpc_reg_operand" "r"))
8443 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8444 (match_operand:SI 9 "gpc_reg_operand" "r"))
8445 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8446 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8447 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8449 [(set_attr "type" "store")
8450 (set_attr "update" "yes")
8451 (set_attr "indexed" "yes")
8452 (set_attr "cell_micro" "always")])
8454 (define_insn "*stmsi7"
8455 [(match_parallel 0 "store_multiple_operation"
8456 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8457 (match_operand:SI 2 "gpc_reg_operand" "r"))
8458 (clobber (match_scratch:SI 3 "=X"))
8459 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8460 (match_operand:SI 4 "gpc_reg_operand" "r"))
8461 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8462 (match_operand:SI 5 "gpc_reg_operand" "r"))
8463 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8464 (match_operand:SI 6 "gpc_reg_operand" "r"))
8465 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8466 (match_operand:SI 7 "gpc_reg_operand" "r"))
8467 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8468 (match_operand:SI 8 "gpc_reg_operand" "r"))
8469 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8470 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8471 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8473 [(set_attr "type" "store")
8474 (set_attr "update" "yes")
8475 (set_attr "indexed" "yes")
8476 (set_attr "cell_micro" "always")])
8478 (define_insn "*stmsi6"
8479 [(match_parallel 0 "store_multiple_operation"
8480 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8481 (match_operand:SI 2 "gpc_reg_operand" "r"))
8482 (clobber (match_scratch:SI 3 "=X"))
8483 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8484 (match_operand:SI 4 "gpc_reg_operand" "r"))
8485 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8486 (match_operand:SI 5 "gpc_reg_operand" "r"))
8487 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8488 (match_operand:SI 6 "gpc_reg_operand" "r"))
8489 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8490 (match_operand:SI 7 "gpc_reg_operand" "r"))
8491 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8492 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8493 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8495 [(set_attr "type" "store")
8496 (set_attr "update" "yes")
8497 (set_attr "indexed" "yes")
8498 (set_attr "cell_micro" "always")])
8500 (define_insn "*stmsi5"
8501 [(match_parallel 0 "store_multiple_operation"
8502 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8503 (match_operand:SI 2 "gpc_reg_operand" "r"))
8504 (clobber (match_scratch:SI 3 "=X"))
8505 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8506 (match_operand:SI 4 "gpc_reg_operand" "r"))
8507 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8508 (match_operand:SI 5 "gpc_reg_operand" "r"))
8509 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8510 (match_operand:SI 6 "gpc_reg_operand" "r"))
8511 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8512 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8513 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8515 [(set_attr "type" "store")
8516 (set_attr "update" "yes")
8517 (set_attr "indexed" "yes")
8518 (set_attr "cell_micro" "always")])
8520 (define_insn "*stmsi4"
8521 [(match_parallel 0 "store_multiple_operation"
8522 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8523 (match_operand:SI 2 "gpc_reg_operand" "r"))
8524 (clobber (match_scratch:SI 3 "=X"))
8525 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8526 (match_operand:SI 4 "gpc_reg_operand" "r"))
8527 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8528 (match_operand:SI 5 "gpc_reg_operand" "r"))
8529 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8530 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8531 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8533 [(set_attr "type" "store")
8534 (set_attr "update" "yes")
8535 (set_attr "indexed" "yes")
8536 (set_attr "cell_micro" "always")])
8538 (define_insn "*stmsi3"
8539 [(match_parallel 0 "store_multiple_operation"
8540 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8541 (match_operand:SI 2 "gpc_reg_operand" "r"))
8542 (clobber (match_scratch:SI 3 "=X"))
8543 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8544 (match_operand:SI 4 "gpc_reg_operand" "r"))
8545 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8546 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8547 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8549 [(set_attr "type" "store")
8550 (set_attr "update" "yes")
8551 (set_attr "indexed" "yes")
8552 (set_attr "cell_micro" "always")])
8554 (define_expand "setmemsi"
8555 [(parallel [(set (match_operand:BLK 0 "" "")
8556 (match_operand 2 "const_int_operand" ""))
8557 (use (match_operand:SI 1 "" ""))
8558 (use (match_operand:SI 3 "" ""))])]
8562 /* If value to set is not zero, use the library routine. */
8563 if (operands[2] != const0_rtx)
8566 if (expand_block_clear (operands))
8572 ;; String/block move insn.
8573 ;; Argument 0 is the destination
8574 ;; Argument 1 is the source
8575 ;; Argument 2 is the length
8576 ;; Argument 3 is the alignment
8578 (define_expand "movmemsi"
8579 [(parallel [(set (match_operand:BLK 0 "" "")
8580 (match_operand:BLK 1 "" ""))
8581 (use (match_operand:SI 2 "" ""))
8582 (use (match_operand:SI 3 "" ""))])]
8586 if (expand_block_move (operands))
8592 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
8593 ;; register allocator doesn't have a clue about allocating 8 word registers.
8594 ;; rD/rS = r5 is preferred, efficient form.
8595 (define_expand "movmemsi_8reg"
8596 [(parallel [(set (match_operand 0 "" "")
8597 (match_operand 1 "" ""))
8598 (use (match_operand 2 "" ""))
8599 (use (match_operand 3 "" ""))
8600 (clobber (reg:SI 5))
8601 (clobber (reg:SI 6))
8602 (clobber (reg:SI 7))
8603 (clobber (reg:SI 8))
8604 (clobber (reg:SI 9))
8605 (clobber (reg:SI 10))
8606 (clobber (reg:SI 11))
8607 (clobber (reg:SI 12))
8608 (clobber (match_scratch:SI 4 ""))])]
8613 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8614 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8615 (use (match_operand:SI 2 "immediate_operand" "i"))
8616 (use (match_operand:SI 3 "immediate_operand" "i"))
8617 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8618 (clobber (reg:SI 6))
8619 (clobber (reg:SI 7))
8620 (clobber (reg:SI 8))
8621 (clobber (reg:SI 9))
8622 (clobber (reg:SI 10))
8623 (clobber (reg:SI 11))
8624 (clobber (reg:SI 12))
8625 (clobber (match_scratch:SI 5 "=X"))]
8627 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8628 || INTVAL (operands[2]) == 0)
8629 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8630 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8631 && REGNO (operands[4]) == 5"
8632 "lswi %4,%1,%2\;stswi %4,%0,%2"
8633 [(set_attr "type" "store")
8634 (set_attr "update" "yes")
8635 (set_attr "indexed" "yes")
8636 (set_attr "cell_micro" "always")
8637 (set_attr "length" "8")])
8639 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
8640 ;; register allocator doesn't have a clue about allocating 6 word registers.
8641 ;; rD/rS = r5 is preferred, efficient form.
8642 (define_expand "movmemsi_6reg"
8643 [(parallel [(set (match_operand 0 "" "")
8644 (match_operand 1 "" ""))
8645 (use (match_operand 2 "" ""))
8646 (use (match_operand 3 "" ""))
8647 (clobber (reg:SI 5))
8648 (clobber (reg:SI 6))
8649 (clobber (reg:SI 7))
8650 (clobber (reg:SI 8))
8651 (clobber (reg:SI 9))
8652 (clobber (reg:SI 10))
8653 (clobber (match_scratch:SI 4 ""))])]
8658 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8659 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8660 (use (match_operand:SI 2 "immediate_operand" "i"))
8661 (use (match_operand:SI 3 "immediate_operand" "i"))
8662 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8663 (clobber (reg:SI 6))
8664 (clobber (reg:SI 7))
8665 (clobber (reg:SI 8))
8666 (clobber (reg:SI 9))
8667 (clobber (reg:SI 10))
8668 (clobber (match_scratch:SI 5 "=X"))]
8670 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8671 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8672 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8673 && REGNO (operands[4]) == 5"
8674 "lswi %4,%1,%2\;stswi %4,%0,%2"
8675 [(set_attr "type" "store")
8676 (set_attr "update" "yes")
8677 (set_attr "indexed" "yes")
8678 (set_attr "cell_micro" "always")
8679 (set_attr "length" "8")])
8681 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8682 ;; problems with TImode.
8683 ;; rD/rS = r5 is preferred, efficient form.
8684 (define_expand "movmemsi_4reg"
8685 [(parallel [(set (match_operand 0 "" "")
8686 (match_operand 1 "" ""))
8687 (use (match_operand 2 "" ""))
8688 (use (match_operand 3 "" ""))
8689 (clobber (reg:SI 5))
8690 (clobber (reg:SI 6))
8691 (clobber (reg:SI 7))
8692 (clobber (reg:SI 8))
8693 (clobber (match_scratch:SI 4 ""))])]
8698 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8699 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8700 (use (match_operand:SI 2 "immediate_operand" "i"))
8701 (use (match_operand:SI 3 "immediate_operand" "i"))
8702 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8703 (clobber (reg:SI 6))
8704 (clobber (reg:SI 7))
8705 (clobber (reg:SI 8))
8706 (clobber (match_scratch:SI 5 "=X"))]
8708 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8709 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8710 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8711 && REGNO (operands[4]) == 5"
8712 "lswi %4,%1,%2\;stswi %4,%0,%2"
8713 [(set_attr "type" "store")
8714 (set_attr "update" "yes")
8715 (set_attr "indexed" "yes")
8716 (set_attr "cell_micro" "always")
8717 (set_attr "length" "8")])
8719 ;; Move up to 8 bytes at a time.
8720 (define_expand "movmemsi_2reg"
8721 [(parallel [(set (match_operand 0 "" "")
8722 (match_operand 1 "" ""))
8723 (use (match_operand 2 "" ""))
8724 (use (match_operand 3 "" ""))
8725 (clobber (match_scratch:DI 4 ""))
8726 (clobber (match_scratch:SI 5 ""))])]
8727 "TARGET_STRING && ! TARGET_POWERPC64"
8731 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8732 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8733 (use (match_operand:SI 2 "immediate_operand" "i"))
8734 (use (match_operand:SI 3 "immediate_operand" "i"))
8735 (clobber (match_scratch:DI 4 "=&r"))
8736 (clobber (match_scratch:SI 5 "=X"))]
8737 "TARGET_STRING && ! TARGET_POWERPC64
8738 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8739 "lswi %4,%1,%2\;stswi %4,%0,%2"
8740 [(set_attr "type" "store")
8741 (set_attr "update" "yes")
8742 (set_attr "indexed" "yes")
8743 (set_attr "cell_micro" "always")
8744 (set_attr "length" "8")])
8746 ;; Move up to 4 bytes at a time.
8747 (define_expand "movmemsi_1reg"
8748 [(parallel [(set (match_operand 0 "" "")
8749 (match_operand 1 "" ""))
8750 (use (match_operand 2 "" ""))
8751 (use (match_operand 3 "" ""))
8752 (clobber (match_scratch:SI 4 ""))
8753 (clobber (match_scratch:SI 5 ""))])]
8758 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8759 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8760 (use (match_operand:SI 2 "immediate_operand" "i"))
8761 (use (match_operand:SI 3 "immediate_operand" "i"))
8762 (clobber (match_scratch:SI 4 "=&r"))
8763 (clobber (match_scratch:SI 5 "=X"))]
8764 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8765 "lswi %4,%1,%2\;stswi %4,%0,%2"
8766 [(set_attr "type" "store")
8767 (set_attr "update" "yes")
8768 (set_attr "indexed" "yes")
8769 (set_attr "cell_micro" "always")
8770 (set_attr "length" "8")])
8772 ;; Define insns that do load or store with update. Some of these we can
8773 ;; get by using pre-decrement or pre-increment, but the hardware can also
8774 ;; do cases where the increment is not the size of the object.
8776 ;; In all these cases, we use operands 0 and 1 for the register being
8777 ;; incremented because those are the operands that local-alloc will
8778 ;; tie and these are the pair most likely to be tieable (and the ones
8779 ;; that will benefit the most).
8781 (define_insn "*movdi_update1"
8782 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8783 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8784 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8785 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8786 (plus:DI (match_dup 1) (match_dup 2)))]
8787 "TARGET_POWERPC64 && TARGET_UPDATE
8788 && (!avoiding_indexed_address_p (DImode)
8789 || !gpc_reg_operand (operands[2], DImode))"
8793 [(set_attr "type" "load")
8794 (set_attr "update" "yes")
8795 (set_attr "indexed" "yes,no")])
8797 (define_insn "movdi_<mode>_update"
8798 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8799 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8800 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8801 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8802 (plus:P (match_dup 1) (match_dup 2)))]
8803 "TARGET_POWERPC64 && TARGET_UPDATE
8804 && (!avoiding_indexed_address_p (Pmode)
8805 || !gpc_reg_operand (operands[2], Pmode)
8806 || (REG_P (operands[0])
8807 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8811 [(set_attr "type" "store")
8812 (set_attr "update" "yes")
8813 (set_attr "indexed" "yes,no")])
8815 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8816 ;; needed for stack allocation, even if the user passes -mno-update.
8817 (define_insn "movdi_<mode>_update_stack"
8818 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8819 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8820 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8821 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8822 (plus:P (match_dup 1) (match_dup 2)))]
8827 [(set_attr "type" "store")
8828 (set_attr "update" "yes")
8829 (set_attr "indexed" "yes,no")])
8831 (define_insn "*movsi_update1"
8832 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8833 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8834 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8835 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8836 (plus:SI (match_dup 1) (match_dup 2)))]
8838 && (!avoiding_indexed_address_p (SImode)
8839 || !gpc_reg_operand (operands[2], SImode))"
8843 [(set_attr "type" "load")
8844 (set_attr "update" "yes")
8845 (set_attr "indexed" "yes,no")])
8847 (define_insn "*movsi_update2"
8848 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8850 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8851 (match_operand:DI 2 "gpc_reg_operand" "r")))))
8852 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8853 (plus:DI (match_dup 1) (match_dup 2)))]
8854 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8855 && !avoiding_indexed_address_p (DImode)"
8857 [(set_attr "type" "load")
8858 (set_attr "sign_extend" "yes")
8859 (set_attr "update" "yes")
8860 (set_attr "indexed" "yes")])
8862 (define_insn "movsi_update"
8863 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8864 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8865 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8866 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8867 (plus:SI (match_dup 1) (match_dup 2)))]
8869 && (!avoiding_indexed_address_p (SImode)
8870 || !gpc_reg_operand (operands[2], SImode)
8871 || (REG_P (operands[0])
8872 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8876 [(set_attr "type" "store")
8877 (set_attr "update" "yes")
8878 (set_attr "indexed" "yes,no")])
8880 ;; This is an unconditional pattern; needed for stack allocation, even
8881 ;; if the user passes -mno-update.
8882 (define_insn "movsi_update_stack"
8883 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8884 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8885 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8886 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8887 (plus:SI (match_dup 1) (match_dup 2)))]
8892 [(set_attr "type" "store")
8893 (set_attr "update" "yes")
8894 (set_attr "indexed" "yes,no")])
8896 (define_insn "*movhi_update1"
8897 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8898 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8899 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8900 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8901 (plus:SI (match_dup 1) (match_dup 2)))]
8903 && (!avoiding_indexed_address_p (SImode)
8904 || !gpc_reg_operand (operands[2], SImode))"
8908 [(set_attr "type" "load")
8909 (set_attr "update" "yes")
8910 (set_attr "indexed" "yes,no")])
8912 (define_insn "*movhi_update2"
8913 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8915 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8916 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8917 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8918 (plus:SI (match_dup 1) (match_dup 2)))]
8920 && (!avoiding_indexed_address_p (SImode)
8921 || !gpc_reg_operand (operands[2], SImode))"
8925 [(set_attr "type" "load")
8926 (set_attr "update" "yes")
8927 (set_attr "indexed" "yes,no")])
8929 (define_insn "*movhi_update3"
8930 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8932 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8933 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8934 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8935 (plus:SI (match_dup 1) (match_dup 2)))]
8936 "TARGET_UPDATE && rs6000_gen_cell_microcode
8937 && (!avoiding_indexed_address_p (SImode)
8938 || !gpc_reg_operand (operands[2], SImode))"
8942 [(set_attr "type" "load")
8943 (set_attr "sign_extend" "yes")
8944 (set_attr "update" "yes")
8945 (set_attr "indexed" "yes,no")])
8947 (define_insn "*movhi_update4"
8948 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8949 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8950 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8951 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8952 (plus:SI (match_dup 1) (match_dup 2)))]
8954 && (!avoiding_indexed_address_p (SImode)
8955 || !gpc_reg_operand (operands[2], SImode))"
8959 [(set_attr "type" "store")
8960 (set_attr "update" "yes")
8961 (set_attr "indexed" "yes,no")])
8963 (define_insn "*movqi_update1"
8964 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8965 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8966 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8967 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8968 (plus:SI (match_dup 1) (match_dup 2)))]
8970 && (!avoiding_indexed_address_p (SImode)
8971 || !gpc_reg_operand (operands[2], SImode))"
8975 [(set_attr "type" "load")
8976 (set_attr "update" "yes")
8977 (set_attr "indexed" "yes,no")])
8979 (define_insn "*movqi_update2"
8980 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8982 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8983 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8984 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8985 (plus:SI (match_dup 1) (match_dup 2)))]
8987 && (!avoiding_indexed_address_p (SImode)
8988 || !gpc_reg_operand (operands[2], SImode))"
8992 [(set_attr "type" "load")
8993 (set_attr "update" "yes")
8994 (set_attr "indexed" "yes,no")])
8996 (define_insn "*movqi_update3"
8997 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8998 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8999 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9000 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9001 (plus:SI (match_dup 1) (match_dup 2)))]
9003 && (!avoiding_indexed_address_p (SImode)
9004 || !gpc_reg_operand (operands[2], SImode))"
9008 [(set_attr "type" "store")
9009 (set_attr "update" "yes")
9010 (set_attr "indexed" "yes,no")])
9012 (define_insn "*movsf_update1"
9013 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9014 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9015 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9016 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9017 (plus:SI (match_dup 1) (match_dup 2)))]
9018 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9019 && (!avoiding_indexed_address_p (SImode)
9020 || !gpc_reg_operand (operands[2], SImode))"
9024 [(set_attr "type" "fpload")
9025 (set_attr "update" "yes")
9026 (set_attr "indexed" "yes,no")])
9028 (define_insn "*movsf_update2"
9029 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9030 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9031 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9032 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9033 (plus:SI (match_dup 1) (match_dup 2)))]
9034 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9035 && (!avoiding_indexed_address_p (SImode)
9036 || !gpc_reg_operand (operands[2], SImode))"
9040 [(set_attr "type" "fpstore")
9041 (set_attr "update" "yes")
9042 (set_attr "indexed" "yes,no")])
9044 (define_insn "*movsf_update3"
9045 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9046 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9047 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9048 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9049 (plus:SI (match_dup 1) (match_dup 2)))]
9050 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9051 && (!avoiding_indexed_address_p (SImode)
9052 || !gpc_reg_operand (operands[2], SImode))"
9056 [(set_attr "type" "load")
9057 (set_attr "update" "yes")
9058 (set_attr "indexed" "yes,no")])
9060 (define_insn "*movsf_update4"
9061 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9062 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9063 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9064 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9065 (plus:SI (match_dup 1) (match_dup 2)))]
9066 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9067 && (!avoiding_indexed_address_p (SImode)
9068 || !gpc_reg_operand (operands[2], SImode))"
9072 [(set_attr "type" "store")
9073 (set_attr "update" "yes")
9074 (set_attr "indexed" "yes,no")])
9076 (define_insn "*movdf_update1"
9077 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9078 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9079 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9080 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9081 (plus:SI (match_dup 1) (match_dup 2)))]
9082 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9083 && (!avoiding_indexed_address_p (SImode)
9084 || !gpc_reg_operand (operands[2], SImode))"
9088 [(set_attr "type" "fpload")
9089 (set_attr "update" "yes")
9090 (set_attr "indexed" "yes,no")
9091 (set_attr "size" "64")])
9093 (define_insn "*movdf_update2"
9094 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9095 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9096 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9097 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9098 (plus:SI (match_dup 1) (match_dup 2)))]
9099 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9100 && (!avoiding_indexed_address_p (SImode)
9101 || !gpc_reg_operand (operands[2], SImode))"
9105 [(set_attr "type" "fpstore")
9106 (set_attr "update" "yes")
9107 (set_attr "indexed" "yes,no")])
9110 ;; After inserting conditional returns we can sometimes have
9111 ;; unnecessary register moves. Unfortunately we cannot have a
9112 ;; modeless peephole here, because some single SImode sets have early
9113 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9114 ;; sequences, using get_attr_length here will smash the operands
9115 ;; array. Neither is there an early_cobbler_p predicate.
9116 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9117 ;; Also this optimization interferes with scalars going into
9118 ;; altivec registers (the code does reloading through the FPRs).
9120 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9121 (match_operand:DF 1 "any_operand" ""))
9122 (set (match_operand:DF 2 "gpc_reg_operand" "")
9124 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9125 && !TARGET_UPPER_REGS_DF
9126 && peep2_reg_dead_p (2, operands[0])"
9127 [(set (match_dup 2) (match_dup 1))])
9130 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9131 (match_operand:SF 1 "any_operand" ""))
9132 (set (match_operand:SF 2 "gpc_reg_operand" "")
9134 "!TARGET_UPPER_REGS_SF
9135 && peep2_reg_dead_p (2, operands[0])"
9136 [(set (match_dup 2) (match_dup 1))])
9141 ;; Mode attributes for different ABIs.
9142 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9143 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9144 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9145 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9147 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9148 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9149 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9150 (match_operand 4 "" "g")))
9151 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9152 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9154 (clobber (reg:SI LR_REGNO))]
9155 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9157 if (TARGET_CMODEL != CMODEL_SMALL)
9158 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9161 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9163 "&& TARGET_TLS_MARKERS"
9165 (unspec:TLSmode [(match_dup 1)
9168 (parallel [(set (match_dup 0)
9169 (call (mem:TLSmode (match_dup 3))
9171 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9172 (clobber (reg:SI LR_REGNO))])]
9174 [(set_attr "type" "two")
9175 (set (attr "length")
9176 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9180 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9181 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9182 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9183 (match_operand 4 "" "g")))
9184 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9185 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9187 (clobber (reg:SI LR_REGNO))]
9188 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9192 if (TARGET_SECURE_PLT && flag_pic == 2)
9193 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9195 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9198 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9200 "&& TARGET_TLS_MARKERS"
9202 (unspec:TLSmode [(match_dup 1)
9205 (parallel [(set (match_dup 0)
9206 (call (mem:TLSmode (match_dup 3))
9208 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9209 (clobber (reg:SI LR_REGNO))])]
9211 [(set_attr "type" "two")
9212 (set_attr "length" "8")])
9214 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9215 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9216 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9217 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9219 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9220 "addi %0,%1,%2@got@tlsgd"
9221 "&& TARGET_CMODEL != CMODEL_SMALL"
9224 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9226 (lo_sum:TLSmode (match_dup 3)
9227 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9230 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9232 [(set (attr "length")
9233 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9237 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9238 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9240 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9241 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9243 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9244 "addis %0,%1,%2@got@tlsgd@ha"
9245 [(set_attr "length" "4")])
9247 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9248 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9249 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9250 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9251 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9253 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9254 "addi %0,%1,%2@got@tlsgd@l"
9255 [(set_attr "length" "4")])
9257 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9258 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9259 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9260 (match_operand 2 "" "g")))
9261 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9263 (clobber (reg:SI LR_REGNO))]
9264 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9265 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9266 "bl %z1(%3@tlsgd)\;nop"
9267 [(set_attr "type" "branch")
9268 (set_attr "length" "8")])
9270 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9271 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9272 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9273 (match_operand 2 "" "g")))
9274 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9276 (clobber (reg:SI LR_REGNO))]
9277 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9281 if (TARGET_SECURE_PLT && flag_pic == 2)
9282 return "bl %z1+32768(%3@tlsgd)@plt";
9283 return "bl %z1(%3@tlsgd)@plt";
9285 return "bl %z1(%3@tlsgd)";
9287 [(set_attr "type" "branch")
9288 (set_attr "length" "4")])
9290 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9291 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9292 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9293 (match_operand 3 "" "g")))
9294 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9296 (clobber (reg:SI LR_REGNO))]
9297 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9299 if (TARGET_CMODEL != CMODEL_SMALL)
9300 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9303 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9305 "&& TARGET_TLS_MARKERS"
9307 (unspec:TLSmode [(match_dup 1)]
9309 (parallel [(set (match_dup 0)
9310 (call (mem:TLSmode (match_dup 2))
9312 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9313 (clobber (reg:SI LR_REGNO))])]
9315 [(set_attr "type" "two")
9316 (set (attr "length")
9317 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9321 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9322 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9323 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9324 (match_operand 3 "" "g")))
9325 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9327 (clobber (reg:SI LR_REGNO))]
9328 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9332 if (TARGET_SECURE_PLT && flag_pic == 2)
9333 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9335 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9338 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9340 "&& TARGET_TLS_MARKERS"
9342 (unspec:TLSmode [(match_dup 1)]
9344 (parallel [(set (match_dup 0)
9345 (call (mem:TLSmode (match_dup 2))
9347 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9348 (clobber (reg:SI LR_REGNO))])]
9350 [(set_attr "length" "8")])
9352 (define_insn_and_split "*tls_ld<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")]
9356 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9357 "addi %0,%1,%&@got@tlsld"
9358 "&& TARGET_CMODEL != CMODEL_SMALL"
9361 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9363 (lo_sum:TLSmode (match_dup 2)
9364 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9367 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9369 [(set (attr "length")
9370 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9374 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9375 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9377 (unspec:TLSmode [(const_int 0)
9378 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9380 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9381 "addis %0,%1,%&@got@tlsld@ha"
9382 [(set_attr "length" "4")])
9384 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9385 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9386 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9387 (unspec:TLSmode [(const_int 0)
9388 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9390 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9391 "addi %0,%1,%&@got@tlsld@l"
9392 [(set_attr "length" "4")])
9394 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9395 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9396 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9397 (match_operand 2 "" "g")))
9398 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9399 (clobber (reg:SI LR_REGNO))]
9400 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9401 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9402 "bl %z1(%&@tlsld)\;nop"
9403 [(set_attr "type" "branch")
9404 (set_attr "length" "8")])
9406 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9407 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9408 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9409 (match_operand 2 "" "g")))
9410 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9411 (clobber (reg:SI LR_REGNO))]
9412 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9416 if (TARGET_SECURE_PLT && flag_pic == 2)
9417 return "bl %z1+32768(%&@tlsld)@plt";
9418 return "bl %z1(%&@tlsld)@plt";
9420 return "bl %z1(%&@tlsld)";
9422 [(set_attr "type" "branch")
9423 (set_attr "length" "4")])
9425 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9426 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9427 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9428 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9431 "addi %0,%1,%2@dtprel")
9433 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9434 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9435 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9436 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9437 UNSPEC_TLSDTPRELHA))]
9439 "addis %0,%1,%2@dtprel@ha")
9441 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9442 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9443 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9444 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9445 UNSPEC_TLSDTPRELLO))]
9447 "addi %0,%1,%2@dtprel@l")
9449 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9450 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9451 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9452 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9453 UNSPEC_TLSGOTDTPREL))]
9455 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9456 "&& TARGET_CMODEL != CMODEL_SMALL"
9459 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9461 (lo_sum:TLSmode (match_dup 3)
9462 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9465 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9467 [(set (attr "length")
9468 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9472 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9473 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9475 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9476 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9477 UNSPEC_TLSGOTDTPREL)))]
9478 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9479 "addis %0,%1,%2@got@dtprel@ha"
9480 [(set_attr "length" "4")])
9482 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9483 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9484 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9485 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9486 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9487 UNSPEC_TLSGOTDTPREL)))]
9488 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9489 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9490 [(set_attr "length" "4")])
9492 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9493 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9494 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9495 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9498 "addi %0,%1,%2@tprel")
9500 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9501 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9502 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9503 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9504 UNSPEC_TLSTPRELHA))]
9506 "addis %0,%1,%2@tprel@ha")
9508 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9509 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9510 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9511 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9512 UNSPEC_TLSTPRELLO))]
9514 "addi %0,%1,%2@tprel@l")
9516 ;; "b" output constraint here and on tls_tls input to support linker tls
9517 ;; optimization. The linker may edit the instructions emitted by a
9518 ;; tls_got_tprel/tls_tls pair to addis,addi.
9519 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9520 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9521 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9522 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9523 UNSPEC_TLSGOTTPREL))]
9525 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9526 "&& TARGET_CMODEL != CMODEL_SMALL"
9529 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9531 (lo_sum:TLSmode (match_dup 3)
9532 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9535 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9537 [(set (attr "length")
9538 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9542 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9543 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9545 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9546 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9547 UNSPEC_TLSGOTTPREL)))]
9548 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9549 "addis %0,%1,%2@got@tprel@ha"
9550 [(set_attr "length" "4")])
9552 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9553 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9554 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9555 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9556 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9557 UNSPEC_TLSGOTTPREL)))]
9558 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9559 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9560 [(set_attr "length" "4")])
9562 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9563 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9564 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9565 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9567 "TARGET_ELF && HAVE_AS_TLS"
9570 (define_expand "tls_get_tpointer"
9571 [(set (match_operand:SI 0 "gpc_reg_operand" "")
9572 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9573 "TARGET_XCOFF && HAVE_AS_TLS"
9576 emit_insn (gen_tls_get_tpointer_internal ());
9577 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9581 (define_insn "tls_get_tpointer_internal"
9583 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9584 (clobber (reg:SI LR_REGNO))]
9585 "TARGET_XCOFF && HAVE_AS_TLS"
9586 "bla __get_tpointer")
9588 (define_expand "tls_get_addr<mode>"
9589 [(set (match_operand:P 0 "gpc_reg_operand" "")
9590 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9591 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9592 "TARGET_XCOFF && HAVE_AS_TLS"
9595 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9596 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9597 emit_insn (gen_tls_get_addr_internal<mode> ());
9598 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9602 (define_insn "tls_get_addr_internal<mode>"
9604 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9608 (clobber (reg:P 11))
9609 (clobber (reg:CC CR0_REGNO))
9610 (clobber (reg:P LR_REGNO))]
9611 "TARGET_XCOFF && HAVE_AS_TLS"
9612 "bla __tls_get_addr")
9614 ;; Next come insns related to the calling sequence.
9616 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9617 ;; We move the back-chain and decrement the stack pointer.
9619 (define_expand "allocate_stack"
9620 [(set (match_operand 0 "gpc_reg_operand" "")
9621 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9623 (minus (reg 1) (match_dup 1)))]
9626 { rtx chain = gen_reg_rtx (Pmode);
9627 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9629 rtx insn, par, set, mem;
9631 emit_move_insn (chain, stack_bot);
9633 /* Check stack bounds if necessary. */
9634 if (crtl->limit_stack)
9637 available = expand_binop (Pmode, sub_optab,
9638 stack_pointer_rtx, stack_limit_rtx,
9639 NULL_RTX, 1, OPTAB_WIDEN);
9640 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9643 if (GET_CODE (operands[1]) != CONST_INT
9644 || INTVAL (operands[1]) < -32767
9645 || INTVAL (operands[1]) > 32768)
9647 neg_op0 = gen_reg_rtx (Pmode);
9649 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9651 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9654 neg_op0 = GEN_INT (- INTVAL (operands[1]));
9656 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9657 : gen_movdi_di_update_stack))
9658 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9660 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9661 it now and set the alias set/attributes. The above gen_*_update
9662 calls will generate a PARALLEL with the MEM set being the first
9664 par = PATTERN (insn);
9665 gcc_assert (GET_CODE (par) == PARALLEL);
9666 set = XVECEXP (par, 0, 0);
9667 gcc_assert (GET_CODE (set) == SET);
9668 mem = SET_DEST (set);
9669 gcc_assert (MEM_P (mem));
9670 MEM_NOTRAP_P (mem) = 1;
9671 set_mem_alias_set (mem, get_frame_alias_set ());
9673 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9677 ;; These patterns say how to save and restore the stack pointer. We need not
9678 ;; save the stack pointer at function level since we are careful to
9679 ;; preserve the backchain. At block level, we have to restore the backchain
9680 ;; when we restore the stack pointer.
9682 ;; For nonlocal gotos, we must save both the stack pointer and its
9683 ;; backchain and restore both. Note that in the nonlocal case, the
9684 ;; save area is a memory location.
9686 (define_expand "save_stack_function"
9687 [(match_operand 0 "any_operand" "")
9688 (match_operand 1 "any_operand" "")]
9692 (define_expand "restore_stack_function"
9693 [(match_operand 0 "any_operand" "")
9694 (match_operand 1 "any_operand" "")]
9698 ;; Adjust stack pointer (op0) to a new value (op1).
9699 ;; First copy old stack backchain to new location, and ensure that the
9700 ;; scheduler won't reorder the sp assignment before the backchain write.
9701 (define_expand "restore_stack_block"
9702 [(set (match_dup 2) (match_dup 3))
9703 (set (match_dup 4) (match_dup 2))
9705 (set (match_operand 0 "register_operand" "")
9706 (match_operand 1 "register_operand" ""))]
9712 operands[1] = force_reg (Pmode, operands[1]);
9713 operands[2] = gen_reg_rtx (Pmode);
9714 operands[3] = gen_frame_mem (Pmode, operands[0]);
9715 operands[4] = gen_frame_mem (Pmode, operands[1]);
9716 p = rtvec_alloc (1);
9717 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9719 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9722 (define_expand "save_stack_nonlocal"
9723 [(set (match_dup 3) (match_dup 4))
9724 (set (match_operand 0 "memory_operand" "") (match_dup 3))
9725 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9729 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9731 /* Copy the backchain to the first word, sp to the second. */
9732 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9733 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9734 operands[3] = gen_reg_rtx (Pmode);
9735 operands[4] = gen_frame_mem (Pmode, operands[1]);
9738 (define_expand "restore_stack_nonlocal"
9739 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9740 (set (match_dup 3) (match_dup 4))
9741 (set (match_dup 5) (match_dup 2))
9743 (set (match_operand 0 "register_operand" "") (match_dup 3))]
9747 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9750 /* Restore the backchain from the first word, sp from the second. */
9751 operands[2] = gen_reg_rtx (Pmode);
9752 operands[3] = gen_reg_rtx (Pmode);
9753 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9754 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9755 operands[5] = gen_frame_mem (Pmode, operands[3]);
9756 p = rtvec_alloc (1);
9757 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9759 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9762 ;; TOC register handling.
9764 ;; Code to initialize the TOC register...
9766 (define_insn "load_toc_aix_si"
9767 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9768 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9770 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9774 extern int need_toc_init;
9776 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9777 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9778 operands[2] = gen_rtx_REG (Pmode, 2);
9779 return \"lwz %0,%1(%2)\";
9781 [(set_attr "type" "load")
9782 (set_attr "update" "no")
9783 (set_attr "indexed" "no")])
9785 (define_insn "load_toc_aix_di"
9786 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9787 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9789 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9793 extern int need_toc_init;
9795 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9796 !TARGET_ELF || !TARGET_MINIMAL_TOC);
9798 strcat (buf, \"@toc\");
9799 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9800 operands[2] = gen_rtx_REG (Pmode, 2);
9801 return \"ld %0,%1(%2)\";
9803 [(set_attr "type" "load")
9804 (set_attr "update" "no")
9805 (set_attr "indexed" "no")])
9807 (define_insn "load_toc_v4_pic_si"
9808 [(set (reg:SI LR_REGNO)
9809 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9810 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9811 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9812 [(set_attr "type" "branch")
9813 (set_attr "length" "4")])
9815 (define_expand "load_toc_v4_PIC_1"
9816 [(parallel [(set (reg:SI LR_REGNO)
9817 (match_operand:SI 0 "immediate_operand" "s"))
9818 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9819 "TARGET_ELF && DEFAULT_ABI == ABI_V4
9820 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9823 (define_insn "load_toc_v4_PIC_1_normal"
9824 [(set (reg:SI LR_REGNO)
9825 (match_operand:SI 0 "immediate_operand" "s"))
9826 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9827 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9828 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9829 "bcl 20,31,%0\\n%0:"
9830 [(set_attr "type" "branch")
9831 (set_attr "length" "4")
9832 (set_attr "cannot_copy" "yes")])
9834 (define_insn "load_toc_v4_PIC_1_476"
9835 [(set (reg:SI LR_REGNO)
9836 (match_operand:SI 0 "immediate_operand" "s"))
9837 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9838 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9839 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9843 static char templ[32];
9845 get_ppc476_thunk_name (name);
9846 sprintf (templ, \"bl %s\\n%%0:\", name);
9849 [(set_attr "type" "branch")
9850 (set_attr "length" "4")
9851 (set_attr "cannot_copy" "yes")])
9853 (define_expand "load_toc_v4_PIC_1b"
9854 [(parallel [(set (reg:SI LR_REGNO)
9855 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9856 (label_ref (match_operand 1 "" ""))]
9859 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9862 (define_insn "load_toc_v4_PIC_1b_normal"
9863 [(set (reg:SI LR_REGNO)
9864 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9865 (label_ref (match_operand 1 "" ""))]
9868 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9869 "bcl 20,31,$+8\;.long %0-$"
9870 [(set_attr "type" "branch")
9871 (set_attr "length" "8")])
9873 (define_insn "load_toc_v4_PIC_1b_476"
9874 [(set (reg:SI LR_REGNO)
9875 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9876 (label_ref (match_operand 1 "" ""))]
9879 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9883 static char templ[32];
9885 get_ppc476_thunk_name (name);
9886 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9889 [(set_attr "type" "branch")
9890 (set_attr "length" "16")])
9892 (define_insn "load_toc_v4_PIC_2"
9893 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9894 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9895 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9896 (match_operand:SI 3 "immediate_operand" "s")))))]
9897 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9899 [(set_attr "type" "load")])
9901 (define_insn "load_toc_v4_PIC_3b"
9902 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9903 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9905 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9906 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9907 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9908 "addis %0,%1,%2-%3@ha")
9910 (define_insn "load_toc_v4_PIC_3c"
9911 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9912 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9913 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9914 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9915 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9916 "addi %0,%1,%2-%3@l")
9918 ;; If the TOC is shared over a translation unit, as happens with all
9919 ;; the kinds of PIC that we support, we need to restore the TOC
9920 ;; pointer only when jumping over units of translation.
9921 ;; On Darwin, we need to reload the picbase.
9923 (define_expand "builtin_setjmp_receiver"
9924 [(use (label_ref (match_operand 0 "" "")))]
9925 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9926 || (TARGET_TOC && TARGET_MINIMAL_TOC)
9927 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9931 if (DEFAULT_ABI == ABI_DARWIN)
9933 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9934 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9938 crtl->uses_pic_offset_table = 1;
9939 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9940 CODE_LABEL_NUMBER (operands[0]));
9941 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9943 emit_insn (gen_load_macho_picbase (tmplabrtx));
9944 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9945 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9949 rs6000_emit_load_toc_table (FALSE);
9954 (define_insn "*largetoc_high"
9955 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9957 (unspec [(match_operand:DI 1 "" "")
9958 (match_operand:DI 2 "gpc_reg_operand" "b")]
9960 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9961 "addis %0,%2,%1@toc@ha")
9963 (define_insn "*largetoc_high_aix<mode>"
9964 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9966 (unspec [(match_operand:P 1 "" "")
9967 (match_operand:P 2 "gpc_reg_operand" "b")]
9969 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9970 "addis %0,%1@u(%2)")
9972 (define_insn "*largetoc_high_plus"
9973 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9976 (unspec [(match_operand:DI 1 "" "")
9977 (match_operand:DI 2 "gpc_reg_operand" "b")]
9979 (match_operand:DI 3 "add_cint_operand" "n"))))]
9980 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9981 "addis %0,%2,%1+%3@toc@ha")
9983 (define_insn "*largetoc_high_plus_aix<mode>"
9984 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9987 (unspec [(match_operand:P 1 "" "")
9988 (match_operand:P 2 "gpc_reg_operand" "b")]
9990 (match_operand:P 3 "add_cint_operand" "n"))))]
9991 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9992 "addis %0,%1+%3@u(%2)")
9994 (define_insn "*largetoc_low"
9995 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9996 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9997 (match_operand:DI 2 "" "")))]
9998 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10001 (define_insn "*largetoc_low_aix<mode>"
10002 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10003 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10004 (match_operand:P 2 "" "")))]
10005 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10008 (define_insn_and_split "*tocref<mode>"
10009 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10010 (match_operand:P 1 "small_toc_ref" "R"))]
10013 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10014 [(set (match_dup 0) (high:P (match_dup 1)))
10015 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10017 ;; Elf specific ways of loading addresses for non-PIC code.
10018 ;; The output of this could be r0, but we make a very strong
10019 ;; preference for a base register because it will usually
10020 ;; be needed there.
10021 (define_insn "elf_high"
10022 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10023 (high:SI (match_operand 1 "" "")))]
10024 "TARGET_ELF && ! TARGET_64BIT"
10027 (define_insn "elf_low"
10028 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10029 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10030 (match_operand 2 "" "")))]
10031 "TARGET_ELF && ! TARGET_64BIT"
10034 ;; Call and call_value insns
10035 (define_expand "call"
10036 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10037 (match_operand 1 "" ""))
10038 (use (match_operand 2 "" ""))
10039 (clobber (reg:SI LR_REGNO))])]
10044 if (MACHOPIC_INDIRECT)
10045 operands[0] = machopic_indirect_call_target (operands[0]);
10048 gcc_assert (GET_CODE (operands[0]) == MEM);
10049 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10051 operands[0] = XEXP (operands[0], 0);
10053 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10055 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10059 if (GET_CODE (operands[0]) != SYMBOL_REF
10060 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10062 if (INTVAL (operands[2]) & CALL_LONG)
10063 operands[0] = rs6000_longcall_ref (operands[0]);
10065 switch (DEFAULT_ABI)
10069 operands[0] = force_reg (Pmode, operands[0]);
10073 gcc_unreachable ();
10078 (define_expand "call_value"
10079 [(parallel [(set (match_operand 0 "" "")
10080 (call (mem:SI (match_operand 1 "address_operand" ""))
10081 (match_operand 2 "" "")))
10082 (use (match_operand 3 "" ""))
10083 (clobber (reg:SI LR_REGNO))])]
10088 if (MACHOPIC_INDIRECT)
10089 operands[1] = machopic_indirect_call_target (operands[1]);
10092 gcc_assert (GET_CODE (operands[1]) == MEM);
10093 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10095 operands[1] = XEXP (operands[1], 0);
10097 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10099 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10103 if (GET_CODE (operands[1]) != SYMBOL_REF
10104 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10106 if (INTVAL (operands[3]) & CALL_LONG)
10107 operands[1] = rs6000_longcall_ref (operands[1]);
10109 switch (DEFAULT_ABI)
10113 operands[1] = force_reg (Pmode, operands[1]);
10117 gcc_unreachable ();
10122 ;; Call to function in current module. No TOC pointer reload needed.
10123 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10124 ;; either the function was not prototyped, or it was prototyped as a
10125 ;; variable argument function. It is > 0 if FP registers were passed
10126 ;; and < 0 if they were not.
10128 (define_insn "*call_local32"
10129 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10130 (match_operand 1 "" "g,g"))
10131 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10132 (clobber (reg:SI LR_REGNO))]
10133 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10136 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10137 output_asm_insn (\"crxor 6,6,6\", operands);
10139 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10140 output_asm_insn (\"creqv 6,6,6\", operands);
10142 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10144 [(set_attr "type" "branch")
10145 (set_attr "length" "4,8")])
10147 (define_insn "*call_local64"
10148 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10149 (match_operand 1 "" "g,g"))
10150 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10151 (clobber (reg:SI LR_REGNO))]
10152 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10155 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10156 output_asm_insn (\"crxor 6,6,6\", operands);
10158 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10159 output_asm_insn (\"creqv 6,6,6\", operands);
10161 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10163 [(set_attr "type" "branch")
10164 (set_attr "length" "4,8")])
10166 (define_insn "*call_value_local32"
10167 [(set (match_operand 0 "" "")
10168 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10169 (match_operand 2 "" "g,g")))
10170 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10171 (clobber (reg:SI LR_REGNO))]
10172 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10175 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10176 output_asm_insn (\"crxor 6,6,6\", operands);
10178 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10179 output_asm_insn (\"creqv 6,6,6\", operands);
10181 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10183 [(set_attr "type" "branch")
10184 (set_attr "length" "4,8")])
10187 (define_insn "*call_value_local64"
10188 [(set (match_operand 0 "" "")
10189 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10190 (match_operand 2 "" "g,g")))
10191 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10192 (clobber (reg:SI LR_REGNO))]
10193 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10196 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10197 output_asm_insn (\"crxor 6,6,6\", operands);
10199 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10200 output_asm_insn (\"creqv 6,6,6\", operands);
10202 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10204 [(set_attr "type" "branch")
10205 (set_attr "length" "4,8")])
10208 ;; A function pointer under System V is just a normal pointer
10209 ;; operands[0] is the function pointer
10210 ;; operands[1] is the stack size to clean up
10211 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10212 ;; which indicates how to set cr1
10214 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10215 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10216 (match_operand 1 "" "g,g,g,g"))
10217 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10218 (clobber (reg:SI LR_REGNO))]
10219 "DEFAULT_ABI == ABI_V4
10220 || DEFAULT_ABI == ABI_DARWIN"
10222 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10223 output_asm_insn ("crxor 6,6,6", operands);
10225 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10226 output_asm_insn ("creqv 6,6,6", operands);
10230 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10231 (set_attr "length" "4,4,8,8")])
10233 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10234 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10235 (match_operand 1 "" "g,g"))
10236 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10237 (clobber (reg:SI LR_REGNO))]
10238 "(DEFAULT_ABI == ABI_DARWIN
10239 || (DEFAULT_ABI == ABI_V4
10240 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10242 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10243 output_asm_insn ("crxor 6,6,6", operands);
10245 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10246 output_asm_insn ("creqv 6,6,6", operands);
10249 return output_call(insn, operands, 0, 2);
10251 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10253 gcc_assert (!TARGET_SECURE_PLT);
10254 return "bl %z0@plt";
10260 "DEFAULT_ABI == ABI_V4
10261 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10262 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10263 [(parallel [(call (mem:SI (match_dup 0))
10265 (use (match_dup 2))
10266 (use (match_dup 3))
10267 (clobber (reg:SI LR_REGNO))])]
10269 operands[3] = pic_offset_table_rtx;
10271 [(set_attr "type" "branch,branch")
10272 (set_attr "length" "4,8")])
10274 (define_insn "*call_nonlocal_sysv_secure<mode>"
10275 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10276 (match_operand 1 "" "g,g"))
10277 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10278 (use (match_operand:SI 3 "register_operand" "r,r"))
10279 (clobber (reg:SI LR_REGNO))]
10280 "(DEFAULT_ABI == ABI_V4
10281 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10282 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10284 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10285 output_asm_insn ("crxor 6,6,6", operands);
10287 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10288 output_asm_insn ("creqv 6,6,6", operands);
10291 /* The magic 32768 offset here and in the other sysv call insns
10292 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10293 See sysv4.h:toc_section. */
10294 return "bl %z0+32768@plt";
10296 return "bl %z0@plt";
10298 [(set_attr "type" "branch,branch")
10299 (set_attr "length" "4,8")])
10301 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10302 [(set (match_operand 0 "" "")
10303 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10304 (match_operand 2 "" "g,g,g,g")))
10305 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10306 (clobber (reg:SI LR_REGNO))]
10307 "DEFAULT_ABI == ABI_V4
10308 || DEFAULT_ABI == ABI_DARWIN"
10310 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10311 output_asm_insn ("crxor 6,6,6", operands);
10313 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10314 output_asm_insn ("creqv 6,6,6", operands);
10318 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10319 (set_attr "length" "4,4,8,8")])
10321 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10322 [(set (match_operand 0 "" "")
10323 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10324 (match_operand 2 "" "g,g")))
10325 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10326 (clobber (reg:SI LR_REGNO))]
10327 "(DEFAULT_ABI == ABI_DARWIN
10328 || (DEFAULT_ABI == ABI_V4
10329 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10331 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10332 output_asm_insn ("crxor 6,6,6", operands);
10334 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10335 output_asm_insn ("creqv 6,6,6", operands);
10338 return output_call(insn, operands, 1, 3);
10340 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10342 gcc_assert (!TARGET_SECURE_PLT);
10343 return "bl %z1@plt";
10349 "DEFAULT_ABI == ABI_V4
10350 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10351 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10352 [(parallel [(set (match_dup 0)
10353 (call (mem:SI (match_dup 1))
10355 (use (match_dup 3))
10356 (use (match_dup 4))
10357 (clobber (reg:SI LR_REGNO))])]
10359 operands[4] = pic_offset_table_rtx;
10361 [(set_attr "type" "branch,branch")
10362 (set_attr "length" "4,8")])
10364 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10365 [(set (match_operand 0 "" "")
10366 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10367 (match_operand 2 "" "g,g")))
10368 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10369 (use (match_operand:SI 4 "register_operand" "r,r"))
10370 (clobber (reg:SI LR_REGNO))]
10371 "(DEFAULT_ABI == ABI_V4
10372 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10373 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10375 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10376 output_asm_insn ("crxor 6,6,6", operands);
10378 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10379 output_asm_insn ("creqv 6,6,6", operands);
10382 return "bl %z1+32768@plt";
10384 return "bl %z1@plt";
10386 [(set_attr "type" "branch,branch")
10387 (set_attr "length" "4,8")])
10390 ;; Call to AIX abi function in the same module.
10392 (define_insn "*call_local_aix<mode>"
10393 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10394 (match_operand 1 "" "g"))
10395 (clobber (reg:P LR_REGNO))]
10396 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10398 [(set_attr "type" "branch")
10399 (set_attr "length" "4")])
10401 (define_insn "*call_value_local_aix<mode>"
10402 [(set (match_operand 0 "" "")
10403 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10404 (match_operand 2 "" "g")))
10405 (clobber (reg:P LR_REGNO))]
10406 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10408 [(set_attr "type" "branch")
10409 (set_attr "length" "4")])
10411 ;; Call to AIX abi function which may be in another module.
10412 ;; Restore the TOC pointer (r2) after the call.
10414 (define_insn "*call_nonlocal_aix<mode>"
10415 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10416 (match_operand 1 "" "g"))
10417 (clobber (reg:P LR_REGNO))]
10418 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10420 [(set_attr "type" "branch")
10421 (set_attr "length" "8")])
10423 (define_insn "*call_value_nonlocal_aix<mode>"
10424 [(set (match_operand 0 "" "")
10425 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10426 (match_operand 2 "" "g")))
10427 (clobber (reg:P LR_REGNO))]
10428 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10430 [(set_attr "type" "branch")
10431 (set_attr "length" "8")])
10433 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10434 ;; Operand0 is the addresss of the function to call
10435 ;; Operand2 is the location in the function descriptor to load r2 from
10436 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10438 (define_insn "*call_indirect_aix<mode>"
10439 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10440 (match_operand 1 "" "g,g"))
10441 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10442 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10443 (clobber (reg:P LR_REGNO))]
10444 "DEFAULT_ABI == ABI_AIX"
10445 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10446 [(set_attr "type" "jmpreg")
10447 (set_attr "length" "12")])
10449 (define_insn "*call_value_indirect_aix<mode>"
10450 [(set (match_operand 0 "" "")
10451 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10452 (match_operand 2 "" "g,g")))
10453 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10454 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10455 (clobber (reg:P LR_REGNO))]
10456 "DEFAULT_ABI == ABI_AIX"
10457 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10458 [(set_attr "type" "jmpreg")
10459 (set_attr "length" "12")])
10461 ;; Call to indirect functions with the ELFv2 ABI.
10462 ;; Operand0 is the addresss of the function to call
10463 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10465 (define_insn "*call_indirect_elfv2<mode>"
10466 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10467 (match_operand 1 "" "g,g"))
10468 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10469 (clobber (reg:P LR_REGNO))]
10470 "DEFAULT_ABI == ABI_ELFv2"
10471 "b%T0l\;<ptrload> 2,%2(1)"
10472 [(set_attr "type" "jmpreg")
10473 (set_attr "length" "8")])
10475 (define_insn "*call_value_indirect_elfv2<mode>"
10476 [(set (match_operand 0 "" "")
10477 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10478 (match_operand 2 "" "g,g")))
10479 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10480 (clobber (reg:P LR_REGNO))]
10481 "DEFAULT_ABI == ABI_ELFv2"
10482 "b%T1l\;<ptrload> 2,%3(1)"
10483 [(set_attr "type" "jmpreg")
10484 (set_attr "length" "8")])
10487 ;; Call subroutine returning any type.
10488 (define_expand "untyped_call"
10489 [(parallel [(call (match_operand 0 "" "")
10491 (match_operand 1 "" "")
10492 (match_operand 2 "" "")])]
10498 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10500 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10502 rtx set = XVECEXP (operands[2], 0, i);
10503 emit_move_insn (SET_DEST (set), SET_SRC (set));
10506 /* The optimizer does not know that the call sets the function value
10507 registers we stored in the result block. We avoid problems by
10508 claiming that all hard registers are used and clobbered at this
10510 emit_insn (gen_blockage ());
10515 ;; sibling call patterns
10516 (define_expand "sibcall"
10517 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10518 (match_operand 1 "" ""))
10519 (use (match_operand 2 "" ""))
10520 (use (reg:SI LR_REGNO))
10526 if (MACHOPIC_INDIRECT)
10527 operands[0] = machopic_indirect_call_target (operands[0]);
10530 gcc_assert (GET_CODE (operands[0]) == MEM);
10531 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10533 operands[0] = XEXP (operands[0], 0);
10535 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10537 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10542 (define_expand "sibcall_value"
10543 [(parallel [(set (match_operand 0 "register_operand" "")
10544 (call (mem:SI (match_operand 1 "address_operand" ""))
10545 (match_operand 2 "" "")))
10546 (use (match_operand 3 "" ""))
10547 (use (reg:SI LR_REGNO))
10553 if (MACHOPIC_INDIRECT)
10554 operands[1] = machopic_indirect_call_target (operands[1]);
10557 gcc_assert (GET_CODE (operands[1]) == MEM);
10558 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10560 operands[1] = XEXP (operands[1], 0);
10562 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10564 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10569 ;; this and similar patterns must be marked as using LR, otherwise
10570 ;; dataflow will try to delete the store into it. This is true
10571 ;; even when the actual reg to jump to is in CTR, when LR was
10572 ;; saved and restored around the PIC-setting BCL.
10573 (define_insn "*sibcall_local32"
10574 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10575 (match_operand 1 "" "g,g"))
10576 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10577 (use (reg:SI LR_REGNO))
10579 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10582 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10583 output_asm_insn (\"crxor 6,6,6\", operands);
10585 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10586 output_asm_insn (\"creqv 6,6,6\", operands);
10588 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10590 [(set_attr "type" "branch")
10591 (set_attr "length" "4,8")])
10593 (define_insn "*sibcall_local64"
10594 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10595 (match_operand 1 "" "g,g"))
10596 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10597 (use (reg:SI LR_REGNO))
10599 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10602 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10603 output_asm_insn (\"crxor 6,6,6\", operands);
10605 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10606 output_asm_insn (\"creqv 6,6,6\", operands);
10608 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10610 [(set_attr "type" "branch")
10611 (set_attr "length" "4,8")])
10613 (define_insn "*sibcall_value_local32"
10614 [(set (match_operand 0 "" "")
10615 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10616 (match_operand 2 "" "g,g")))
10617 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10618 (use (reg:SI LR_REGNO))
10620 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10623 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10624 output_asm_insn (\"crxor 6,6,6\", operands);
10626 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10627 output_asm_insn (\"creqv 6,6,6\", operands);
10629 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10631 [(set_attr "type" "branch")
10632 (set_attr "length" "4,8")])
10634 (define_insn "*sibcall_value_local64"
10635 [(set (match_operand 0 "" "")
10636 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10637 (match_operand 2 "" "g,g")))
10638 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10639 (use (reg:SI LR_REGNO))
10641 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10644 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10645 output_asm_insn (\"crxor 6,6,6\", operands);
10647 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10648 output_asm_insn (\"creqv 6,6,6\", operands);
10650 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10652 [(set_attr "type" "branch")
10653 (set_attr "length" "4,8")])
10655 (define_insn "*sibcall_nonlocal_sysv<mode>"
10656 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10657 (match_operand 1 "" ""))
10658 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10659 (use (reg:SI LR_REGNO))
10661 "(DEFAULT_ABI == ABI_DARWIN
10662 || DEFAULT_ABI == ABI_V4)
10663 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10666 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10667 output_asm_insn (\"crxor 6,6,6\", operands);
10669 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10670 output_asm_insn (\"creqv 6,6,6\", operands);
10672 if (which_alternative >= 2)
10674 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10676 gcc_assert (!TARGET_SECURE_PLT);
10677 return \"b %z0@plt\";
10682 [(set_attr "type" "branch")
10683 (set_attr "length" "4,8,4,8")])
10685 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10686 [(set (match_operand 0 "" "")
10687 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10688 (match_operand 2 "" "")))
10689 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10690 (use (reg:SI LR_REGNO))
10692 "(DEFAULT_ABI == ABI_DARWIN
10693 || DEFAULT_ABI == ABI_V4)
10694 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10697 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10698 output_asm_insn (\"crxor 6,6,6\", operands);
10700 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10701 output_asm_insn (\"creqv 6,6,6\", operands);
10703 if (which_alternative >= 2)
10705 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10707 gcc_assert (!TARGET_SECURE_PLT);
10708 return \"b %z1@plt\";
10713 [(set_attr "type" "branch")
10714 (set_attr "length" "4,8,4,8")])
10716 ;; AIX ABI sibling call patterns.
10718 (define_insn "*sibcall_aix<mode>"
10719 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10720 (match_operand 1 "" "g,g"))
10722 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10726 [(set_attr "type" "branch")
10727 (set_attr "length" "4")])
10729 (define_insn "*sibcall_value_aix<mode>"
10730 [(set (match_operand 0 "" "")
10731 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10732 (match_operand 2 "" "g,g")))
10734 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10738 [(set_attr "type" "branch")
10739 (set_attr "length" "4")])
10741 (define_expand "sibcall_epilogue"
10742 [(use (const_int 0))]
10745 if (!TARGET_SCHED_PROLOG)
10746 emit_insn (gen_blockage ());
10747 rs6000_emit_epilogue (TRUE);
10751 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10752 ;; all of memory. This blocks insns from being moved across this point.
10754 (define_insn "blockage"
10755 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10759 (define_expand "probe_stack_address"
10760 [(use (match_operand 0 "address_operand"))]
10763 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10764 MEM_VOLATILE_P (operands[0]) = 1;
10767 emit_insn (gen_probe_stack_di (operands[0]));
10769 emit_insn (gen_probe_stack_si (operands[0]));
10773 (define_insn "probe_stack_<mode>"
10774 [(set (match_operand:P 0 "memory_operand" "=m")
10775 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10778 operands[1] = gen_rtx_REG (Pmode, 0);
10779 return "st<wd>%U0%X0 %1,%0";
10781 [(set_attr "type" "store")
10782 (set (attr "update")
10783 (if_then_else (match_operand 0 "update_address_mem")
10784 (const_string "yes")
10785 (const_string "no")))
10786 (set (attr "indexed")
10787 (if_then_else (match_operand 0 "indexed_address_mem")
10788 (const_string "yes")
10789 (const_string "no")))
10790 (set_attr "length" "4")])
10792 (define_insn "probe_stack_range<P:mode>"
10793 [(set (match_operand:P 0 "register_operand" "=r")
10794 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10795 (match_operand:P 2 "register_operand" "r")]
10796 UNSPECV_PROBE_STACK_RANGE))]
10798 "* return output_probe_stack_range (operands[0], operands[2]);"
10799 [(set_attr "type" "three")])
10801 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
10802 ;; signed & unsigned, and one type of branch.
10804 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10805 ;; insns, and branches.
10807 (define_expand "cbranch<mode>4"
10808 [(use (match_operator 0 "rs6000_cbranch_operator"
10809 [(match_operand:GPR 1 "gpc_reg_operand" "")
10810 (match_operand:GPR 2 "reg_or_short_operand" "")]))
10811 (use (match_operand 3 ""))]
10815 /* Take care of the possibility that operands[2] might be negative but
10816 this might be a logical operation. That insn doesn't exist. */
10817 if (GET_CODE (operands[2]) == CONST_INT
10818 && INTVAL (operands[2]) < 0)
10820 operands[2] = force_reg (<MODE>mode, operands[2]);
10821 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10822 GET_MODE (operands[0]),
10823 operands[1], operands[2]);
10826 rs6000_emit_cbranch (<MODE>mode, operands);
10830 (define_expand "cbranch<mode>4"
10831 [(use (match_operator 0 "rs6000_cbranch_operator"
10832 [(match_operand:FP 1 "gpc_reg_operand" "")
10833 (match_operand:FP 2 "gpc_reg_operand" "")]))
10834 (use (match_operand 3 ""))]
10838 rs6000_emit_cbranch (<MODE>mode, operands);
10842 (define_expand "cstore<mode>4_signed"
10843 [(use (match_operator 1 "signed_comparison_operator"
10844 [(match_operand:P 2 "gpc_reg_operand")
10845 (match_operand:P 3 "gpc_reg_operand")]))
10846 (clobber (match_operand:P 0 "gpc_reg_operand"))]
10849 enum rtx_code cond_code = GET_CODE (operands[1]);
10851 rtx op0 = operands[0];
10852 rtx op1 = operands[2];
10853 rtx op2 = operands[3];
10855 if (cond_code == GE || cond_code == LT)
10857 cond_code = swap_condition (cond_code);
10858 std::swap (op1, op2);
10861 rtx tmp1 = gen_reg_rtx (<MODE>mode);
10862 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10863 rtx tmp3 = gen_reg_rtx (<MODE>mode);
10865 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10866 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10867 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10869 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10871 if (cond_code == LE)
10872 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
10875 rtx tmp4 = gen_reg_rtx (<MODE>mode);
10876 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
10877 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
10883 (define_expand "cstore<mode>4_unsigned"
10884 [(use (match_operator 1 "unsigned_comparison_operator"
10885 [(match_operand:P 2 "gpc_reg_operand")
10886 (match_operand:P 3 "reg_or_short_operand")]))
10887 (clobber (match_operand:P 0 "gpc_reg_operand"))]
10890 enum rtx_code cond_code = GET_CODE (operands[1]);
10892 rtx op0 = operands[0];
10893 rtx op1 = operands[2];
10894 rtx op2 = operands[3];
10896 if (cond_code == GEU || cond_code == LTU)
10898 cond_code = swap_condition (cond_code);
10899 std::swap (op1, op2);
10902 if (!gpc_reg_operand (op1, <MODE>mode))
10903 op1 = force_reg (<MODE>mode, op1);
10904 if (!reg_or_short_operand (op2, <MODE>mode))
10905 op2 = force_reg (<MODE>mode, op2);
10907 rtx tmp = gen_reg_rtx (<MODE>mode);
10908 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10910 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10911 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10913 if (cond_code == LEU)
10914 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10916 emit_insn (gen_neg<mode>2 (op0, tmp2));
10921 (define_expand "cstore_si_as_di"
10922 [(use (match_operator 1 "unsigned_comparison_operator"
10923 [(match_operand:SI 2 "gpc_reg_operand")
10924 (match_operand:SI 3 "reg_or_short_operand")]))
10925 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10928 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10929 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10931 operands[2] = force_reg (SImode, operands[2]);
10932 operands[3] = force_reg (SImode, operands[3]);
10933 rtx op1 = gen_reg_rtx (DImode);
10934 rtx op2 = gen_reg_rtx (DImode);
10935 convert_move (op1, operands[2], uns_flag);
10936 convert_move (op2, operands[3], uns_flag);
10938 if (cond_code == GT || cond_code == LE)
10940 cond_code = swap_condition (cond_code);
10941 std::swap (op1, op2);
10944 rtx tmp = gen_reg_rtx (DImode);
10945 rtx tmp2 = gen_reg_rtx (DImode);
10946 emit_insn (gen_subdi3 (tmp, op1, op2));
10947 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
10953 gcc_unreachable ();
10958 tmp3 = gen_reg_rtx (DImode);
10959 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
10963 convert_move (operands[0], tmp3, 1);
10968 (define_expand "cstore<mode>4_signed_imm"
10969 [(use (match_operator 1 "signed_comparison_operator"
10970 [(match_operand:GPR 2 "gpc_reg_operand")
10971 (match_operand:GPR 3 "immediate_operand")]))
10972 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10975 bool invert = false;
10977 enum rtx_code cond_code = GET_CODE (operands[1]);
10979 rtx op0 = operands[0];
10980 rtx op1 = operands[2];
10981 HOST_WIDE_INT val = INTVAL (operands[3]);
10983 if (cond_code == GE || cond_code == GT)
10985 cond_code = reverse_condition (cond_code);
10989 if (cond_code == LE)
10992 rtx tmp = gen_reg_rtx (<MODE>mode);
10993 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10994 rtx x = gen_reg_rtx (<MODE>mode);
10996 emit_insn (gen_and<mode>3 (x, op1, tmp));
10998 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11002 rtx tmp = gen_reg_rtx (<MODE>mode);
11003 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11007 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11008 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11013 (define_expand "cstore<mode>4_unsigned_imm"
11014 [(use (match_operator 1 "unsigned_comparison_operator"
11015 [(match_operand:GPR 2 "gpc_reg_operand")
11016 (match_operand:GPR 3 "immediate_operand")]))
11017 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11020 bool invert = false;
11022 enum rtx_code cond_code = GET_CODE (operands[1]);
11024 rtx op0 = operands[0];
11025 rtx op1 = operands[2];
11026 HOST_WIDE_INT val = INTVAL (operands[3]);
11028 if (cond_code == GEU || cond_code == GTU)
11030 cond_code = reverse_condition (cond_code);
11034 if (cond_code == LEU)
11037 rtx tmp = gen_reg_rtx (<MODE>mode);
11038 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11039 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11040 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11041 rtx x = gen_reg_rtx (<MODE>mode);
11043 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11045 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11049 rtx tmp = gen_reg_rtx (<MODE>mode);
11050 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11054 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11055 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11060 (define_expand "cstore<mode>4"
11061 [(use (match_operator 1 "rs6000_cbranch_operator"
11062 [(match_operand:GPR 2 "gpc_reg_operand")
11063 (match_operand:GPR 3 "reg_or_short_operand")]))
11064 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11067 /* Use ISEL if the user asked for it. */
11069 rs6000_emit_sISEL (<MODE>mode, operands);
11071 /* Expanding EQ and NE directly to some machine instructions does not help
11072 but does hurt combine. So don't. */
11073 else if (GET_CODE (operands[1]) == EQ)
11074 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11075 else if (<MODE>mode == Pmode
11076 && GET_CODE (operands[1]) == NE)
11077 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11078 else if (GET_CODE (operands[1]) == NE)
11080 rtx tmp = gen_reg_rtx (<MODE>mode);
11081 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11082 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11085 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11086 etc. combinations magically work out just right. */
11087 else if (<MODE>mode == Pmode
11088 && unsigned_comparison_operator (operands[1], VOIDmode))
11089 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11090 operands[2], operands[3]));
11092 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11093 else if (<MODE>mode == SImode && Pmode == DImode)
11094 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11095 operands[2], operands[3]));
11097 /* For signed comparisons against a constant, we can do some simple
11099 else if (signed_comparison_operator (operands[1], VOIDmode)
11100 && CONST_INT_P (operands[3]))
11101 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11102 operands[2], operands[3]));
11104 /* And similarly for unsigned comparisons. */
11105 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11106 && CONST_INT_P (operands[3]))
11107 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11108 operands[2], operands[3]));
11110 /* We also do not want to use mfcr for signed comparisons. */
11111 else if (<MODE>mode == Pmode
11112 && signed_comparison_operator (operands[1], VOIDmode))
11113 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11114 operands[2], operands[3]));
11116 /* Everything else, use the mfcr brute force. */
11118 rs6000_emit_sCOND (<MODE>mode, operands);
11123 (define_expand "cstore<mode>4"
11124 [(use (match_operator 1 "rs6000_cbranch_operator"
11125 [(match_operand:FP 2 "gpc_reg_operand")
11126 (match_operand:FP 3 "gpc_reg_operand")]))
11127 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11130 rs6000_emit_sCOND (<MODE>mode, operands);
11135 (define_expand "stack_protect_set"
11136 [(match_operand 0 "memory_operand" "")
11137 (match_operand 1 "memory_operand" "")]
11140 #ifdef TARGET_THREAD_SSP_OFFSET
11141 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11142 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11143 operands[1] = gen_rtx_MEM (Pmode, addr);
11146 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11148 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11152 (define_insn "stack_protect_setsi"
11153 [(set (match_operand:SI 0 "memory_operand" "=m")
11154 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11155 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11157 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11158 [(set_attr "type" "three")
11159 (set_attr "length" "12")])
11161 (define_insn "stack_protect_setdi"
11162 [(set (match_operand:DI 0 "memory_operand" "=Y")
11163 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11164 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11166 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11167 [(set_attr "type" "three")
11168 (set_attr "length" "12")])
11170 (define_expand "stack_protect_test"
11171 [(match_operand 0 "memory_operand" "")
11172 (match_operand 1 "memory_operand" "")
11173 (match_operand 2 "" "")]
11176 rtx test, op0, op1;
11177 #ifdef TARGET_THREAD_SSP_OFFSET
11178 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11179 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11180 operands[1] = gen_rtx_MEM (Pmode, addr);
11183 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11184 test = gen_rtx_EQ (VOIDmode, op0, op1);
11185 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11189 (define_insn "stack_protect_testsi"
11190 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11191 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11192 (match_operand:SI 2 "memory_operand" "m,m")]
11194 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11195 (clobber (match_scratch:SI 3 "=&r,&r"))]
11198 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11199 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11200 [(set_attr "length" "16,20")])
11202 (define_insn "stack_protect_testdi"
11203 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11204 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11205 (match_operand:DI 2 "memory_operand" "Y,Y")]
11207 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11208 (clobber (match_scratch:DI 3 "=&r,&r"))]
11211 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11212 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11213 [(set_attr "length" "16,20")])
11216 ;; Here are the actual compare insns.
11217 (define_insn "*cmp<mode>_signed"
11218 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11219 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11220 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11222 "cmp<wd>%I2 %0,%1,%2"
11223 [(set_attr "type" "cmp")])
11225 (define_insn "*cmp<mode>_unsigned"
11226 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11227 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11228 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11230 "cmpl<wd>%I2 %0,%1,%2"
11231 [(set_attr "type" "cmp")])
11233 ;; If we are comparing a register for equality with a large constant,
11234 ;; we can do this with an XOR followed by a compare. But this is profitable
11235 ;; only if the large constant is only used for the comparison (and in this
11236 ;; case we already have a register to reuse as scratch).
11238 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11239 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11242 [(set (match_operand:SI 0 "register_operand")
11243 (match_operand:SI 1 "logical_const_operand" ""))
11244 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11246 (match_operand:SI 2 "logical_const_operand" "")]))
11247 (set (match_operand:CC 4 "cc_reg_operand" "")
11248 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11251 (if_then_else (match_operator 6 "equality_operator"
11252 [(match_dup 4) (const_int 0)])
11253 (match_operand 7 "" "")
11254 (match_operand 8 "" "")))]
11255 "peep2_reg_dead_p (3, operands[0])
11256 && peep2_reg_dead_p (4, operands[4])
11257 && REGNO (operands[0]) != REGNO (operands[5])"
11258 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11259 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11260 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11263 /* Get the constant we are comparing against, and see what it looks like
11264 when sign-extended from 16 to 32 bits. Then see what constant we could
11265 XOR with SEXTC to get the sign-extended value. */
11266 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11268 operands[1], operands[2]);
11269 HOST_WIDE_INT c = INTVAL (cnst);
11270 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11271 HOST_WIDE_INT xorv = c ^ sextc;
11273 operands[9] = GEN_INT (xorv);
11274 operands[10] = GEN_INT (sextc);
11277 ;; The following two insns don't exist as single insns, but if we provide
11278 ;; them, we can swap an add and compare, which will enable us to overlap more
11279 ;; of the required delay between a compare and branch. We generate code for
11280 ;; them by splitting.
11283 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11284 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11285 (match_operand:SI 2 "short_cint_operand" "i")))
11286 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11287 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11290 [(set_attr "length" "8")])
11293 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11294 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11295 (match_operand:SI 2 "u_short_cint_operand" "i")))
11296 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11297 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11300 [(set_attr "length" "8")])
11303 [(set (match_operand:CC 3 "cc_reg_operand" "")
11304 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11305 (match_operand:SI 2 "short_cint_operand" "")))
11306 (set (match_operand:SI 0 "gpc_reg_operand" "")
11307 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11309 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11310 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11313 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11314 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11315 (match_operand:SI 2 "u_short_cint_operand" "")))
11316 (set (match_operand:SI 0 "gpc_reg_operand" "")
11317 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11319 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11320 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11322 ;; Only need to compare second words if first words equal
11323 (define_insn "*cmp<mode>_internal1"
11324 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11325 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11326 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11327 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11328 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11329 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11330 [(set_attr "type" "fpcompare")
11331 (set_attr "length" "12")])
11333 (define_insn_and_split "*cmp<mode>_internal2"
11334 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11335 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11336 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11337 (clobber (match_scratch:DF 3 "=d"))
11338 (clobber (match_scratch:DF 4 "=d"))
11339 (clobber (match_scratch:DF 5 "=d"))
11340 (clobber (match_scratch:DF 6 "=d"))
11341 (clobber (match_scratch:DF 7 "=d"))
11342 (clobber (match_scratch:DF 8 "=d"))
11343 (clobber (match_scratch:DF 9 "=d"))
11344 (clobber (match_scratch:DF 10 "=d"))
11345 (clobber (match_scratch:GPR 11 "=b"))]
11346 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11347 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11349 "&& reload_completed"
11350 [(set (match_dup 3) (match_dup 14))
11351 (set (match_dup 4) (match_dup 15))
11352 (set (match_dup 9) (abs:DF (match_dup 5)))
11353 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11354 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11355 (label_ref (match_dup 12))
11357 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11358 (set (pc) (label_ref (match_dup 13)))
11360 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11361 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11362 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11363 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11366 REAL_VALUE_TYPE rv;
11367 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11368 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11370 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11371 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11372 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11373 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11374 operands[12] = gen_label_rtx ();
11375 operands[13] = gen_label_rtx ();
11377 operands[14] = force_const_mem (DFmode,
11378 const_double_from_real_value (rv, DFmode));
11379 operands[15] = force_const_mem (DFmode,
11380 const_double_from_real_value (dconst0,
11385 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11386 operands[14] = gen_const_mem (DFmode, tocref);
11387 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11388 operands[15] = gen_const_mem (DFmode, tocref);
11389 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11390 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11394 ;; Now we have the scc insns. We can do some combinations because of the
11395 ;; way the machine works.
11397 ;; Note that this is probably faster if we can put an insn between the
11398 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11399 ;; cases the insns below which don't use an intermediate CR field will
11400 ;; be used instead.
11402 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11403 (match_operator:SI 1 "scc_comparison_operator"
11404 [(match_operand 2 "cc_reg_operand" "y")
11407 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11408 [(set (attr "type")
11409 (cond [(match_test "TARGET_MFCRF")
11410 (const_string "mfcrf")
11412 (const_string "mfcr")))
11413 (set_attr "length" "8")])
11415 ;; Same as above, but get the GT bit.
11416 (define_insn "move_from_CR_gt_bit"
11417 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11418 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11419 "TARGET_HARD_FLOAT && !TARGET_FPRS"
11420 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11421 [(set_attr "type" "mfcr")
11422 (set_attr "length" "8")])
11424 ;; Same as above, but get the OV/ORDERED bit.
11425 (define_insn "move_from_CR_ov_bit"
11426 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11427 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11430 "mfcr %0\;rlwinm %0,%0,%t1,1"
11431 [(set_attr "type" "mfcr")
11432 (set_attr "length" "8")])
11435 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11436 (match_operator:DI 1 "scc_comparison_operator"
11437 [(match_operand 2 "cc_reg_operand" "y")
11440 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11441 [(set (attr "type")
11442 (cond [(match_test "TARGET_MFCRF")
11443 (const_string "mfcrf")
11445 (const_string "mfcr")))
11446 (set_attr "length" "8")])
11449 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11450 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11451 [(match_operand 2 "cc_reg_operand" "y,y")
11454 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11455 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11458 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11460 [(set_attr "type" "shift")
11461 (set_attr "dot" "yes")
11462 (set_attr "length" "8,16")])
11465 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11466 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11467 [(match_operand 2 "cc_reg_operand" "")
11470 (set (match_operand:SI 3 "gpc_reg_operand" "")
11471 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11472 "TARGET_32BIT && reload_completed"
11473 [(set (match_dup 3)
11474 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11476 (compare:CC (match_dup 3)
11481 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11482 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11483 [(match_operand 2 "cc_reg_operand" "y")
11485 (match_operand:SI 3 "const_int_operand" "n")))]
11489 int is_bit = ccr_bit (operands[1], 1);
11490 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11493 if (is_bit >= put_bit)
11494 count = is_bit - put_bit;
11496 count = 32 - (put_bit - is_bit);
11498 operands[4] = GEN_INT (count);
11499 operands[5] = GEN_INT (put_bit);
11501 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11503 [(set (attr "type")
11504 (cond [(match_test "TARGET_MFCRF")
11505 (const_string "mfcrf")
11507 (const_string "mfcr")))
11508 (set_attr "length" "8")])
11511 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11513 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11514 [(match_operand 2 "cc_reg_operand" "y,y")
11516 (match_operand:SI 3 "const_int_operand" "n,n"))
11518 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11519 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11524 int is_bit = ccr_bit (operands[1], 1);
11525 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11528 /* Force split for non-cc0 compare. */
11529 if (which_alternative == 1)
11532 if (is_bit >= put_bit)
11533 count = is_bit - put_bit;
11535 count = 32 - (put_bit - is_bit);
11537 operands[5] = GEN_INT (count);
11538 operands[6] = GEN_INT (put_bit);
11540 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11542 [(set_attr "type" "shift")
11543 (set_attr "dot" "yes")
11544 (set_attr "length" "8,16")])
11547 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11549 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11550 [(match_operand 2 "cc_reg_operand" "")
11552 (match_operand:SI 3 "const_int_operand" ""))
11554 (set (match_operand:SI 4 "gpc_reg_operand" "")
11555 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11558 [(set (match_dup 4)
11559 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11562 (compare:CC (match_dup 4)
11567 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11570 (define_insn_and_split "eq<mode>3"
11571 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11572 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11573 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11574 (clobber (match_scratch:GPR 3 "=r"))
11575 (clobber (match_scratch:GPR 4 "=r"))]
11579 [(set (match_dup 4)
11580 (clz:GPR (match_dup 3)))
11582 (lshiftrt:GPR (match_dup 4)
11585 operands[3] = rs6000_emit_eqne (<MODE>mode,
11586 operands[1], operands[2], operands[3]);
11588 if (GET_CODE (operands[4]) == SCRATCH)
11589 operands[4] = gen_reg_rtx (<MODE>mode);
11591 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11593 [(set (attr "length")
11594 (if_then_else (match_test "operands[2] == const0_rtx")
11596 (const_string "12")))])
11598 (define_insn_and_split "ne<mode>3"
11599 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11600 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11601 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11602 (clobber (match_scratch:P 3 "=r"))
11603 (clobber (match_scratch:P 4 "=r"))
11604 (clobber (reg:P CA_REGNO))]
11608 [(parallel [(set (match_dup 4)
11609 (plus:P (match_dup 3)
11611 (set (reg:P CA_REGNO)
11612 (ne:P (match_dup 3)
11614 (parallel [(set (match_dup 0)
11615 (plus:P (plus:P (not:P (match_dup 4))
11618 (clobber (reg:P CA_REGNO))])]
11620 operands[3] = rs6000_emit_eqne (<MODE>mode,
11621 operands[1], operands[2], operands[3]);
11623 if (GET_CODE (operands[4]) == SCRATCH)
11624 operands[4] = gen_reg_rtx (<MODE>mode);
11626 [(set (attr "length")
11627 (if_then_else (match_test "operands[2] == const0_rtx")
11629 (const_string "12")))])
11631 (define_insn_and_split "*neg_eq_<mode>"
11632 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11633 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11634 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11635 (clobber (match_scratch:P 3 "=r"))
11636 (clobber (match_scratch:P 4 "=r"))
11637 (clobber (reg:P CA_REGNO))]
11641 [(parallel [(set (match_dup 4)
11642 (plus:P (match_dup 3)
11644 (set (reg:P CA_REGNO)
11645 (ne:P (match_dup 3)
11647 (parallel [(set (match_dup 0)
11648 (plus:P (reg:P CA_REGNO)
11650 (clobber (reg:P CA_REGNO))])]
11652 operands[3] = rs6000_emit_eqne (<MODE>mode,
11653 operands[1], operands[2], operands[3]);
11655 if (GET_CODE (operands[4]) == SCRATCH)
11656 operands[4] = gen_reg_rtx (<MODE>mode);
11658 [(set (attr "length")
11659 (if_then_else (match_test "operands[2] == const0_rtx")
11661 (const_string "12")))])
11663 (define_insn_and_split "*neg_ne_<mode>"
11664 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11665 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11666 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11667 (clobber (match_scratch:P 3 "=r"))
11668 (clobber (match_scratch:P 4 "=r"))
11669 (clobber (reg:P CA_REGNO))]
11673 [(parallel [(set (match_dup 4)
11674 (neg:P (match_dup 3)))
11675 (set (reg:P CA_REGNO)
11676 (eq:P (match_dup 3)
11678 (parallel [(set (match_dup 0)
11679 (plus:P (reg:P CA_REGNO)
11681 (clobber (reg:P CA_REGNO))])]
11683 operands[3] = rs6000_emit_eqne (<MODE>mode,
11684 operands[1], operands[2], operands[3]);
11686 if (GET_CODE (operands[4]) == SCRATCH)
11687 operands[4] = gen_reg_rtx (<MODE>mode);
11689 [(set (attr "length")
11690 (if_then_else (match_test "operands[2] == const0_rtx")
11692 (const_string "12")))])
11694 (define_insn_and_split "*plus_eq_<mode>"
11695 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11696 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11697 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11698 (match_operand:P 3 "gpc_reg_operand" "r")))
11699 (clobber (match_scratch:P 4 "=r"))
11700 (clobber (match_scratch:P 5 "=r"))
11701 (clobber (reg:P CA_REGNO))]
11705 [(parallel [(set (match_dup 5)
11706 (neg:P (match_dup 4)))
11707 (set (reg:P CA_REGNO)
11708 (eq:P (match_dup 4)
11710 (parallel [(set (match_dup 0)
11711 (plus:P (match_dup 3)
11713 (clobber (reg:P CA_REGNO))])]
11715 operands[4] = rs6000_emit_eqne (<MODE>mode,
11716 operands[1], operands[2], operands[4]);
11718 if (GET_CODE (operands[5]) == SCRATCH)
11719 operands[5] = gen_reg_rtx (<MODE>mode);
11721 [(set (attr "length")
11722 (if_then_else (match_test "operands[2] == const0_rtx")
11724 (const_string "12")))])
11726 (define_insn_and_split "*plus_ne_<mode>"
11727 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11728 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11729 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11730 (match_operand:P 3 "gpc_reg_operand" "r")))
11731 (clobber (match_scratch:P 4 "=r"))
11732 (clobber (match_scratch:P 5 "=r"))
11733 (clobber (reg:P CA_REGNO))]
11737 [(parallel [(set (match_dup 5)
11738 (plus:P (match_dup 4)
11740 (set (reg:P CA_REGNO)
11741 (ne:P (match_dup 4)
11743 (parallel [(set (match_dup 0)
11744 (plus:P (match_dup 3)
11746 (clobber (reg:P CA_REGNO))])]
11748 operands[4] = rs6000_emit_eqne (<MODE>mode,
11749 operands[1], operands[2], operands[4]);
11751 if (GET_CODE (operands[5]) == SCRATCH)
11752 operands[5] = gen_reg_rtx (<MODE>mode);
11754 [(set (attr "length")
11755 (if_then_else (match_test "operands[2] == const0_rtx")
11757 (const_string "12")))])
11759 (define_insn_and_split "*minus_eq_<mode>"
11760 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11761 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11762 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11763 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11764 (clobber (match_scratch:P 4 "=r"))
11765 (clobber (match_scratch:P 5 "=r"))
11766 (clobber (reg:P CA_REGNO))]
11770 [(parallel [(set (match_dup 5)
11771 (plus:P (match_dup 4)
11773 (set (reg:P CA_REGNO)
11774 (ne:P (match_dup 4)
11776 (parallel [(set (match_dup 0)
11777 (plus:P (plus:P (match_dup 3)
11780 (clobber (reg:P CA_REGNO))])]
11782 operands[4] = rs6000_emit_eqne (<MODE>mode,
11783 operands[1], operands[2], operands[4]);
11785 if (GET_CODE (operands[5]) == SCRATCH)
11786 operands[5] = gen_reg_rtx (<MODE>mode);
11788 [(set (attr "length")
11789 (if_then_else (match_test "operands[2] == const0_rtx")
11791 (const_string "12")))])
11793 (define_insn_and_split "*minus_ne_<mode>"
11794 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11795 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11796 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11797 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11798 (clobber (match_scratch:P 4 "=r"))
11799 (clobber (match_scratch:P 5 "=r"))
11800 (clobber (reg:P CA_REGNO))]
11804 [(parallel [(set (match_dup 5)
11805 (neg:P (match_dup 4)))
11806 (set (reg:P CA_REGNO)
11807 (eq:P (match_dup 4)
11809 (parallel [(set (match_dup 0)
11810 (plus:P (plus:P (match_dup 3)
11813 (clobber (reg:P CA_REGNO))])]
11815 operands[4] = rs6000_emit_eqne (<MODE>mode,
11816 operands[1], operands[2], operands[4]);
11818 if (GET_CODE (operands[5]) == SCRATCH)
11819 operands[5] = gen_reg_rtx (<MODE>mode);
11821 [(set (attr "length")
11822 (if_then_else (match_test "operands[2] == const0_rtx")
11824 (const_string "12")))])
11826 (define_insn_and_split "*eqsi3_ext<mode>"
11827 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11828 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11829 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11830 (clobber (match_scratch:SI 3 "=r"))
11831 (clobber (match_scratch:SI 4 "=r"))]
11835 [(set (match_dup 4)
11836 (clz:SI (match_dup 3)))
11839 (lshiftrt:SI (match_dup 4)
11842 operands[3] = rs6000_emit_eqne (SImode,
11843 operands[1], operands[2], operands[3]);
11845 if (GET_CODE (operands[4]) == SCRATCH)
11846 operands[4] = gen_reg_rtx (SImode);
11848 [(set (attr "length")
11849 (if_then_else (match_test "operands[2] == const0_rtx")
11851 (const_string "12")))])
11853 (define_insn_and_split "*nesi3_ext<mode>"
11854 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11855 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11856 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11857 (clobber (match_scratch:SI 3 "=r"))
11858 (clobber (match_scratch:SI 4 "=r"))
11859 (clobber (match_scratch:EXTSI 5 "=r"))]
11863 [(set (match_dup 4)
11864 (clz:SI (match_dup 3)))
11867 (lshiftrt:SI (match_dup 4)
11870 (xor:EXTSI (match_dup 5)
11873 operands[3] = rs6000_emit_eqne (SImode,
11874 operands[1], operands[2], operands[3]);
11876 if (GET_CODE (operands[4]) == SCRATCH)
11877 operands[4] = gen_reg_rtx (SImode);
11878 if (GET_CODE (operands[5]) == SCRATCH)
11879 operands[5] = gen_reg_rtx (<MODE>mode);
11881 [(set (attr "length")
11882 (if_then_else (match_test "operands[2] == const0_rtx")
11883 (const_string "12")
11884 (const_string "16")))])
11886 ;; Define both directions of branch and return. If we need a reload
11887 ;; register, we'd rather use CR0 since it is much easier to copy a
11888 ;; register CC value to there.
11892 (if_then_else (match_operator 1 "branch_comparison_operator"
11894 "cc_reg_operand" "y")
11896 (label_ref (match_operand 0 "" ""))
11901 return output_cbranch (operands[1], \"%l0\", 0, insn);
11903 [(set_attr "type" "branch")])
11907 (if_then_else (match_operator 0 "branch_comparison_operator"
11909 "cc_reg_operand" "y")
11916 return output_cbranch (operands[0], NULL, 0, insn);
11918 [(set_attr "type" "jmpreg")
11919 (set_attr "length" "4")])
11923 (if_then_else (match_operator 1 "branch_comparison_operator"
11925 "cc_reg_operand" "y")
11928 (label_ref (match_operand 0 "" ""))))]
11932 return output_cbranch (operands[1], \"%l0\", 1, insn);
11934 [(set_attr "type" "branch")])
11938 (if_then_else (match_operator 0 "branch_comparison_operator"
11940 "cc_reg_operand" "y")
11947 return output_cbranch (operands[0], NULL, 1, insn);
11949 [(set_attr "type" "jmpreg")
11950 (set_attr "length" "4")])
11952 ;; Logic on condition register values.
11954 ; This pattern matches things like
11955 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11956 ; (eq:SI (reg:CCFP 68) (const_int 0)))
11958 ; which are generated by the branch logic.
11959 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11961 (define_insn "*cceq_ior_compare"
11962 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11963 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11964 [(match_operator:SI 2
11965 "branch_positive_comparison_operator"
11967 "cc_reg_operand" "y,y")
11969 (match_operator:SI 4
11970 "branch_positive_comparison_operator"
11972 "cc_reg_operand" "0,y")
11976 "cr%q1 %E0,%j2,%j4"
11977 [(set_attr "type" "cr_logical,delayed_cr")])
11979 ; Why is the constant -1 here, but 1 in the previous pattern?
11980 ; Because ~1 has all but the low bit set.
11982 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11983 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11984 [(not:SI (match_operator:SI 2
11985 "branch_positive_comparison_operator"
11987 "cc_reg_operand" "y,y")
11989 (match_operator:SI 4
11990 "branch_positive_comparison_operator"
11992 "cc_reg_operand" "0,y")
11996 "cr%q1 %E0,%j2,%j4"
11997 [(set_attr "type" "cr_logical,delayed_cr")])
11999 (define_insn "*cceq_rev_compare"
12000 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12001 (compare:CCEQ (match_operator:SI 1
12002 "branch_positive_comparison_operator"
12004 "cc_reg_operand" "0,y")
12009 [(set_attr "type" "cr_logical,delayed_cr")])
12011 ;; If we are comparing the result of two comparisons, this can be done
12012 ;; using creqv or crxor.
12014 (define_insn_and_split ""
12015 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12016 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12017 [(match_operand 2 "cc_reg_operand" "y")
12019 (match_operator 3 "branch_comparison_operator"
12020 [(match_operand 4 "cc_reg_operand" "y")
12025 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12029 int positive_1, positive_2;
12031 positive_1 = branch_positive_comparison_operator (operands[1],
12032 GET_MODE (operands[1]));
12033 positive_2 = branch_positive_comparison_operator (operands[3],
12034 GET_MODE (operands[3]));
12037 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12038 GET_CODE (operands[1])),
12040 operands[2], const0_rtx);
12041 else if (GET_MODE (operands[1]) != SImode)
12042 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12043 operands[2], const0_rtx);
12046 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12047 GET_CODE (operands[3])),
12049 operands[4], const0_rtx);
12050 else if (GET_MODE (operands[3]) != SImode)
12051 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12052 operands[4], const0_rtx);
12054 if (positive_1 == positive_2)
12056 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12057 operands[5] = constm1_rtx;
12061 operands[5] = const1_rtx;
12065 ;; Unconditional branch and return.
12067 (define_insn "jump"
12069 (label_ref (match_operand 0 "" "")))]
12072 [(set_attr "type" "branch")])
12074 (define_insn "<return_str>return"
12078 [(set_attr "type" "jmpreg")])
12080 (define_expand "indirect_jump"
12081 [(set (pc) (match_operand 0 "register_operand" ""))])
12083 (define_insn "*indirect_jump<mode>"
12084 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12089 [(set_attr "type" "jmpreg")])
12091 ;; Table jump for switch statements:
12092 (define_expand "tablejump"
12093 [(use (match_operand 0 "" ""))
12094 (use (label_ref (match_operand 1 "" "")))]
12099 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12101 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12105 (define_expand "tablejumpsi"
12106 [(set (match_dup 3)
12107 (plus:SI (match_operand:SI 0 "" "")
12109 (parallel [(set (pc) (match_dup 3))
12110 (use (label_ref (match_operand 1 "" "")))])]
12113 { operands[0] = force_reg (SImode, operands[0]);
12114 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12115 operands[3] = gen_reg_rtx (SImode);
12118 (define_expand "tablejumpdi"
12119 [(set (match_dup 4)
12120 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12122 (plus:DI (match_dup 4)
12124 (parallel [(set (pc) (match_dup 3))
12125 (use (label_ref (match_operand 1 "" "")))])]
12128 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12129 operands[3] = gen_reg_rtx (DImode);
12130 operands[4] = gen_reg_rtx (DImode);
12133 (define_insn "*tablejump<mode>_internal1"
12135 (match_operand:P 0 "register_operand" "c,*l"))
12136 (use (label_ref (match_operand 1 "" "")))]
12141 [(set_attr "type" "jmpreg")])
12144 [(unspec [(const_int 0)] UNSPEC_NOP)]
12148 (define_insn "group_ending_nop"
12149 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12153 if (rs6000_cpu_attr == CPU_POWER6)
12154 return \"ori 1,1,0\";
12155 return \"ori 2,2,0\";
12158 ;; Define the subtract-one-and-jump insns, starting with the template
12159 ;; so loop.c knows what to generate.
12161 (define_expand "doloop_end"
12162 [(use (match_operand 0 "" "")) ; loop pseudo
12163 (use (match_operand 1 "" ""))] ; label
12169 if (GET_MODE (operands[0]) != DImode)
12171 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12175 if (GET_MODE (operands[0]) != SImode)
12177 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12182 (define_expand "ctr<mode>"
12183 [(parallel [(set (pc)
12184 (if_then_else (ne (match_operand:P 0 "register_operand" "")
12186 (label_ref (match_operand 1 "" ""))
12189 (plus:P (match_dup 0)
12191 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12192 (clobber (match_scratch:CC 2 ""))
12193 (clobber (match_scratch:P 3 ""))])]
12197 ;; We need to be able to do this for any operand, including MEM, or we
12198 ;; will cause reload to blow up since we don't allow output reloads on
12200 ;; For the length attribute to be calculated correctly, the
12201 ;; label MUST be operand 0.
12202 ;; The UNSPEC is present to prevent combine creating this pattern.
12204 (define_insn "*ctr<mode>_internal1"
12206 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12208 (label_ref (match_operand 0 "" ""))
12210 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12211 (plus:P (match_dup 1)
12213 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12214 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12215 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12219 if (which_alternative != 0)
12221 else if (get_attr_length (insn) == 4)
12222 return \"bdnz %l0\";
12224 return \"bdz $+8\;b %l0\";
12226 [(set_attr "type" "branch")
12227 (set_attr "length" "*,16,20,20")])
12229 (define_insn "*ctr<mode>_internal2"
12231 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12234 (label_ref (match_operand 0 "" ""))))
12235 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12236 (plus:P (match_dup 1)
12238 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12239 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12240 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12244 if (which_alternative != 0)
12246 else if (get_attr_length (insn) == 4)
12247 return \"bdz %l0\";
12249 return \"bdnz $+8\;b %l0\";
12251 [(set_attr "type" "branch")
12252 (set_attr "length" "*,16,20,20")])
12254 ;; Similar but use EQ
12256 (define_insn "*ctr<mode>_internal5"
12258 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12260 (label_ref (match_operand 0 "" ""))
12262 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12263 (plus:P (match_dup 1)
12265 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12266 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12267 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12271 if (which_alternative != 0)
12273 else if (get_attr_length (insn) == 4)
12274 return \"bdz %l0\";
12276 return \"bdnz $+8\;b %l0\";
12278 [(set_attr "type" "branch")
12279 (set_attr "length" "*,16,20,20")])
12281 (define_insn "*ctr<mode>_internal6"
12283 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12286 (label_ref (match_operand 0 "" ""))))
12287 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12288 (plus:P (match_dup 1)
12290 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12291 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12292 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12296 if (which_alternative != 0)
12298 else if (get_attr_length (insn) == 4)
12299 return \"bdnz %l0\";
12301 return \"bdz $+8\;b %l0\";
12303 [(set_attr "type" "branch")
12304 (set_attr "length" "*,16,20,20")])
12306 ;; Now the splitters if we could not allocate the CTR register
12310 (if_then_else (match_operator 2 "comparison_operator"
12311 [(match_operand:P 1 "gpc_reg_operand" "")
12313 (match_operand 5 "" "")
12314 (match_operand 6 "" "")))
12315 (set (match_operand:P 0 "int_reg_operand" "")
12316 (plus:P (match_dup 1) (const_int -1)))
12317 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12318 (clobber (match_scratch:CC 3 ""))
12319 (clobber (match_scratch:P 4 ""))]
12321 [(set (match_dup 3)
12322 (compare:CC (match_dup 1)
12325 (plus:P (match_dup 1)
12327 (set (pc) (if_then_else (match_dup 7)
12331 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12332 operands[3], const0_rtx); }")
12336 (if_then_else (match_operator 2 "comparison_operator"
12337 [(match_operand:P 1 "gpc_reg_operand" "")
12339 (match_operand 5 "" "")
12340 (match_operand 6 "" "")))
12341 (set (match_operand:P 0 "nonimmediate_operand" "")
12342 (plus:P (match_dup 1) (const_int -1)))
12343 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12344 (clobber (match_scratch:CC 3 ""))
12345 (clobber (match_scratch:P 4 ""))]
12346 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12347 [(set (match_dup 3)
12348 (compare:CC (match_dup 1)
12351 (plus:P (match_dup 1)
12355 (set (pc) (if_then_else (match_dup 7)
12359 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12360 operands[3], const0_rtx); }")
12362 (define_insn "trap"
12363 [(trap_if (const_int 1) (const_int 0))]
12366 [(set_attr "type" "trap")])
12368 (define_expand "ctrap<mode>4"
12369 [(trap_if (match_operator 0 "ordered_comparison_operator"
12370 [(match_operand:GPR 1 "register_operand")
12371 (match_operand:GPR 2 "reg_or_short_operand")])
12372 (match_operand 3 "zero_constant" ""))]
12377 [(trap_if (match_operator 0 "ordered_comparison_operator"
12378 [(match_operand:GPR 1 "register_operand" "r")
12379 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12382 "t<wd>%V0%I2 %1,%2"
12383 [(set_attr "type" "trap")])
12385 ;; Insns related to generating the function prologue and epilogue.
12387 (define_expand "prologue"
12388 [(use (const_int 0))]
12391 rs6000_emit_prologue ();
12392 if (!TARGET_SCHED_PROLOG)
12393 emit_insn (gen_blockage ());
12397 (define_insn "*movesi_from_cr_one"
12398 [(match_parallel 0 "mfcr_operation"
12399 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12400 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12401 (match_operand 3 "immediate_operand" "n")]
12402 UNSPEC_MOVESI_FROM_CR))])]
12408 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12410 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12411 operands[4] = GEN_INT (mask);
12412 output_asm_insn (\"mfcr %1,%4\", operands);
12416 [(set_attr "type" "mfcrf")])
12418 (define_insn "movesi_from_cr"
12419 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12420 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12421 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12422 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12423 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12424 UNSPEC_MOVESI_FROM_CR))]
12427 [(set_attr "type" "mfcr")])
12429 (define_insn "*crsave"
12430 [(match_parallel 0 "crsave_operation"
12431 [(set (match_operand:SI 1 "memory_operand" "=m")
12432 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12435 [(set_attr "type" "store")])
12437 (define_insn "*stmw"
12438 [(match_parallel 0 "stmw_operation"
12439 [(set (match_operand:SI 1 "memory_operand" "=m")
12440 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12443 [(set_attr "type" "store")
12444 (set_attr "update" "yes")
12445 (set_attr "indexed" "yes")])
12447 ; The following comment applies to:
12451 ; return_and_restore_gpregs*
12452 ; return_and_restore_fpregs*
12453 ; return_and_restore_fpregs_aix*
12455 ; The out-of-line save / restore functions expects one input argument.
12456 ; Since those are not standard call_insn's, we must avoid using
12457 ; MATCH_OPERAND for that argument. That way the register rename
12458 ; optimization will not try to rename this register.
12459 ; Each pattern is repeated for each possible register number used in
12460 ; various ABIs (r11, r1, and for some functions r12)
12462 (define_insn "*save_gpregs_<mode>_r11"
12463 [(match_parallel 0 "any_parallel_operand"
12464 [(clobber (reg:P 65))
12465 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12467 (set (match_operand:P 2 "memory_operand" "=m")
12468 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12471 [(set_attr "type" "branch")
12472 (set_attr "length" "4")])
12474 (define_insn "*save_gpregs_<mode>_r12"
12475 [(match_parallel 0 "any_parallel_operand"
12476 [(clobber (reg:P 65))
12477 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12479 (set (match_operand:P 2 "memory_operand" "=m")
12480 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12483 [(set_attr "type" "branch")
12484 (set_attr "length" "4")])
12486 (define_insn "*save_gpregs_<mode>_r1"
12487 [(match_parallel 0 "any_parallel_operand"
12488 [(clobber (reg:P 65))
12489 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12491 (set (match_operand:P 2 "memory_operand" "=m")
12492 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12495 [(set_attr "type" "branch")
12496 (set_attr "length" "4")])
12498 (define_insn "*save_fpregs_<mode>_r11"
12499 [(match_parallel 0 "any_parallel_operand"
12500 [(clobber (reg:P 65))
12501 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12503 (set (match_operand:DF 2 "memory_operand" "=m")
12504 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12507 [(set_attr "type" "branch")
12508 (set_attr "length" "4")])
12510 (define_insn "*save_fpregs_<mode>_r12"
12511 [(match_parallel 0 "any_parallel_operand"
12512 [(clobber (reg:P 65))
12513 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12515 (set (match_operand:DF 2 "memory_operand" "=m")
12516 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12519 [(set_attr "type" "branch")
12520 (set_attr "length" "4")])
12522 (define_insn "*save_fpregs_<mode>_r1"
12523 [(match_parallel 0 "any_parallel_operand"
12524 [(clobber (reg:P 65))
12525 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12527 (set (match_operand:DF 2 "memory_operand" "=m")
12528 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12531 [(set_attr "type" "branch")
12532 (set_attr "length" "4")])
12534 ; This is to explain that changes to the stack pointer should
12535 ; not be moved over loads from or stores to stack memory.
12536 (define_insn "stack_tie"
12537 [(match_parallel 0 "tie_operand"
12538 [(set (mem:BLK (reg 1)) (const_int 0))])]
12541 [(set_attr "length" "0")])
12543 (define_expand "epilogue"
12544 [(use (const_int 0))]
12547 if (!TARGET_SCHED_PROLOG)
12548 emit_insn (gen_blockage ());
12549 rs6000_emit_epilogue (FALSE);
12553 ; On some processors, doing the mtcrf one CC register at a time is
12554 ; faster (like on the 604e). On others, doing them all at once is
12555 ; faster; for instance, on the 601 and 750.
12557 (define_expand "movsi_to_cr_one"
12558 [(set (match_operand:CC 0 "cc_reg_operand" "")
12559 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12560 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12562 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12564 (define_insn "*movsi_to_cr"
12565 [(match_parallel 0 "mtcrf_operation"
12566 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12567 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12568 (match_operand 3 "immediate_operand" "n")]
12569 UNSPEC_MOVESI_TO_CR))])]
12575 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12576 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12577 operands[4] = GEN_INT (mask);
12578 return \"mtcrf %4,%2\";
12580 [(set_attr "type" "mtcr")])
12582 (define_insn "*mtcrfsi"
12583 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12584 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12585 (match_operand 2 "immediate_operand" "n")]
12586 UNSPEC_MOVESI_TO_CR))]
12587 "GET_CODE (operands[0]) == REG
12588 && CR_REGNO_P (REGNO (operands[0]))
12589 && GET_CODE (operands[2]) == CONST_INT
12590 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12592 [(set_attr "type" "mtcr")])
12594 ; The load-multiple instructions have similar properties.
12595 ; Note that "load_multiple" is a name known to the machine-independent
12596 ; code that actually corresponds to the PowerPC load-string.
12598 (define_insn "*lmw"
12599 [(match_parallel 0 "lmw_operation"
12600 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12601 (match_operand:SI 2 "memory_operand" "m"))])]
12604 [(set_attr "type" "load")
12605 (set_attr "update" "yes")
12606 (set_attr "indexed" "yes")
12607 (set_attr "cell_micro" "always")])
12609 (define_insn "*return_internal_<mode>"
12611 (use (match_operand:P 0 "register_operand" "lc"))]
12614 [(set_attr "type" "jmpreg")])
12616 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12617 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
12619 ; The following comment applies to:
12623 ; return_and_restore_gpregs*
12624 ; return_and_restore_fpregs*
12625 ; return_and_restore_fpregs_aix*
12627 ; The out-of-line save / restore functions expects one input argument.
12628 ; Since those are not standard call_insn's, we must avoid using
12629 ; MATCH_OPERAND for that argument. That way the register rename
12630 ; optimization will not try to rename this register.
12631 ; Each pattern is repeated for each possible register number used in
12632 ; various ABIs (r11, r1, and for some functions r12)
12634 (define_insn "*restore_gpregs_<mode>_r11"
12635 [(match_parallel 0 "any_parallel_operand"
12636 [(clobber (match_operand:P 1 "register_operand" "=l"))
12637 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12639 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12640 (match_operand:P 4 "memory_operand" "m"))])]
12643 [(set_attr "type" "branch")
12644 (set_attr "length" "4")])
12646 (define_insn "*restore_gpregs_<mode>_r12"
12647 [(match_parallel 0 "any_parallel_operand"
12648 [(clobber (match_operand:P 1 "register_operand" "=l"))
12649 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12651 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12652 (match_operand:P 4 "memory_operand" "m"))])]
12655 [(set_attr "type" "branch")
12656 (set_attr "length" "4")])
12658 (define_insn "*restore_gpregs_<mode>_r1"
12659 [(match_parallel 0 "any_parallel_operand"
12660 [(clobber (match_operand:P 1 "register_operand" "=l"))
12661 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12663 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12664 (match_operand:P 4 "memory_operand" "m"))])]
12667 [(set_attr "type" "branch")
12668 (set_attr "length" "4")])
12670 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12671 [(match_parallel 0 "any_parallel_operand"
12673 (clobber (match_operand:P 1 "register_operand" "=l"))
12674 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12676 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12677 (match_operand:P 4 "memory_operand" "m"))])]
12680 [(set_attr "type" "branch")
12681 (set_attr "length" "4")])
12683 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12684 [(match_parallel 0 "any_parallel_operand"
12686 (clobber (match_operand:P 1 "register_operand" "=l"))
12687 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12689 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12690 (match_operand:P 4 "memory_operand" "m"))])]
12693 [(set_attr "type" "branch")
12694 (set_attr "length" "4")])
12696 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12697 [(match_parallel 0 "any_parallel_operand"
12699 (clobber (match_operand:P 1 "register_operand" "=l"))
12700 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12702 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12703 (match_operand:P 4 "memory_operand" "m"))])]
12706 [(set_attr "type" "branch")
12707 (set_attr "length" "4")])
12709 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12710 [(match_parallel 0 "any_parallel_operand"
12712 (clobber (match_operand:P 1 "register_operand" "=l"))
12713 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12715 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12716 (match_operand:DF 4 "memory_operand" "m"))])]
12719 [(set_attr "type" "branch")
12720 (set_attr "length" "4")])
12722 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12723 [(match_parallel 0 "any_parallel_operand"
12725 (clobber (match_operand:P 1 "register_operand" "=l"))
12726 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12728 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12729 (match_operand:DF 4 "memory_operand" "m"))])]
12732 [(set_attr "type" "branch")
12733 (set_attr "length" "4")])
12735 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12736 [(match_parallel 0 "any_parallel_operand"
12738 (clobber (match_operand:P 1 "register_operand" "=l"))
12739 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12741 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12742 (match_operand:DF 4 "memory_operand" "m"))])]
12745 [(set_attr "type" "branch")
12746 (set_attr "length" "4")])
12748 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12749 [(match_parallel 0 "any_parallel_operand"
12751 (use (match_operand:P 1 "register_operand" "l"))
12752 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12754 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12755 (match_operand:DF 4 "memory_operand" "m"))])]
12758 [(set_attr "type" "branch")
12759 (set_attr "length" "4")])
12761 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12762 [(match_parallel 0 "any_parallel_operand"
12764 (use (match_operand:P 1 "register_operand" "l"))
12765 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12767 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12768 (match_operand:DF 4 "memory_operand" "m"))])]
12771 [(set_attr "type" "branch")
12772 (set_attr "length" "4")])
12774 ; This is used in compiling the unwind routines.
12775 (define_expand "eh_return"
12776 [(use (match_operand 0 "general_operand" ""))]
12781 emit_insn (gen_eh_set_lr_si (operands[0]));
12783 emit_insn (gen_eh_set_lr_di (operands[0]));
12787 ; We can't expand this before we know where the link register is stored.
12788 (define_insn "eh_set_lr_<mode>"
12789 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12791 (clobber (match_scratch:P 1 "=&b"))]
12796 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12797 (clobber (match_scratch 1 ""))]
12802 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12806 (define_insn "prefetch"
12807 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12808 (match_operand:SI 1 "const_int_operand" "n")
12809 (match_operand:SI 2 "const_int_operand" "n"))]
12813 if (GET_CODE (operands[0]) == REG)
12814 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12815 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12817 [(set_attr "type" "load")])
12819 ;; Handle -fsplit-stack.
12821 (define_expand "split_stack_prologue"
12825 rs6000_expand_split_stack_prologue ();
12829 (define_expand "load_split_stack_limit"
12830 [(set (match_operand 0)
12831 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12834 emit_insn (gen_rtx_SET (operands[0],
12835 gen_rtx_UNSPEC (Pmode,
12836 gen_rtvec (1, const0_rtx),
12837 UNSPEC_STACK_CHECK)));
12841 (define_insn "load_split_stack_limit_di"
12842 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12843 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12845 "ld %0,-0x7040(13)"
12846 [(set_attr "type" "load")
12847 (set_attr "update" "no")
12848 (set_attr "indexed" "no")])
12850 (define_insn "load_split_stack_limit_si"
12851 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12852 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12854 "lwz %0,-0x7020(2)"
12855 [(set_attr "type" "load")
12856 (set_attr "update" "no")
12857 (set_attr "indexed" "no")])
12859 ;; A return instruction which the middle-end doesn't see.
12860 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
12861 ;; after the call to __morestack.
12862 (define_insn "split_stack_return"
12863 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
12866 [(set_attr "type" "jmpreg")])
12868 ;; If there are operand 0 bytes available on the stack, jump to
12870 (define_expand "split_stack_space_check"
12871 [(set (match_dup 2)
12872 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12874 (minus (reg STACK_POINTER_REGNUM)
12875 (match_operand 0)))
12876 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12877 (set (pc) (if_then_else
12878 (geu (match_dup 4) (const_int 0))
12879 (label_ref (match_operand 1))
12883 rs6000_split_stack_space_check (operands[0], operands[1]);
12887 (define_insn "bpermd_<mode>"
12888 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12889 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12890 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12893 [(set_attr "type" "popcnt")])
12896 ;; Builtin fma support. Handle
12897 ;; Note that the conditions for expansion are in the FMA_F iterator.
12899 (define_expand "fma<mode>4"
12900 [(set (match_operand:FMA_F 0 "register_operand" "")
12902 (match_operand:FMA_F 1 "register_operand" "")
12903 (match_operand:FMA_F 2 "register_operand" "")
12904 (match_operand:FMA_F 3 "register_operand" "")))]
12908 (define_insn "*fma<mode>4_fpr"
12909 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12911 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12912 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12913 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12914 "TARGET_<MODE>_FPR"
12916 fmadd<Ftrad> %0,%1,%2,%3
12917 xsmadda<Fvsx> %x0,%x1,%x2
12918 xsmaddm<Fvsx> %x0,%x1,%x3"
12919 [(set_attr "type" "fp")
12920 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12922 ; Altivec only has fma and nfms.
12923 (define_expand "fms<mode>4"
12924 [(set (match_operand:FMA_F 0 "register_operand" "")
12926 (match_operand:FMA_F 1 "register_operand" "")
12927 (match_operand:FMA_F 2 "register_operand" "")
12928 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12929 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12932 (define_insn "*fms<mode>4_fpr"
12933 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12935 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12936 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12937 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12938 "TARGET_<MODE>_FPR"
12940 fmsub<Ftrad> %0,%1,%2,%3
12941 xsmsuba<Fvsx> %x0,%x1,%x2
12942 xsmsubm<Fvsx> %x0,%x1,%x3"
12943 [(set_attr "type" "fp")
12944 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12946 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12947 (define_expand "fnma<mode>4"
12948 [(set (match_operand:FMA_F 0 "register_operand" "")
12951 (match_operand:FMA_F 1 "register_operand" "")
12952 (match_operand:FMA_F 2 "register_operand" "")
12953 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12954 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12957 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12958 (define_expand "fnms<mode>4"
12959 [(set (match_operand:FMA_F 0 "register_operand" "")
12962 (match_operand:FMA_F 1 "register_operand" "")
12963 (match_operand:FMA_F 2 "register_operand" "")
12964 (match_operand:FMA_F 3 "register_operand" ""))))]
12965 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12968 ; Not an official optab name, but used from builtins.
12969 (define_expand "nfma<mode>4"
12970 [(set (match_operand:FMA_F 0 "register_operand" "")
12973 (match_operand:FMA_F 1 "register_operand" "")
12974 (match_operand:FMA_F 2 "register_operand" "")
12975 (match_operand:FMA_F 3 "register_operand" ""))))]
12976 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12979 (define_insn "*nfma<mode>4_fpr"
12980 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12983 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12984 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12985 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12986 "TARGET_<MODE>_FPR"
12988 fnmadd<Ftrad> %0,%1,%2,%3
12989 xsnmadda<Fvsx> %x0,%x1,%x2
12990 xsnmaddm<Fvsx> %x0,%x1,%x3"
12991 [(set_attr "type" "fp")
12992 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12994 ; Not an official optab name, but used from builtins.
12995 (define_expand "nfms<mode>4"
12996 [(set (match_operand:FMA_F 0 "register_operand" "")
12999 (match_operand:FMA_F 1 "register_operand" "")
13000 (match_operand:FMA_F 2 "register_operand" "")
13001 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13005 (define_insn "*nfmssf4_fpr"
13006 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13009 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13010 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13012 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13013 "TARGET_<MODE>_FPR"
13015 fnmsub<Ftrad> %0,%1,%2,%3
13016 xsnmsuba<Fvsx> %x0,%x1,%x2
13017 xsnmsubm<Fvsx> %x0,%x1,%x3"
13018 [(set_attr "type" "fp")
13019 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13022 (define_expand "rs6000_get_timebase"
13023 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13026 if (TARGET_POWERPC64)
13027 emit_insn (gen_rs6000_mftb_di (operands[0]));
13029 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13033 (define_insn "rs6000_get_timebase_ppc32"
13034 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13035 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13036 (clobber (match_scratch:SI 1 "=r"))
13037 (clobber (match_scratch:CC 2 "=y"))]
13038 "!TARGET_POWERPC64"
13040 if (WORDS_BIG_ENDIAN)
13043 return "mfspr %0,269\;"
13051 return "mftbu %0\;"
13060 return "mfspr %L0,269\;"
13068 return "mftbu %L0\;"
13075 [(set_attr "length" "20")])
13077 (define_insn "rs6000_mftb_<mode>"
13078 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13079 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13083 return "mfspr %0,268";
13089 (define_insn "rs6000_mffs"
13090 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13091 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13092 "TARGET_HARD_FLOAT && TARGET_FPRS"
13095 (define_insn "rs6000_mtfsf"
13096 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13097 (match_operand:DF 1 "gpc_reg_operand" "d")]
13099 "TARGET_HARD_FLOAT && TARGET_FPRS"
13103 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13104 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13105 ;; register that is being loaded. The fused ops must be physically adjacent.
13107 ;; There are two parts to addis fusion. The support for fused TOCs occur
13108 ;; before register allocation, and is meant to reduce the lifetime for the
13109 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13110 ;; to use the register that is being load. The peephole2 then gathers any
13111 ;; other fused possibilities that it can find after register allocation. If
13112 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13114 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13115 ;; before register allocation, so that we can avoid allocating a temporary base
13116 ;; register that won't be used, and that we try to load into base registers,
13117 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13118 ;; (addis followed by load) even on power8.
13121 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13122 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13123 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13124 [(parallel [(set (match_dup 0) (match_dup 2))
13125 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13126 (use (match_dup 3))
13127 (clobber (scratch:DI))])]
13129 operands[2] = fusion_wrap_memory_address (operands[1]);
13130 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13133 (define_insn "*toc_fusionload_<mode>"
13134 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13135 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13136 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13137 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13138 (clobber (match_scratch:DI 3 "=X,&b"))]
13139 "TARGET_TOC_FUSION_INT"
13141 if (base_reg_operand (operands[0], <MODE>mode))
13142 return emit_fusion_gpr_load (operands[0], operands[1]);
13144 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13146 [(set_attr "type" "load")
13147 (set_attr "length" "8")])
13149 (define_insn "*toc_fusionload_di"
13150 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13151 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13152 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13153 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13154 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13155 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13156 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13158 if (base_reg_operand (operands[0], DImode))
13159 return emit_fusion_gpr_load (operands[0], operands[1]);
13161 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13163 [(set_attr "type" "load")
13164 (set_attr "length" "8")])
13167 ;; Find cases where the addis that feeds into a load instruction is either used
13168 ;; once or is the same as the target register, and replace it with the fusion
13172 [(set (match_operand:P 0 "base_reg_operand" "")
13173 (match_operand:P 1 "fusion_gpr_addis" ""))
13174 (set (match_operand:INT1 2 "base_reg_operand" "")
13175 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13177 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13181 expand_fusion_gpr_load (operands);
13185 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13188 (define_insn "fusion_gpr_load_<mode>"
13189 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13190 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13191 UNSPEC_FUSION_GPR))]
13194 return emit_fusion_gpr_load (operands[0], operands[1]);
13196 [(set_attr "type" "load")
13197 (set_attr "length" "8")])
13200 ;; ISA 3.0 (power9) fusion support
13201 ;; Merge addis with floating load/store to FPRs (or GPRs).
13203 [(set (match_operand:P 0 "base_reg_operand" "")
13204 (match_operand:P 1 "fusion_gpr_addis" ""))
13205 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13206 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13207 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13208 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13211 expand_fusion_p9_load (operands);
13216 [(set (match_operand:P 0 "base_reg_operand" "")
13217 (match_operand:P 1 "fusion_gpr_addis" ""))
13218 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13219 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13220 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13221 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13224 expand_fusion_p9_store (operands);
13229 [(set (match_operand:SDI 0 "int_reg_operand" "")
13230 (match_operand:SDI 1 "upper16_cint_operand" ""))
13232 (ior:SDI (match_dup 0)
13233 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13235 [(set (match_dup 0)
13236 (unspec:SDI [(match_dup 1)
13237 (match_dup 2)] UNSPEC_FUSION_P9))])
13240 [(set (match_operand:SDI 0 "int_reg_operand" "")
13241 (match_operand:SDI 1 "upper16_cint_operand" ""))
13242 (set (match_operand:SDI 2 "int_reg_operand" "")
13243 (ior:SDI (match_dup 0)
13244 (match_operand:SDI 3 "u_short_cint_operand" "")))]
13246 && !rtx_equal_p (operands[0], operands[2])
13247 && peep2_reg_dead_p (2, operands[0])"
13248 [(set (match_dup 2)
13249 (unspec:SDI [(match_dup 1)
13250 (match_dup 3)] UNSPEC_FUSION_P9))])
13252 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13253 ;; reload). Because we want to eventually have secondary_reload generate
13254 ;; these, they have to have a single alternative that gives the register
13255 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13256 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13257 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13259 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13261 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13264 /* This insn is a secondary reload insn, which cannot have alternatives.
13265 If we are not loading up register 0, use the power8 fusion instead. */
13266 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13267 return emit_fusion_gpr_load (operands[0], operands[1]);
13269 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13271 [(set_attr "type" "load")
13272 (set_attr "length" "8")])
13274 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13275 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13277 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13279 (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
13282 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13284 [(set_attr "type" "store")
13285 (set_attr "length" "8")])
13287 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
13288 [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
13290 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13292 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13295 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13297 [(set_attr "type" "fpload")
13298 (set_attr "length" "8")])
13300 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
13301 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13303 [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
13305 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13308 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13310 [(set_attr "type" "fpstore")
13311 (set_attr "length" "8")])
13313 (define_insn "*fusion_p9_<mode>_constant"
13314 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13315 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13316 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13317 UNSPEC_FUSION_P9))]
13320 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13321 return "ori %0,%0,%2";
13323 [(set_attr "type" "two")
13324 (set_attr "length" "8")])
13327 ;; Miscellaneous ISA 2.06 (power7) instructions
13328 (define_insn "addg6s"
13329 [(set (match_operand:SI 0 "register_operand" "=r")
13330 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13331 (match_operand:SI 2 "register_operand" "r")]
13335 [(set_attr "type" "integer")
13336 (set_attr "length" "4")])
13338 (define_insn "cdtbcd"
13339 [(set (match_operand:SI 0 "register_operand" "=r")
13340 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13344 [(set_attr "type" "integer")
13345 (set_attr "length" "4")])
13347 (define_insn "cbcdtd"
13348 [(set (match_operand:SI 0 "register_operand" "=r")
13349 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13353 [(set_attr "type" "integer")
13354 (set_attr "length" "4")])
13356 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13361 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13362 (UNSPEC_DIVEO "eo")
13363 (UNSPEC_DIVEU "eu")
13364 (UNSPEC_DIVEUO "euo")])
13366 (define_insn "div<div_extend>_<mode>"
13367 [(set (match_operand:GPR 0 "register_operand" "=r")
13368 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13369 (match_operand:GPR 2 "register_operand" "r")]
13370 UNSPEC_DIV_EXTEND))]
13372 "div<wd><div_extend> %0,%1,%2"
13373 [(set_attr "type" "div")
13374 (set_attr "size" "<bits>")])
13377 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13379 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13380 (define_mode_attr FP128_64 [(TF "DF")
13385 (define_expand "unpack<mode>"
13386 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13388 [(match_operand:FMOVE128 1 "register_operand" "")
13389 (match_operand:QI 2 "const_0_to_1_operand" "")]
13390 UNSPEC_UNPACK_128BIT))]
13391 "FLOAT128_2REG_P (<MODE>mode)"
13394 (define_insn_and_split "unpack<mode>_dm"
13395 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13397 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13398 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13399 UNSPEC_UNPACK_128BIT))]
13400 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13402 "&& reload_completed"
13403 [(set (match_dup 0) (match_dup 3))]
13405 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13407 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13409 emit_note (NOTE_INSN_DELETED);
13413 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13415 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13416 (set_attr "length" "4")])
13418 (define_insn_and_split "unpack<mode>_nodm"
13419 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13421 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13422 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13423 UNSPEC_UNPACK_128BIT))]
13424 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13426 "&& reload_completed"
13427 [(set (match_dup 0) (match_dup 3))]
13429 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13431 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13433 emit_note (NOTE_INSN_DELETED);
13437 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13439 [(set_attr "type" "fp,fpstore")
13440 (set_attr "length" "4")])
13442 (define_insn_and_split "pack<mode>"
13443 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13445 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13446 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13447 UNSPEC_PACK_128BIT))]
13448 "FLOAT128_2REG_P (<MODE>mode)"
13452 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13453 [(set (match_dup 3) (match_dup 1))
13454 (set (match_dup 4) (match_dup 2))]
13456 unsigned dest_hi = REGNO (operands[0]);
13457 unsigned dest_lo = dest_hi + 1;
13459 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13460 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13462 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13463 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13465 [(set_attr "type" "fpsimple,fp")
13466 (set_attr "length" "4,8")])
13468 (define_insn "unpack<mode>"
13469 [(set (match_operand:DI 0 "register_operand" "=d,d")
13470 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13471 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13472 UNSPEC_UNPACK_128BIT))]
13473 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13475 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13476 return ASM_COMMENT_START " xxpermdi to same register";
13478 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13479 return "xxpermdi %x0,%x1,%x1,%3";
13481 [(set_attr "type" "vecperm")])
13483 (define_insn "pack<mode>"
13484 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13485 (unspec:FMOVE128_VSX
13486 [(match_operand:DI 1 "register_operand" "d")
13487 (match_operand:DI 2 "register_operand" "d")]
13488 UNSPEC_PACK_128BIT))]
13490 "xxpermdi %x0,%x1,%x2,0"
13491 [(set_attr "type" "vecperm")])
13495 ;; ISA 2.08 IEEE 128-bit floating point support.
13497 (define_insn "add<mode>3"
13498 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13500 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13501 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13502 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13504 [(set_attr "type" "vecfloat")
13505 (set_attr "size" "128")])
13507 (define_insn "sub<mode>3"
13508 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13510 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13511 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13512 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13514 [(set_attr "type" "vecfloat")
13515 (set_attr "size" "128")])
13517 (define_insn "mul<mode>3"
13518 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13520 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13521 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13522 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13524 [(set_attr "type" "vecfloat")
13525 (set_attr "size" "128")])
13527 (define_insn "div<mode>3"
13528 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13530 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13531 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13532 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13534 [(set_attr "type" "vecdiv")
13535 (set_attr "size" "128")])
13537 (define_insn "sqrt<mode>2"
13538 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13540 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13541 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13543 [(set_attr "type" "vecdiv")
13544 (set_attr "size" "128")])
13546 (define_expand "copysign<mode>3"
13547 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13548 (use (match_operand:IEEE128 1 "altivec_register_operand"))
13549 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13550 "FLOAT128_IEEE_P (<MODE>mode)"
13552 if (TARGET_FLOAT128_HW)
13553 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13557 rtx tmp = gen_reg_rtx (<MODE>mode);
13558 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13559 operands[2], tmp));
13564 (define_insn "copysign<mode>3_hard"
13565 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13567 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13568 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13570 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13571 "xscpsgnqp %0,%2,%1"
13572 [(set_attr "type" "vecmove")
13573 (set_attr "size" "128")])
13575 (define_insn "copysign<mode>3_soft"
13576 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13578 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13579 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13580 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
13582 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13583 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13584 [(set_attr "type" "veccomplex")
13585 (set_attr "length" "8")])
13587 (define_insn "neg<mode>2_hw"
13588 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13590 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13591 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13593 [(set_attr "type" "vecmove")
13594 (set_attr "size" "128")])
13597 (define_insn "abs<mode>2_hw"
13598 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13600 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13601 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13603 [(set_attr "type" "vecmove")
13604 (set_attr "size" "128")])
13607 (define_insn "*nabs<mode>2_hw"
13608 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13611 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13612 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13614 [(set_attr "type" "vecmove")
13615 (set_attr "size" "128")])
13617 ;; Initially don't worry about doing fusion
13618 (define_insn "*fma<mode>4_hw"
13619 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13621 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13622 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13623 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13624 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13625 "xsmaddqp %0,%1,%2"
13626 [(set_attr "type" "vecfloat")
13627 (set_attr "size" "128")])
13629 (define_insn "*fms<mode>4_hw"
13630 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13632 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13633 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13635 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13636 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13637 "xsmsubqp %0,%1,%2"
13638 [(set_attr "type" "vecfloat")
13639 (set_attr "size" "128")])
13641 (define_insn "*nfma<mode>4_hw"
13642 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13645 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13646 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13647 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13648 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13649 "xsnmaddqp %0,%1,%2"
13650 [(set_attr "type" "vecfloat")
13651 (set_attr "size" "128")])
13653 (define_insn "*nfms<mode>4_hw"
13654 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13657 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13658 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13660 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13661 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13662 "xsnmsubqp %0,%1,%2"
13663 [(set_attr "type" "vecfloat")
13664 (set_attr "size" "128")])
13666 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13667 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13668 (float_extend:IEEE128
13669 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13670 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13672 [(set_attr "type" "vecfloat")
13673 (set_attr "size" "128")])
13675 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13676 ;; point is a simple copy.
13677 (define_insn_and_split "extendkftf2"
13678 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13679 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13680 "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13684 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13687 emit_note (NOTE_INSN_DELETED);
13690 [(set_attr "type" "*,veclogical")
13691 (set_attr "length" "0,4")])
13693 (define_insn_and_split "trunctfkf2"
13694 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13695 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13696 "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13700 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13703 emit_note (NOTE_INSN_DELETED);
13706 [(set_attr "type" "*,veclogical")
13707 (set_attr "length" "0,4")])
13709 (define_insn "trunc<mode>df2_hw"
13710 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13712 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13713 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13715 [(set_attr "type" "vecfloat")
13716 (set_attr "size" "128")])
13718 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13719 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13721 (define_insn_and_split "trunc<mode>sf2_hw"
13722 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13724 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13725 (clobber (match_scratch:DF 2 "=v"))]
13726 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13729 [(set (match_dup 2)
13730 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13732 (float_truncate:SF (match_dup 2)))]
13734 if (GET_CODE (operands[2]) == SCRATCH)
13735 operands[2] = gen_reg_rtx (DFmode);
13737 [(set_attr "type" "vecfloat")
13738 (set_attr "length" "8")])
13740 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13741 ;; allowed in the traditional floating point registers. Use V2DImode so that
13742 ;; we can get a value in an Altivec register.
13744 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13745 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13746 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13747 (clobber (match_scratch:V2DI 2 "=v,v"))]
13748 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13753 convert_float128_to_int (operands, <CODE>);
13756 [(set_attr "length" "8")
13757 (set_attr "type" "mftgpr,fpstore")])
13759 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13760 [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13761 (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13762 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13763 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13768 convert_float128_to_int (operands, <CODE>);
13771 [(set_attr "length" "8")
13772 (set_attr "type" "mftgpr,vecsimple,fpstore")])
13774 (define_insn_and_split "float<uns>_<mode>si2_hw"
13775 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13776 (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13777 (clobber (match_scratch:V2DI 2 "=v,v"))]
13778 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13783 convert_int_to_float128 (operands, <CODE>);
13786 [(set_attr "length" "8")
13787 (set_attr "type" "vecfloat")])
13789 (define_insn_and_split "float<uns>_<mode>di2_hw"
13790 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13791 (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13792 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13793 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13798 convert_int_to_float128 (operands, <CODE>);
13801 [(set_attr "length" "8")
13802 (set_attr "type" "vecfloat")])
13804 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13805 (define_insn "*xscvqp<su>wz_<mode>"
13806 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13809 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13810 UNSPEC_IEEE128_CONVERT))]
13811 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13812 "xscvqp<su>wz %0,%1"
13813 [(set_attr "type" "vecfloat")
13814 (set_attr "size" "128")])
13816 (define_insn "*xscvqp<su>dz_<mode>"
13817 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13820 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13821 UNSPEC_IEEE128_CONVERT))]
13822 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13823 "xscvqp<su>dz %0,%1"
13824 [(set_attr "type" "vecfloat")
13825 (set_attr "size" "128")])
13827 (define_insn "*xscv<su>dqp_<mode>"
13828 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13830 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13831 UNSPEC_IEEE128_CONVERT)))]
13832 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13833 "xscv<su>dqp %0,%1"
13834 [(set_attr "type" "vecfloat")
13835 (set_attr "size" "128")])
13837 (define_insn "*ieee128_mfvsrd_64bit"
13838 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13839 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13840 UNSPEC_IEEE128_MOVE))]
13841 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13846 [(set_attr "type" "mftgpr,fpstore,veclogical")])
13849 (define_insn "*ieee128_mfvsrd_32bit"
13850 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13851 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13852 UNSPEC_IEEE128_MOVE))]
13853 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13857 [(set_attr "type" "fpstore,veclogical")])
13859 (define_insn "*ieee128_mfvsrwz"
13860 [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13861 (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13862 UNSPEC_IEEE128_MOVE))]
13863 "TARGET_FLOAT128_HW"
13867 [(set_attr "type" "mftgpr,fpstore")])
13869 ;; 0 says do sign-extension, 1 says zero-extension
13870 (define_insn "*ieee128_mtvsrw"
13871 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13872 (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13873 (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13874 UNSPEC_IEEE128_MOVE))]
13875 "TARGET_FLOAT128_HW"
13881 [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13884 (define_insn "*ieee128_mtvsrd_64bit"
13885 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13886 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13887 UNSPEC_IEEE128_MOVE))]
13888 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13893 [(set_attr "type" "mffgpr,fpload,veclogical")])
13895 (define_insn "*ieee128_mtvsrd_32bit"
13896 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
13897 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
13898 UNSPEC_IEEE128_MOVE))]
13899 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13903 [(set_attr "type" "fpload,veclogical")])
13905 ;; IEEE 128-bit instructions with round to odd semantics
13906 (define_insn "*trunc<mode>df2_odd"
13907 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13908 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13909 UNSPEC_ROUND_TO_ODD))]
13910 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13912 [(set_attr "type" "vecfloat")
13913 (set_attr "size" "128")])
13915 ;; IEEE 128-bit comparisons
13916 (define_insn "*cmp<mode>_hw"
13917 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13918 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13919 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13920 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13921 "xscmpuqp %0,%1,%2"
13922 [(set_attr "type" "veccmp")
13923 (set_attr "size" "128")])
13927 (include "sync.md")
13928 (include "vector.md")
13930 (include "altivec.md")
13933 (include "paired.md")
13934 (include "crypto.md")