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 "wY") (SD "wn")])
450 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
451 (define_mode_attr f32_li2 [(SF "lxssp %0,%1") (SD "lfiwzx %0,%y1")])
452 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
454 ; Definitions for store from 32-bit fpr register
455 (define_mode_attr f32_sr [(SF "f") (SD "wx")])
456 (define_mode_attr f32_sr2 [(SF "wb") (SD "wn")])
457 (define_mode_attr f32_sm [(SF "m") (SD "Z")])
458 (define_mode_attr f32_sm2 [(SF "wY") (SD "wn")])
459 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
460 (define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")])
461 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "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.
4326 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4327 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4329 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4330 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4331 (match_operand 2 "gpc_reg_operand" "")))]
4332 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4333 && can_create_pseudo_p () && flag_finite_math_only
4334 && !flag_trapping_math && flag_reciprocal_math"
4337 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4341 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4342 ;; appropriate fixup.
4343 (define_expand "rsqrt<mode>2"
4344 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4345 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4346 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4348 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4352 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4353 ;; modes here, and also add in conditional vsx/power8-vector support to access
4354 ;; values in the traditional Altivec registers if the appropriate
4355 ;; -mupper-regs-{df,sf} option is enabled.
4357 (define_expand "abs<mode>2"
4358 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4359 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4360 "TARGET_<MODE>_INSN"
4363 (define_insn "*abs<mode>2_fpr"
4364 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4365 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4370 [(set_attr "type" "fpsimple")
4371 (set_attr "fp_type" "fp_addsub_<Fs>")])
4373 (define_insn "*nabs<mode>2_fpr"
4374 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4377 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4382 [(set_attr "type" "fpsimple")
4383 (set_attr "fp_type" "fp_addsub_<Fs>")])
4385 (define_expand "neg<mode>2"
4386 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4387 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4388 "TARGET_<MODE>_INSN"
4391 (define_insn "*neg<mode>2_fpr"
4392 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4393 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4398 [(set_attr "type" "fpsimple")
4399 (set_attr "fp_type" "fp_addsub_<Fs>")])
4401 (define_expand "add<mode>3"
4402 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4403 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4404 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4405 "TARGET_<MODE>_INSN"
4408 (define_insn "*add<mode>3_fpr"
4409 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4410 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4411 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4414 fadd<Ftrad> %0,%1,%2
4415 xsadd<Fvsx> %x0,%x1,%x2"
4416 [(set_attr "type" "fp")
4417 (set_attr "fp_type" "fp_addsub_<Fs>")])
4419 (define_expand "sub<mode>3"
4420 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4421 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4422 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4423 "TARGET_<MODE>_INSN"
4426 (define_insn "*sub<mode>3_fpr"
4427 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4428 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4429 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4432 fsub<Ftrad> %0,%1,%2
4433 xssub<Fvsx> %x0,%x1,%x2"
4434 [(set_attr "type" "fp")
4435 (set_attr "fp_type" "fp_addsub_<Fs>")])
4437 (define_expand "mul<mode>3"
4438 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4439 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4440 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4441 "TARGET_<MODE>_INSN"
4444 (define_insn "*mul<mode>3_fpr"
4445 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4446 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4447 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4450 fmul<Ftrad> %0,%1,%2
4451 xsmul<Fvsx> %x0,%x1,%x2"
4452 [(set_attr "type" "dmul")
4453 (set_attr "fp_type" "fp_mul_<Fs>")])
4455 (define_expand "div<mode>3"
4456 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4457 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4458 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4459 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4462 (define_insn "*div<mode>3_fpr"
4463 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4464 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4465 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4466 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4468 fdiv<Ftrad> %0,%1,%2
4469 xsdiv<Fvsx> %x0,%x1,%x2"
4470 [(set_attr "type" "<Fs>div")
4471 (set_attr "fp_type" "fp_div_<Fs>")])
4473 (define_insn "*sqrt<mode>2_internal"
4474 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4475 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4476 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4477 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4480 xssqrt<Fvsx> %x0,%x1"
4481 [(set_attr "type" "<Fs>sqrt")
4482 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4484 (define_expand "sqrt<mode>2"
4485 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4486 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4487 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4488 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4490 if (<MODE>mode == SFmode
4491 && TARGET_RECIP_PRECISION
4492 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4493 && !optimize_function_for_size_p (cfun)
4494 && flag_finite_math_only && !flag_trapping_math
4495 && flag_unsafe_math_optimizations)
4497 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4502 ;; Floating point reciprocal approximation
4503 (define_insn "fre<Fs>"
4504 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4505 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4511 [(set_attr "type" "fp")])
4513 (define_insn "*rsqrt<mode>2"
4514 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4515 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4517 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4519 frsqrte<Ftrad> %0,%1
4520 xsrsqrte<Fvsx> %x0,%x1"
4521 [(set_attr "type" "fp")])
4523 ;; Floating point comparisons
4524 (define_insn "*cmp<mode>_fpr"
4525 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4526 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4527 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4531 xscmpudp %0,%x1,%x2"
4532 [(set_attr "type" "fpcompare")])
4534 ;; Floating point conversions
4535 (define_expand "extendsfdf2"
4536 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4537 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4538 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4541 (define_insn_and_split "*extendsfdf2_fpr"
4542 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4543 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4544 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4550 xscpsgndp %x0,%x1,%x1
4553 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4556 emit_note (NOTE_INSN_DELETED);
4559 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4561 (define_expand "truncdfsf2"
4562 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4563 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4564 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4567 (define_insn "*truncdfsf2_fpr"
4568 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4569 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4570 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4574 [(set_attr "type" "fp")])
4576 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4577 ;; builtins.c and optabs.c that are not correct for IBM long double
4578 ;; when little-endian.
4579 (define_expand "signbit<mode>2"
4581 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4583 (subreg:DI (match_dup 2) 0))
4586 (set (match_operand:SI 0 "gpc_reg_operand" "")
4589 && (TARGET_FPRS || TARGET_E500_DOUBLE)
4590 && (!FLOAT128_IEEE_P (<MODE>mode)
4591 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4593 if (FLOAT128_IEEE_P (<MODE>mode))
4595 if (<MODE>mode == KFmode)
4596 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4597 else if (<MODE>mode == TFmode)
4598 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4603 operands[2] = gen_reg_rtx (DFmode);
4604 operands[3] = gen_reg_rtx (DImode);
4605 if (TARGET_POWERPC64)
4607 operands[4] = gen_reg_rtx (DImode);
4608 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4609 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4610 WORDS_BIG_ENDIAN ? 4 : 0);
4614 operands[4] = gen_reg_rtx (SImode);
4615 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4616 WORDS_BIG_ENDIAN ? 0 : 4);
4617 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4621 (define_expand "copysign<mode>3"
4623 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4625 (neg:SFDF (abs:SFDF (match_dup 1))))
4626 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4627 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4631 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4632 && ((TARGET_PPC_GFXOPT
4633 && !HONOR_NANS (<MODE>mode)
4634 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4636 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4638 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4640 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4645 operands[3] = gen_reg_rtx (<MODE>mode);
4646 operands[4] = gen_reg_rtx (<MODE>mode);
4647 operands[5] = CONST0_RTX (<MODE>mode);
4650 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4652 (define_insn_and_split "signbit<mode>2_dm"
4653 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4655 [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,m,r")]
4657 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4659 "&& reload_completed"
4662 rs6000_split_signbit (operands[0], operands[1]);
4665 [(set_attr "length" "8,8,12")
4666 (set_attr "type" "mftgpr,load,integer")])
4668 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4669 ;; point types, which makes normal SUBREG's problematical. Instead use a
4670 ;; special pattern to avoid using a normal movdi.
4671 (define_insn "signbit<mode>2_dm2"
4672 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4673 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
4676 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4678 [(set_attr "type" "mftgpr")])
4681 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4682 ;; compiler from optimizing -0.0
4683 (define_insn "copysign<mode>3_fcpsgn"
4684 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4685 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4686 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4688 "TARGET_<MODE>_FPR && TARGET_CMPB"
4691 xscpsgndp %x0,%x2,%x1"
4692 [(set_attr "type" "fpsimple")])
4694 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4695 ;; fsel instruction and some auxiliary computations. Then we just have a
4696 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4698 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4699 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4700 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4701 ;; define_splits to make them if made by combine. On VSX machines we have the
4702 ;; min/max instructions.
4704 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4705 ;; to allow either DF/SF to use only traditional registers.
4707 (define_expand "s<minmax><mode>3"
4708 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4709 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4710 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4711 "TARGET_MINMAX_<MODE>"
4713 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4717 (define_insn "*s<minmax><mode>3_vsx"
4718 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4719 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4720 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4721 "TARGET_VSX && TARGET_<MODE>_FPR"
4723 return (TARGET_P9_MINMAX
4724 ? "xs<minmax>cdp %x0,%x1,%x2"
4725 : "xs<minmax>dp %x0,%x1,%x2");
4727 [(set_attr "type" "fp")])
4729 ;; The conditional move instructions allow us to perform max and min operations
4730 ;; even when we don't have the appropriate max/min instruction using the FSEL
4733 (define_insn_and_split "*s<minmax><mode>3_fpr"
4734 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4735 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4736 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4737 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4742 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4746 (define_expand "mov<mode>cc"
4747 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4748 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4749 (match_operand:GPR 2 "gpc_reg_operand" "")
4750 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4754 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4760 ;; We use the BASE_REGS for the isel input operands because, if rA is
4761 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4762 ;; because we may switch the operands and rB may end up being rA.
4764 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4765 ;; leave out the mode in operand 4 and use one pattern, but reload can
4766 ;; change the mode underneath our feet and then gets confused trying
4767 ;; to reload the value.
4768 (define_insn "isel_signed_<mode>"
4769 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4771 (match_operator 1 "scc_comparison_operator"
4772 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4774 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4775 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4778 { return output_isel (operands); }"
4779 [(set_attr "type" "isel")
4780 (set_attr "length" "4")])
4782 (define_insn "isel_unsigned_<mode>"
4783 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4785 (match_operator 1 "scc_comparison_operator"
4786 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4788 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4789 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4792 { return output_isel (operands); }"
4793 [(set_attr "type" "isel")
4794 (set_attr "length" "4")])
4796 ;; These patterns can be useful for combine; they let combine know that
4797 ;; isel can handle reversed comparisons so long as the operands are
4800 (define_insn "*isel_reversed_signed_<mode>"
4801 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4803 (match_operator 1 "scc_rev_comparison_operator"
4804 [(match_operand:CC 4 "cc_reg_operand" "y")
4806 (match_operand:GPR 2 "gpc_reg_operand" "b")
4807 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4810 { return output_isel (operands); }"
4811 [(set_attr "type" "isel")
4812 (set_attr "length" "4")])
4814 (define_insn "*isel_reversed_unsigned_<mode>"
4815 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4817 (match_operator 1 "scc_rev_comparison_operator"
4818 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4820 (match_operand:GPR 2 "gpc_reg_operand" "b")
4821 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4824 { return output_isel (operands); }"
4825 [(set_attr "type" "isel")
4826 (set_attr "length" "4")])
4828 ;; Floating point conditional move
4829 (define_expand "mov<mode>cc"
4830 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4831 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4832 (match_operand:SFDF 2 "gpc_reg_operand" "")
4833 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4834 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4837 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4843 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4844 [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4846 (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4847 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4848 (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4849 (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4850 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4852 [(set_attr "type" "fp")])
4854 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4855 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4857 (match_operator:CCFP 1 "fpmask_comparison_operator"
4858 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4859 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4860 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4861 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4862 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4867 (if_then_else:V2DI (match_dup 1)
4871 (if_then_else:SFDF (ne (match_dup 6)
4876 if (GET_CODE (operands[6]) == SCRATCH)
4877 operands[6] = gen_reg_rtx (V2DImode);
4879 operands[7] = CONSTM1_RTX (V2DImode);
4880 operands[8] = CONST0_RTX (V2DImode);
4882 [(set_attr "length" "8")
4883 (set_attr "type" "vecperm")])
4885 ;; Handle inverting the fpmask comparisons.
4886 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
4887 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4889 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
4890 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4891 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4892 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4893 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4894 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4899 (if_then_else:V2DI (match_dup 9)
4903 (if_then_else:SFDF (ne (match_dup 6)
4908 rtx op1 = operands[1];
4909 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
4911 if (GET_CODE (operands[6]) == SCRATCH)
4912 operands[6] = gen_reg_rtx (V2DImode);
4914 operands[7] = CONSTM1_RTX (V2DImode);
4915 operands[8] = CONST0_RTX (V2DImode);
4917 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
4919 [(set_attr "length" "8")
4920 (set_attr "type" "vecperm")])
4922 (define_insn "*fpmask<mode>"
4923 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
4925 (match_operator:CCFP 1 "fpmask_comparison_operator"
4926 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
4927 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
4928 (match_operand:V2DI 4 "all_ones_constant" "")
4929 (match_operand:V2DI 5 "zero_constant" "")))]
4931 "xscmp%V1dp %x0,%x2,%x3"
4932 [(set_attr "type" "fpcompare")])
4934 (define_insn "*xxsel<mode>"
4935 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4936 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
4937 (match_operand:V2DI 2 "zero_constant" ""))
4938 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
4939 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
4941 "xxsel %x0,%x4,%x3,%x1"
4942 [(set_attr "type" "vecmove")])
4945 ;; Conversions to and from floating-point.
4947 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4948 ; don't want to support putting SImode in FPR registers.
4949 (define_insn "lfiwax"
4950 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4951 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4953 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4958 [(set_attr "type" "fpload,fpload,mffgpr")])
4960 ; This split must be run before register allocation because it allocates the
4961 ; memory slot that is needed to move values to/from the FPR. We don't allocate
4962 ; it earlier to allow for the combiner to merge insns together where it might
4963 ; not be needed and also in case the insns are deleted as dead code.
4965 (define_insn_and_split "floatsi<mode>2_lfiwax"
4966 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4967 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4968 (clobber (match_scratch:DI 2 "=wi"))]
4969 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4970 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4976 rtx dest = operands[0];
4977 rtx src = operands[1];
4980 if (!MEM_P (src) && TARGET_POWERPC64
4981 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4982 tmp = convert_to_mode (DImode, src, false);
4986 if (GET_CODE (tmp) == SCRATCH)
4987 tmp = gen_reg_rtx (DImode);
4990 src = rs6000_address_for_fpconvert (src);
4991 emit_insn (gen_lfiwax (tmp, src));
4995 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4996 emit_move_insn (stack, src);
4997 emit_insn (gen_lfiwax (tmp, stack));
5000 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5003 [(set_attr "length" "12")
5004 (set_attr "type" "fpload")])
5006 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5007 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5010 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5011 (clobber (match_scratch:DI 2 "=wi"))]
5012 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5019 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5020 if (GET_CODE (operands[2]) == SCRATCH)
5021 operands[2] = gen_reg_rtx (DImode);
5022 emit_insn (gen_lfiwax (operands[2], operands[1]));
5023 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5026 [(set_attr "length" "8")
5027 (set_attr "type" "fpload")])
5029 (define_insn "lfiwzx"
5030 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
5031 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
5033 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5038 [(set_attr "type" "fpload,fpload,mftgpr")])
5040 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5041 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5042 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5043 (clobber (match_scratch:DI 2 "=wi"))]
5044 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5051 rtx dest = operands[0];
5052 rtx src = operands[1];
5055 if (!MEM_P (src) && TARGET_POWERPC64
5056 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5057 tmp = convert_to_mode (DImode, src, true);
5061 if (GET_CODE (tmp) == SCRATCH)
5062 tmp = gen_reg_rtx (DImode);
5065 src = rs6000_address_for_fpconvert (src);
5066 emit_insn (gen_lfiwzx (tmp, src));
5070 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5071 emit_move_insn (stack, src);
5072 emit_insn (gen_lfiwzx (tmp, stack));
5075 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5078 [(set_attr "length" "12")
5079 (set_attr "type" "fpload")])
5081 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5082 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5083 (unsigned_float:SFDF
5085 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5086 (clobber (match_scratch:DI 2 "=wi"))]
5087 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5094 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5095 if (GET_CODE (operands[2]) == SCRATCH)
5096 operands[2] = gen_reg_rtx (DImode);
5097 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5098 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5101 [(set_attr "length" "8")
5102 (set_attr "type" "fpload")])
5104 ; For each of these conversions, there is a define_expand, a define_insn
5105 ; with a '#' template, and a define_split (with C code). The idea is
5106 ; to allow constant folding with the template of the define_insn,
5107 ; then to have the insns split later (between sched1 and final).
5109 (define_expand "floatsidf2"
5110 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5111 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5114 (clobber (match_dup 4))
5115 (clobber (match_dup 5))
5116 (clobber (match_dup 6))])]
5118 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5121 if (TARGET_E500_DOUBLE)
5123 if (!REG_P (operands[1]))
5124 operands[1] = force_reg (SImode, operands[1]);
5125 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5128 else if (TARGET_LFIWAX && TARGET_FCFID)
5130 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5133 else if (TARGET_FCFID)
5135 rtx dreg = operands[1];
5137 dreg = force_reg (SImode, dreg);
5138 dreg = convert_to_mode (DImode, dreg, false);
5139 emit_insn (gen_floatdidf2 (operands[0], dreg));
5143 if (!REG_P (operands[1]))
5144 operands[1] = force_reg (SImode, operands[1]);
5145 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5146 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5147 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5148 operands[5] = gen_reg_rtx (DFmode);
5149 operands[6] = gen_reg_rtx (SImode);
5152 (define_insn_and_split "*floatsidf2_internal"
5153 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5154 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5155 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5156 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5157 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5158 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5159 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5160 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5166 rtx lowword, highword;
5167 gcc_assert (MEM_P (operands[4]));
5168 highword = adjust_address (operands[4], SImode, 0);
5169 lowword = adjust_address (operands[4], SImode, 4);
5170 if (! WORDS_BIG_ENDIAN)
5171 std::swap (lowword, highword);
5173 emit_insn (gen_xorsi3 (operands[6], operands[1],
5174 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5175 emit_move_insn (lowword, operands[6]);
5176 emit_move_insn (highword, operands[2]);
5177 emit_move_insn (operands[5], operands[4]);
5178 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5181 [(set_attr "length" "24")
5182 (set_attr "type" "fp")])
5184 ;; If we don't have a direct conversion to single precision, don't enable this
5185 ;; conversion for 32-bit without fast math, because we don't have the insn to
5186 ;; generate the fixup swizzle to avoid double rounding problems.
5187 (define_expand "floatunssisf2"
5188 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5189 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5190 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5193 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5194 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5195 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5200 if (!REG_P (operands[1]))
5201 operands[1] = force_reg (SImode, operands[1]);
5203 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5205 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5210 rtx dreg = operands[1];
5212 dreg = force_reg (SImode, dreg);
5213 dreg = convert_to_mode (DImode, dreg, true);
5214 emit_insn (gen_floatdisf2 (operands[0], dreg));
5219 (define_expand "floatunssidf2"
5220 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5221 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5224 (clobber (match_dup 4))
5225 (clobber (match_dup 5))])]
5227 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5230 if (TARGET_E500_DOUBLE)
5232 if (!REG_P (operands[1]))
5233 operands[1] = force_reg (SImode, operands[1]);
5234 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5237 else if (TARGET_LFIWZX && TARGET_FCFID)
5239 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5242 else if (TARGET_FCFID)
5244 rtx dreg = operands[1];
5246 dreg = force_reg (SImode, dreg);
5247 dreg = convert_to_mode (DImode, dreg, true);
5248 emit_insn (gen_floatdidf2 (operands[0], dreg));
5252 if (!REG_P (operands[1]))
5253 operands[1] = force_reg (SImode, operands[1]);
5254 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5255 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5256 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5257 operands[5] = gen_reg_rtx (DFmode);
5260 (define_insn_and_split "*floatunssidf2_internal"
5261 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5262 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5263 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5264 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5265 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5266 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5267 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5268 && !(TARGET_FCFID && TARGET_POWERPC64)"
5274 rtx lowword, highword;
5275 gcc_assert (MEM_P (operands[4]));
5276 highword = adjust_address (operands[4], SImode, 0);
5277 lowword = adjust_address (operands[4], SImode, 4);
5278 if (! WORDS_BIG_ENDIAN)
5279 std::swap (lowword, highword);
5281 emit_move_insn (lowword, operands[1]);
5282 emit_move_insn (highword, operands[2]);
5283 emit_move_insn (operands[5], operands[4]);
5284 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5287 [(set_attr "length" "20")
5288 (set_attr "type" "fp")])
5290 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5291 ;; vector registers. At the moment, QI/HImode are not allowed in floating
5292 ;; point or vector registers, so we use UNSPEC's to use the load byte and
5293 ;; half-word instructions.
5295 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5296 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5298 (match_operand:QHI 1 "input_operand")))
5299 (clobber (match_scratch:DI 2))
5300 (clobber (match_scratch:DI 3))])]
5301 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5303 if (MEM_P (operands[1]))
5304 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5307 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5308 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5310 (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5311 (clobber (match_scratch:DI 2 "=wi,v"))
5312 (clobber (match_scratch:DI 3 "=r,X"))]
5313 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5314 && TARGET_UPPER_REGS_DI"
5316 "&& reload_completed"
5319 rtx result = operands[0];
5320 rtx input = operands[1];
5321 rtx di = operands[2];
5325 rtx tmp = operands[3];
5326 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5327 emit_move_insn (di, tmp);
5334 emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5336 if (<MODE>mode == QImode)
5338 else if (<MODE>mode == HImode)
5343 di_vector = gen_rtx_REG (vmode, REGNO (di));
5344 emit_insn (gen_vsx_sign_extend_<QHI:mode>_di (di, di_vector));
5347 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5351 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5352 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "")
5353 (unsigned_float:FP_ISA3
5354 (match_operand:QHI 1 "input_operand" "")))
5355 (clobber (match_scratch:DI 2 ""))
5356 (clobber (match_scratch:DI 3 ""))])]
5357 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5359 if (MEM_P (operands[1]))
5360 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5363 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5364 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5365 (unsigned_float:FP_ISA3
5366 (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5367 (clobber (match_scratch:DI 2 "=wi,wi"))
5368 (clobber (match_scratch:DI 3 "=r,X"))]
5369 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5371 "&& reload_completed"
5374 rtx result = operands[0];
5375 rtx input = operands[1];
5376 rtx di = operands[2];
5377 rtx tmp = operands[3];
5381 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5382 emit_move_insn (di, tmp);
5385 emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5387 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5391 (define_expand "fix_trunc<mode>si2"
5392 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5393 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5394 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5397 if (!<E500_CONVERT>)
5399 rtx src = force_reg (<MODE>mode, operands[1]);
5402 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5405 rtx tmp = gen_reg_rtx (DImode);
5406 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5407 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5414 ; Like the convert to float patterns, this insn must be split before
5415 ; register allocation so that it can allocate the memory slot if it
5417 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5418 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5419 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5420 (clobber (match_scratch:DI 2 "=d"))]
5421 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5422 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5423 && TARGET_STFIWX && can_create_pseudo_p ()"
5428 rtx dest = operands[0];
5429 rtx src = operands[1];
5430 rtx tmp = operands[2];
5432 if (GET_CODE (tmp) == SCRATCH)
5433 tmp = gen_reg_rtx (DImode);
5435 emit_insn (gen_fctiwz_<mode> (tmp, src));
5438 dest = rs6000_address_for_fpconvert (dest);
5439 emit_insn (gen_stfiwx (dest, tmp));
5442 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5444 dest = gen_lowpart (DImode, dest);
5445 emit_move_insn (dest, tmp);
5450 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5451 emit_insn (gen_stfiwx (stack, tmp));
5452 emit_move_insn (dest, stack);
5456 [(set_attr "length" "12")
5457 (set_attr "type" "fp")])
5459 (define_insn_and_split "fix_trunc<mode>si2_internal"
5460 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5461 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5462 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5463 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5464 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5471 gcc_assert (MEM_P (operands[3]));
5472 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5474 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5475 emit_move_insn (operands[3], operands[2]);
5476 emit_move_insn (operands[0], lowword);
5479 [(set_attr "length" "16")
5480 (set_attr "type" "fp")])
5482 (define_expand "fix_trunc<mode>di2"
5483 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5484 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5485 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5489 (define_insn "*fix_trunc<mode>di2_fctidz"
5490 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5491 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5492 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5497 [(set_attr "type" "fp")])
5499 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5500 [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5501 (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5502 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5504 rtx op0 = operands[0];
5505 rtx op1 = operands[1];
5506 rtx di_tmp = gen_reg_rtx (DImode);
5509 op0 = rs6000_address_for_fpconvert (op0);
5511 emit_insn (gen_fctiwz_<SFDF:mode> (di_tmp, op1));
5512 emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5516 (define_expand "fixuns_trunc<mode>si2"
5517 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5518 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5520 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5524 if (!<E500_CONVERT>)
5526 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5531 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5532 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5533 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5534 (clobber (match_scratch:DI 2 "=d"))]
5535 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5536 && TARGET_STFIWX && can_create_pseudo_p ()"
5541 rtx dest = operands[0];
5542 rtx src = operands[1];
5543 rtx tmp = operands[2];
5545 if (GET_CODE (tmp) == SCRATCH)
5546 tmp = gen_reg_rtx (DImode);
5548 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5551 dest = rs6000_address_for_fpconvert (dest);
5552 emit_insn (gen_stfiwx (dest, tmp));
5555 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5557 dest = gen_lowpart (DImode, dest);
5558 emit_move_insn (dest, tmp);
5563 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5564 emit_insn (gen_stfiwx (stack, tmp));
5565 emit_move_insn (dest, stack);
5569 [(set_attr "length" "12")
5570 (set_attr "type" "fp")])
5572 (define_expand "fixuns_trunc<mode>di2"
5573 [(set (match_operand:DI 0 "register_operand" "")
5574 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5575 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5578 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5579 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5580 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5581 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5586 [(set_attr "type" "fp")])
5588 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5589 [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5590 (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5591 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5593 rtx op0 = operands[0];
5594 rtx op1 = operands[1];
5595 rtx di_tmp = gen_reg_rtx (DImode);
5598 op0 = rs6000_address_for_fpconvert (op0);
5600 emit_insn (gen_fctiwuz_<SFDF:mode> (di_tmp, op1));
5601 emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5605 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5606 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5607 ; because the first makes it clear that operand 0 is not live
5608 ; before the instruction.
5609 (define_insn "fctiwz_<mode>"
5610 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5611 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5613 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5617 [(set_attr "type" "fp")])
5619 (define_insn "fctiwuz_<mode>"
5620 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5621 (unspec:DI [(unsigned_fix:SI
5622 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5624 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5628 [(set_attr "type" "fp")])
5630 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5631 ;; since the friz instruction does not truncate the value if the floating
5632 ;; point value is < LONG_MIN or > LONG_MAX.
5633 (define_insn "*friz"
5634 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5635 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5636 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5637 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5641 [(set_attr "type" "fp")])
5643 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5644 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5645 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5646 ;; extend it, store it back on the stack from the GPR, load it back into the
5647 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5648 ;; disable using store and load to sign/zero extend the value.
5649 (define_insn_and_split "*round32<mode>2_fprs"
5650 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5652 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5653 (clobber (match_scratch:DI 2 "=d"))
5654 (clobber (match_scratch:DI 3 "=d"))]
5655 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5656 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5657 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5662 rtx dest = operands[0];
5663 rtx src = operands[1];
5664 rtx tmp1 = operands[2];
5665 rtx tmp2 = operands[3];
5666 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5668 if (GET_CODE (tmp1) == SCRATCH)
5669 tmp1 = gen_reg_rtx (DImode);
5670 if (GET_CODE (tmp2) == SCRATCH)
5671 tmp2 = gen_reg_rtx (DImode);
5673 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5674 emit_insn (gen_stfiwx (stack, tmp1));
5675 emit_insn (gen_lfiwax (tmp2, stack));
5676 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5679 [(set_attr "type" "fpload")
5680 (set_attr "length" "16")])
5682 (define_insn_and_split "*roundu32<mode>2_fprs"
5683 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5684 (unsigned_float:SFDF
5685 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5686 (clobber (match_scratch:DI 2 "=d"))
5687 (clobber (match_scratch:DI 3 "=d"))]
5688 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5689 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5690 && can_create_pseudo_p ()"
5695 rtx dest = operands[0];
5696 rtx src = operands[1];
5697 rtx tmp1 = operands[2];
5698 rtx tmp2 = operands[3];
5699 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5701 if (GET_CODE (tmp1) == SCRATCH)
5702 tmp1 = gen_reg_rtx (DImode);
5703 if (GET_CODE (tmp2) == SCRATCH)
5704 tmp2 = gen_reg_rtx (DImode);
5706 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5707 emit_insn (gen_stfiwx (stack, tmp1));
5708 emit_insn (gen_lfiwzx (tmp2, stack));
5709 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5712 [(set_attr "type" "fpload")
5713 (set_attr "length" "16")])
5715 ;; No VSX equivalent to fctid
5716 (define_insn "lrint<mode>di2"
5717 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5718 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5720 "TARGET_<MODE>_FPR && TARGET_FPRND"
5722 [(set_attr "type" "fp")])
5724 (define_insn "btrunc<mode>2"
5725 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5726 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5728 "TARGET_<MODE>_FPR && TARGET_FPRND"
5732 [(set_attr "type" "fp")
5733 (set_attr "fp_type" "fp_addsub_<Fs>")])
5735 (define_insn "ceil<mode>2"
5736 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5737 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5739 "TARGET_<MODE>_FPR && TARGET_FPRND"
5743 [(set_attr "type" "fp")
5744 (set_attr "fp_type" "fp_addsub_<Fs>")])
5746 (define_insn "floor<mode>2"
5747 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5748 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5750 "TARGET_<MODE>_FPR && TARGET_FPRND"
5754 [(set_attr "type" "fp")
5755 (set_attr "fp_type" "fp_addsub_<Fs>")])
5757 ;; No VSX equivalent to frin
5758 (define_insn "round<mode>2"
5759 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5760 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5762 "TARGET_<MODE>_FPR && TARGET_FPRND"
5764 [(set_attr "type" "fp")
5765 (set_attr "fp_type" "fp_addsub_<Fs>")])
5767 (define_insn "*xsrdpi<mode>2"
5768 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5769 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5771 "TARGET_<MODE>_FPR && TARGET_VSX"
5773 [(set_attr "type" "fp")
5774 (set_attr "fp_type" "fp_addsub_<Fs>")])
5776 (define_expand "lround<mode>di2"
5778 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5780 (set (match_operand:DI 0 "gpc_reg_operand" "")
5781 (unspec:DI [(match_dup 2)]
5783 "TARGET_<MODE>_FPR && TARGET_VSX"
5785 operands[2] = gen_reg_rtx (<MODE>mode);
5788 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5789 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5790 ; is only generated for Power8 or later.
5791 (define_insn "stfiwx"
5792 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5793 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5799 [(set_attr "type" "fpstore")])
5801 ;; If we don't have a direct conversion to single precision, don't enable this
5802 ;; conversion for 32-bit without fast math, because we don't have the insn to
5803 ;; generate the fixup swizzle to avoid double rounding problems.
5804 (define_expand "floatsisf2"
5805 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5806 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5807 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5810 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5811 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5812 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5817 if (!REG_P (operands[1]))
5818 operands[1] = force_reg (SImode, operands[1]);
5820 else if (TARGET_FCFIDS && TARGET_LFIWAX)
5822 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5825 else if (TARGET_FCFID && TARGET_LFIWAX)
5827 rtx dfreg = gen_reg_rtx (DFmode);
5828 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5829 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5834 rtx dreg = operands[1];
5836 dreg = force_reg (SImode, dreg);
5837 dreg = convert_to_mode (DImode, dreg, false);
5838 emit_insn (gen_floatdisf2 (operands[0], dreg));
5843 (define_expand "floatdidf2"
5844 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5845 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5846 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5849 (define_insn "*floatdidf2_fpr"
5850 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5851 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5852 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5856 [(set_attr "type" "fp")])
5858 ; Allow the combiner to merge source memory operands to the conversion so that
5859 ; the optimizer/register allocator doesn't try to load the value too early in a
5860 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5861 ; hit. We will split after reload to avoid the trip through the GPRs
5863 (define_insn_and_split "*floatdidf2_mem"
5864 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5865 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5866 (clobber (match_scratch:DI 2 "=d,wi"))]
5867 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5869 "&& reload_completed"
5870 [(set (match_dup 2) (match_dup 1))
5871 (set (match_dup 0) (float:DF (match_dup 2)))]
5873 [(set_attr "length" "8")
5874 (set_attr "type" "fpload")])
5876 (define_expand "floatunsdidf2"
5877 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5879 (match_operand:DI 1 "gpc_reg_operand" "")))]
5880 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5883 (define_insn "*floatunsdidf2_fcfidu"
5884 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5885 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5886 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5890 [(set_attr "type" "fp")
5891 (set_attr "length" "4")])
5893 (define_insn_and_split "*floatunsdidf2_mem"
5894 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5895 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5896 (clobber (match_scratch:DI 2 "=d,wi"))]
5897 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5899 "&& reload_completed"
5900 [(set (match_dup 2) (match_dup 1))
5901 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5903 [(set_attr "length" "8")
5904 (set_attr "type" "fpload")])
5906 (define_expand "floatdisf2"
5907 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5908 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5909 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5910 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5915 rtx val = operands[1];
5916 if (!flag_unsafe_math_optimizations)
5918 rtx label = gen_label_rtx ();
5919 val = gen_reg_rtx (DImode);
5920 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5923 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5928 (define_insn "floatdisf2_fcfids"
5929 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5930 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5931 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5932 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5936 [(set_attr "type" "fp")])
5938 (define_insn_and_split "*floatdisf2_mem"
5939 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5940 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5941 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5942 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5943 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5945 "&& reload_completed"
5949 emit_move_insn (operands[2], operands[1]);
5950 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5953 [(set_attr "length" "8")])
5955 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5956 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5957 ;; from double rounding.
5958 ;; Instead of creating a new cpu type for two FP operations, just use fp
5959 (define_insn_and_split "floatdisf2_internal1"
5960 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5961 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5962 (clobber (match_scratch:DF 2 "=d"))]
5963 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5966 "&& reload_completed"
5968 (float:DF (match_dup 1)))
5970 (float_truncate:SF (match_dup 2)))]
5972 [(set_attr "length" "8")
5973 (set_attr "type" "fp")])
5975 ;; Twiddles bits to avoid double rounding.
5976 ;; Bits that might be truncated when converting to DFmode are replaced
5977 ;; by a bit that won't be lost at that stage, but is below the SFmode
5978 ;; rounding position.
5979 (define_expand "floatdisf2_internal2"
5980 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5982 (clobber (reg:DI CA_REGNO))])
5983 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5985 (set (match_dup 3) (plus:DI (match_dup 3)
5987 (set (match_dup 0) (plus:DI (match_dup 0)
5989 (set (match_dup 4) (compare:CCUNS (match_dup 3)
5991 (set (match_dup 0) (ior:DI (match_dup 0)
5993 (set (match_dup 0) (and:DI (match_dup 0)
5995 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5996 (label_ref (match_operand:DI 2 "" ""))
5998 (set (match_dup 0) (match_dup 1))]
5999 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6003 operands[3] = gen_reg_rtx (DImode);
6004 operands[4] = gen_reg_rtx (CCUNSmode);
6007 (define_expand "floatunsdisf2"
6008 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6009 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6010 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6011 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6014 (define_insn "floatunsdisf2_fcfidus"
6015 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6016 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6017 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6018 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6022 [(set_attr "type" "fp")])
6024 (define_insn_and_split "*floatunsdisf2_mem"
6025 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6026 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6027 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6028 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6029 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6031 "&& reload_completed"
6035 emit_move_insn (operands[2], operands[1]);
6036 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6039 [(set_attr "length" "8")
6040 (set_attr "type" "fpload")])
6042 ;; Define the TImode operations that can be done in a small number
6043 ;; of instructions. The & constraints are to prevent the register
6044 ;; allocator from allocating registers that overlap with the inputs
6045 ;; (for example, having an input in 7,8 and an output in 6,7). We
6046 ;; also allow for the output being the same as one of the inputs.
6048 (define_expand "addti3"
6049 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6050 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6051 (match_operand:TI 2 "reg_or_short_operand" "")))]
6054 rtx lo0 = gen_lowpart (DImode, operands[0]);
6055 rtx lo1 = gen_lowpart (DImode, operands[1]);
6056 rtx lo2 = gen_lowpart (DImode, operands[2]);
6057 rtx hi0 = gen_highpart (DImode, operands[0]);
6058 rtx hi1 = gen_highpart (DImode, operands[1]);
6059 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6061 if (!reg_or_short_operand (lo2, DImode))
6062 lo2 = force_reg (DImode, lo2);
6063 if (!adde_operand (hi2, DImode))
6064 hi2 = force_reg (DImode, hi2);
6066 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6067 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6071 (define_expand "subti3"
6072 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6073 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6074 (match_operand:TI 2 "gpc_reg_operand" "")))]
6077 rtx lo0 = gen_lowpart (DImode, operands[0]);
6078 rtx lo1 = gen_lowpart (DImode, operands[1]);
6079 rtx lo2 = gen_lowpart (DImode, operands[2]);
6080 rtx hi0 = gen_highpart (DImode, operands[0]);
6081 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6082 rtx hi2 = gen_highpart (DImode, operands[2]);
6084 if (!reg_or_short_operand (lo1, DImode))
6085 lo1 = force_reg (DImode, lo1);
6086 if (!adde_operand (hi1, DImode))
6087 hi1 = force_reg (DImode, hi1);
6089 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6090 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6094 ;; 128-bit logical operations expanders
6096 (define_expand "and<mode>3"
6097 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6098 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6099 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6103 (define_expand "ior<mode>3"
6104 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6105 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6106 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6110 (define_expand "xor<mode>3"
6111 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6112 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6113 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6117 (define_expand "one_cmpl<mode>2"
6118 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6119 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6123 (define_expand "nor<mode>3"
6124 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6126 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6127 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6131 (define_expand "andc<mode>3"
6132 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6134 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6135 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6139 ;; Power8 vector logical instructions.
6140 (define_expand "eqv<mode>3"
6141 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6143 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6144 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6145 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6148 ;; Rewrite nand into canonical form
6149 (define_expand "nand<mode>3"
6150 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6152 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6153 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6154 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6157 ;; The canonical form is to have the negated element first, so we need to
6158 ;; reverse arguments.
6159 (define_expand "orc<mode>3"
6160 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6162 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6163 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6164 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6167 ;; 128-bit logical operations insns and split operations
6168 (define_insn_and_split "*and<mode>3_internal"
6169 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6171 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6172 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6175 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6176 return "xxland %x0,%x1,%x2";
6178 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6179 return "vand %0,%1,%2";
6183 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6186 rs6000_split_logical (operands, AND, false, false, false);
6191 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6192 (const_string "veclogical")
6193 (const_string "integer")))
6194 (set (attr "length")
6196 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6199 (match_test "TARGET_POWERPC64")
6201 (const_string "16"))))])
6204 (define_insn_and_split "*bool<mode>3_internal"
6205 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6206 (match_operator:BOOL_128 3 "boolean_or_operator"
6207 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6208 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6211 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6212 return "xxl%q3 %x0,%x1,%x2";
6214 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6215 return "v%q3 %0,%1,%2";
6219 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6222 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6227 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6228 (const_string "veclogical")
6229 (const_string "integer")))
6230 (set (attr "length")
6232 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6235 (match_test "TARGET_POWERPC64")
6237 (const_string "16"))))])
6240 (define_insn_and_split "*boolc<mode>3_internal1"
6241 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6242 (match_operator:BOOL_128 3 "boolean_operator"
6244 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6245 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6246 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6248 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6249 return "xxl%q3 %x0,%x1,%x2";
6251 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6252 return "v%q3 %0,%1,%2";
6256 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6257 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6260 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6265 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6266 (const_string "veclogical")
6267 (const_string "integer")))
6268 (set (attr "length")
6270 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6273 (match_test "TARGET_POWERPC64")
6275 (const_string "16"))))])
6277 (define_insn_and_split "*boolc<mode>3_internal2"
6278 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6279 (match_operator:TI2 3 "boolean_operator"
6281 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6282 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6283 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6285 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6288 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6291 [(set_attr "type" "integer")
6292 (set (attr "length")
6294 (match_test "TARGET_POWERPC64")
6296 (const_string "16")))])
6299 (define_insn_and_split "*boolcc<mode>3_internal1"
6300 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6301 (match_operator:BOOL_128 3 "boolean_operator"
6303 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6305 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6306 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6308 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6309 return "xxl%q3 %x0,%x1,%x2";
6311 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6312 return "v%q3 %0,%1,%2";
6316 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6317 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6320 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6325 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6326 (const_string "veclogical")
6327 (const_string "integer")))
6328 (set (attr "length")
6330 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6333 (match_test "TARGET_POWERPC64")
6335 (const_string "16"))))])
6337 (define_insn_and_split "*boolcc<mode>3_internal2"
6338 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6339 (match_operator:TI2 3 "boolean_operator"
6341 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6343 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6344 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6346 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6349 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6352 [(set_attr "type" "integer")
6353 (set (attr "length")
6355 (match_test "TARGET_POWERPC64")
6357 (const_string "16")))])
6361 (define_insn_and_split "*eqv<mode>3_internal1"
6362 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6365 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6366 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6369 if (vsx_register_operand (operands[0], <MODE>mode))
6370 return "xxleqv %x0,%x1,%x2";
6374 "TARGET_P8_VECTOR && reload_completed
6375 && int_reg_operand (operands[0], <MODE>mode)"
6378 rs6000_split_logical (operands, XOR, true, false, false);
6383 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6384 (const_string "veclogical")
6385 (const_string "integer")))
6386 (set (attr "length")
6388 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6391 (match_test "TARGET_POWERPC64")
6393 (const_string "16"))))])
6395 (define_insn_and_split "*eqv<mode>3_internal2"
6396 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6399 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6400 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6403 "reload_completed && !TARGET_P8_VECTOR"
6406 rs6000_split_logical (operands, XOR, true, false, false);
6409 [(set_attr "type" "integer")
6410 (set (attr "length")
6412 (match_test "TARGET_POWERPC64")
6414 (const_string "16")))])
6416 ;; 128-bit one's complement
6417 (define_insn_and_split "*one_cmpl<mode>3_internal"
6418 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6420 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6423 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6424 return "xxlnor %x0,%x1,%x1";
6426 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6427 return "vnor %0,%1,%1";
6431 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6434 rs6000_split_logical (operands, NOT, false, false, false);
6439 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6440 (const_string "veclogical")
6441 (const_string "integer")))
6442 (set (attr "length")
6444 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6447 (match_test "TARGET_POWERPC64")
6449 (const_string "16"))))])
6452 ;; Now define ways of moving data around.
6454 ;; Set up a register with a value from the GOT table
6456 (define_expand "movsi_got"
6457 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6458 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6459 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6460 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6463 if (GET_CODE (operands[1]) == CONST)
6465 rtx offset = const0_rtx;
6466 HOST_WIDE_INT value;
6468 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6469 value = INTVAL (offset);
6472 rtx tmp = (!can_create_pseudo_p ()
6474 : gen_reg_rtx (Pmode));
6475 emit_insn (gen_movsi_got (tmp, operands[1]));
6476 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6481 operands[2] = rs6000_got_register (operands[1]);
6484 (define_insn "*movsi_got_internal"
6485 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6486 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6487 (match_operand:SI 2 "gpc_reg_operand" "b")]
6489 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6490 "lwz %0,%a1@got(%2)"
6491 [(set_attr "type" "load")])
6493 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6494 ;; didn't get allocated to a hard register.
6496 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6497 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6498 (match_operand:SI 2 "memory_operand" "")]
6500 "DEFAULT_ABI == ABI_V4
6502 && (reload_in_progress || reload_completed)"
6503 [(set (match_dup 0) (match_dup 2))
6504 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6508 ;; For SI, we special-case integers that can't be loaded in one insn. We
6509 ;; do the load 16-bits at a time. We could do this by loading from memory,
6510 ;; and this is even supposed to be faster, but it is simpler not to get
6511 ;; integers in the TOC.
6512 (define_insn "movsi_low"
6513 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6514 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6515 (match_operand 2 "" ""))))]
6516 "TARGET_MACHO && ! TARGET_64BIT"
6517 "lwz %0,lo16(%2)(%1)"
6518 [(set_attr "type" "load")
6519 (set_attr "length" "4")])
6521 (define_insn "*movsi_internal1"
6522 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6523 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6524 "!TARGET_SINGLE_FPU &&
6525 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6538 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6539 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6541 (define_insn "*movsi_internal1_single"
6542 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6543 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6544 "TARGET_SINGLE_FPU &&
6545 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6560 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6561 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6563 ;; Split a load of a large constant into the appropriate two-insn
6567 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6568 (match_operand:SI 1 "const_int_operand" ""))]
6569 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6570 && (INTVAL (operands[1]) & 0xffff) != 0"
6574 (ior:SI (match_dup 0)
6578 if (rs6000_emit_set_const (operands[0], operands[1]))
6584 (define_insn "*mov<mode>_internal2"
6585 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6586 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6588 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6594 [(set_attr "type" "cmp,logical,cmp")
6595 (set_attr "dot" "yes")
6596 (set_attr "length" "4,4,8")])
6599 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6600 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6602 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6604 [(set (match_dup 0) (match_dup 1))
6606 (compare:CC (match_dup 0)
6610 (define_insn "*movhi_internal"
6611 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6612 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6613 "gpc_reg_operand (operands[0], HImode)
6614 || gpc_reg_operand (operands[1], HImode)"
6623 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6625 (define_expand "mov<mode>"
6626 [(set (match_operand:INT 0 "general_operand" "")
6627 (match_operand:INT 1 "any_operand" ""))]
6629 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6631 (define_insn "*movqi_internal"
6632 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6633 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6634 "gpc_reg_operand (operands[0], QImode)
6635 || gpc_reg_operand (operands[1], QImode)"
6644 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6646 ;; Here is how to move condition codes around. When we store CC data in
6647 ;; an integer register or memory, we store just the high-order 4 bits.
6648 ;; This lets us not shift in the most common case of CR0.
6649 (define_expand "movcc"
6650 [(set (match_operand:CC 0 "nonimmediate_operand" "")
6651 (match_operand:CC 1 "nonimmediate_operand" ""))]
6655 (define_insn "*movcc_internal1"
6656 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6657 (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6658 "register_operand (operands[0], CCmode)
6659 || register_operand (operands[1], CCmode)"
6663 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6666 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6674 (cond [(eq_attr "alternative" "0,3")
6675 (const_string "cr_logical")
6676 (eq_attr "alternative" "1,2")
6677 (const_string "mtcr")
6678 (eq_attr "alternative" "6,7")
6679 (const_string "integer")
6680 (eq_attr "alternative" "8")
6681 (const_string "mfjmpr")
6682 (eq_attr "alternative" "9")
6683 (const_string "mtjmpr")
6684 (eq_attr "alternative" "10")
6685 (const_string "load")
6686 (eq_attr "alternative" "11")
6687 (const_string "store")
6688 (match_test "TARGET_MFCRF")
6689 (const_string "mfcrf")
6691 (const_string "mfcr")))
6692 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6694 ;; For floating-point, we normally deal with the floating-point registers
6695 ;; unless -msoft-float is used. The sole exception is that parameter passing
6696 ;; can produce floating-point values in fixed-point registers. Unless the
6697 ;; value is a simple constant or already in memory, we deal with this by
6698 ;; allocating memory and copying the value explicitly via that memory location.
6700 ;; Move 32-bit binary/decimal floating point
6701 (define_expand "mov<mode>"
6702 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6703 (match_operand:FMOVE32 1 "any_operand" ""))]
6705 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6708 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6709 (match_operand:FMOVE32 1 "const_double_operand" ""))]
6711 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6712 || (GET_CODE (operands[0]) == SUBREG
6713 && GET_CODE (SUBREG_REG (operands[0])) == REG
6714 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6715 [(set (match_dup 2) (match_dup 3))]
6720 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6722 if (! TARGET_POWERPC64)
6723 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6725 operands[2] = gen_lowpart (SImode, operands[0]);
6727 operands[3] = gen_int_mode (l, SImode);
6730 (define_insn "mov<mode>_hardfloat"
6731 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
6732 "=!r, <f32_lr>, <f32_lr2>, <f32_av>, m, <f32_sm>,
6733 <f32_sm2>, Z, <f32_vsx>, !r, ?<f32_dm>, ?r,
6734 f, <f32_vsx>, !r, *c*l, !r, *h")
6735 (match_operand:FMOVE32 1 "input_operand"
6736 "m, <f32_lm>, <f32_lm2>, Z, r, <f32_sr>,
6737 <f32_sr2>, <f32_av>, <zero_fp>, <zero_fp>, r, <f32_dm>,
6738 f, <f32_vsx>, r, r, *h, 0"))]
6739 "(gpc_reg_operand (operands[0], <MODE>mode)
6740 || gpc_reg_operand (operands[1], <MODE>mode))
6741 && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6756 xscpsgndp %x0,%x1,%x1
6761 [(set_attr "type" "load,fpload,fpload,fpload,store,fpstore,fpstore,fpstore,veclogical,integer,mffgpr,mftgpr,fpsimple,fpsimple,*,mtjmpr,mfjmpr,*")])
6763 (define_insn "*mov<mode>_softfloat"
6764 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6765 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6766 "(gpc_reg_operand (operands[0], <MODE>mode)
6767 || gpc_reg_operand (operands[1], <MODE>mode))
6768 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6780 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6781 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6784 ;; Move 64-bit binary/decimal floating point
6785 (define_expand "mov<mode>"
6786 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6787 (match_operand:FMOVE64 1 "any_operand" ""))]
6789 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6792 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6793 (match_operand:FMOVE64 1 "const_int_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 4))
6800 (set (match_dup 3) (match_dup 1))]
6803 int endian = (WORDS_BIG_ENDIAN == 0);
6804 HOST_WIDE_INT value = INTVAL (operands[1]);
6806 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6807 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6808 operands[4] = GEN_INT (value >> 32);
6809 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6813 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6814 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6815 "! TARGET_POWERPC64 && reload_completed
6816 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6817 || (GET_CODE (operands[0]) == SUBREG
6818 && GET_CODE (SUBREG_REG (operands[0])) == REG
6819 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6820 [(set (match_dup 2) (match_dup 4))
6821 (set (match_dup 3) (match_dup 5))]
6824 int endian = (WORDS_BIG_ENDIAN == 0);
6827 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6829 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6830 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6831 operands[4] = gen_int_mode (l[endian], SImode);
6832 operands[5] = gen_int_mode (l[1 - endian], SImode);
6836 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6837 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6838 "TARGET_POWERPC64 && reload_completed
6839 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6840 || (GET_CODE (operands[0]) == SUBREG
6841 && GET_CODE (SUBREG_REG (operands[0])) == REG
6842 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6843 [(set (match_dup 2) (match_dup 3))]
6846 int endian = (WORDS_BIG_ENDIAN == 0);
6850 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6852 operands[2] = gen_lowpart (DImode, operands[0]);
6853 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
6854 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6855 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6857 operands[3] = gen_int_mode (val, DImode);
6860 ;; Don't have reload use general registers to load a constant. It is
6861 ;; less efficient than loading the constant into an FP register, since
6862 ;; it will probably be used there.
6864 ;; The move constraints are ordered to prefer floating point registers before
6865 ;; general purpose registers to avoid doing a store and a load to get the value
6866 ;; into a floating point register when it is needed for a floating point
6867 ;; operation. Prefer traditional floating point registers over VSX registers,
6868 ;; since the D-form version of the memory instructions does not need a GPR for
6869 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6872 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6873 ;; except for 0.0 which can be created on VSX with an xor instruction.
6875 (define_insn "*mov<mode>_hardfloat32"
6876 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6877 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
6878 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6879 && (gpc_reg_operand (operands[0], <MODE>mode)
6880 || gpc_reg_operand (operands[1], <MODE>mode))"
6895 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
6896 (set_attr "size" "64")
6897 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6899 (define_insn "*mov<mode>_softfloat32"
6900 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6901 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6903 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
6904 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6905 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6906 && (gpc_reg_operand (operands[0], <MODE>mode)
6907 || gpc_reg_operand (operands[1], <MODE>mode))"
6909 [(set_attr "type" "store,load,two,*,*,*")
6910 (set_attr "length" "8,8,8,8,12,16")])
6912 ; ld/std require word-aligned displacements -> 'Y' constraint.
6913 ; List Y->r and r->Y before r->r for reload.
6914 (define_insn "*mov<mode>_hardfloat64"
6915 [(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>")
6916 (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"))]
6917 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6918 && (gpc_reg_operand (operands[0], <MODE>mode)
6919 || gpc_reg_operand (operands[1], <MODE>mode))"
6941 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6942 (set_attr "size" "64")
6943 (set_attr "length" "4")])
6945 (define_insn "*mov<mode>_softfloat64"
6946 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6947 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6948 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6949 && (gpc_reg_operand (operands[0], <MODE>mode)
6950 || gpc_reg_operand (operands[1], <MODE>mode))"
6961 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6962 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6964 (define_expand "mov<mode>"
6965 [(set (match_operand:FMOVE128 0 "general_operand" "")
6966 (match_operand:FMOVE128 1 "any_operand" ""))]
6968 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6970 ;; It's important to list Y->r and r->Y before r->r because otherwise
6971 ;; reload, given m->r, will try to pick r->r and reload it, which
6972 ;; doesn't make progress.
6974 ;; We can't split little endian direct moves of TDmode, because the words are
6975 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
6976 ;; problematical. Don't allow direct move for this case.
6978 (define_insn_and_split "*mov<mode>_64bit_dm"
6979 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
6980 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
6981 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6982 && FLOAT128_2REG_P (<MODE>mode)
6983 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6984 && (gpc_reg_operand (operands[0], <MODE>mode)
6985 || gpc_reg_operand (operands[1], <MODE>mode))"
6987 "&& reload_completed"
6989 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6990 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6992 (define_insn_and_split "*movtd_64bit_nodm"
6993 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
6994 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
6995 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6996 && (gpc_reg_operand (operands[0], TDmode)
6997 || gpc_reg_operand (operands[1], TDmode))"
6999 "&& reload_completed"
7001 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7002 [(set_attr "length" "8,8,8,12,12,8")])
7004 (define_insn_and_split "*mov<mode>_32bit"
7005 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7006 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7007 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7008 && (FLOAT128_2REG_P (<MODE>mode)
7009 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7010 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7011 && (gpc_reg_operand (operands[0], <MODE>mode)
7012 || gpc_reg_operand (operands[1], <MODE>mode))"
7014 "&& reload_completed"
7016 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7017 [(set_attr "length" "8,8,8,8,20,20,16")])
7019 (define_insn_and_split "*mov<mode>_softfloat"
7020 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7021 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7022 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7023 && (gpc_reg_operand (operands[0], <MODE>mode)
7024 || gpc_reg_operand (operands[1], <MODE>mode))"
7026 "&& reload_completed"
7028 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7029 [(set_attr "length" "20,20,16")])
7031 (define_expand "extenddf<mode>2"
7032 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7033 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7034 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7035 && TARGET_LONG_DOUBLE_128"
7037 if (FLOAT128_IEEE_P (<MODE>mode))
7038 rs6000_expand_float128_convert (operands[0], operands[1], false);
7039 else if (TARGET_E500_DOUBLE)
7041 gcc_assert (<MODE>mode == TFmode);
7042 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7044 else if (TARGET_VSX)
7046 if (<MODE>mode == TFmode)
7047 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7048 else if (<MODE>mode == IFmode)
7049 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7055 rtx zero = gen_reg_rtx (DFmode);
7056 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7058 if (<MODE>mode == TFmode)
7059 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7060 else if (<MODE>mode == IFmode)
7061 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7068 ;; Allow memory operands for the source to be created by the combiner.
7069 (define_insn_and_split "extenddf<mode>2_fprs"
7070 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7071 (float_extend:IBM128
7072 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7073 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7074 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7075 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7077 "&& reload_completed"
7078 [(set (match_dup 3) (match_dup 1))
7079 (set (match_dup 4) (match_dup 2))]
7081 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7082 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7084 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7085 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7088 (define_insn_and_split "extenddf<mode>2_vsx"
7089 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7090 (float_extend:IBM128
7091 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7092 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7094 "&& reload_completed"
7095 [(set (match_dup 2) (match_dup 1))
7096 (set (match_dup 3) (match_dup 4))]
7098 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7099 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7101 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7102 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7103 operands[4] = CONST0_RTX (DFmode);
7106 (define_expand "extendsf<mode>2"
7107 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7108 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7110 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7111 && TARGET_LONG_DOUBLE_128"
7113 if (FLOAT128_IEEE_P (<MODE>mode))
7114 rs6000_expand_float128_convert (operands[0], operands[1], false);
7117 rtx tmp = gen_reg_rtx (DFmode);
7118 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7119 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7124 (define_expand "trunc<mode>df2"
7125 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7126 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7128 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7129 && TARGET_LONG_DOUBLE_128"
7131 if (FLOAT128_IEEE_P (<MODE>mode))
7133 rs6000_expand_float128_convert (operands[0], operands[1], false);
7138 (define_insn_and_split "trunc<mode>df2_internal1"
7139 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7141 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7142 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7143 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7147 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7150 emit_note (NOTE_INSN_DELETED);
7153 [(set_attr "type" "fpsimple")])
7155 (define_insn "trunc<mode>df2_internal2"
7156 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7157 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7158 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7159 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7161 [(set_attr "type" "fp")
7162 (set_attr "fp_type" "fp_addsub_d")])
7164 (define_expand "trunc<mode>sf2"
7165 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7166 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7168 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7169 && TARGET_LONG_DOUBLE_128"
7171 if (FLOAT128_IEEE_P (<MODE>mode))
7172 rs6000_expand_float128_convert (operands[0], operands[1], false);
7173 else if (TARGET_E500_DOUBLE)
7175 gcc_assert (<MODE>mode == TFmode);
7176 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7178 else if (<MODE>mode == TFmode)
7179 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7180 else if (<MODE>mode == IFmode)
7181 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7187 (define_insn_and_split "trunc<mode>sf2_fprs"
7188 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7189 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7190 (clobber (match_scratch:DF 2 "=d"))]
7191 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7192 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7194 "&& reload_completed"
7196 (float_truncate:DF (match_dup 1)))
7198 (float_truncate:SF (match_dup 2)))]
7201 (define_expand "floatsi<mode>2"
7202 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7203 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7205 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7206 && TARGET_LONG_DOUBLE_128"
7208 if (FLOAT128_IEEE_P (<MODE>mode))
7209 rs6000_expand_float128_convert (operands[0], operands[1], false);
7212 rtx tmp = gen_reg_rtx (DFmode);
7213 expand_float (tmp, operands[1], false);
7214 if (<MODE>mode == TFmode)
7215 emit_insn (gen_extenddftf2 (operands[0], tmp));
7216 else if (<MODE>mode == IFmode)
7217 emit_insn (gen_extenddfif2 (operands[0], tmp));
7224 ; fadd, but rounding towards zero.
7225 ; This is probably not the optimal code sequence.
7226 (define_insn "fix_trunc_helper<mode>"
7227 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7228 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7229 UNSPEC_FIX_TRUNC_TF))
7230 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7231 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7232 && FLOAT128_IBM_P (<MODE>mode)"
7233 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7234 [(set_attr "type" "fp")
7235 (set_attr "length" "20")])
7237 (define_expand "fix_trunc<mode>si2"
7238 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7239 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7241 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7243 if (FLOAT128_IEEE_P (<MODE>mode))
7244 rs6000_expand_float128_convert (operands[0], operands[1], false);
7245 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7246 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7247 else if (<MODE>mode == TFmode)
7248 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7249 else if (<MODE>mode == IFmode)
7250 emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7256 (define_expand "fix_trunc<mode>si2_fprs"
7257 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7258 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7259 (clobber (match_dup 2))
7260 (clobber (match_dup 3))
7261 (clobber (match_dup 4))
7262 (clobber (match_dup 5))])]
7263 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7265 operands[2] = gen_reg_rtx (DFmode);
7266 operands[3] = gen_reg_rtx (DFmode);
7267 operands[4] = gen_reg_rtx (DImode);
7268 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7271 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7272 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7273 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7274 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7275 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7276 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7277 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7278 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7284 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7287 gcc_assert (MEM_P (operands[5]));
7288 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7290 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7291 emit_move_insn (operands[5], operands[4]);
7292 emit_move_insn (operands[0], lowword);
7296 (define_expand "fix_trunc<mode>di2"
7297 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7298 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7301 rs6000_expand_float128_convert (operands[0], operands[1], false);
7305 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7306 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7307 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7310 rs6000_expand_float128_convert (operands[0], operands[1], true);
7314 (define_expand "floatdi<mode>2"
7315 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7316 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7319 rs6000_expand_float128_convert (operands[0], operands[1], false);
7323 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7324 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7325 (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7328 rs6000_expand_float128_convert (operands[0], operands[1], true);
7332 (define_expand "neg<mode>2"
7333 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7334 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7335 "FLOAT128_IEEE_P (<MODE>mode)
7336 || (FLOAT128_IBM_P (<MODE>mode)
7337 && TARGET_HARD_FLOAT
7338 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7341 if (FLOAT128_IEEE_P (<MODE>mode))
7343 if (TARGET_FLOAT128_HW)
7345 if (<MODE>mode == TFmode)
7346 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7347 else if (<MODE>mode == KFmode)
7348 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7352 else if (TARGET_FLOAT128)
7354 if (<MODE>mode == TFmode)
7355 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7356 else if (<MODE>mode == KFmode)
7357 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7363 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7364 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7366 operands[1], <MODE>mode);
7368 if (target && !rtx_equal_p (target, operands[0]))
7369 emit_move_insn (operands[0], target);
7375 (define_insn "neg<mode>2_internal"
7376 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7377 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7378 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7381 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7382 return \"fneg %L0,%L1\;fneg %0,%1\";
7384 return \"fneg %0,%1\;fneg %L0,%L1\";
7386 [(set_attr "type" "fpsimple")
7387 (set_attr "length" "8")])
7389 (define_expand "abs<mode>2"
7390 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7391 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7392 "FLOAT128_IEEE_P (<MODE>mode)
7393 || (FLOAT128_IBM_P (<MODE>mode)
7394 && TARGET_HARD_FLOAT
7395 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7400 if (FLOAT128_IEEE_P (<MODE>mode))
7402 if (TARGET_FLOAT128_HW)
7404 if (<MODE>mode == TFmode)
7405 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7406 else if (<MODE>mode == KFmode)
7407 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7412 else if (TARGET_FLOAT128)
7414 if (<MODE>mode == TFmode)
7415 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7416 else if (<MODE>mode == KFmode)
7417 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7426 label = gen_label_rtx ();
7427 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7429 if (flag_finite_math_only && !flag_trapping_math)
7430 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7432 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7434 else if (<MODE>mode == TFmode)
7435 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7436 else if (<MODE>mode == TFmode)
7437 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7444 (define_expand "abs<mode>2_internal"
7445 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7446 (match_operand:IBM128 1 "gpc_reg_operand" ""))
7447 (set (match_dup 3) (match_dup 5))
7448 (set (match_dup 5) (abs:DF (match_dup 5)))
7449 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7450 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7451 (label_ref (match_operand 2 "" ""))
7453 (set (match_dup 6) (neg:DF (match_dup 6)))]
7454 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7455 && TARGET_LONG_DOUBLE_128"
7458 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7459 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7460 operands[3] = gen_reg_rtx (DFmode);
7461 operands[4] = gen_reg_rtx (CCFPmode);
7462 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7463 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7467 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7470 (define_expand "ieee_128bit_negative_zero"
7471 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7474 rtvec v = rtvec_alloc (16);
7477 for (i = 0; i < 16; i++)
7478 RTVEC_ELT (v, i) = const0_rtx;
7480 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7481 RTVEC_ELT (v, high) = GEN_INT (0x80);
7483 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7487 ;; IEEE 128-bit negate
7489 ;; We have 2 insns here for negate and absolute value. The first uses
7490 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7491 ;; insns, and second insn after the first split pass loads up the bit to
7492 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
7493 ;; neg/abs to create the constant just once.
7495 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7496 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7497 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7498 (clobber (match_scratch:V16QI 2 "=v"))]
7499 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7502 [(parallel [(set (match_dup 0)
7503 (neg:IEEE128 (match_dup 1)))
7504 (use (match_dup 2))])]
7506 if (GET_CODE (operands[2]) == SCRATCH)
7507 operands[2] = gen_reg_rtx (V16QImode);
7509 operands[3] = gen_reg_rtx (V16QImode);
7510 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7512 [(set_attr "length" "8")
7513 (set_attr "type" "vecsimple")])
7515 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7516 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7517 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7518 (use (match_operand:V16QI 2 "register_operand" "v"))]
7519 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7520 "xxlxor %x0,%x1,%x2"
7521 [(set_attr "type" "veclogical")])
7523 ;; IEEE 128-bit absolute value
7524 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7525 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7526 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7527 (clobber (match_scratch:V16QI 2 "=v"))]
7528 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7531 [(parallel [(set (match_dup 0)
7532 (abs:IEEE128 (match_dup 1)))
7533 (use (match_dup 2))])]
7535 if (GET_CODE (operands[2]) == SCRATCH)
7536 operands[2] = gen_reg_rtx (V16QImode);
7538 operands[3] = gen_reg_rtx (V16QImode);
7539 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7541 [(set_attr "length" "8")
7542 (set_attr "type" "vecsimple")])
7544 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7545 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7546 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7547 (use (match_operand:V16QI 2 "register_operand" "v"))]
7548 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7549 "xxlandc %x0,%x1,%x2"
7550 [(set_attr "type" "veclogical")])
7552 ;; IEEE 128-bit negative absolute value
7553 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7554 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7557 (match_operand:IEEE128 1 "register_operand" "wa"))))
7558 (clobber (match_scratch:V16QI 2 "=v"))]
7559 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7562 [(parallel [(set (match_dup 0)
7563 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7564 (use (match_dup 2))])]
7566 if (GET_CODE (operands[2]) == SCRATCH)
7567 operands[2] = gen_reg_rtx (V16QImode);
7569 operands[3] = gen_reg_rtx (V16QImode);
7570 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7572 [(set_attr "length" "8")
7573 (set_attr "type" "vecsimple")])
7575 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7576 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7579 (match_operand:IEEE128 1 "register_operand" "wa"))))
7580 (use (match_operand:V16QI 2 "register_operand" "v"))]
7581 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7583 [(set_attr "type" "veclogical")])
7585 ;; Float128 conversion functions. These expand to library function calls.
7586 ;; We use expand to convert from IBM double double to IEEE 128-bit
7587 ;; and trunc for the opposite.
7588 (define_expand "extendiftf2"
7589 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7590 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7593 rs6000_expand_float128_convert (operands[0], operands[1], false);
7597 (define_expand "extendifkf2"
7598 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7599 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7602 rs6000_expand_float128_convert (operands[0], operands[1], false);
7606 (define_expand "extendtfkf2"
7607 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7608 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7611 rs6000_expand_float128_convert (operands[0], operands[1], false);
7615 (define_expand "trunciftf2"
7616 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7617 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7620 rs6000_expand_float128_convert (operands[0], operands[1], false);
7624 (define_expand "truncifkf2"
7625 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7626 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7629 rs6000_expand_float128_convert (operands[0], operands[1], false);
7633 (define_expand "trunckftf2"
7634 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7635 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7638 rs6000_expand_float128_convert (operands[0], operands[1], false);
7642 (define_expand "trunctfif2"
7643 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7644 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7647 rs6000_expand_float128_convert (operands[0], operands[1], false);
7652 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
7653 ;; must have 3 arguments, and scratch register constraint must be a single
7656 ;; Reload patterns to support gpr load/store with misaligned mem.
7657 ;; and multiple gpr load/store at offset >= 0xfffc
7658 (define_expand "reload_<mode>_store"
7659 [(parallel [(match_operand 0 "memory_operand" "=m")
7660 (match_operand 1 "gpc_reg_operand" "r")
7661 (match_operand:GPR 2 "register_operand" "=&b")])]
7664 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7668 (define_expand "reload_<mode>_load"
7669 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7670 (match_operand 1 "memory_operand" "m")
7671 (match_operand:GPR 2 "register_operand" "=b")])]
7674 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7679 ;; Reload patterns for various types using the vector registers. We may need
7680 ;; an additional base register to convert the reg+offset addressing to reg+reg
7681 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7682 ;; index register for gpr registers.
7683 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7684 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7685 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7686 (match_operand:P 2 "register_operand" "=b")])]
7689 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7693 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7694 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7695 (match_operand:RELOAD 1 "memory_operand" "m")
7696 (match_operand:P 2 "register_operand" "=b")])]
7699 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7704 ;; Reload sometimes tries to move the address to a GPR, and can generate
7705 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
7706 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7708 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7709 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7710 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7711 (match_operand:P 2 "reg_or_cint_operand" "rI"))
7713 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7715 "&& reload_completed"
7717 (plus:P (match_dup 1)
7720 (and:P (match_dup 0)
7723 ;; Power8 merge instructions to allow direct move to/from floating point
7724 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
7725 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
7726 ;; value, since it is allocated in reload and not all of the flow information
7727 ;; is setup for it. We have two patterns to do the two moves between gprs and
7728 ;; fprs. There isn't a dependancy between the two, but we could potentially
7729 ;; schedule other instructions between the two instructions.
7731 (define_insn "p8_fmrgow_<mode>"
7732 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7734 (match_operand:DF 1 "register_operand" "d")
7735 (match_operand:DF 2 "register_operand" "d")]
7736 UNSPEC_P8V_FMRGOW))]
7737 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7739 [(set_attr "type" "fpsimple")])
7741 (define_insn "p8_mtvsrwz"
7742 [(set (match_operand:DF 0 "register_operand" "=d")
7743 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7744 UNSPEC_P8V_MTVSRWZ))]
7745 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7747 [(set_attr "type" "mftgpr")])
7749 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7750 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7751 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7752 UNSPEC_P8V_RELOAD_FROM_GPR))
7753 (clobber (match_operand:IF 2 "register_operand" "=d"))]
7754 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7756 "&& reload_completed"
7759 rtx dest = operands[0];
7760 rtx src = operands[1];
7761 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7762 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7763 rtx gpr_hi_reg = gen_highpart (SImode, src);
7764 rtx gpr_lo_reg = gen_lowpart (SImode, src);
7766 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7767 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7768 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7771 [(set_attr "length" "12")
7772 (set_attr "type" "three")])
7774 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7775 (define_insn "p8_mtvsrd_df"
7776 [(set (match_operand:DF 0 "register_operand" "=wa")
7777 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7778 UNSPEC_P8V_MTVSRD))]
7779 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7781 [(set_attr "type" "mftgpr")])
7783 (define_insn "p8_xxpermdi_<mode>"
7784 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7785 (unspec:FMOVE128_GPR [
7786 (match_operand:DF 1 "register_operand" "wa")
7787 (match_operand:DF 2 "register_operand" "wa")]
7788 UNSPEC_P8V_XXPERMDI))]
7789 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7790 "xxpermdi %x0,%x1,%x2,0"
7791 [(set_attr "type" "vecperm")])
7793 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7794 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7795 (unspec:FMOVE128_GPR
7796 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7797 UNSPEC_P8V_RELOAD_FROM_GPR))
7798 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
7799 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7801 "&& reload_completed"
7804 rtx dest = operands[0];
7805 rtx src = operands[1];
7806 /* You might think that we could use op0 as one temp and a DF clobber
7807 as op2, but you'd be wrong. Secondary reload move patterns don't
7808 check for overlap of the clobber and the destination. */
7809 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7810 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7811 rtx gpr_hi_reg = gen_highpart (DImode, src);
7812 rtx gpr_lo_reg = gen_lowpart (DImode, src);
7814 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
7815 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
7816 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
7819 [(set_attr "length" "12")
7820 (set_attr "type" "three")])
7823 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7824 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7826 && (int_reg_operand (operands[0], <MODE>mode)
7827 || int_reg_operand (operands[1], <MODE>mode))
7828 && (!TARGET_DIRECT_MOVE_128
7829 || (!vsx_register_operand (operands[0], <MODE>mode)
7830 && !vsx_register_operand (operands[1], <MODE>mode)))"
7832 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7834 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
7835 ;; type is stored internally as double precision in the VSX registers, we have
7836 ;; to convert it from the vector format.
7837 (define_insn "p8_mtvsrd_sf"
7838 [(set (match_operand:SF 0 "register_operand" "=wa")
7839 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
7840 UNSPEC_P8V_MTVSRD))]
7841 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7843 [(set_attr "type" "mftgpr")])
7845 (define_insn_and_split "reload_vsx_from_gprsf"
7846 [(set (match_operand:SF 0 "register_operand" "=wa")
7847 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7848 UNSPEC_P8V_RELOAD_FROM_GPR))
7849 (clobber (match_operand:DI 2 "register_operand" "=r"))]
7850 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7852 "&& reload_completed"
7855 rtx op0 = operands[0];
7856 rtx op1 = operands[1];
7857 rtx op2 = operands[2];
7858 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7860 /* Move SF value to upper 32-bits for xscvspdpn. */
7861 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7862 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7863 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7866 [(set_attr "length" "8")
7867 (set_attr "type" "two")])
7869 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7870 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7871 ;; and then doing a move of that.
7872 (define_insn "p8_mfvsrd_3_<mode>"
7873 [(set (match_operand:DF 0 "register_operand" "=r")
7874 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7875 UNSPEC_P8V_RELOAD_FROM_VSX))]
7876 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7878 [(set_attr "type" "mftgpr")])
7880 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7881 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7882 (unspec:FMOVE128_GPR
7883 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7884 UNSPEC_P8V_RELOAD_FROM_VSX))
7885 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7886 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7888 "&& reload_completed"
7891 rtx dest = operands[0];
7892 rtx src = operands[1];
7893 rtx tmp = operands[2];
7894 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7895 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7897 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7898 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7899 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7902 [(set_attr "length" "12")
7903 (set_attr "type" "three")])
7905 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
7906 ;; type is stored internally as double precision, we have to convert it to the
7909 (define_insn_and_split "reload_gpr_from_vsxsf"
7910 [(set (match_operand:SF 0 "register_operand" "=r")
7911 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7912 UNSPEC_P8V_RELOAD_FROM_VSX))
7913 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7914 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7916 "&& reload_completed"
7919 rtx op0 = operands[0];
7920 rtx op1 = operands[1];
7921 rtx op2 = operands[2];
7922 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7924 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7925 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7926 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7929 [(set_attr "length" "12")
7930 (set_attr "type" "three")])
7932 (define_insn "p8_mfvsrd_4_disf"
7933 [(set (match_operand:DI 0 "register_operand" "=r")
7934 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7935 UNSPEC_P8V_RELOAD_FROM_VSX))]
7936 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7938 [(set_attr "type" "mftgpr")])
7941 ;; Next come the multi-word integer load and store and the load and store
7944 ;; List r->r after r->Y, otherwise reload will try to reload a
7945 ;; non-offsettable address by using r->r which won't make progress.
7946 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7947 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7949 ;; GPR store GPR load GPR move FPR store FPR load FPR move
7950 ;; GPR const AVX store AVX store AVX load AVX load VSX move
7951 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
7954 (define_insn "*movdi_internal32"
7955 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
7956 "=Y, r, r, ?m, ?*d, ?*d,
7957 r, ?wY, ?Z, ?*wb, ?*wv, ?wi,
7958 ?wo, ?wo, ?wv, ?wi, ?wi, ?wv,
7961 (match_operand:DI 1 "input_operand"
7963 IJKnGHF, wb, wv, wY, Z, wi,
7964 Oj, wM, OjwM, Oj, wM, wS,
7968 && (gpc_reg_operand (operands[0], DImode)
7969 || gpc_reg_operand (operands[1], DImode))"
7991 "store, load, *, fpstore, fpload, fpsimple,
7992 *, fpstore, fpstore, fpload, fpload, veclogical,
7993 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
7995 (set_attr "size" "64")])
7998 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7999 (match_operand:DI 1 "const_int_operand" ""))]
8000 "! TARGET_POWERPC64 && reload_completed
8001 && gpr_or_gpr_p (operands[0], operands[1])
8002 && !direct_move_p (operands[0], operands[1])"
8003 [(set (match_dup 2) (match_dup 4))
8004 (set (match_dup 3) (match_dup 1))]
8007 HOST_WIDE_INT value = INTVAL (operands[1]);
8008 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8010 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8012 operands[4] = GEN_INT (value >> 32);
8013 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8017 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8018 (match_operand:DIFD 1 "input_operand" ""))]
8019 "reload_completed && !TARGET_POWERPC64
8020 && gpr_or_gpr_p (operands[0], operands[1])
8021 && !direct_move_p (operands[0], operands[1])"
8023 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8025 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8026 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8027 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8028 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8029 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8030 (define_insn "*movdi_internal64"
8031 [(set (match_operand:DI 0 "nonimmediate_operand"
8033 ?m, ?*d, ?*d, ?wY, ?Z, ?*wb,
8034 ?*wv, ?wi, ?wo, ?wo, ?wv, ?wi,
8035 ?wi, ?wv, ?wv, r, *h, *h,
8036 ?*r, ?*wg, ?*r, ?*wj")
8038 (match_operand:DI 1 "input_operand"
8040 d, m, d, wb, wv, wY,
8041 Z, wi, Oj, wM, OjwM, Oj,
8042 wM, wS, wB, *h, r, 0,
8046 && (gpc_reg_operand (operands[0], DImode)
8047 || gpc_reg_operand (operands[1], DImode))"
8078 "store, load, *, *, *, *,
8079 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8080 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8081 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8082 mftgpr, mffgpr, mftgpr, mffgpr")
8084 (set_attr "size" "64")
8092 ; Some DImode loads are best done as a load of -1 followed by a mask
8095 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8096 (match_operand:DI 1 "const_int_operand"))]
8098 && num_insns_constant (operands[1], DImode) > 1
8099 && rs6000_is_valid_and_mask (operands[1], DImode)"
8103 (and:DI (match_dup 0)
8107 ;; Split a load of a large constant into the appropriate five-instruction
8108 ;; sequence. Handle anything in a constant number of insns.
8109 ;; When non-easy constants can go in the TOC, this should use
8110 ;; easy_fp_constant predicate.
8112 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8113 (match_operand:DI 1 "const_int_operand" ""))]
8114 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8115 [(set (match_dup 0) (match_dup 2))
8116 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8119 if (rs6000_emit_set_const (operands[0], operands[1]))
8126 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8127 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8128 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8129 [(set (match_dup 0) (match_dup 2))
8130 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8133 if (rs6000_emit_set_const (operands[0], operands[1]))
8140 [(set (match_operand:DI 0 "altivec_register_operand" "")
8141 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8142 "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8145 rtx op0 = operands[0];
8146 rtx op1 = operands[1];
8147 int r = REGNO (op0);
8148 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8150 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8151 if (op1 != const0_rtx && op1 != constm1_rtx)
8153 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8154 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8160 [(set (match_operand:DI 0 "altivec_register_operand" "")
8161 (match_operand:DI 1 "xxspltib_constant_split" ""))]
8162 "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8165 rtx op0 = operands[0];
8166 rtx op1 = operands[1];
8167 int r = REGNO (op0);
8168 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8170 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8171 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8176 ;; TImode/PTImode is similar, except that we usually want to compute the
8177 ;; address into a register and use lsi/stsi (the exception is during reload).
8179 (define_insn "*mov<mode>_string"
8180 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8181 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8183 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8184 && (gpc_reg_operand (operands[0], <MODE>mode)
8185 || gpc_reg_operand (operands[1], <MODE>mode))"
8188 switch (which_alternative)
8194 return \"stswi %1,%P0,16\";
8199 /* If the address is not used in the output, we can use lsi. Otherwise,
8200 fall through to generating four loads. */
8202 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8203 return \"lswi %0,%P1,16\";
8211 [(set_attr "type" "store,store,load,load,*,*")
8212 (set_attr "update" "yes")
8213 (set_attr "indexed" "yes")
8214 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8215 (const_string "always")
8216 (const_string "conditional")))])
8218 (define_insn "*mov<mode>_ppc64"
8219 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8220 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8221 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8222 && (gpc_reg_operand (operands[0], <MODE>mode)
8223 || gpc_reg_operand (operands[1], <MODE>mode)))"
8225 return rs6000_output_move_128bit (operands);
8227 [(set_attr "type" "store,store,load,load,*,*")
8228 (set_attr "length" "8")])
8231 [(set (match_operand:TI2 0 "int_reg_operand" "")
8232 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8234 && (VECTOR_MEM_NONE_P (<MODE>mode)
8235 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8236 [(set (match_dup 2) (match_dup 4))
8237 (set (match_dup 3) (match_dup 5))]
8240 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8242 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8244 if (CONST_WIDE_INT_P (operands[1]))
8246 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8247 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8249 else if (CONST_INT_P (operands[1]))
8251 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8252 operands[5] = operands[1];
8259 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8260 (match_operand:TI2 1 "input_operand" ""))]
8262 && gpr_or_gpr_p (operands[0], operands[1])
8263 && !direct_move_p (operands[0], operands[1])
8264 && !quad_load_store_p (operands[0], operands[1])"
8266 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8268 (define_expand "load_multiple"
8269 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8270 (match_operand:SI 1 "" ""))
8271 (use (match_operand:SI 2 "" ""))])]
8272 "TARGET_STRING && !TARGET_POWERPC64"
8280 /* Support only loading a constant number of fixed-point registers from
8281 memory and only bother with this if more than two; the machine
8282 doesn't support more than eight. */
8283 if (GET_CODE (operands[2]) != CONST_INT
8284 || INTVAL (operands[2]) <= 2
8285 || INTVAL (operands[2]) > 8
8286 || GET_CODE (operands[1]) != MEM
8287 || GET_CODE (operands[0]) != REG
8288 || REGNO (operands[0]) >= 32)
8291 count = INTVAL (operands[2]);
8292 regno = REGNO (operands[0]);
8294 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8295 op1 = replace_equiv_address (operands[1],
8296 force_reg (SImode, XEXP (operands[1], 0)));
8298 for (i = 0; i < count; i++)
8299 XVECEXP (operands[3], 0, i)
8300 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8301 adjust_address_nv (op1, SImode, i * 4));
8304 (define_insn "*ldmsi8"
8305 [(match_parallel 0 "load_multiple_operation"
8306 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8307 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8308 (set (match_operand:SI 3 "gpc_reg_operand" "")
8309 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8310 (set (match_operand:SI 4 "gpc_reg_operand" "")
8311 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8312 (set (match_operand:SI 5 "gpc_reg_operand" "")
8313 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8314 (set (match_operand:SI 6 "gpc_reg_operand" "")
8315 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8316 (set (match_operand:SI 7 "gpc_reg_operand" "")
8317 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8318 (set (match_operand:SI 8 "gpc_reg_operand" "")
8319 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8320 (set (match_operand:SI 9 "gpc_reg_operand" "")
8321 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8322 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8324 { return rs6000_output_load_multiple (operands); }"
8325 [(set_attr "type" "load")
8326 (set_attr "update" "yes")
8327 (set_attr "indexed" "yes")
8328 (set_attr "length" "32")])
8330 (define_insn "*ldmsi7"
8331 [(match_parallel 0 "load_multiple_operation"
8332 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8333 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8334 (set (match_operand:SI 3 "gpc_reg_operand" "")
8335 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8336 (set (match_operand:SI 4 "gpc_reg_operand" "")
8337 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8338 (set (match_operand:SI 5 "gpc_reg_operand" "")
8339 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8340 (set (match_operand:SI 6 "gpc_reg_operand" "")
8341 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8342 (set (match_operand:SI 7 "gpc_reg_operand" "")
8343 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8344 (set (match_operand:SI 8 "gpc_reg_operand" "")
8345 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8346 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8348 { return rs6000_output_load_multiple (operands); }"
8349 [(set_attr "type" "load")
8350 (set_attr "update" "yes")
8351 (set_attr "indexed" "yes")
8352 (set_attr "length" "32")])
8354 (define_insn "*ldmsi6"
8355 [(match_parallel 0 "load_multiple_operation"
8356 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8357 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8358 (set (match_operand:SI 3 "gpc_reg_operand" "")
8359 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8360 (set (match_operand:SI 4 "gpc_reg_operand" "")
8361 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8362 (set (match_operand:SI 5 "gpc_reg_operand" "")
8363 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8364 (set (match_operand:SI 6 "gpc_reg_operand" "")
8365 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8366 (set (match_operand:SI 7 "gpc_reg_operand" "")
8367 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8368 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8370 { return rs6000_output_load_multiple (operands); }"
8371 [(set_attr "type" "load")
8372 (set_attr "update" "yes")
8373 (set_attr "indexed" "yes")
8374 (set_attr "length" "32")])
8376 (define_insn "*ldmsi5"
8377 [(match_parallel 0 "load_multiple_operation"
8378 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8379 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8380 (set (match_operand:SI 3 "gpc_reg_operand" "")
8381 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8382 (set (match_operand:SI 4 "gpc_reg_operand" "")
8383 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8384 (set (match_operand:SI 5 "gpc_reg_operand" "")
8385 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8386 (set (match_operand:SI 6 "gpc_reg_operand" "")
8387 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8388 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8390 { return rs6000_output_load_multiple (operands); }"
8391 [(set_attr "type" "load")
8392 (set_attr "update" "yes")
8393 (set_attr "indexed" "yes")
8394 (set_attr "length" "32")])
8396 (define_insn "*ldmsi4"
8397 [(match_parallel 0 "load_multiple_operation"
8398 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8399 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8400 (set (match_operand:SI 3 "gpc_reg_operand" "")
8401 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8402 (set (match_operand:SI 4 "gpc_reg_operand" "")
8403 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8404 (set (match_operand:SI 5 "gpc_reg_operand" "")
8405 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8406 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8408 { return rs6000_output_load_multiple (operands); }"
8409 [(set_attr "type" "load")
8410 (set_attr "update" "yes")
8411 (set_attr "indexed" "yes")
8412 (set_attr "length" "32")])
8414 (define_insn "*ldmsi3"
8415 [(match_parallel 0 "load_multiple_operation"
8416 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8417 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8418 (set (match_operand:SI 3 "gpc_reg_operand" "")
8419 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8420 (set (match_operand:SI 4 "gpc_reg_operand" "")
8421 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8422 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8424 { return rs6000_output_load_multiple (operands); }"
8425 [(set_attr "type" "load")
8426 (set_attr "update" "yes")
8427 (set_attr "indexed" "yes")
8428 (set_attr "length" "32")])
8430 (define_expand "store_multiple"
8431 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8432 (match_operand:SI 1 "" ""))
8433 (clobber (scratch:SI))
8434 (use (match_operand:SI 2 "" ""))])]
8435 "TARGET_STRING && !TARGET_POWERPC64"
8444 /* Support only storing a constant number of fixed-point registers to
8445 memory and only bother with this if more than two; the machine
8446 doesn't support more than eight. */
8447 if (GET_CODE (operands[2]) != CONST_INT
8448 || INTVAL (operands[2]) <= 2
8449 || INTVAL (operands[2]) > 8
8450 || GET_CODE (operands[0]) != MEM
8451 || GET_CODE (operands[1]) != REG
8452 || REGNO (operands[1]) >= 32)
8455 count = INTVAL (operands[2]);
8456 regno = REGNO (operands[1]);
8458 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8459 to = force_reg (SImode, XEXP (operands[0], 0));
8460 op0 = replace_equiv_address (operands[0], to);
8462 XVECEXP (operands[3], 0, 0)
8463 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8464 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8465 gen_rtx_SCRATCH (SImode));
8467 for (i = 1; i < count; i++)
8468 XVECEXP (operands[3], 0, i + 1)
8469 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8470 gen_rtx_REG (SImode, regno + i));
8473 (define_insn "*stmsi8"
8474 [(match_parallel 0 "store_multiple_operation"
8475 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8476 (match_operand:SI 2 "gpc_reg_operand" "r"))
8477 (clobber (match_scratch:SI 3 "=X"))
8478 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8479 (match_operand:SI 4 "gpc_reg_operand" "r"))
8480 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8481 (match_operand:SI 5 "gpc_reg_operand" "r"))
8482 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8483 (match_operand:SI 6 "gpc_reg_operand" "r"))
8484 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8485 (match_operand:SI 7 "gpc_reg_operand" "r"))
8486 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8487 (match_operand:SI 8 "gpc_reg_operand" "r"))
8488 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8489 (match_operand:SI 9 "gpc_reg_operand" "r"))
8490 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8491 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8492 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8494 [(set_attr "type" "store")
8495 (set_attr "update" "yes")
8496 (set_attr "indexed" "yes")
8497 (set_attr "cell_micro" "always")])
8499 (define_insn "*stmsi7"
8500 [(match_parallel 0 "store_multiple_operation"
8501 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8502 (match_operand:SI 2 "gpc_reg_operand" "r"))
8503 (clobber (match_scratch:SI 3 "=X"))
8504 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8505 (match_operand:SI 4 "gpc_reg_operand" "r"))
8506 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8507 (match_operand:SI 5 "gpc_reg_operand" "r"))
8508 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8509 (match_operand:SI 6 "gpc_reg_operand" "r"))
8510 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8511 (match_operand:SI 7 "gpc_reg_operand" "r"))
8512 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8513 (match_operand:SI 8 "gpc_reg_operand" "r"))
8514 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8515 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8516 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8518 [(set_attr "type" "store")
8519 (set_attr "update" "yes")
8520 (set_attr "indexed" "yes")
8521 (set_attr "cell_micro" "always")])
8523 (define_insn "*stmsi6"
8524 [(match_parallel 0 "store_multiple_operation"
8525 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8526 (match_operand:SI 2 "gpc_reg_operand" "r"))
8527 (clobber (match_scratch:SI 3 "=X"))
8528 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8529 (match_operand:SI 4 "gpc_reg_operand" "r"))
8530 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8531 (match_operand:SI 5 "gpc_reg_operand" "r"))
8532 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8533 (match_operand:SI 6 "gpc_reg_operand" "r"))
8534 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8535 (match_operand:SI 7 "gpc_reg_operand" "r"))
8536 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8537 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8538 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8540 [(set_attr "type" "store")
8541 (set_attr "update" "yes")
8542 (set_attr "indexed" "yes")
8543 (set_attr "cell_micro" "always")])
8545 (define_insn "*stmsi5"
8546 [(match_parallel 0 "store_multiple_operation"
8547 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8548 (match_operand:SI 2 "gpc_reg_operand" "r"))
8549 (clobber (match_scratch:SI 3 "=X"))
8550 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8551 (match_operand:SI 4 "gpc_reg_operand" "r"))
8552 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8553 (match_operand:SI 5 "gpc_reg_operand" "r"))
8554 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8555 (match_operand:SI 6 "gpc_reg_operand" "r"))
8556 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8557 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8558 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8560 [(set_attr "type" "store")
8561 (set_attr "update" "yes")
8562 (set_attr "indexed" "yes")
8563 (set_attr "cell_micro" "always")])
8565 (define_insn "*stmsi4"
8566 [(match_parallel 0 "store_multiple_operation"
8567 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8568 (match_operand:SI 2 "gpc_reg_operand" "r"))
8569 (clobber (match_scratch:SI 3 "=X"))
8570 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8571 (match_operand:SI 4 "gpc_reg_operand" "r"))
8572 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8573 (match_operand:SI 5 "gpc_reg_operand" "r"))
8574 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8575 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8576 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8578 [(set_attr "type" "store")
8579 (set_attr "update" "yes")
8580 (set_attr "indexed" "yes")
8581 (set_attr "cell_micro" "always")])
8583 (define_insn "*stmsi3"
8584 [(match_parallel 0 "store_multiple_operation"
8585 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8586 (match_operand:SI 2 "gpc_reg_operand" "r"))
8587 (clobber (match_scratch:SI 3 "=X"))
8588 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8589 (match_operand:SI 4 "gpc_reg_operand" "r"))
8590 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8591 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8592 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8594 [(set_attr "type" "store")
8595 (set_attr "update" "yes")
8596 (set_attr "indexed" "yes")
8597 (set_attr "cell_micro" "always")])
8599 (define_expand "setmemsi"
8600 [(parallel [(set (match_operand:BLK 0 "" "")
8601 (match_operand 2 "const_int_operand" ""))
8602 (use (match_operand:SI 1 "" ""))
8603 (use (match_operand:SI 3 "" ""))])]
8607 /* If value to set is not zero, use the library routine. */
8608 if (operands[2] != const0_rtx)
8611 if (expand_block_clear (operands))
8617 ;; String/block compare insn.
8618 ;; Argument 0 is the target (result)
8619 ;; Argument 1 is the destination
8620 ;; Argument 2 is the source
8621 ;; Argument 3 is the length
8622 ;; Argument 4 is the alignment
8624 (define_expand "cmpmemsi"
8625 [(parallel [(set (match_operand:SI 0)
8626 (compare:SI (match_operand:BLK 1)
8627 (match_operand:BLK 2)))
8628 (use (match_operand:SI 3))
8629 (use (match_operand:SI 4))])]
8632 if (expand_block_compare (operands))
8638 ;; String/block move insn.
8639 ;; Argument 0 is the destination
8640 ;; Argument 1 is the source
8641 ;; Argument 2 is the length
8642 ;; Argument 3 is the alignment
8644 (define_expand "movmemsi"
8645 [(parallel [(set (match_operand:BLK 0 "" "")
8646 (match_operand:BLK 1 "" ""))
8647 (use (match_operand:SI 2 "" ""))
8648 (use (match_operand:SI 3 "" ""))])]
8652 if (expand_block_move (operands))
8658 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
8659 ;; register allocator doesn't have a clue about allocating 8 word registers.
8660 ;; rD/rS = r5 is preferred, efficient form.
8661 (define_expand "movmemsi_8reg"
8662 [(parallel [(set (match_operand 0 "" "")
8663 (match_operand 1 "" ""))
8664 (use (match_operand 2 "" ""))
8665 (use (match_operand 3 "" ""))
8666 (clobber (reg:SI 5))
8667 (clobber (reg:SI 6))
8668 (clobber (reg:SI 7))
8669 (clobber (reg:SI 8))
8670 (clobber (reg:SI 9))
8671 (clobber (reg:SI 10))
8672 (clobber (reg:SI 11))
8673 (clobber (reg:SI 12))
8674 (clobber (match_scratch:SI 4 ""))])]
8679 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8680 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8681 (use (match_operand:SI 2 "immediate_operand" "i"))
8682 (use (match_operand:SI 3 "immediate_operand" "i"))
8683 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8684 (clobber (reg:SI 6))
8685 (clobber (reg:SI 7))
8686 (clobber (reg:SI 8))
8687 (clobber (reg:SI 9))
8688 (clobber (reg:SI 10))
8689 (clobber (reg:SI 11))
8690 (clobber (reg:SI 12))
8691 (clobber (match_scratch:SI 5 "=X"))]
8693 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8694 || INTVAL (operands[2]) == 0)
8695 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8696 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8697 && REGNO (operands[4]) == 5"
8698 "lswi %4,%1,%2\;stswi %4,%0,%2"
8699 [(set_attr "type" "store")
8700 (set_attr "update" "yes")
8701 (set_attr "indexed" "yes")
8702 (set_attr "cell_micro" "always")
8703 (set_attr "length" "8")])
8705 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
8706 ;; register allocator doesn't have a clue about allocating 6 word registers.
8707 ;; rD/rS = r5 is preferred, efficient form.
8708 (define_expand "movmemsi_6reg"
8709 [(parallel [(set (match_operand 0 "" "")
8710 (match_operand 1 "" ""))
8711 (use (match_operand 2 "" ""))
8712 (use (match_operand 3 "" ""))
8713 (clobber (reg:SI 5))
8714 (clobber (reg:SI 6))
8715 (clobber (reg:SI 7))
8716 (clobber (reg:SI 8))
8717 (clobber (reg:SI 9))
8718 (clobber (reg:SI 10))
8719 (clobber (match_scratch:SI 4 ""))])]
8724 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8725 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8726 (use (match_operand:SI 2 "immediate_operand" "i"))
8727 (use (match_operand:SI 3 "immediate_operand" "i"))
8728 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8729 (clobber (reg:SI 6))
8730 (clobber (reg:SI 7))
8731 (clobber (reg:SI 8))
8732 (clobber (reg:SI 9))
8733 (clobber (reg:SI 10))
8734 (clobber (match_scratch:SI 5 "=X"))]
8736 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8737 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8738 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8739 && REGNO (operands[4]) == 5"
8740 "lswi %4,%1,%2\;stswi %4,%0,%2"
8741 [(set_attr "type" "store")
8742 (set_attr "update" "yes")
8743 (set_attr "indexed" "yes")
8744 (set_attr "cell_micro" "always")
8745 (set_attr "length" "8")])
8747 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8748 ;; problems with TImode.
8749 ;; rD/rS = r5 is preferred, efficient form.
8750 (define_expand "movmemsi_4reg"
8751 [(parallel [(set (match_operand 0 "" "")
8752 (match_operand 1 "" ""))
8753 (use (match_operand 2 "" ""))
8754 (use (match_operand 3 "" ""))
8755 (clobber (reg:SI 5))
8756 (clobber (reg:SI 6))
8757 (clobber (reg:SI 7))
8758 (clobber (reg:SI 8))
8759 (clobber (match_scratch:SI 4 ""))])]
8764 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8765 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8766 (use (match_operand:SI 2 "immediate_operand" "i"))
8767 (use (match_operand:SI 3 "immediate_operand" "i"))
8768 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8769 (clobber (reg:SI 6))
8770 (clobber (reg:SI 7))
8771 (clobber (reg:SI 8))
8772 (clobber (match_scratch:SI 5 "=X"))]
8774 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8775 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8776 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8777 && REGNO (operands[4]) == 5"
8778 "lswi %4,%1,%2\;stswi %4,%0,%2"
8779 [(set_attr "type" "store")
8780 (set_attr "update" "yes")
8781 (set_attr "indexed" "yes")
8782 (set_attr "cell_micro" "always")
8783 (set_attr "length" "8")])
8785 ;; Move up to 8 bytes at a time.
8786 (define_expand "movmemsi_2reg"
8787 [(parallel [(set (match_operand 0 "" "")
8788 (match_operand 1 "" ""))
8789 (use (match_operand 2 "" ""))
8790 (use (match_operand 3 "" ""))
8791 (clobber (match_scratch:DI 4 ""))
8792 (clobber (match_scratch:SI 5 ""))])]
8793 "TARGET_STRING && ! TARGET_POWERPC64"
8797 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8798 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8799 (use (match_operand:SI 2 "immediate_operand" "i"))
8800 (use (match_operand:SI 3 "immediate_operand" "i"))
8801 (clobber (match_scratch:DI 4 "=&r"))
8802 (clobber (match_scratch:SI 5 "=X"))]
8803 "TARGET_STRING && ! TARGET_POWERPC64
8804 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8805 "lswi %4,%1,%2\;stswi %4,%0,%2"
8806 [(set_attr "type" "store")
8807 (set_attr "update" "yes")
8808 (set_attr "indexed" "yes")
8809 (set_attr "cell_micro" "always")
8810 (set_attr "length" "8")])
8812 ;; Move up to 4 bytes at a time.
8813 (define_expand "movmemsi_1reg"
8814 [(parallel [(set (match_operand 0 "" "")
8815 (match_operand 1 "" ""))
8816 (use (match_operand 2 "" ""))
8817 (use (match_operand 3 "" ""))
8818 (clobber (match_scratch:SI 4 ""))
8819 (clobber (match_scratch:SI 5 ""))])]
8824 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8825 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8826 (use (match_operand:SI 2 "immediate_operand" "i"))
8827 (use (match_operand:SI 3 "immediate_operand" "i"))
8828 (clobber (match_scratch:SI 4 "=&r"))
8829 (clobber (match_scratch:SI 5 "=X"))]
8830 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8831 "lswi %4,%1,%2\;stswi %4,%0,%2"
8832 [(set_attr "type" "store")
8833 (set_attr "update" "yes")
8834 (set_attr "indexed" "yes")
8835 (set_attr "cell_micro" "always")
8836 (set_attr "length" "8")])
8838 ;; Define insns that do load or store with update. Some of these we can
8839 ;; get by using pre-decrement or pre-increment, but the hardware can also
8840 ;; do cases where the increment is not the size of the object.
8842 ;; In all these cases, we use operands 0 and 1 for the register being
8843 ;; incremented because those are the operands that local-alloc will
8844 ;; tie and these are the pair most likely to be tieable (and the ones
8845 ;; that will benefit the most).
8847 (define_insn "*movdi_update1"
8848 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8849 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8850 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8851 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8852 (plus:DI (match_dup 1) (match_dup 2)))]
8853 "TARGET_POWERPC64 && TARGET_UPDATE
8854 && (!avoiding_indexed_address_p (DImode)
8855 || !gpc_reg_operand (operands[2], DImode))"
8859 [(set_attr "type" "load")
8860 (set_attr "update" "yes")
8861 (set_attr "indexed" "yes,no")])
8863 (define_insn "movdi_<mode>_update"
8864 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8865 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8866 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8867 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8868 (plus:P (match_dup 1) (match_dup 2)))]
8869 "TARGET_POWERPC64 && TARGET_UPDATE
8870 && (!avoiding_indexed_address_p (Pmode)
8871 || !gpc_reg_operand (operands[2], Pmode)
8872 || (REG_P (operands[0])
8873 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8877 [(set_attr "type" "store")
8878 (set_attr "update" "yes")
8879 (set_attr "indexed" "yes,no")])
8881 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8882 ;; needed for stack allocation, even if the user passes -mno-update.
8883 (define_insn "movdi_<mode>_update_stack"
8884 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8885 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8886 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8887 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8888 (plus:P (match_dup 1) (match_dup 2)))]
8893 [(set_attr "type" "store")
8894 (set_attr "update" "yes")
8895 (set_attr "indexed" "yes,no")])
8897 (define_insn "*movsi_update1"
8898 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8899 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8900 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8901 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8902 (plus:SI (match_dup 1) (match_dup 2)))]
8904 && (!avoiding_indexed_address_p (SImode)
8905 || !gpc_reg_operand (operands[2], SImode))"
8909 [(set_attr "type" "load")
8910 (set_attr "update" "yes")
8911 (set_attr "indexed" "yes,no")])
8913 (define_insn "*movsi_update2"
8914 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8916 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8917 (match_operand:DI 2 "gpc_reg_operand" "r")))))
8918 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8919 (plus:DI (match_dup 1) (match_dup 2)))]
8920 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8921 && !avoiding_indexed_address_p (DImode)"
8923 [(set_attr "type" "load")
8924 (set_attr "sign_extend" "yes")
8925 (set_attr "update" "yes")
8926 (set_attr "indexed" "yes")])
8928 (define_insn "movsi_update"
8929 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8930 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8931 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8932 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8933 (plus:SI (match_dup 1) (match_dup 2)))]
8935 && (!avoiding_indexed_address_p (SImode)
8936 || !gpc_reg_operand (operands[2], SImode)
8937 || (REG_P (operands[0])
8938 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8942 [(set_attr "type" "store")
8943 (set_attr "update" "yes")
8944 (set_attr "indexed" "yes,no")])
8946 ;; This is an unconditional pattern; needed for stack allocation, even
8947 ;; if the user passes -mno-update.
8948 (define_insn "movsi_update_stack"
8949 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8950 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8951 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8952 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8953 (plus:SI (match_dup 1) (match_dup 2)))]
8958 [(set_attr "type" "store")
8959 (set_attr "update" "yes")
8960 (set_attr "indexed" "yes,no")])
8962 (define_insn "*movhi_update1"
8963 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8964 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8965 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8966 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8967 (plus:SI (match_dup 1) (match_dup 2)))]
8969 && (!avoiding_indexed_address_p (SImode)
8970 || !gpc_reg_operand (operands[2], SImode))"
8974 [(set_attr "type" "load")
8975 (set_attr "update" "yes")
8976 (set_attr "indexed" "yes,no")])
8978 (define_insn "*movhi_update2"
8979 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8981 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8982 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8983 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8984 (plus:SI (match_dup 1) (match_dup 2)))]
8986 && (!avoiding_indexed_address_p (SImode)
8987 || !gpc_reg_operand (operands[2], SImode))"
8991 [(set_attr "type" "load")
8992 (set_attr "update" "yes")
8993 (set_attr "indexed" "yes,no")])
8995 (define_insn "*movhi_update3"
8996 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8998 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8999 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9000 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9001 (plus:SI (match_dup 1) (match_dup 2)))]
9002 "TARGET_UPDATE && rs6000_gen_cell_microcode
9003 && (!avoiding_indexed_address_p (SImode)
9004 || !gpc_reg_operand (operands[2], SImode))"
9008 [(set_attr "type" "load")
9009 (set_attr "sign_extend" "yes")
9010 (set_attr "update" "yes")
9011 (set_attr "indexed" "yes,no")])
9013 (define_insn "*movhi_update4"
9014 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9015 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9016 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9017 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9018 (plus:SI (match_dup 1) (match_dup 2)))]
9020 && (!avoiding_indexed_address_p (SImode)
9021 || !gpc_reg_operand (operands[2], SImode))"
9025 [(set_attr "type" "store")
9026 (set_attr "update" "yes")
9027 (set_attr "indexed" "yes,no")])
9029 (define_insn "*movqi_update1"
9030 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9031 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9032 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9033 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9034 (plus:SI (match_dup 1) (match_dup 2)))]
9036 && (!avoiding_indexed_address_p (SImode)
9037 || !gpc_reg_operand (operands[2], SImode))"
9041 [(set_attr "type" "load")
9042 (set_attr "update" "yes")
9043 (set_attr "indexed" "yes,no")])
9045 (define_insn "*movqi_update2"
9046 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9048 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9049 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9050 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9051 (plus:SI (match_dup 1) (match_dup 2)))]
9053 && (!avoiding_indexed_address_p (SImode)
9054 || !gpc_reg_operand (operands[2], SImode))"
9058 [(set_attr "type" "load")
9059 (set_attr "update" "yes")
9060 (set_attr "indexed" "yes,no")])
9062 (define_insn "*movqi_update3"
9063 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9064 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9065 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9066 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9067 (plus:SI (match_dup 1) (match_dup 2)))]
9069 && (!avoiding_indexed_address_p (SImode)
9070 || !gpc_reg_operand (operands[2], SImode))"
9074 [(set_attr "type" "store")
9075 (set_attr "update" "yes")
9076 (set_attr "indexed" "yes,no")])
9078 (define_insn "*movsf_update1"
9079 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9080 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9081 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9082 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9083 (plus:SI (match_dup 1) (match_dup 2)))]
9084 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9085 && (!avoiding_indexed_address_p (SImode)
9086 || !gpc_reg_operand (operands[2], SImode))"
9090 [(set_attr "type" "fpload")
9091 (set_attr "update" "yes")
9092 (set_attr "indexed" "yes,no")])
9094 (define_insn "*movsf_update2"
9095 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9096 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9097 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9098 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9099 (plus:SI (match_dup 1) (match_dup 2)))]
9100 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9101 && (!avoiding_indexed_address_p (SImode)
9102 || !gpc_reg_operand (operands[2], SImode))"
9106 [(set_attr "type" "fpstore")
9107 (set_attr "update" "yes")
9108 (set_attr "indexed" "yes,no")])
9110 (define_insn "*movsf_update3"
9111 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9112 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9113 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9114 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9115 (plus:SI (match_dup 1) (match_dup 2)))]
9116 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9117 && (!avoiding_indexed_address_p (SImode)
9118 || !gpc_reg_operand (operands[2], SImode))"
9122 [(set_attr "type" "load")
9123 (set_attr "update" "yes")
9124 (set_attr "indexed" "yes,no")])
9126 (define_insn "*movsf_update4"
9127 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9128 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9129 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9130 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9131 (plus:SI (match_dup 1) (match_dup 2)))]
9132 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9133 && (!avoiding_indexed_address_p (SImode)
9134 || !gpc_reg_operand (operands[2], SImode))"
9138 [(set_attr "type" "store")
9139 (set_attr "update" "yes")
9140 (set_attr "indexed" "yes,no")])
9142 (define_insn "*movdf_update1"
9143 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9144 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9145 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9146 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9147 (plus:SI (match_dup 1) (match_dup 2)))]
9148 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9149 && (!avoiding_indexed_address_p (SImode)
9150 || !gpc_reg_operand (operands[2], SImode))"
9154 [(set_attr "type" "fpload")
9155 (set_attr "update" "yes")
9156 (set_attr "indexed" "yes,no")
9157 (set_attr "size" "64")])
9159 (define_insn "*movdf_update2"
9160 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9161 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9162 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9163 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9164 (plus:SI (match_dup 1) (match_dup 2)))]
9165 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9166 && (!avoiding_indexed_address_p (SImode)
9167 || !gpc_reg_operand (operands[2], SImode))"
9171 [(set_attr "type" "fpstore")
9172 (set_attr "update" "yes")
9173 (set_attr "indexed" "yes,no")])
9176 ;; After inserting conditional returns we can sometimes have
9177 ;; unnecessary register moves. Unfortunately we cannot have a
9178 ;; modeless peephole here, because some single SImode sets have early
9179 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9180 ;; sequences, using get_attr_length here will smash the operands
9181 ;; array. Neither is there an early_cobbler_p predicate.
9182 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9183 ;; Also this optimization interferes with scalars going into
9184 ;; altivec registers (the code does reloading through the FPRs).
9186 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9187 (match_operand:DF 1 "any_operand" ""))
9188 (set (match_operand:DF 2 "gpc_reg_operand" "")
9190 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9191 && !TARGET_UPPER_REGS_DF
9192 && peep2_reg_dead_p (2, operands[0])"
9193 [(set (match_dup 2) (match_dup 1))])
9196 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9197 (match_operand:SF 1 "any_operand" ""))
9198 (set (match_operand:SF 2 "gpc_reg_operand" "")
9200 "!TARGET_UPPER_REGS_SF
9201 && peep2_reg_dead_p (2, operands[0])"
9202 [(set (match_dup 2) (match_dup 1))])
9207 ;; Mode attributes for different ABIs.
9208 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9209 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9210 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9211 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9213 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9214 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9215 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9216 (match_operand 4 "" "g")))
9217 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9218 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9220 (clobber (reg:SI LR_REGNO))]
9221 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9223 if (TARGET_CMODEL != CMODEL_SMALL)
9224 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9227 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9229 "&& TARGET_TLS_MARKERS"
9231 (unspec:TLSmode [(match_dup 1)
9234 (parallel [(set (match_dup 0)
9235 (call (mem:TLSmode (match_dup 3))
9237 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9238 (clobber (reg:SI LR_REGNO))])]
9240 [(set_attr "type" "two")
9241 (set (attr "length")
9242 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9246 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9247 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9248 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9249 (match_operand 4 "" "g")))
9250 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9251 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9253 (clobber (reg:SI LR_REGNO))]
9254 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9258 if (TARGET_SECURE_PLT && flag_pic == 2)
9259 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9261 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9264 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9266 "&& TARGET_TLS_MARKERS"
9268 (unspec:TLSmode [(match_dup 1)
9271 (parallel [(set (match_dup 0)
9272 (call (mem:TLSmode (match_dup 3))
9274 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9275 (clobber (reg:SI LR_REGNO))])]
9277 [(set_attr "type" "two")
9278 (set_attr "length" "8")])
9280 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9281 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9282 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9283 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9285 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9286 "addi %0,%1,%2@got@tlsgd"
9287 "&& TARGET_CMODEL != CMODEL_SMALL"
9290 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9292 (lo_sum:TLSmode (match_dup 3)
9293 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9296 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9298 [(set (attr "length")
9299 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9303 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9304 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9306 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9307 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9309 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9310 "addis %0,%1,%2@got@tlsgd@ha"
9311 [(set_attr "length" "4")])
9313 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9314 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9315 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9316 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9317 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9319 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9320 "addi %0,%1,%2@got@tlsgd@l"
9321 [(set_attr "length" "4")])
9323 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9324 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9325 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9326 (match_operand 2 "" "g")))
9327 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9329 (clobber (reg:SI LR_REGNO))]
9330 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9331 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9332 "bl %z1(%3@tlsgd)\;nop"
9333 [(set_attr "type" "branch")
9334 (set_attr "length" "8")])
9336 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9337 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9338 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9339 (match_operand 2 "" "g")))
9340 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9342 (clobber (reg:SI LR_REGNO))]
9343 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9347 if (TARGET_SECURE_PLT && flag_pic == 2)
9348 return "bl %z1+32768(%3@tlsgd)@plt";
9349 return "bl %z1(%3@tlsgd)@plt";
9351 return "bl %z1(%3@tlsgd)";
9353 [(set_attr "type" "branch")
9354 (set_attr "length" "4")])
9356 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9357 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9358 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9359 (match_operand 3 "" "g")))
9360 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9362 (clobber (reg:SI LR_REGNO))]
9363 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9365 if (TARGET_CMODEL != CMODEL_SMALL)
9366 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9369 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9371 "&& TARGET_TLS_MARKERS"
9373 (unspec:TLSmode [(match_dup 1)]
9375 (parallel [(set (match_dup 0)
9376 (call (mem:TLSmode (match_dup 2))
9378 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9379 (clobber (reg:SI LR_REGNO))])]
9381 [(set_attr "type" "two")
9382 (set (attr "length")
9383 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9387 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9388 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9389 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9390 (match_operand 3 "" "g")))
9391 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9393 (clobber (reg:SI LR_REGNO))]
9394 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9398 if (TARGET_SECURE_PLT && flag_pic == 2)
9399 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9401 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9404 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9406 "&& TARGET_TLS_MARKERS"
9408 (unspec:TLSmode [(match_dup 1)]
9410 (parallel [(set (match_dup 0)
9411 (call (mem:TLSmode (match_dup 2))
9413 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9414 (clobber (reg:SI LR_REGNO))])]
9416 [(set_attr "length" "8")])
9418 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9419 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9420 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9422 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9423 "addi %0,%1,%&@got@tlsld"
9424 "&& TARGET_CMODEL != CMODEL_SMALL"
9427 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9429 (lo_sum:TLSmode (match_dup 2)
9430 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9433 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9435 [(set (attr "length")
9436 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9440 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9441 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9443 (unspec:TLSmode [(const_int 0)
9444 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9446 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9447 "addis %0,%1,%&@got@tlsld@ha"
9448 [(set_attr "length" "4")])
9450 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9451 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9452 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9453 (unspec:TLSmode [(const_int 0)
9454 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9456 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9457 "addi %0,%1,%&@got@tlsld@l"
9458 [(set_attr "length" "4")])
9460 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9461 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9462 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9463 (match_operand 2 "" "g")))
9464 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9465 (clobber (reg:SI LR_REGNO))]
9466 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9467 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9468 "bl %z1(%&@tlsld)\;nop"
9469 [(set_attr "type" "branch")
9470 (set_attr "length" "8")])
9472 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9473 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9474 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9475 (match_operand 2 "" "g")))
9476 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9477 (clobber (reg:SI LR_REGNO))]
9478 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9482 if (TARGET_SECURE_PLT && flag_pic == 2)
9483 return "bl %z1+32768(%&@tlsld)@plt";
9484 return "bl %z1(%&@tlsld)@plt";
9486 return "bl %z1(%&@tlsld)";
9488 [(set_attr "type" "branch")
9489 (set_attr "length" "4")])
9491 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9492 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9493 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9494 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9497 "addi %0,%1,%2@dtprel")
9499 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9500 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9501 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9502 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9503 UNSPEC_TLSDTPRELHA))]
9505 "addis %0,%1,%2@dtprel@ha")
9507 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9508 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9509 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9510 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9511 UNSPEC_TLSDTPRELLO))]
9513 "addi %0,%1,%2@dtprel@l")
9515 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9516 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9517 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9518 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9519 UNSPEC_TLSGOTDTPREL))]
9521 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9522 "&& TARGET_CMODEL != CMODEL_SMALL"
9525 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9527 (lo_sum:TLSmode (match_dup 3)
9528 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9531 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9533 [(set (attr "length")
9534 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9538 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9539 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9541 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9542 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9543 UNSPEC_TLSGOTDTPREL)))]
9544 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9545 "addis %0,%1,%2@got@dtprel@ha"
9546 [(set_attr "length" "4")])
9548 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9549 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9550 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9551 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9552 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9553 UNSPEC_TLSGOTDTPREL)))]
9554 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9555 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9556 [(set_attr "length" "4")])
9558 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9559 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9560 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9561 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9564 "addi %0,%1,%2@tprel")
9566 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9567 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9568 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9569 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9570 UNSPEC_TLSTPRELHA))]
9572 "addis %0,%1,%2@tprel@ha")
9574 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9575 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9576 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9577 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9578 UNSPEC_TLSTPRELLO))]
9580 "addi %0,%1,%2@tprel@l")
9582 ;; "b" output constraint here and on tls_tls input to support linker tls
9583 ;; optimization. The linker may edit the instructions emitted by a
9584 ;; tls_got_tprel/tls_tls pair to addis,addi.
9585 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9586 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9587 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9588 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9589 UNSPEC_TLSGOTTPREL))]
9591 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9592 "&& TARGET_CMODEL != CMODEL_SMALL"
9595 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9597 (lo_sum:TLSmode (match_dup 3)
9598 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9601 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9603 [(set (attr "length")
9604 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9608 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9609 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9611 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9612 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9613 UNSPEC_TLSGOTTPREL)))]
9614 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9615 "addis %0,%1,%2@got@tprel@ha"
9616 [(set_attr "length" "4")])
9618 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9619 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9620 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9621 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9622 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9623 UNSPEC_TLSGOTTPREL)))]
9624 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9625 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9626 [(set_attr "length" "4")])
9628 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9629 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9630 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9631 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9633 "TARGET_ELF && HAVE_AS_TLS"
9636 (define_expand "tls_get_tpointer"
9637 [(set (match_operand:SI 0 "gpc_reg_operand" "")
9638 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9639 "TARGET_XCOFF && HAVE_AS_TLS"
9642 emit_insn (gen_tls_get_tpointer_internal ());
9643 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9647 (define_insn "tls_get_tpointer_internal"
9649 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9650 (clobber (reg:SI LR_REGNO))]
9651 "TARGET_XCOFF && HAVE_AS_TLS"
9652 "bla __get_tpointer")
9654 (define_expand "tls_get_addr<mode>"
9655 [(set (match_operand:P 0 "gpc_reg_operand" "")
9656 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9657 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9658 "TARGET_XCOFF && HAVE_AS_TLS"
9661 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9662 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9663 emit_insn (gen_tls_get_addr_internal<mode> ());
9664 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9668 (define_insn "tls_get_addr_internal<mode>"
9670 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9674 (clobber (reg:P 11))
9675 (clobber (reg:CC CR0_REGNO))
9676 (clobber (reg:P LR_REGNO))]
9677 "TARGET_XCOFF && HAVE_AS_TLS"
9678 "bla __tls_get_addr")
9680 ;; Next come insns related to the calling sequence.
9682 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9683 ;; We move the back-chain and decrement the stack pointer.
9685 (define_expand "allocate_stack"
9686 [(set (match_operand 0 "gpc_reg_operand" "")
9687 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9689 (minus (reg 1) (match_dup 1)))]
9692 { rtx chain = gen_reg_rtx (Pmode);
9693 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9695 rtx insn, par, set, mem;
9697 emit_move_insn (chain, stack_bot);
9699 /* Check stack bounds if necessary. */
9700 if (crtl->limit_stack)
9703 available = expand_binop (Pmode, sub_optab,
9704 stack_pointer_rtx, stack_limit_rtx,
9705 NULL_RTX, 1, OPTAB_WIDEN);
9706 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9709 if (GET_CODE (operands[1]) != CONST_INT
9710 || INTVAL (operands[1]) < -32767
9711 || INTVAL (operands[1]) > 32768)
9713 neg_op0 = gen_reg_rtx (Pmode);
9715 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9717 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9720 neg_op0 = GEN_INT (- INTVAL (operands[1]));
9722 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9723 : gen_movdi_di_update_stack))
9724 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9726 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9727 it now and set the alias set/attributes. The above gen_*_update
9728 calls will generate a PARALLEL with the MEM set being the first
9730 par = PATTERN (insn);
9731 gcc_assert (GET_CODE (par) == PARALLEL);
9732 set = XVECEXP (par, 0, 0);
9733 gcc_assert (GET_CODE (set) == SET);
9734 mem = SET_DEST (set);
9735 gcc_assert (MEM_P (mem));
9736 MEM_NOTRAP_P (mem) = 1;
9737 set_mem_alias_set (mem, get_frame_alias_set ());
9739 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9743 ;; These patterns say how to save and restore the stack pointer. We need not
9744 ;; save the stack pointer at function level since we are careful to
9745 ;; preserve the backchain. At block level, we have to restore the backchain
9746 ;; when we restore the stack pointer.
9748 ;; For nonlocal gotos, we must save both the stack pointer and its
9749 ;; backchain and restore both. Note that in the nonlocal case, the
9750 ;; save area is a memory location.
9752 (define_expand "save_stack_function"
9753 [(match_operand 0 "any_operand" "")
9754 (match_operand 1 "any_operand" "")]
9758 (define_expand "restore_stack_function"
9759 [(match_operand 0 "any_operand" "")
9760 (match_operand 1 "any_operand" "")]
9764 ;; Adjust stack pointer (op0) to a new value (op1).
9765 ;; First copy old stack backchain to new location, and ensure that the
9766 ;; scheduler won't reorder the sp assignment before the backchain write.
9767 (define_expand "restore_stack_block"
9768 [(set (match_dup 2) (match_dup 3))
9769 (set (match_dup 4) (match_dup 2))
9771 (set (match_operand 0 "register_operand" "")
9772 (match_operand 1 "register_operand" ""))]
9778 operands[1] = force_reg (Pmode, operands[1]);
9779 operands[2] = gen_reg_rtx (Pmode);
9780 operands[3] = gen_frame_mem (Pmode, operands[0]);
9781 operands[4] = gen_frame_mem (Pmode, operands[1]);
9782 p = rtvec_alloc (1);
9783 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9785 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9788 (define_expand "save_stack_nonlocal"
9789 [(set (match_dup 3) (match_dup 4))
9790 (set (match_operand 0 "memory_operand" "") (match_dup 3))
9791 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9795 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9797 /* Copy the backchain to the first word, sp to the second. */
9798 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9799 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9800 operands[3] = gen_reg_rtx (Pmode);
9801 operands[4] = gen_frame_mem (Pmode, operands[1]);
9804 (define_expand "restore_stack_nonlocal"
9805 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9806 (set (match_dup 3) (match_dup 4))
9807 (set (match_dup 5) (match_dup 2))
9809 (set (match_operand 0 "register_operand" "") (match_dup 3))]
9813 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9816 /* Restore the backchain from the first word, sp from the second. */
9817 operands[2] = gen_reg_rtx (Pmode);
9818 operands[3] = gen_reg_rtx (Pmode);
9819 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9820 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9821 operands[5] = gen_frame_mem (Pmode, operands[3]);
9822 p = rtvec_alloc (1);
9823 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9825 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9828 ;; TOC register handling.
9830 ;; Code to initialize the TOC register...
9832 (define_insn "load_toc_aix_si"
9833 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9834 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9836 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9840 extern int need_toc_init;
9842 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9843 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9844 operands[2] = gen_rtx_REG (Pmode, 2);
9845 return \"lwz %0,%1(%2)\";
9847 [(set_attr "type" "load")
9848 (set_attr "update" "no")
9849 (set_attr "indexed" "no")])
9851 (define_insn "load_toc_aix_di"
9852 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9853 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9855 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9859 extern int need_toc_init;
9861 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9862 !TARGET_ELF || !TARGET_MINIMAL_TOC);
9864 strcat (buf, \"@toc\");
9865 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9866 operands[2] = gen_rtx_REG (Pmode, 2);
9867 return \"ld %0,%1(%2)\";
9869 [(set_attr "type" "load")
9870 (set_attr "update" "no")
9871 (set_attr "indexed" "no")])
9873 (define_insn "load_toc_v4_pic_si"
9874 [(set (reg:SI LR_REGNO)
9875 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9876 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9877 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9878 [(set_attr "type" "branch")
9879 (set_attr "length" "4")])
9881 (define_expand "load_toc_v4_PIC_1"
9882 [(parallel [(set (reg:SI LR_REGNO)
9883 (match_operand:SI 0 "immediate_operand" "s"))
9884 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9885 "TARGET_ELF && DEFAULT_ABI == ABI_V4
9886 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9889 (define_insn "load_toc_v4_PIC_1_normal"
9890 [(set (reg:SI LR_REGNO)
9891 (match_operand:SI 0 "immediate_operand" "s"))
9892 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9893 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9894 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9895 "bcl 20,31,%0\\n%0:"
9896 [(set_attr "type" "branch")
9897 (set_attr "length" "4")
9898 (set_attr "cannot_copy" "yes")])
9900 (define_insn "load_toc_v4_PIC_1_476"
9901 [(set (reg:SI LR_REGNO)
9902 (match_operand:SI 0 "immediate_operand" "s"))
9903 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9904 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9905 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9909 static char templ[32];
9911 get_ppc476_thunk_name (name);
9912 sprintf (templ, \"bl %s\\n%%0:\", name);
9915 [(set_attr "type" "branch")
9916 (set_attr "length" "4")
9917 (set_attr "cannot_copy" "yes")])
9919 (define_expand "load_toc_v4_PIC_1b"
9920 [(parallel [(set (reg:SI LR_REGNO)
9921 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9922 (label_ref (match_operand 1 "" ""))]
9925 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9928 (define_insn "load_toc_v4_PIC_1b_normal"
9929 [(set (reg:SI LR_REGNO)
9930 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9931 (label_ref (match_operand 1 "" ""))]
9934 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9935 "bcl 20,31,$+8\;.long %0-$"
9936 [(set_attr "type" "branch")
9937 (set_attr "length" "8")])
9939 (define_insn "load_toc_v4_PIC_1b_476"
9940 [(set (reg:SI LR_REGNO)
9941 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9942 (label_ref (match_operand 1 "" ""))]
9945 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9949 static char templ[32];
9951 get_ppc476_thunk_name (name);
9952 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9955 [(set_attr "type" "branch")
9956 (set_attr "length" "16")])
9958 (define_insn "load_toc_v4_PIC_2"
9959 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9960 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9961 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9962 (match_operand:SI 3 "immediate_operand" "s")))))]
9963 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9965 [(set_attr "type" "load")])
9967 (define_insn "load_toc_v4_PIC_3b"
9968 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9969 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9971 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9972 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9973 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9974 "addis %0,%1,%2-%3@ha")
9976 (define_insn "load_toc_v4_PIC_3c"
9977 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9978 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9979 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9980 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9981 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9982 "addi %0,%1,%2-%3@l")
9984 ;; If the TOC is shared over a translation unit, as happens with all
9985 ;; the kinds of PIC that we support, we need to restore the TOC
9986 ;; pointer only when jumping over units of translation.
9987 ;; On Darwin, we need to reload the picbase.
9989 (define_expand "builtin_setjmp_receiver"
9990 [(use (label_ref (match_operand 0 "" "")))]
9991 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9992 || (TARGET_TOC && TARGET_MINIMAL_TOC)
9993 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9997 if (DEFAULT_ABI == ABI_DARWIN)
9999 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10000 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10004 crtl->uses_pic_offset_table = 1;
10005 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10006 CODE_LABEL_NUMBER (operands[0]));
10007 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10009 emit_insn (gen_load_macho_picbase (tmplabrtx));
10010 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10011 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10015 rs6000_emit_load_toc_table (FALSE);
10019 ;; Largetoc support
10020 (define_insn "*largetoc_high"
10021 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10023 (unspec [(match_operand:DI 1 "" "")
10024 (match_operand:DI 2 "gpc_reg_operand" "b")]
10026 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10027 "addis %0,%2,%1@toc@ha")
10029 (define_insn "*largetoc_high_aix<mode>"
10030 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10032 (unspec [(match_operand:P 1 "" "")
10033 (match_operand:P 2 "gpc_reg_operand" "b")]
10035 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10036 "addis %0,%1@u(%2)")
10038 (define_insn "*largetoc_high_plus"
10039 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10042 (unspec [(match_operand:DI 1 "" "")
10043 (match_operand:DI 2 "gpc_reg_operand" "b")]
10045 (match_operand:DI 3 "add_cint_operand" "n"))))]
10046 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10047 "addis %0,%2,%1+%3@toc@ha")
10049 (define_insn "*largetoc_high_plus_aix<mode>"
10050 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10053 (unspec [(match_operand:P 1 "" "")
10054 (match_operand:P 2 "gpc_reg_operand" "b")]
10056 (match_operand:P 3 "add_cint_operand" "n"))))]
10057 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10058 "addis %0,%1+%3@u(%2)")
10060 (define_insn "*largetoc_low"
10061 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10062 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10063 (match_operand:DI 2 "" "")))]
10064 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10067 (define_insn "*largetoc_low_aix<mode>"
10068 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10069 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10070 (match_operand:P 2 "" "")))]
10071 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10074 (define_insn_and_split "*tocref<mode>"
10075 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10076 (match_operand:P 1 "small_toc_ref" "R"))]
10079 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10080 [(set (match_dup 0) (high:P (match_dup 1)))
10081 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10083 ;; Elf specific ways of loading addresses for non-PIC code.
10084 ;; The output of this could be r0, but we make a very strong
10085 ;; preference for a base register because it will usually
10086 ;; be needed there.
10087 (define_insn "elf_high"
10088 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10089 (high:SI (match_operand 1 "" "")))]
10090 "TARGET_ELF && ! TARGET_64BIT"
10093 (define_insn "elf_low"
10094 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10095 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10096 (match_operand 2 "" "")))]
10097 "TARGET_ELF && ! TARGET_64BIT"
10100 ;; Call and call_value insns
10101 (define_expand "call"
10102 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10103 (match_operand 1 "" ""))
10104 (use (match_operand 2 "" ""))
10105 (clobber (reg:SI LR_REGNO))])]
10110 if (MACHOPIC_INDIRECT)
10111 operands[0] = machopic_indirect_call_target (operands[0]);
10114 gcc_assert (GET_CODE (operands[0]) == MEM);
10115 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10117 operands[0] = XEXP (operands[0], 0);
10119 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10121 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10125 if (GET_CODE (operands[0]) != SYMBOL_REF
10126 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10128 if (INTVAL (operands[2]) & CALL_LONG)
10129 operands[0] = rs6000_longcall_ref (operands[0]);
10131 switch (DEFAULT_ABI)
10135 operands[0] = force_reg (Pmode, operands[0]);
10139 gcc_unreachable ();
10144 (define_expand "call_value"
10145 [(parallel [(set (match_operand 0 "" "")
10146 (call (mem:SI (match_operand 1 "address_operand" ""))
10147 (match_operand 2 "" "")))
10148 (use (match_operand 3 "" ""))
10149 (clobber (reg:SI LR_REGNO))])]
10154 if (MACHOPIC_INDIRECT)
10155 operands[1] = machopic_indirect_call_target (operands[1]);
10158 gcc_assert (GET_CODE (operands[1]) == MEM);
10159 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10161 operands[1] = XEXP (operands[1], 0);
10163 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10165 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10169 if (GET_CODE (operands[1]) != SYMBOL_REF
10170 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10172 if (INTVAL (operands[3]) & CALL_LONG)
10173 operands[1] = rs6000_longcall_ref (operands[1]);
10175 switch (DEFAULT_ABI)
10179 operands[1] = force_reg (Pmode, operands[1]);
10183 gcc_unreachable ();
10188 ;; Call to function in current module. No TOC pointer reload needed.
10189 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10190 ;; either the function was not prototyped, or it was prototyped as a
10191 ;; variable argument function. It is > 0 if FP registers were passed
10192 ;; and < 0 if they were not.
10194 (define_insn "*call_local32"
10195 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10196 (match_operand 1 "" "g,g"))
10197 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10198 (clobber (reg:SI LR_REGNO))]
10199 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10202 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10203 output_asm_insn (\"crxor 6,6,6\", operands);
10205 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10206 output_asm_insn (\"creqv 6,6,6\", operands);
10208 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10210 [(set_attr "type" "branch")
10211 (set_attr "length" "4,8")])
10213 (define_insn "*call_local64"
10214 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10215 (match_operand 1 "" "g,g"))
10216 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10217 (clobber (reg:SI LR_REGNO))]
10218 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10221 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10222 output_asm_insn (\"crxor 6,6,6\", operands);
10224 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10225 output_asm_insn (\"creqv 6,6,6\", operands);
10227 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10229 [(set_attr "type" "branch")
10230 (set_attr "length" "4,8")])
10232 (define_insn "*call_value_local32"
10233 [(set (match_operand 0 "" "")
10234 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10235 (match_operand 2 "" "g,g")))
10236 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10237 (clobber (reg:SI LR_REGNO))]
10238 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10241 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10242 output_asm_insn (\"crxor 6,6,6\", operands);
10244 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10245 output_asm_insn (\"creqv 6,6,6\", operands);
10247 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10249 [(set_attr "type" "branch")
10250 (set_attr "length" "4,8")])
10253 (define_insn "*call_value_local64"
10254 [(set (match_operand 0 "" "")
10255 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10256 (match_operand 2 "" "g,g")))
10257 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10258 (clobber (reg:SI LR_REGNO))]
10259 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10262 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10263 output_asm_insn (\"crxor 6,6,6\", operands);
10265 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10266 output_asm_insn (\"creqv 6,6,6\", operands);
10268 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10270 [(set_attr "type" "branch")
10271 (set_attr "length" "4,8")])
10274 ;; A function pointer under System V is just a normal pointer
10275 ;; operands[0] is the function pointer
10276 ;; operands[1] is the stack size to clean up
10277 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10278 ;; which indicates how to set cr1
10280 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10281 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10282 (match_operand 1 "" "g,g,g,g"))
10283 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10284 (clobber (reg:SI LR_REGNO))]
10285 "DEFAULT_ABI == ABI_V4
10286 || DEFAULT_ABI == ABI_DARWIN"
10288 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10289 output_asm_insn ("crxor 6,6,6", operands);
10291 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10292 output_asm_insn ("creqv 6,6,6", operands);
10296 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10297 (set_attr "length" "4,4,8,8")])
10299 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10300 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10301 (match_operand 1 "" "g,g"))
10302 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10303 (clobber (reg:SI LR_REGNO))]
10304 "(DEFAULT_ABI == ABI_DARWIN
10305 || (DEFAULT_ABI == ABI_V4
10306 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10308 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10309 output_asm_insn ("crxor 6,6,6", operands);
10311 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10312 output_asm_insn ("creqv 6,6,6", operands);
10315 return output_call(insn, operands, 0, 2);
10317 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10319 gcc_assert (!TARGET_SECURE_PLT);
10320 return "bl %z0@plt";
10326 "DEFAULT_ABI == ABI_V4
10327 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10328 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10329 [(parallel [(call (mem:SI (match_dup 0))
10331 (use (match_dup 2))
10332 (use (match_dup 3))
10333 (clobber (reg:SI LR_REGNO))])]
10335 operands[3] = pic_offset_table_rtx;
10337 [(set_attr "type" "branch,branch")
10338 (set_attr "length" "4,8")])
10340 (define_insn "*call_nonlocal_sysv_secure<mode>"
10341 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10342 (match_operand 1 "" "g,g"))
10343 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10344 (use (match_operand:SI 3 "register_operand" "r,r"))
10345 (clobber (reg:SI LR_REGNO))]
10346 "(DEFAULT_ABI == ABI_V4
10347 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10348 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10350 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10351 output_asm_insn ("crxor 6,6,6", operands);
10353 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10354 output_asm_insn ("creqv 6,6,6", operands);
10357 /* The magic 32768 offset here and in the other sysv call insns
10358 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10359 See sysv4.h:toc_section. */
10360 return "bl %z0+32768@plt";
10362 return "bl %z0@plt";
10364 [(set_attr "type" "branch,branch")
10365 (set_attr "length" "4,8")])
10367 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10368 [(set (match_operand 0 "" "")
10369 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10370 (match_operand 2 "" "g,g,g,g")))
10371 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10372 (clobber (reg:SI LR_REGNO))]
10373 "DEFAULT_ABI == ABI_V4
10374 || DEFAULT_ABI == ABI_DARWIN"
10376 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10377 output_asm_insn ("crxor 6,6,6", operands);
10379 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10380 output_asm_insn ("creqv 6,6,6", operands);
10384 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10385 (set_attr "length" "4,4,8,8")])
10387 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10388 [(set (match_operand 0 "" "")
10389 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10390 (match_operand 2 "" "g,g")))
10391 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10392 (clobber (reg:SI LR_REGNO))]
10393 "(DEFAULT_ABI == ABI_DARWIN
10394 || (DEFAULT_ABI == ABI_V4
10395 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10397 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10398 output_asm_insn ("crxor 6,6,6", operands);
10400 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10401 output_asm_insn ("creqv 6,6,6", operands);
10404 return output_call(insn, operands, 1, 3);
10406 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10408 gcc_assert (!TARGET_SECURE_PLT);
10409 return "bl %z1@plt";
10415 "DEFAULT_ABI == ABI_V4
10416 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10417 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10418 [(parallel [(set (match_dup 0)
10419 (call (mem:SI (match_dup 1))
10421 (use (match_dup 3))
10422 (use (match_dup 4))
10423 (clobber (reg:SI LR_REGNO))])]
10425 operands[4] = pic_offset_table_rtx;
10427 [(set_attr "type" "branch,branch")
10428 (set_attr "length" "4,8")])
10430 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10431 [(set (match_operand 0 "" "")
10432 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10433 (match_operand 2 "" "g,g")))
10434 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10435 (use (match_operand:SI 4 "register_operand" "r,r"))
10436 (clobber (reg:SI LR_REGNO))]
10437 "(DEFAULT_ABI == ABI_V4
10438 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10439 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10441 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10442 output_asm_insn ("crxor 6,6,6", operands);
10444 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10445 output_asm_insn ("creqv 6,6,6", operands);
10448 return "bl %z1+32768@plt";
10450 return "bl %z1@plt";
10452 [(set_attr "type" "branch,branch")
10453 (set_attr "length" "4,8")])
10456 ;; Call to AIX abi function in the same module.
10458 (define_insn "*call_local_aix<mode>"
10459 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10460 (match_operand 1 "" "g"))
10461 (clobber (reg:P LR_REGNO))]
10462 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10464 [(set_attr "type" "branch")
10465 (set_attr "length" "4")])
10467 (define_insn "*call_value_local_aix<mode>"
10468 [(set (match_operand 0 "" "")
10469 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10470 (match_operand 2 "" "g")))
10471 (clobber (reg:P LR_REGNO))]
10472 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10474 [(set_attr "type" "branch")
10475 (set_attr "length" "4")])
10477 ;; Call to AIX abi function which may be in another module.
10478 ;; Restore the TOC pointer (r2) after the call.
10480 (define_insn "*call_nonlocal_aix<mode>"
10481 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10482 (match_operand 1 "" "g"))
10483 (clobber (reg:P LR_REGNO))]
10484 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10486 [(set_attr "type" "branch")
10487 (set_attr "length" "8")])
10489 (define_insn "*call_value_nonlocal_aix<mode>"
10490 [(set (match_operand 0 "" "")
10491 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10492 (match_operand 2 "" "g")))
10493 (clobber (reg:P LR_REGNO))]
10494 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10496 [(set_attr "type" "branch")
10497 (set_attr "length" "8")])
10499 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10500 ;; Operand0 is the addresss of the function to call
10501 ;; Operand2 is the location in the function descriptor to load r2 from
10502 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10504 (define_insn "*call_indirect_aix<mode>"
10505 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10506 (match_operand 1 "" "g,g"))
10507 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10508 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10509 (clobber (reg:P LR_REGNO))]
10510 "DEFAULT_ABI == ABI_AIX"
10511 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10512 [(set_attr "type" "jmpreg")
10513 (set_attr "length" "12")])
10515 (define_insn "*call_value_indirect_aix<mode>"
10516 [(set (match_operand 0 "" "")
10517 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10518 (match_operand 2 "" "g,g")))
10519 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10520 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10521 (clobber (reg:P LR_REGNO))]
10522 "DEFAULT_ABI == ABI_AIX"
10523 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10524 [(set_attr "type" "jmpreg")
10525 (set_attr "length" "12")])
10527 ;; Call to indirect functions with the ELFv2 ABI.
10528 ;; Operand0 is the addresss of the function to call
10529 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10531 (define_insn "*call_indirect_elfv2<mode>"
10532 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10533 (match_operand 1 "" "g,g"))
10534 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10535 (clobber (reg:P LR_REGNO))]
10536 "DEFAULT_ABI == ABI_ELFv2"
10537 "b%T0l\;<ptrload> 2,%2(1)"
10538 [(set_attr "type" "jmpreg")
10539 (set_attr "length" "8")])
10541 (define_insn "*call_value_indirect_elfv2<mode>"
10542 [(set (match_operand 0 "" "")
10543 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10544 (match_operand 2 "" "g,g")))
10545 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10546 (clobber (reg:P LR_REGNO))]
10547 "DEFAULT_ABI == ABI_ELFv2"
10548 "b%T1l\;<ptrload> 2,%3(1)"
10549 [(set_attr "type" "jmpreg")
10550 (set_attr "length" "8")])
10553 ;; Call subroutine returning any type.
10554 (define_expand "untyped_call"
10555 [(parallel [(call (match_operand 0 "" "")
10557 (match_operand 1 "" "")
10558 (match_operand 2 "" "")])]
10564 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10566 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10568 rtx set = XVECEXP (operands[2], 0, i);
10569 emit_move_insn (SET_DEST (set), SET_SRC (set));
10572 /* The optimizer does not know that the call sets the function value
10573 registers we stored in the result block. We avoid problems by
10574 claiming that all hard registers are used and clobbered at this
10576 emit_insn (gen_blockage ());
10581 ;; sibling call patterns
10582 (define_expand "sibcall"
10583 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10584 (match_operand 1 "" ""))
10585 (use (match_operand 2 "" ""))
10591 if (MACHOPIC_INDIRECT)
10592 operands[0] = machopic_indirect_call_target (operands[0]);
10595 gcc_assert (GET_CODE (operands[0]) == MEM);
10596 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10598 operands[0] = XEXP (operands[0], 0);
10600 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10602 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10607 (define_expand "sibcall_value"
10608 [(parallel [(set (match_operand 0 "register_operand" "")
10609 (call (mem:SI (match_operand 1 "address_operand" ""))
10610 (match_operand 2 "" "")))
10611 (use (match_operand 3 "" ""))
10617 if (MACHOPIC_INDIRECT)
10618 operands[1] = machopic_indirect_call_target (operands[1]);
10621 gcc_assert (GET_CODE (operands[1]) == MEM);
10622 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10624 operands[1] = XEXP (operands[1], 0);
10626 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10628 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10633 (define_insn "*sibcall_local32"
10634 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10635 (match_operand 1 "" "g,g"))
10636 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10638 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10641 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10642 output_asm_insn (\"crxor 6,6,6\", operands);
10644 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10645 output_asm_insn (\"creqv 6,6,6\", operands);
10647 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10649 [(set_attr "type" "branch")
10650 (set_attr "length" "4,8")])
10652 (define_insn "*sibcall_local64"
10653 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10654 (match_operand 1 "" "g,g"))
10655 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10657 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10660 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10661 output_asm_insn (\"crxor 6,6,6\", operands);
10663 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10664 output_asm_insn (\"creqv 6,6,6\", operands);
10666 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10668 [(set_attr "type" "branch")
10669 (set_attr "length" "4,8")])
10671 (define_insn "*sibcall_value_local32"
10672 [(set (match_operand 0 "" "")
10673 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10674 (match_operand 2 "" "g,g")))
10675 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10677 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10680 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10681 output_asm_insn (\"crxor 6,6,6\", operands);
10683 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10684 output_asm_insn (\"creqv 6,6,6\", operands);
10686 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10688 [(set_attr "type" "branch")
10689 (set_attr "length" "4,8")])
10691 (define_insn "*sibcall_value_local64"
10692 [(set (match_operand 0 "" "")
10693 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10694 (match_operand 2 "" "g,g")))
10695 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10697 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10700 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10701 output_asm_insn (\"crxor 6,6,6\", operands);
10703 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10704 output_asm_insn (\"creqv 6,6,6\", operands);
10706 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10708 [(set_attr "type" "branch")
10709 (set_attr "length" "4,8")])
10711 (define_insn "*sibcall_nonlocal_sysv<mode>"
10712 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10713 (match_operand 1 "" ""))
10714 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10716 "(DEFAULT_ABI == ABI_DARWIN
10717 || DEFAULT_ABI == ABI_V4)
10718 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10721 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10722 output_asm_insn (\"crxor 6,6,6\", operands);
10724 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10725 output_asm_insn (\"creqv 6,6,6\", operands);
10727 if (which_alternative >= 2)
10729 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10731 gcc_assert (!TARGET_SECURE_PLT);
10732 return \"b %z0@plt\";
10737 [(set_attr "type" "branch")
10738 (set_attr "length" "4,8,4,8")])
10740 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10741 [(set (match_operand 0 "" "")
10742 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10743 (match_operand 2 "" "")))
10744 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10746 "(DEFAULT_ABI == ABI_DARWIN
10747 || DEFAULT_ABI == ABI_V4)
10748 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10751 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10752 output_asm_insn (\"crxor 6,6,6\", operands);
10754 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10755 output_asm_insn (\"creqv 6,6,6\", operands);
10757 if (which_alternative >= 2)
10759 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10761 gcc_assert (!TARGET_SECURE_PLT);
10762 return \"b %z1@plt\";
10767 [(set_attr "type" "branch")
10768 (set_attr "length" "4,8,4,8")])
10770 ;; AIX ABI sibling call patterns.
10772 (define_insn "*sibcall_aix<mode>"
10773 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10774 (match_operand 1 "" "g,g"))
10776 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10780 [(set_attr "type" "branch")
10781 (set_attr "length" "4")])
10783 (define_insn "*sibcall_value_aix<mode>"
10784 [(set (match_operand 0 "" "")
10785 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10786 (match_operand 2 "" "g,g")))
10788 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10792 [(set_attr "type" "branch")
10793 (set_attr "length" "4")])
10795 (define_expand "sibcall_epilogue"
10796 [(use (const_int 0))]
10799 if (!TARGET_SCHED_PROLOG)
10800 emit_insn (gen_blockage ());
10801 rs6000_emit_epilogue (TRUE);
10805 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10806 ;; all of memory. This blocks insns from being moved across this point.
10808 (define_insn "blockage"
10809 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10813 (define_expand "probe_stack_address"
10814 [(use (match_operand 0 "address_operand"))]
10817 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10818 MEM_VOLATILE_P (operands[0]) = 1;
10821 emit_insn (gen_probe_stack_di (operands[0]));
10823 emit_insn (gen_probe_stack_si (operands[0]));
10827 (define_insn "probe_stack_<mode>"
10828 [(set (match_operand:P 0 "memory_operand" "=m")
10829 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10832 operands[1] = gen_rtx_REG (Pmode, 0);
10833 return "st<wd>%U0%X0 %1,%0";
10835 [(set_attr "type" "store")
10836 (set (attr "update")
10837 (if_then_else (match_operand 0 "update_address_mem")
10838 (const_string "yes")
10839 (const_string "no")))
10840 (set (attr "indexed")
10841 (if_then_else (match_operand 0 "indexed_address_mem")
10842 (const_string "yes")
10843 (const_string "no")))
10844 (set_attr "length" "4")])
10846 (define_insn "probe_stack_range<P:mode>"
10847 [(set (match_operand:P 0 "register_operand" "=r")
10848 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10849 (match_operand:P 2 "register_operand" "r")]
10850 UNSPECV_PROBE_STACK_RANGE))]
10852 "* return output_probe_stack_range (operands[0], operands[2]);"
10853 [(set_attr "type" "three")])
10855 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
10856 ;; signed & unsigned, and one type of branch.
10858 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10859 ;; insns, and branches.
10861 (define_expand "cbranch<mode>4"
10862 [(use (match_operator 0 "rs6000_cbranch_operator"
10863 [(match_operand:GPR 1 "gpc_reg_operand" "")
10864 (match_operand:GPR 2 "reg_or_short_operand" "")]))
10865 (use (match_operand 3 ""))]
10869 /* Take care of the possibility that operands[2] might be negative but
10870 this might be a logical operation. That insn doesn't exist. */
10871 if (GET_CODE (operands[2]) == CONST_INT
10872 && INTVAL (operands[2]) < 0)
10874 operands[2] = force_reg (<MODE>mode, operands[2]);
10875 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10876 GET_MODE (operands[0]),
10877 operands[1], operands[2]);
10880 rs6000_emit_cbranch (<MODE>mode, operands);
10884 (define_expand "cbranch<mode>4"
10885 [(use (match_operator 0 "rs6000_cbranch_operator"
10886 [(match_operand:FP 1 "gpc_reg_operand" "")
10887 (match_operand:FP 2 "gpc_reg_operand" "")]))
10888 (use (match_operand 3 ""))]
10892 rs6000_emit_cbranch (<MODE>mode, operands);
10896 (define_expand "cstore<mode>4_signed"
10897 [(use (match_operator 1 "signed_comparison_operator"
10898 [(match_operand:P 2 "gpc_reg_operand")
10899 (match_operand:P 3 "gpc_reg_operand")]))
10900 (clobber (match_operand:P 0 "gpc_reg_operand"))]
10903 enum rtx_code cond_code = GET_CODE (operands[1]);
10905 rtx op0 = operands[0];
10906 rtx op1 = operands[2];
10907 rtx op2 = operands[3];
10909 if (cond_code == GE || cond_code == LT)
10911 cond_code = swap_condition (cond_code);
10912 std::swap (op1, op2);
10915 rtx tmp1 = gen_reg_rtx (<MODE>mode);
10916 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10917 rtx tmp3 = gen_reg_rtx (<MODE>mode);
10919 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10920 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10921 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10923 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10925 if (cond_code == LE)
10926 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
10929 rtx tmp4 = gen_reg_rtx (<MODE>mode);
10930 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
10931 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
10937 (define_expand "cstore<mode>4_unsigned"
10938 [(use (match_operator 1 "unsigned_comparison_operator"
10939 [(match_operand:P 2 "gpc_reg_operand")
10940 (match_operand:P 3 "reg_or_short_operand")]))
10941 (clobber (match_operand:P 0 "gpc_reg_operand"))]
10944 enum rtx_code cond_code = GET_CODE (operands[1]);
10946 rtx op0 = operands[0];
10947 rtx op1 = operands[2];
10948 rtx op2 = operands[3];
10950 if (cond_code == GEU || cond_code == LTU)
10952 cond_code = swap_condition (cond_code);
10953 std::swap (op1, op2);
10956 if (!gpc_reg_operand (op1, <MODE>mode))
10957 op1 = force_reg (<MODE>mode, op1);
10958 if (!reg_or_short_operand (op2, <MODE>mode))
10959 op2 = force_reg (<MODE>mode, op2);
10961 rtx tmp = gen_reg_rtx (<MODE>mode);
10962 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10964 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10965 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10967 if (cond_code == LEU)
10968 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10970 emit_insn (gen_neg<mode>2 (op0, tmp2));
10975 (define_expand "cstore_si_as_di"
10976 [(use (match_operator 1 "unsigned_comparison_operator"
10977 [(match_operand:SI 2 "gpc_reg_operand")
10978 (match_operand:SI 3 "reg_or_short_operand")]))
10979 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10982 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10983 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10985 operands[2] = force_reg (SImode, operands[2]);
10986 operands[3] = force_reg (SImode, operands[3]);
10987 rtx op1 = gen_reg_rtx (DImode);
10988 rtx op2 = gen_reg_rtx (DImode);
10989 convert_move (op1, operands[2], uns_flag);
10990 convert_move (op2, operands[3], uns_flag);
10992 if (cond_code == GT || cond_code == LE)
10994 cond_code = swap_condition (cond_code);
10995 std::swap (op1, op2);
10998 rtx tmp = gen_reg_rtx (DImode);
10999 rtx tmp2 = gen_reg_rtx (DImode);
11000 emit_insn (gen_subdi3 (tmp, op1, op2));
11001 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11007 gcc_unreachable ();
11012 tmp3 = gen_reg_rtx (DImode);
11013 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11017 convert_move (operands[0], tmp3, 1);
11022 (define_expand "cstore<mode>4_signed_imm"
11023 [(use (match_operator 1 "signed_comparison_operator"
11024 [(match_operand:GPR 2 "gpc_reg_operand")
11025 (match_operand:GPR 3 "immediate_operand")]))
11026 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11029 bool invert = false;
11031 enum rtx_code cond_code = GET_CODE (operands[1]);
11033 rtx op0 = operands[0];
11034 rtx op1 = operands[2];
11035 HOST_WIDE_INT val = INTVAL (operands[3]);
11037 if (cond_code == GE || cond_code == GT)
11039 cond_code = reverse_condition (cond_code);
11043 if (cond_code == LE)
11046 rtx tmp = gen_reg_rtx (<MODE>mode);
11047 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11048 rtx x = gen_reg_rtx (<MODE>mode);
11050 emit_insn (gen_and<mode>3 (x, op1, tmp));
11052 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11056 rtx tmp = gen_reg_rtx (<MODE>mode);
11057 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11061 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11062 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11067 (define_expand "cstore<mode>4_unsigned_imm"
11068 [(use (match_operator 1 "unsigned_comparison_operator"
11069 [(match_operand:GPR 2 "gpc_reg_operand")
11070 (match_operand:GPR 3 "immediate_operand")]))
11071 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11074 bool invert = false;
11076 enum rtx_code cond_code = GET_CODE (operands[1]);
11078 rtx op0 = operands[0];
11079 rtx op1 = operands[2];
11080 HOST_WIDE_INT val = INTVAL (operands[3]);
11082 if (cond_code == GEU || cond_code == GTU)
11084 cond_code = reverse_condition (cond_code);
11088 if (cond_code == LEU)
11091 rtx tmp = gen_reg_rtx (<MODE>mode);
11092 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11093 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11094 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11095 rtx x = gen_reg_rtx (<MODE>mode);
11097 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11099 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11103 rtx tmp = gen_reg_rtx (<MODE>mode);
11104 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11108 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11109 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11114 (define_expand "cstore<mode>4"
11115 [(use (match_operator 1 "rs6000_cbranch_operator"
11116 [(match_operand:GPR 2 "gpc_reg_operand")
11117 (match_operand:GPR 3 "reg_or_short_operand")]))
11118 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11121 /* Use ISEL if the user asked for it. */
11123 rs6000_emit_sISEL (<MODE>mode, operands);
11125 /* Expanding EQ and NE directly to some machine instructions does not help
11126 but does hurt combine. So don't. */
11127 else if (GET_CODE (operands[1]) == EQ)
11128 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11129 else if (<MODE>mode == Pmode
11130 && GET_CODE (operands[1]) == NE)
11131 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11132 else if (GET_CODE (operands[1]) == NE)
11134 rtx tmp = gen_reg_rtx (<MODE>mode);
11135 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11136 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11139 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11140 etc. combinations magically work out just right. */
11141 else if (<MODE>mode == Pmode
11142 && unsigned_comparison_operator (operands[1], VOIDmode))
11143 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11144 operands[2], operands[3]));
11146 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11147 else if (<MODE>mode == SImode && Pmode == DImode)
11148 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11149 operands[2], operands[3]));
11151 /* For signed comparisons against a constant, we can do some simple
11153 else if (signed_comparison_operator (operands[1], VOIDmode)
11154 && CONST_INT_P (operands[3]))
11155 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11156 operands[2], operands[3]));
11158 /* And similarly for unsigned comparisons. */
11159 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11160 && CONST_INT_P (operands[3]))
11161 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11162 operands[2], operands[3]));
11164 /* We also do not want to use mfcr for signed comparisons. */
11165 else if (<MODE>mode == Pmode
11166 && signed_comparison_operator (operands[1], VOIDmode))
11167 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11168 operands[2], operands[3]));
11170 /* Everything else, use the mfcr brute force. */
11172 rs6000_emit_sCOND (<MODE>mode, operands);
11177 (define_expand "cstore<mode>4"
11178 [(use (match_operator 1 "rs6000_cbranch_operator"
11179 [(match_operand:FP 2 "gpc_reg_operand")
11180 (match_operand:FP 3 "gpc_reg_operand")]))
11181 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11184 rs6000_emit_sCOND (<MODE>mode, operands);
11189 (define_expand "stack_protect_set"
11190 [(match_operand 0 "memory_operand" "")
11191 (match_operand 1 "memory_operand" "")]
11194 #ifdef TARGET_THREAD_SSP_OFFSET
11195 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11196 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11197 operands[1] = gen_rtx_MEM (Pmode, addr);
11200 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11202 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11206 (define_insn "stack_protect_setsi"
11207 [(set (match_operand:SI 0 "memory_operand" "=m")
11208 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11209 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11211 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11212 [(set_attr "type" "three")
11213 (set_attr "length" "12")])
11215 (define_insn "stack_protect_setdi"
11216 [(set (match_operand:DI 0 "memory_operand" "=Y")
11217 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11218 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11220 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11221 [(set_attr "type" "three")
11222 (set_attr "length" "12")])
11224 (define_expand "stack_protect_test"
11225 [(match_operand 0 "memory_operand" "")
11226 (match_operand 1 "memory_operand" "")
11227 (match_operand 2 "" "")]
11230 rtx test, op0, op1;
11231 #ifdef TARGET_THREAD_SSP_OFFSET
11232 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11233 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11234 operands[1] = gen_rtx_MEM (Pmode, addr);
11237 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11238 test = gen_rtx_EQ (VOIDmode, op0, op1);
11239 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11243 (define_insn "stack_protect_testsi"
11244 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11245 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11246 (match_operand:SI 2 "memory_operand" "m,m")]
11248 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11249 (clobber (match_scratch:SI 3 "=&r,&r"))]
11252 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11253 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11254 [(set_attr "length" "16,20")])
11256 (define_insn "stack_protect_testdi"
11257 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11258 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11259 (match_operand:DI 2 "memory_operand" "Y,Y")]
11261 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11262 (clobber (match_scratch:DI 3 "=&r,&r"))]
11265 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11266 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11267 [(set_attr "length" "16,20")])
11270 ;; Here are the actual compare insns.
11271 (define_insn "*cmp<mode>_signed"
11272 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11273 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11274 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11276 "cmp<wd>%I2 %0,%1,%2"
11277 [(set_attr "type" "cmp")])
11279 (define_insn "*cmp<mode>_unsigned"
11280 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11281 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11282 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11284 "cmpl<wd>%I2 %0,%1,%2"
11285 [(set_attr "type" "cmp")])
11287 ;; If we are comparing a register for equality with a large constant,
11288 ;; we can do this with an XOR followed by a compare. But this is profitable
11289 ;; only if the large constant is only used for the comparison (and in this
11290 ;; case we already have a register to reuse as scratch).
11292 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11293 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11296 [(set (match_operand:SI 0 "register_operand")
11297 (match_operand:SI 1 "logical_const_operand" ""))
11298 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11300 (match_operand:SI 2 "logical_const_operand" "")]))
11301 (set (match_operand:CC 4 "cc_reg_operand" "")
11302 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11305 (if_then_else (match_operator 6 "equality_operator"
11306 [(match_dup 4) (const_int 0)])
11307 (match_operand 7 "" "")
11308 (match_operand 8 "" "")))]
11309 "peep2_reg_dead_p (3, operands[0])
11310 && peep2_reg_dead_p (4, operands[4])
11311 && REGNO (operands[0]) != REGNO (operands[5])"
11312 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11313 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11314 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11317 /* Get the constant we are comparing against, and see what it looks like
11318 when sign-extended from 16 to 32 bits. Then see what constant we could
11319 XOR with SEXTC to get the sign-extended value. */
11320 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11322 operands[1], operands[2]);
11323 HOST_WIDE_INT c = INTVAL (cnst);
11324 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11325 HOST_WIDE_INT xorv = c ^ sextc;
11327 operands[9] = GEN_INT (xorv);
11328 operands[10] = GEN_INT (sextc);
11331 ;; The following two insns don't exist as single insns, but if we provide
11332 ;; them, we can swap an add and compare, which will enable us to overlap more
11333 ;; of the required delay between a compare and branch. We generate code for
11334 ;; them by splitting.
11337 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11338 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11339 (match_operand:SI 2 "short_cint_operand" "i")))
11340 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11341 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11344 [(set_attr "length" "8")])
11347 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11348 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11349 (match_operand:SI 2 "u_short_cint_operand" "i")))
11350 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11351 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11354 [(set_attr "length" "8")])
11357 [(set (match_operand:CC 3 "cc_reg_operand" "")
11358 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11359 (match_operand:SI 2 "short_cint_operand" "")))
11360 (set (match_operand:SI 0 "gpc_reg_operand" "")
11361 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11363 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11364 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11367 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11368 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11369 (match_operand:SI 2 "u_short_cint_operand" "")))
11370 (set (match_operand:SI 0 "gpc_reg_operand" "")
11371 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11373 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11374 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11376 ;; Only need to compare second words if first words equal
11377 (define_insn "*cmp<mode>_internal1"
11378 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11379 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11380 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11381 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11382 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11383 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11384 [(set_attr "type" "fpcompare")
11385 (set_attr "length" "12")])
11387 (define_insn_and_split "*cmp<mode>_internal2"
11388 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11389 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11390 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11391 (clobber (match_scratch:DF 3 "=d"))
11392 (clobber (match_scratch:DF 4 "=d"))
11393 (clobber (match_scratch:DF 5 "=d"))
11394 (clobber (match_scratch:DF 6 "=d"))
11395 (clobber (match_scratch:DF 7 "=d"))
11396 (clobber (match_scratch:DF 8 "=d"))
11397 (clobber (match_scratch:DF 9 "=d"))
11398 (clobber (match_scratch:DF 10 "=d"))
11399 (clobber (match_scratch:GPR 11 "=b"))]
11400 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11401 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11403 "&& reload_completed"
11404 [(set (match_dup 3) (match_dup 14))
11405 (set (match_dup 4) (match_dup 15))
11406 (set (match_dup 9) (abs:DF (match_dup 5)))
11407 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11408 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11409 (label_ref (match_dup 12))
11411 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11412 (set (pc) (label_ref (match_dup 13)))
11414 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11415 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11416 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11417 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11420 REAL_VALUE_TYPE rv;
11421 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11422 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11424 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11425 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11426 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11427 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11428 operands[12] = gen_label_rtx ();
11429 operands[13] = gen_label_rtx ();
11431 operands[14] = force_const_mem (DFmode,
11432 const_double_from_real_value (rv, DFmode));
11433 operands[15] = force_const_mem (DFmode,
11434 const_double_from_real_value (dconst0,
11439 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11440 operands[14] = gen_const_mem (DFmode, tocref);
11441 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11442 operands[15] = gen_const_mem (DFmode, tocref);
11443 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11444 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11448 ;; Now we have the scc insns. We can do some combinations because of the
11449 ;; way the machine works.
11451 ;; Note that this is probably faster if we can put an insn between the
11452 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11453 ;; cases the insns below which don't use an intermediate CR field will
11454 ;; be used instead.
11456 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11457 (match_operator:SI 1 "scc_comparison_operator"
11458 [(match_operand 2 "cc_reg_operand" "y")
11461 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11462 [(set (attr "type")
11463 (cond [(match_test "TARGET_MFCRF")
11464 (const_string "mfcrf")
11466 (const_string "mfcr")))
11467 (set_attr "length" "8")])
11469 ;; Same as above, but get the GT bit.
11470 (define_insn "move_from_CR_gt_bit"
11471 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11472 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11473 "TARGET_HARD_FLOAT && !TARGET_FPRS"
11474 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11475 [(set_attr "type" "mfcr")
11476 (set_attr "length" "8")])
11478 ;; Same as above, but get the OV/ORDERED bit.
11479 (define_insn "move_from_CR_ov_bit"
11480 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11481 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11484 "mfcr %0\;rlwinm %0,%0,%t1,1"
11485 [(set_attr "type" "mfcr")
11486 (set_attr "length" "8")])
11489 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11490 (match_operator:DI 1 "scc_comparison_operator"
11491 [(match_operand 2 "cc_reg_operand" "y")
11494 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11495 [(set (attr "type")
11496 (cond [(match_test "TARGET_MFCRF")
11497 (const_string "mfcrf")
11499 (const_string "mfcr")))
11500 (set_attr "length" "8")])
11503 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11504 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11505 [(match_operand 2 "cc_reg_operand" "y,y")
11508 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11509 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11512 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11514 [(set_attr "type" "shift")
11515 (set_attr "dot" "yes")
11516 (set_attr "length" "8,16")])
11519 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11520 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11521 [(match_operand 2 "cc_reg_operand" "")
11524 (set (match_operand:SI 3 "gpc_reg_operand" "")
11525 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11526 "TARGET_32BIT && reload_completed"
11527 [(set (match_dup 3)
11528 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11530 (compare:CC (match_dup 3)
11535 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11536 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11537 [(match_operand 2 "cc_reg_operand" "y")
11539 (match_operand:SI 3 "const_int_operand" "n")))]
11543 int is_bit = ccr_bit (operands[1], 1);
11544 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11547 if (is_bit >= put_bit)
11548 count = is_bit - put_bit;
11550 count = 32 - (put_bit - is_bit);
11552 operands[4] = GEN_INT (count);
11553 operands[5] = GEN_INT (put_bit);
11555 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11557 [(set (attr "type")
11558 (cond [(match_test "TARGET_MFCRF")
11559 (const_string "mfcrf")
11561 (const_string "mfcr")))
11562 (set_attr "length" "8")])
11565 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11567 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11568 [(match_operand 2 "cc_reg_operand" "y,y")
11570 (match_operand:SI 3 "const_int_operand" "n,n"))
11572 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11573 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11578 int is_bit = ccr_bit (operands[1], 1);
11579 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11582 /* Force split for non-cc0 compare. */
11583 if (which_alternative == 1)
11586 if (is_bit >= put_bit)
11587 count = is_bit - put_bit;
11589 count = 32 - (put_bit - is_bit);
11591 operands[5] = GEN_INT (count);
11592 operands[6] = GEN_INT (put_bit);
11594 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11596 [(set_attr "type" "shift")
11597 (set_attr "dot" "yes")
11598 (set_attr "length" "8,16")])
11601 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11603 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11604 [(match_operand 2 "cc_reg_operand" "")
11606 (match_operand:SI 3 "const_int_operand" ""))
11608 (set (match_operand:SI 4 "gpc_reg_operand" "")
11609 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11612 [(set (match_dup 4)
11613 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11616 (compare:CC (match_dup 4)
11621 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11624 (define_insn_and_split "eq<mode>3"
11625 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11626 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11627 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11628 (clobber (match_scratch:GPR 3 "=r"))
11629 (clobber (match_scratch:GPR 4 "=r"))]
11633 [(set (match_dup 4)
11634 (clz:GPR (match_dup 3)))
11636 (lshiftrt:GPR (match_dup 4)
11639 operands[3] = rs6000_emit_eqne (<MODE>mode,
11640 operands[1], operands[2], operands[3]);
11642 if (GET_CODE (operands[4]) == SCRATCH)
11643 operands[4] = gen_reg_rtx (<MODE>mode);
11645 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11647 [(set (attr "length")
11648 (if_then_else (match_test "operands[2] == const0_rtx")
11650 (const_string "12")))])
11652 (define_insn_and_split "ne<mode>3"
11653 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11654 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11655 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11656 (clobber (match_scratch:P 3 "=r"))
11657 (clobber (match_scratch:P 4 "=r"))
11658 (clobber (reg:P CA_REGNO))]
11662 [(parallel [(set (match_dup 4)
11663 (plus:P (match_dup 3)
11665 (set (reg:P CA_REGNO)
11666 (ne:P (match_dup 3)
11668 (parallel [(set (match_dup 0)
11669 (plus:P (plus:P (not:P (match_dup 4))
11672 (clobber (reg:P CA_REGNO))])]
11674 operands[3] = rs6000_emit_eqne (<MODE>mode,
11675 operands[1], operands[2], operands[3]);
11677 if (GET_CODE (operands[4]) == SCRATCH)
11678 operands[4] = gen_reg_rtx (<MODE>mode);
11680 [(set (attr "length")
11681 (if_then_else (match_test "operands[2] == const0_rtx")
11683 (const_string "12")))])
11685 (define_insn_and_split "*neg_eq_<mode>"
11686 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11687 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11688 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11689 (clobber (match_scratch:P 3 "=r"))
11690 (clobber (match_scratch:P 4 "=r"))
11691 (clobber (reg:P CA_REGNO))]
11695 [(parallel [(set (match_dup 4)
11696 (plus:P (match_dup 3)
11698 (set (reg:P CA_REGNO)
11699 (ne:P (match_dup 3)
11701 (parallel [(set (match_dup 0)
11702 (plus:P (reg:P CA_REGNO)
11704 (clobber (reg:P CA_REGNO))])]
11706 operands[3] = rs6000_emit_eqne (<MODE>mode,
11707 operands[1], operands[2], operands[3]);
11709 if (GET_CODE (operands[4]) == SCRATCH)
11710 operands[4] = gen_reg_rtx (<MODE>mode);
11712 [(set (attr "length")
11713 (if_then_else (match_test "operands[2] == const0_rtx")
11715 (const_string "12")))])
11717 (define_insn_and_split "*neg_ne_<mode>"
11718 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11719 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11720 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11721 (clobber (match_scratch:P 3 "=r"))
11722 (clobber (match_scratch:P 4 "=r"))
11723 (clobber (reg:P CA_REGNO))]
11727 [(parallel [(set (match_dup 4)
11728 (neg:P (match_dup 3)))
11729 (set (reg:P CA_REGNO)
11730 (eq:P (match_dup 3)
11732 (parallel [(set (match_dup 0)
11733 (plus:P (reg:P CA_REGNO)
11735 (clobber (reg:P CA_REGNO))])]
11737 operands[3] = rs6000_emit_eqne (<MODE>mode,
11738 operands[1], operands[2], operands[3]);
11740 if (GET_CODE (operands[4]) == SCRATCH)
11741 operands[4] = gen_reg_rtx (<MODE>mode);
11743 [(set (attr "length")
11744 (if_then_else (match_test "operands[2] == const0_rtx")
11746 (const_string "12")))])
11748 (define_insn_and_split "*plus_eq_<mode>"
11749 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11750 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11751 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11752 (match_operand:P 3 "gpc_reg_operand" "r")))
11753 (clobber (match_scratch:P 4 "=r"))
11754 (clobber (match_scratch:P 5 "=r"))
11755 (clobber (reg:P CA_REGNO))]
11759 [(parallel [(set (match_dup 5)
11760 (neg:P (match_dup 4)))
11761 (set (reg:P CA_REGNO)
11762 (eq:P (match_dup 4)
11764 (parallel [(set (match_dup 0)
11765 (plus:P (match_dup 3)
11767 (clobber (reg:P CA_REGNO))])]
11769 operands[4] = rs6000_emit_eqne (<MODE>mode,
11770 operands[1], operands[2], operands[4]);
11772 if (GET_CODE (operands[5]) == SCRATCH)
11773 operands[5] = gen_reg_rtx (<MODE>mode);
11775 [(set (attr "length")
11776 (if_then_else (match_test "operands[2] == const0_rtx")
11778 (const_string "12")))])
11780 (define_insn_and_split "*plus_ne_<mode>"
11781 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11782 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11783 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11784 (match_operand:P 3 "gpc_reg_operand" "r")))
11785 (clobber (match_scratch:P 4 "=r"))
11786 (clobber (match_scratch:P 5 "=r"))
11787 (clobber (reg:P CA_REGNO))]
11791 [(parallel [(set (match_dup 5)
11792 (plus:P (match_dup 4)
11794 (set (reg:P CA_REGNO)
11795 (ne:P (match_dup 4)
11797 (parallel [(set (match_dup 0)
11798 (plus:P (match_dup 3)
11800 (clobber (reg:P CA_REGNO))])]
11802 operands[4] = rs6000_emit_eqne (<MODE>mode,
11803 operands[1], operands[2], operands[4]);
11805 if (GET_CODE (operands[5]) == SCRATCH)
11806 operands[5] = gen_reg_rtx (<MODE>mode);
11808 [(set (attr "length")
11809 (if_then_else (match_test "operands[2] == const0_rtx")
11811 (const_string "12")))])
11813 (define_insn_and_split "*minus_eq_<mode>"
11814 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11815 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11816 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11817 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11818 (clobber (match_scratch:P 4 "=r"))
11819 (clobber (match_scratch:P 5 "=r"))
11820 (clobber (reg:P CA_REGNO))]
11824 [(parallel [(set (match_dup 5)
11825 (plus:P (match_dup 4)
11827 (set (reg:P CA_REGNO)
11828 (ne:P (match_dup 4)
11830 (parallel [(set (match_dup 0)
11831 (plus:P (plus:P (match_dup 3)
11834 (clobber (reg:P CA_REGNO))])]
11836 operands[4] = rs6000_emit_eqne (<MODE>mode,
11837 operands[1], operands[2], operands[4]);
11839 if (GET_CODE (operands[5]) == SCRATCH)
11840 operands[5] = gen_reg_rtx (<MODE>mode);
11842 [(set (attr "length")
11843 (if_then_else (match_test "operands[2] == const0_rtx")
11845 (const_string "12")))])
11847 (define_insn_and_split "*minus_ne_<mode>"
11848 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11849 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11850 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11851 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11852 (clobber (match_scratch:P 4 "=r"))
11853 (clobber (match_scratch:P 5 "=r"))
11854 (clobber (reg:P CA_REGNO))]
11858 [(parallel [(set (match_dup 5)
11859 (neg:P (match_dup 4)))
11860 (set (reg:P CA_REGNO)
11861 (eq:P (match_dup 4)
11863 (parallel [(set (match_dup 0)
11864 (plus:P (plus:P (match_dup 3)
11867 (clobber (reg:P CA_REGNO))])]
11869 operands[4] = rs6000_emit_eqne (<MODE>mode,
11870 operands[1], operands[2], operands[4]);
11872 if (GET_CODE (operands[5]) == SCRATCH)
11873 operands[5] = gen_reg_rtx (<MODE>mode);
11875 [(set (attr "length")
11876 (if_then_else (match_test "operands[2] == const0_rtx")
11878 (const_string "12")))])
11880 (define_insn_and_split "*eqsi3_ext<mode>"
11881 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11882 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11883 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11884 (clobber (match_scratch:SI 3 "=r"))
11885 (clobber (match_scratch:SI 4 "=r"))]
11889 [(set (match_dup 4)
11890 (clz:SI (match_dup 3)))
11893 (lshiftrt:SI (match_dup 4)
11896 operands[3] = rs6000_emit_eqne (SImode,
11897 operands[1], operands[2], operands[3]);
11899 if (GET_CODE (operands[4]) == SCRATCH)
11900 operands[4] = gen_reg_rtx (SImode);
11902 [(set (attr "length")
11903 (if_then_else (match_test "operands[2] == const0_rtx")
11905 (const_string "12")))])
11907 (define_insn_and_split "*nesi3_ext<mode>"
11908 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11909 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11910 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11911 (clobber (match_scratch:SI 3 "=r"))
11912 (clobber (match_scratch:SI 4 "=r"))
11913 (clobber (match_scratch:EXTSI 5 "=r"))]
11917 [(set (match_dup 4)
11918 (clz:SI (match_dup 3)))
11921 (lshiftrt:SI (match_dup 4)
11924 (xor:EXTSI (match_dup 5)
11927 operands[3] = rs6000_emit_eqne (SImode,
11928 operands[1], operands[2], operands[3]);
11930 if (GET_CODE (operands[4]) == SCRATCH)
11931 operands[4] = gen_reg_rtx (SImode);
11932 if (GET_CODE (operands[5]) == SCRATCH)
11933 operands[5] = gen_reg_rtx (<MODE>mode);
11935 [(set (attr "length")
11936 (if_then_else (match_test "operands[2] == const0_rtx")
11937 (const_string "12")
11938 (const_string "16")))])
11940 ;; Define both directions of branch and return. If we need a reload
11941 ;; register, we'd rather use CR0 since it is much easier to copy a
11942 ;; register CC value to there.
11946 (if_then_else (match_operator 1 "branch_comparison_operator"
11948 "cc_reg_operand" "y")
11950 (label_ref (match_operand 0 "" ""))
11955 return output_cbranch (operands[1], \"%l0\", 0, insn);
11957 [(set_attr "type" "branch")])
11961 (if_then_else (match_operator 0 "branch_comparison_operator"
11963 "cc_reg_operand" "y")
11970 return output_cbranch (operands[0], NULL, 0, insn);
11972 [(set_attr "type" "jmpreg")
11973 (set_attr "length" "4")])
11977 (if_then_else (match_operator 1 "branch_comparison_operator"
11979 "cc_reg_operand" "y")
11982 (label_ref (match_operand 0 "" ""))))]
11986 return output_cbranch (operands[1], \"%l0\", 1, insn);
11988 [(set_attr "type" "branch")])
11992 (if_then_else (match_operator 0 "branch_comparison_operator"
11994 "cc_reg_operand" "y")
12001 return output_cbranch (operands[0], NULL, 1, insn);
12003 [(set_attr "type" "jmpreg")
12004 (set_attr "length" "4")])
12006 ;; Logic on condition register values.
12008 ; This pattern matches things like
12009 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12010 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12012 ; which are generated by the branch logic.
12013 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12015 (define_insn "*cceq_ior_compare"
12016 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12017 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12018 [(match_operator:SI 2
12019 "branch_positive_comparison_operator"
12021 "cc_reg_operand" "y,y")
12023 (match_operator:SI 4
12024 "branch_positive_comparison_operator"
12026 "cc_reg_operand" "0,y")
12030 "cr%q1 %E0,%j2,%j4"
12031 [(set_attr "type" "cr_logical,delayed_cr")])
12033 ; Why is the constant -1 here, but 1 in the previous pattern?
12034 ; Because ~1 has all but the low bit set.
12036 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12037 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12038 [(not:SI (match_operator:SI 2
12039 "branch_positive_comparison_operator"
12041 "cc_reg_operand" "y,y")
12043 (match_operator:SI 4
12044 "branch_positive_comparison_operator"
12046 "cc_reg_operand" "0,y")
12050 "cr%q1 %E0,%j2,%j4"
12051 [(set_attr "type" "cr_logical,delayed_cr")])
12053 (define_insn "*cceq_rev_compare"
12054 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12055 (compare:CCEQ (match_operator:SI 1
12056 "branch_positive_comparison_operator"
12058 "cc_reg_operand" "0,y")
12063 [(set_attr "type" "cr_logical,delayed_cr")])
12065 ;; If we are comparing the result of two comparisons, this can be done
12066 ;; using creqv or crxor.
12068 (define_insn_and_split ""
12069 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12070 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12071 [(match_operand 2 "cc_reg_operand" "y")
12073 (match_operator 3 "branch_comparison_operator"
12074 [(match_operand 4 "cc_reg_operand" "y")
12079 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12083 int positive_1, positive_2;
12085 positive_1 = branch_positive_comparison_operator (operands[1],
12086 GET_MODE (operands[1]));
12087 positive_2 = branch_positive_comparison_operator (operands[3],
12088 GET_MODE (operands[3]));
12091 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12092 GET_CODE (operands[1])),
12094 operands[2], const0_rtx);
12095 else if (GET_MODE (operands[1]) != SImode)
12096 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12097 operands[2], const0_rtx);
12100 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12101 GET_CODE (operands[3])),
12103 operands[4], const0_rtx);
12104 else if (GET_MODE (operands[3]) != SImode)
12105 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12106 operands[4], const0_rtx);
12108 if (positive_1 == positive_2)
12110 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12111 operands[5] = constm1_rtx;
12115 operands[5] = const1_rtx;
12119 ;; Unconditional branch and return.
12121 (define_insn "jump"
12123 (label_ref (match_operand 0 "" "")))]
12126 [(set_attr "type" "branch")])
12128 (define_insn "<return_str>return"
12132 [(set_attr "type" "jmpreg")])
12134 (define_expand "indirect_jump"
12135 [(set (pc) (match_operand 0 "register_operand" ""))])
12137 (define_insn "*indirect_jump<mode>"
12138 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12143 [(set_attr "type" "jmpreg")])
12145 ;; Table jump for switch statements:
12146 (define_expand "tablejump"
12147 [(use (match_operand 0 "" ""))
12148 (use (label_ref (match_operand 1 "" "")))]
12153 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12155 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12159 (define_expand "tablejumpsi"
12160 [(set (match_dup 3)
12161 (plus:SI (match_operand:SI 0 "" "")
12163 (parallel [(set (pc) (match_dup 3))
12164 (use (label_ref (match_operand 1 "" "")))])]
12167 { operands[0] = force_reg (SImode, operands[0]);
12168 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12169 operands[3] = gen_reg_rtx (SImode);
12172 (define_expand "tablejumpdi"
12173 [(set (match_dup 4)
12174 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12176 (plus:DI (match_dup 4)
12178 (parallel [(set (pc) (match_dup 3))
12179 (use (label_ref (match_operand 1 "" "")))])]
12182 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12183 operands[3] = gen_reg_rtx (DImode);
12184 operands[4] = gen_reg_rtx (DImode);
12187 (define_insn "*tablejump<mode>_internal1"
12189 (match_operand:P 0 "register_operand" "c,*l"))
12190 (use (label_ref (match_operand 1 "" "")))]
12195 [(set_attr "type" "jmpreg")])
12198 [(unspec [(const_int 0)] UNSPEC_NOP)]
12202 (define_insn "group_ending_nop"
12203 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12207 if (rs6000_cpu_attr == CPU_POWER6)
12208 return \"ori 1,1,0\";
12209 return \"ori 2,2,0\";
12212 ;; Define the subtract-one-and-jump insns, starting with the template
12213 ;; so loop.c knows what to generate.
12215 (define_expand "doloop_end"
12216 [(use (match_operand 0 "" "")) ; loop pseudo
12217 (use (match_operand 1 "" ""))] ; label
12223 if (GET_MODE (operands[0]) != DImode)
12225 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12229 if (GET_MODE (operands[0]) != SImode)
12231 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12236 (define_expand "ctr<mode>"
12237 [(parallel [(set (pc)
12238 (if_then_else (ne (match_operand:P 0 "register_operand" "")
12240 (label_ref (match_operand 1 "" ""))
12243 (plus:P (match_dup 0)
12245 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12246 (clobber (match_scratch:CC 2 ""))
12247 (clobber (match_scratch:P 3 ""))])]
12251 ;; We need to be able to do this for any operand, including MEM, or we
12252 ;; will cause reload to blow up since we don't allow output reloads on
12254 ;; For the length attribute to be calculated correctly, the
12255 ;; label MUST be operand 0.
12256 ;; The UNSPEC is present to prevent combine creating this pattern.
12258 (define_insn "*ctr<mode>_internal1"
12260 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12262 (label_ref (match_operand 0 "" ""))
12264 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12265 (plus:P (match_dup 1)
12267 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12268 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12269 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12273 if (which_alternative != 0)
12275 else if (get_attr_length (insn) == 4)
12276 return \"bdnz %l0\";
12278 return \"bdz $+8\;b %l0\";
12280 [(set_attr "type" "branch")
12281 (set_attr "length" "*,16,20,20")])
12283 (define_insn "*ctr<mode>_internal2"
12285 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12288 (label_ref (match_operand 0 "" ""))))
12289 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12290 (plus:P (match_dup 1)
12292 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12293 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12294 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12298 if (which_alternative != 0)
12300 else if (get_attr_length (insn) == 4)
12301 return \"bdz %l0\";
12303 return \"bdnz $+8\;b %l0\";
12305 [(set_attr "type" "branch")
12306 (set_attr "length" "*,16,20,20")])
12308 ;; Similar but use EQ
12310 (define_insn "*ctr<mode>_internal5"
12312 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12314 (label_ref (match_operand 0 "" ""))
12316 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12317 (plus:P (match_dup 1)
12319 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12320 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12321 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12325 if (which_alternative != 0)
12327 else if (get_attr_length (insn) == 4)
12328 return \"bdz %l0\";
12330 return \"bdnz $+8\;b %l0\";
12332 [(set_attr "type" "branch")
12333 (set_attr "length" "*,16,20,20")])
12335 (define_insn "*ctr<mode>_internal6"
12337 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12340 (label_ref (match_operand 0 "" ""))))
12341 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12342 (plus:P (match_dup 1)
12344 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12345 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12346 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12350 if (which_alternative != 0)
12352 else if (get_attr_length (insn) == 4)
12353 return \"bdnz %l0\";
12355 return \"bdz $+8\;b %l0\";
12357 [(set_attr "type" "branch")
12358 (set_attr "length" "*,16,20,20")])
12360 ;; Now the splitters if we could not allocate the CTR register
12364 (if_then_else (match_operator 2 "comparison_operator"
12365 [(match_operand:P 1 "gpc_reg_operand" "")
12367 (match_operand 5 "" "")
12368 (match_operand 6 "" "")))
12369 (set (match_operand:P 0 "int_reg_operand" "")
12370 (plus:P (match_dup 1) (const_int -1)))
12371 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12372 (clobber (match_scratch:CC 3 ""))
12373 (clobber (match_scratch:P 4 ""))]
12375 [(set (match_dup 3)
12376 (compare:CC (match_dup 1)
12379 (plus:P (match_dup 1)
12381 (set (pc) (if_then_else (match_dup 7)
12385 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12386 operands[3], const0_rtx); }")
12390 (if_then_else (match_operator 2 "comparison_operator"
12391 [(match_operand:P 1 "gpc_reg_operand" "")
12393 (match_operand 5 "" "")
12394 (match_operand 6 "" "")))
12395 (set (match_operand:P 0 "nonimmediate_operand" "")
12396 (plus:P (match_dup 1) (const_int -1)))
12397 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12398 (clobber (match_scratch:CC 3 ""))
12399 (clobber (match_scratch:P 4 ""))]
12400 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12401 [(set (match_dup 3)
12402 (compare:CC (match_dup 1)
12405 (plus:P (match_dup 1)
12409 (set (pc) (if_then_else (match_dup 7)
12413 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12414 operands[3], const0_rtx); }")
12416 (define_insn "trap"
12417 [(trap_if (const_int 1) (const_int 0))]
12420 [(set_attr "type" "trap")])
12422 (define_expand "ctrap<mode>4"
12423 [(trap_if (match_operator 0 "ordered_comparison_operator"
12424 [(match_operand:GPR 1 "register_operand")
12425 (match_operand:GPR 2 "reg_or_short_operand")])
12426 (match_operand 3 "zero_constant" ""))]
12431 [(trap_if (match_operator 0 "ordered_comparison_operator"
12432 [(match_operand:GPR 1 "register_operand" "r")
12433 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12436 "t<wd>%V0%I2 %1,%2"
12437 [(set_attr "type" "trap")])
12439 ;; Insns related to generating the function prologue and epilogue.
12441 (define_expand "prologue"
12442 [(use (const_int 0))]
12445 rs6000_emit_prologue ();
12446 if (!TARGET_SCHED_PROLOG)
12447 emit_insn (gen_blockage ());
12451 (define_insn "*movesi_from_cr_one"
12452 [(match_parallel 0 "mfcr_operation"
12453 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12454 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12455 (match_operand 3 "immediate_operand" "n")]
12456 UNSPEC_MOVESI_FROM_CR))])]
12462 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12464 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12465 operands[4] = GEN_INT (mask);
12466 output_asm_insn (\"mfcr %1,%4\", operands);
12470 [(set_attr "type" "mfcrf")])
12472 (define_insn "movesi_from_cr"
12473 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12474 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12475 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12476 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12477 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12478 UNSPEC_MOVESI_FROM_CR))]
12481 [(set_attr "type" "mfcr")])
12483 (define_insn "*crsave"
12484 [(match_parallel 0 "crsave_operation"
12485 [(set (match_operand:SI 1 "memory_operand" "=m")
12486 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12489 [(set_attr "type" "store")])
12491 (define_insn "*stmw"
12492 [(match_parallel 0 "stmw_operation"
12493 [(set (match_operand:SI 1 "memory_operand" "=m")
12494 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12497 [(set_attr "type" "store")
12498 (set_attr "update" "yes")
12499 (set_attr "indexed" "yes")])
12501 ; The following comment applies to:
12505 ; return_and_restore_gpregs*
12506 ; return_and_restore_fpregs*
12507 ; return_and_restore_fpregs_aix*
12509 ; The out-of-line save / restore functions expects one input argument.
12510 ; Since those are not standard call_insn's, we must avoid using
12511 ; MATCH_OPERAND for that argument. That way the register rename
12512 ; optimization will not try to rename this register.
12513 ; Each pattern is repeated for each possible register number used in
12514 ; various ABIs (r11, r1, and for some functions r12)
12516 (define_insn "*save_gpregs_<mode>_r11"
12517 [(match_parallel 0 "any_parallel_operand"
12518 [(clobber (reg:P LR_REGNO))
12519 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12521 (set (match_operand:P 2 "memory_operand" "=m")
12522 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12525 [(set_attr "type" "branch")
12526 (set_attr "length" "4")])
12528 (define_insn "*save_gpregs_<mode>_r12"
12529 [(match_parallel 0 "any_parallel_operand"
12530 [(clobber (reg:P LR_REGNO))
12531 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12533 (set (match_operand:P 2 "memory_operand" "=m")
12534 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12537 [(set_attr "type" "branch")
12538 (set_attr "length" "4")])
12540 (define_insn "*save_gpregs_<mode>_r1"
12541 [(match_parallel 0 "any_parallel_operand"
12542 [(clobber (reg:P LR_REGNO))
12543 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12545 (set (match_operand:P 2 "memory_operand" "=m")
12546 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12549 [(set_attr "type" "branch")
12550 (set_attr "length" "4")])
12552 (define_insn "*save_fpregs_<mode>_r11"
12553 [(match_parallel 0 "any_parallel_operand"
12554 [(clobber (reg:P LR_REGNO))
12555 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12557 (set (match_operand:DF 2 "memory_operand" "=m")
12558 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12561 [(set_attr "type" "branch")
12562 (set_attr "length" "4")])
12564 (define_insn "*save_fpregs_<mode>_r12"
12565 [(match_parallel 0 "any_parallel_operand"
12566 [(clobber (reg:P LR_REGNO))
12567 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12569 (set (match_operand:DF 2 "memory_operand" "=m")
12570 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12573 [(set_attr "type" "branch")
12574 (set_attr "length" "4")])
12576 (define_insn "*save_fpregs_<mode>_r1"
12577 [(match_parallel 0 "any_parallel_operand"
12578 [(clobber (reg:P LR_REGNO))
12579 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12581 (set (match_operand:DF 2 "memory_operand" "=m")
12582 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12585 [(set_attr "type" "branch")
12586 (set_attr "length" "4")])
12588 ; This is to explain that changes to the stack pointer should
12589 ; not be moved over loads from or stores to stack memory.
12590 (define_insn "stack_tie"
12591 [(match_parallel 0 "tie_operand"
12592 [(set (mem:BLK (reg 1)) (const_int 0))])]
12595 [(set_attr "length" "0")])
12597 (define_expand "epilogue"
12598 [(use (const_int 0))]
12601 if (!TARGET_SCHED_PROLOG)
12602 emit_insn (gen_blockage ());
12603 rs6000_emit_epilogue (FALSE);
12607 ; On some processors, doing the mtcrf one CC register at a time is
12608 ; faster (like on the 604e). On others, doing them all at once is
12609 ; faster; for instance, on the 601 and 750.
12611 (define_expand "movsi_to_cr_one"
12612 [(set (match_operand:CC 0 "cc_reg_operand" "")
12613 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12614 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12616 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12618 (define_insn "*movsi_to_cr"
12619 [(match_parallel 0 "mtcrf_operation"
12620 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12621 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12622 (match_operand 3 "immediate_operand" "n")]
12623 UNSPEC_MOVESI_TO_CR))])]
12629 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12630 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12631 operands[4] = GEN_INT (mask);
12632 return \"mtcrf %4,%2\";
12634 [(set_attr "type" "mtcr")])
12636 (define_insn "*mtcrfsi"
12637 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12638 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12639 (match_operand 2 "immediate_operand" "n")]
12640 UNSPEC_MOVESI_TO_CR))]
12641 "GET_CODE (operands[0]) == REG
12642 && CR_REGNO_P (REGNO (operands[0]))
12643 && GET_CODE (operands[2]) == CONST_INT
12644 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12646 [(set_attr "type" "mtcr")])
12648 ; The load-multiple instructions have similar properties.
12649 ; Note that "load_multiple" is a name known to the machine-independent
12650 ; code that actually corresponds to the PowerPC load-string.
12652 (define_insn "*lmw"
12653 [(match_parallel 0 "lmw_operation"
12654 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12655 (match_operand:SI 2 "memory_operand" "m"))])]
12658 [(set_attr "type" "load")
12659 (set_attr "update" "yes")
12660 (set_attr "indexed" "yes")
12661 (set_attr "cell_micro" "always")])
12663 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12664 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
12666 ; The following comment applies to:
12670 ; return_and_restore_gpregs*
12671 ; return_and_restore_fpregs*
12672 ; return_and_restore_fpregs_aix*
12674 ; The out-of-line save / restore functions expects one input argument.
12675 ; Since those are not standard call_insn's, we must avoid using
12676 ; MATCH_OPERAND for that argument. That way the register rename
12677 ; optimization will not try to rename this register.
12678 ; Each pattern is repeated for each possible register number used in
12679 ; various ABIs (r11, r1, and for some functions r12)
12681 (define_insn "*restore_gpregs_<mode>_r11"
12682 [(match_parallel 0 "any_parallel_operand"
12683 [(clobber (reg:P LR_REGNO))
12684 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12686 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12687 (match_operand:P 3 "memory_operand" "m"))])]
12690 [(set_attr "type" "branch")
12691 (set_attr "length" "4")])
12693 (define_insn "*restore_gpregs_<mode>_r12"
12694 [(match_parallel 0 "any_parallel_operand"
12695 [(clobber (reg:P LR_REGNO))
12696 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12698 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12699 (match_operand:P 3 "memory_operand" "m"))])]
12702 [(set_attr "type" "branch")
12703 (set_attr "length" "4")])
12705 (define_insn "*restore_gpregs_<mode>_r1"
12706 [(match_parallel 0 "any_parallel_operand"
12707 [(clobber (reg:P LR_REGNO))
12708 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12710 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12711 (match_operand:P 3 "memory_operand" "m"))])]
12714 [(set_attr "type" "branch")
12715 (set_attr "length" "4")])
12717 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12718 [(match_parallel 0 "any_parallel_operand"
12720 (clobber (reg:P LR_REGNO))
12721 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12723 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12724 (match_operand:P 3 "memory_operand" "m"))])]
12727 [(set_attr "type" "branch")
12728 (set_attr "length" "4")])
12730 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12731 [(match_parallel 0 "any_parallel_operand"
12733 (clobber (reg:P LR_REGNO))
12734 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12736 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12737 (match_operand:P 3 "memory_operand" "m"))])]
12740 [(set_attr "type" "branch")
12741 (set_attr "length" "4")])
12743 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12744 [(match_parallel 0 "any_parallel_operand"
12746 (clobber (reg:P LR_REGNO))
12747 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12749 (set (match_operand:P 2 "gpc_reg_operand" "=r")
12750 (match_operand:P 3 "memory_operand" "m"))])]
12753 [(set_attr "type" "branch")
12754 (set_attr "length" "4")])
12756 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12757 [(match_parallel 0 "any_parallel_operand"
12759 (clobber (reg:P LR_REGNO))
12760 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12762 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12763 (match_operand:DF 3 "memory_operand" "m"))])]
12766 [(set_attr "type" "branch")
12767 (set_attr "length" "4")])
12769 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12770 [(match_parallel 0 "any_parallel_operand"
12772 (clobber (reg:P LR_REGNO))
12773 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12775 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12776 (match_operand:DF 3 "memory_operand" "m"))])]
12779 [(set_attr "type" "branch")
12780 (set_attr "length" "4")])
12782 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12783 [(match_parallel 0 "any_parallel_operand"
12785 (clobber (reg:P LR_REGNO))
12786 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12788 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12789 (match_operand:DF 3 "memory_operand" "m"))])]
12792 [(set_attr "type" "branch")
12793 (set_attr "length" "4")])
12795 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12796 [(match_parallel 0 "any_parallel_operand"
12798 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12800 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12801 (match_operand:DF 3 "memory_operand" "m"))])]
12804 [(set_attr "type" "branch")
12805 (set_attr "length" "4")])
12807 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12808 [(match_parallel 0 "any_parallel_operand"
12810 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12812 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
12813 (match_operand:DF 3 "memory_operand" "m"))])]
12816 [(set_attr "type" "branch")
12817 (set_attr "length" "4")])
12819 ; This is used in compiling the unwind routines.
12820 (define_expand "eh_return"
12821 [(use (match_operand 0 "general_operand" ""))]
12826 emit_insn (gen_eh_set_lr_si (operands[0]));
12828 emit_insn (gen_eh_set_lr_di (operands[0]));
12832 ; We can't expand this before we know where the link register is stored.
12833 (define_insn "eh_set_lr_<mode>"
12834 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12836 (clobber (match_scratch:P 1 "=&b"))]
12841 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12842 (clobber (match_scratch 1 ""))]
12847 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12851 (define_insn "prefetch"
12852 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12853 (match_operand:SI 1 "const_int_operand" "n")
12854 (match_operand:SI 2 "const_int_operand" "n"))]
12858 if (GET_CODE (operands[0]) == REG)
12859 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12860 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12862 [(set_attr "type" "load")])
12864 ;; Handle -fsplit-stack.
12866 (define_expand "split_stack_prologue"
12870 rs6000_expand_split_stack_prologue ();
12874 (define_expand "load_split_stack_limit"
12875 [(set (match_operand 0)
12876 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12879 emit_insn (gen_rtx_SET (operands[0],
12880 gen_rtx_UNSPEC (Pmode,
12881 gen_rtvec (1, const0_rtx),
12882 UNSPEC_STACK_CHECK)));
12886 (define_insn "load_split_stack_limit_di"
12887 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12888 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12890 "ld %0,-0x7040(13)"
12891 [(set_attr "type" "load")
12892 (set_attr "update" "no")
12893 (set_attr "indexed" "no")])
12895 (define_insn "load_split_stack_limit_si"
12896 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12897 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12899 "lwz %0,-0x7020(2)"
12900 [(set_attr "type" "load")
12901 (set_attr "update" "no")
12902 (set_attr "indexed" "no")])
12904 ;; A return instruction which the middle-end doesn't see.
12905 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
12906 ;; after the call to __morestack.
12907 (define_insn "split_stack_return"
12908 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
12911 [(set_attr "type" "jmpreg")])
12913 ;; If there are operand 0 bytes available on the stack, jump to
12915 (define_expand "split_stack_space_check"
12916 [(set (match_dup 2)
12917 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12919 (minus (reg STACK_POINTER_REGNUM)
12920 (match_operand 0)))
12921 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12922 (set (pc) (if_then_else
12923 (geu (match_dup 4) (const_int 0))
12924 (label_ref (match_operand 1))
12928 rs6000_split_stack_space_check (operands[0], operands[1]);
12932 (define_insn "bpermd_<mode>"
12933 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12934 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12935 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12938 [(set_attr "type" "popcnt")])
12941 ;; Builtin fma support. Handle
12942 ;; Note that the conditions for expansion are in the FMA_F iterator.
12944 (define_expand "fma<mode>4"
12945 [(set (match_operand:FMA_F 0 "register_operand" "")
12947 (match_operand:FMA_F 1 "register_operand" "")
12948 (match_operand:FMA_F 2 "register_operand" "")
12949 (match_operand:FMA_F 3 "register_operand" "")))]
12953 (define_insn "*fma<mode>4_fpr"
12954 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12956 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12957 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12958 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12959 "TARGET_<MODE>_FPR"
12961 fmadd<Ftrad> %0,%1,%2,%3
12962 xsmadda<Fvsx> %x0,%x1,%x2
12963 xsmaddm<Fvsx> %x0,%x1,%x3"
12964 [(set_attr "type" "fp")
12965 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12967 ; Altivec only has fma and nfms.
12968 (define_expand "fms<mode>4"
12969 [(set (match_operand:FMA_F 0 "register_operand" "")
12971 (match_operand:FMA_F 1 "register_operand" "")
12972 (match_operand:FMA_F 2 "register_operand" "")
12973 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12974 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12977 (define_insn "*fms<mode>4_fpr"
12978 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12980 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12981 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12982 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12983 "TARGET_<MODE>_FPR"
12985 fmsub<Ftrad> %0,%1,%2,%3
12986 xsmsuba<Fvsx> %x0,%x1,%x2
12987 xsmsubm<Fvsx> %x0,%x1,%x3"
12988 [(set_attr "type" "fp")
12989 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12991 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12992 (define_expand "fnma<mode>4"
12993 [(set (match_operand:FMA_F 0 "register_operand" "")
12996 (match_operand:FMA_F 1 "register_operand" "")
12997 (match_operand:FMA_F 2 "register_operand" "")
12998 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12999 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13002 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13003 (define_expand "fnms<mode>4"
13004 [(set (match_operand:FMA_F 0 "register_operand" "")
13007 (match_operand:FMA_F 1 "register_operand" "")
13008 (match_operand:FMA_F 2 "register_operand" "")
13009 (match_operand:FMA_F 3 "register_operand" ""))))]
13010 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13013 ; Not an official optab name, but used from builtins.
13014 (define_expand "nfma<mode>4"
13015 [(set (match_operand:FMA_F 0 "register_operand" "")
13018 (match_operand:FMA_F 1 "register_operand" "")
13019 (match_operand:FMA_F 2 "register_operand" "")
13020 (match_operand:FMA_F 3 "register_operand" ""))))]
13021 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13024 (define_insn "*nfma<mode>4_fpr"
13025 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13028 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13029 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13030 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13031 "TARGET_<MODE>_FPR"
13033 fnmadd<Ftrad> %0,%1,%2,%3
13034 xsnmadda<Fvsx> %x0,%x1,%x2
13035 xsnmaddm<Fvsx> %x0,%x1,%x3"
13036 [(set_attr "type" "fp")
13037 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13039 ; Not an official optab name, but used from builtins.
13040 (define_expand "nfms<mode>4"
13041 [(set (match_operand:FMA_F 0 "register_operand" "")
13044 (match_operand:FMA_F 1 "register_operand" "")
13045 (match_operand:FMA_F 2 "register_operand" "")
13046 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
13050 (define_insn "*nfmssf4_fpr"
13051 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13054 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13055 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13057 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13058 "TARGET_<MODE>_FPR"
13060 fnmsub<Ftrad> %0,%1,%2,%3
13061 xsnmsuba<Fvsx> %x0,%x1,%x2
13062 xsnmsubm<Fvsx> %x0,%x1,%x3"
13063 [(set_attr "type" "fp")
13064 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13067 (define_expand "rs6000_get_timebase"
13068 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13071 if (TARGET_POWERPC64)
13072 emit_insn (gen_rs6000_mftb_di (operands[0]));
13074 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13078 (define_insn "rs6000_get_timebase_ppc32"
13079 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13080 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13081 (clobber (match_scratch:SI 1 "=r"))
13082 (clobber (match_scratch:CC 2 "=y"))]
13083 "!TARGET_POWERPC64"
13085 if (WORDS_BIG_ENDIAN)
13088 return "mfspr %0,269\;"
13096 return "mftbu %0\;"
13105 return "mfspr %L0,269\;"
13113 return "mftbu %L0\;"
13120 [(set_attr "length" "20")])
13122 (define_insn "rs6000_mftb_<mode>"
13123 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13124 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13128 return "mfspr %0,268";
13134 (define_insn "rs6000_mffs"
13135 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13136 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13137 "TARGET_HARD_FLOAT && TARGET_FPRS"
13140 (define_insn "rs6000_mtfsf"
13141 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13142 (match_operand:DF 1 "gpc_reg_operand" "d")]
13144 "TARGET_HARD_FLOAT && TARGET_FPRS"
13148 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13149 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13150 ;; register that is being loaded. The fused ops must be physically adjacent.
13152 ;; There are two parts to addis fusion. The support for fused TOCs occur
13153 ;; before register allocation, and is meant to reduce the lifetime for the
13154 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13155 ;; to use the register that is being load. The peephole2 then gathers any
13156 ;; other fused possibilities that it can find after register allocation. If
13157 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13159 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13160 ;; before register allocation, so that we can avoid allocating a temporary base
13161 ;; register that won't be used, and that we try to load into base registers,
13162 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13163 ;; (addis followed by load) even on power8.
13166 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13167 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13168 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13169 [(parallel [(set (match_dup 0) (match_dup 2))
13170 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13171 (use (match_dup 3))
13172 (clobber (scratch:DI))])]
13174 operands[2] = fusion_wrap_memory_address (operands[1]);
13175 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13178 (define_insn "*toc_fusionload_<mode>"
13179 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13180 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13181 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13182 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13183 (clobber (match_scratch:DI 3 "=X,&b"))]
13184 "TARGET_TOC_FUSION_INT"
13186 if (base_reg_operand (operands[0], <MODE>mode))
13187 return emit_fusion_gpr_load (operands[0], operands[1]);
13189 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13191 [(set_attr "type" "load")
13192 (set_attr "length" "8")])
13194 (define_insn "*toc_fusionload_di"
13195 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13196 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13197 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13198 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13199 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13200 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13201 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13203 if (base_reg_operand (operands[0], DImode))
13204 return emit_fusion_gpr_load (operands[0], operands[1]);
13206 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13208 [(set_attr "type" "load")
13209 (set_attr "length" "8")])
13212 ;; Find cases where the addis that feeds into a load instruction is either used
13213 ;; once or is the same as the target register, and replace it with the fusion
13217 [(set (match_operand:P 0 "base_reg_operand" "")
13218 (match_operand:P 1 "fusion_gpr_addis" ""))
13219 (set (match_operand:INT1 2 "base_reg_operand" "")
13220 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13222 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13226 expand_fusion_gpr_load (operands);
13230 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13233 (define_insn "fusion_gpr_load_<mode>"
13234 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13235 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13236 UNSPEC_FUSION_GPR))]
13239 return emit_fusion_gpr_load (operands[0], operands[1]);
13241 [(set_attr "type" "load")
13242 (set_attr "length" "8")])
13245 ;; ISA 3.0 (power9) fusion support
13246 ;; Merge addis with floating load/store to FPRs (or GPRs).
13248 [(set (match_operand:P 0 "base_reg_operand" "")
13249 (match_operand:P 1 "fusion_gpr_addis" ""))
13250 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13251 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13252 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13253 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13256 expand_fusion_p9_load (operands);
13261 [(set (match_operand:P 0 "base_reg_operand" "")
13262 (match_operand:P 1 "fusion_gpr_addis" ""))
13263 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13264 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13265 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13266 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13269 expand_fusion_p9_store (operands);
13274 [(set (match_operand:SDI 0 "int_reg_operand" "")
13275 (match_operand:SDI 1 "upper16_cint_operand" ""))
13277 (ior:SDI (match_dup 0)
13278 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13280 [(set (match_dup 0)
13281 (unspec:SDI [(match_dup 1)
13282 (match_dup 2)] UNSPEC_FUSION_P9))])
13285 [(set (match_operand:SDI 0 "int_reg_operand" "")
13286 (match_operand:SDI 1 "upper16_cint_operand" ""))
13287 (set (match_operand:SDI 2 "int_reg_operand" "")
13288 (ior:SDI (match_dup 0)
13289 (match_operand:SDI 3 "u_short_cint_operand" "")))]
13291 && !rtx_equal_p (operands[0], operands[2])
13292 && peep2_reg_dead_p (2, operands[0])"
13293 [(set (match_dup 2)
13294 (unspec:SDI [(match_dup 1)
13295 (match_dup 3)] UNSPEC_FUSION_P9))])
13297 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13298 ;; reload). Because we want to eventually have secondary_reload generate
13299 ;; these, they have to have a single alternative that gives the register
13300 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13301 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13302 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13304 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13306 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13309 /* This insn is a secondary reload insn, which cannot have alternatives.
13310 If we are not loading up register 0, use the power8 fusion instead. */
13311 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13312 return emit_fusion_gpr_load (operands[0], operands[1]);
13314 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13316 [(set_attr "type" "load")
13317 (set_attr "length" "8")])
13319 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13320 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13322 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13324 (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
13327 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13329 [(set_attr "type" "store")
13330 (set_attr "length" "8")])
13332 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
13333 [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
13335 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13337 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13340 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13342 [(set_attr "type" "fpload")
13343 (set_attr "length" "8")])
13345 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
13346 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13348 [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
13350 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13353 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13355 [(set_attr "type" "fpstore")
13356 (set_attr "length" "8")])
13358 (define_insn "*fusion_p9_<mode>_constant"
13359 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13360 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13361 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13362 UNSPEC_FUSION_P9))]
13365 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13366 return "ori %0,%0,%2";
13368 [(set_attr "type" "two")
13369 (set_attr "length" "8")])
13372 ;; Miscellaneous ISA 2.06 (power7) instructions
13373 (define_insn "addg6s"
13374 [(set (match_operand:SI 0 "register_operand" "=r")
13375 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13376 (match_operand:SI 2 "register_operand" "r")]
13380 [(set_attr "type" "integer")
13381 (set_attr "length" "4")])
13383 (define_insn "cdtbcd"
13384 [(set (match_operand:SI 0 "register_operand" "=r")
13385 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13389 [(set_attr "type" "integer")
13390 (set_attr "length" "4")])
13392 (define_insn "cbcdtd"
13393 [(set (match_operand:SI 0 "register_operand" "=r")
13394 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13398 [(set_attr "type" "integer")
13399 (set_attr "length" "4")])
13401 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13406 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13407 (UNSPEC_DIVEO "eo")
13408 (UNSPEC_DIVEU "eu")
13409 (UNSPEC_DIVEUO "euo")])
13411 (define_insn "div<div_extend>_<mode>"
13412 [(set (match_operand:GPR 0 "register_operand" "=r")
13413 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13414 (match_operand:GPR 2 "register_operand" "r")]
13415 UNSPEC_DIV_EXTEND))]
13417 "div<wd><div_extend> %0,%1,%2"
13418 [(set_attr "type" "div")
13419 (set_attr "size" "<bits>")])
13422 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13424 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13425 (define_mode_attr FP128_64 [(TF "DF")
13430 (define_expand "unpack<mode>"
13431 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13433 [(match_operand:FMOVE128 1 "register_operand" "")
13434 (match_operand:QI 2 "const_0_to_1_operand" "")]
13435 UNSPEC_UNPACK_128BIT))]
13436 "FLOAT128_2REG_P (<MODE>mode)"
13439 (define_insn_and_split "unpack<mode>_dm"
13440 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13442 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13443 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13444 UNSPEC_UNPACK_128BIT))]
13445 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13447 "&& reload_completed"
13448 [(set (match_dup 0) (match_dup 3))]
13450 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13452 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13454 emit_note (NOTE_INSN_DELETED);
13458 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13460 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13461 (set_attr "length" "4")])
13463 (define_insn_and_split "unpack<mode>_nodm"
13464 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13466 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13467 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13468 UNSPEC_UNPACK_128BIT))]
13469 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13471 "&& reload_completed"
13472 [(set (match_dup 0) (match_dup 3))]
13474 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13476 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13478 emit_note (NOTE_INSN_DELETED);
13482 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13484 [(set_attr "type" "fp,fpstore")
13485 (set_attr "length" "4")])
13487 (define_insn_and_split "pack<mode>"
13488 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13490 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13491 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13492 UNSPEC_PACK_128BIT))]
13493 "FLOAT128_2REG_P (<MODE>mode)"
13497 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13498 [(set (match_dup 3) (match_dup 1))
13499 (set (match_dup 4) (match_dup 2))]
13501 unsigned dest_hi = REGNO (operands[0]);
13502 unsigned dest_lo = dest_hi + 1;
13504 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13505 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13507 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13508 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13510 [(set_attr "type" "fpsimple,fp")
13511 (set_attr "length" "4,8")])
13513 (define_insn "unpack<mode>"
13514 [(set (match_operand:DI 0 "register_operand" "=d,d")
13515 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13516 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13517 UNSPEC_UNPACK_128BIT))]
13518 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13520 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13521 return ASM_COMMENT_START " xxpermdi to same register";
13523 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13524 return "xxpermdi %x0,%x1,%x1,%3";
13526 [(set_attr "type" "vecperm")])
13528 (define_insn "pack<mode>"
13529 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13530 (unspec:FMOVE128_VSX
13531 [(match_operand:DI 1 "register_operand" "d")
13532 (match_operand:DI 2 "register_operand" "d")]
13533 UNSPEC_PACK_128BIT))]
13535 "xxpermdi %x0,%x1,%x2,0"
13536 [(set_attr "type" "vecperm")])
13540 ;; ISA 2.08 IEEE 128-bit floating point support.
13542 (define_insn "add<mode>3"
13543 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13545 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13546 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13547 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13549 [(set_attr "type" "vecfloat")
13550 (set_attr "size" "128")])
13552 (define_insn "sub<mode>3"
13553 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13555 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13556 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13557 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13559 [(set_attr "type" "vecfloat")
13560 (set_attr "size" "128")])
13562 (define_insn "mul<mode>3"
13563 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13565 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13566 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13567 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13569 [(set_attr "type" "vecfloat")
13570 (set_attr "size" "128")])
13572 (define_insn "div<mode>3"
13573 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13575 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13576 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13577 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13579 [(set_attr "type" "vecdiv")
13580 (set_attr "size" "128")])
13582 (define_insn "sqrt<mode>2"
13583 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13585 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13586 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13588 [(set_attr "type" "vecdiv")
13589 (set_attr "size" "128")])
13591 (define_expand "copysign<mode>3"
13592 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13593 (use (match_operand:IEEE128 1 "altivec_register_operand"))
13594 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13595 "FLOAT128_IEEE_P (<MODE>mode)"
13597 if (TARGET_FLOAT128_HW)
13598 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13602 rtx tmp = gen_reg_rtx (<MODE>mode);
13603 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13604 operands[2], tmp));
13609 (define_insn "copysign<mode>3_hard"
13610 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13612 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13613 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13615 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13616 "xscpsgnqp %0,%2,%1"
13617 [(set_attr "type" "vecmove")
13618 (set_attr "size" "128")])
13620 (define_insn "copysign<mode>3_soft"
13621 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13623 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13624 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13625 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
13627 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13628 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13629 [(set_attr "type" "veccomplex")
13630 (set_attr "length" "8")])
13632 (define_insn "neg<mode>2_hw"
13633 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13635 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13636 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13638 [(set_attr "type" "vecmove")
13639 (set_attr "size" "128")])
13642 (define_insn "abs<mode>2_hw"
13643 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13645 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13646 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13648 [(set_attr "type" "vecmove")
13649 (set_attr "size" "128")])
13652 (define_insn "*nabs<mode>2_hw"
13653 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13656 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13657 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13659 [(set_attr "type" "vecmove")
13660 (set_attr "size" "128")])
13662 ;; Initially don't worry about doing fusion
13663 (define_insn "*fma<mode>4_hw"
13664 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13666 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13667 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13668 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13669 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13670 "xsmaddqp %0,%1,%2"
13671 [(set_attr "type" "vecfloat")
13672 (set_attr "size" "128")])
13674 (define_insn "*fms<mode>4_hw"
13675 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13677 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13678 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13680 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13681 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13682 "xsmsubqp %0,%1,%2"
13683 [(set_attr "type" "vecfloat")
13684 (set_attr "size" "128")])
13686 (define_insn "*nfma<mode>4_hw"
13687 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13690 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13691 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13692 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13693 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13694 "xsnmaddqp %0,%1,%2"
13695 [(set_attr "type" "vecfloat")
13696 (set_attr "size" "128")])
13698 (define_insn "*nfms<mode>4_hw"
13699 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13702 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13703 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13705 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13706 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13707 "xsnmsubqp %0,%1,%2"
13708 [(set_attr "type" "vecfloat")
13709 (set_attr "size" "128")])
13711 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13712 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13713 (float_extend:IEEE128
13714 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13715 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13717 [(set_attr "type" "vecfloat")
13718 (set_attr "size" "128")])
13720 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13721 ;; point is a simple copy.
13722 (define_insn_and_split "extendkftf2"
13723 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13724 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13725 "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13729 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13732 emit_note (NOTE_INSN_DELETED);
13735 [(set_attr "type" "*,veclogical")
13736 (set_attr "length" "0,4")])
13738 (define_insn_and_split "trunctfkf2"
13739 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13740 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13741 "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13745 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13748 emit_note (NOTE_INSN_DELETED);
13751 [(set_attr "type" "*,veclogical")
13752 (set_attr "length" "0,4")])
13754 (define_insn "trunc<mode>df2_hw"
13755 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13757 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13758 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13760 [(set_attr "type" "vecfloat")
13761 (set_attr "size" "128")])
13763 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13764 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13766 (define_insn_and_split "trunc<mode>sf2_hw"
13767 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13769 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13770 (clobber (match_scratch:DF 2 "=v"))]
13771 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13774 [(set (match_dup 2)
13775 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13777 (float_truncate:SF (match_dup 2)))]
13779 if (GET_CODE (operands[2]) == SCRATCH)
13780 operands[2] = gen_reg_rtx (DFmode);
13782 [(set_attr "type" "vecfloat")
13783 (set_attr "length" "8")])
13785 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13786 ;; allowed in the traditional floating point registers. Use V2DImode so that
13787 ;; we can get a value in an Altivec register.
13789 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13790 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13791 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13792 (clobber (match_scratch:V2DI 2 "=v,v"))]
13793 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13798 convert_float128_to_int (operands, <CODE>);
13801 [(set_attr "length" "8")
13802 (set_attr "type" "mftgpr,fpstore")])
13804 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13805 [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13806 (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13807 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13808 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13813 convert_float128_to_int (operands, <CODE>);
13816 [(set_attr "length" "8")
13817 (set_attr "type" "mftgpr,vecsimple,fpstore")])
13819 (define_insn_and_split "float<uns>_<mode>si2_hw"
13820 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13821 (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13822 (clobber (match_scratch:V2DI 2 "=v,v"))]
13823 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13828 convert_int_to_float128 (operands, <CODE>);
13831 [(set_attr "length" "8")
13832 (set_attr "type" "vecfloat")])
13834 (define_insn_and_split "float<uns>_<mode>di2_hw"
13835 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13836 (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13837 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13838 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13843 convert_int_to_float128 (operands, <CODE>);
13846 [(set_attr "length" "8")
13847 (set_attr "type" "vecfloat")])
13849 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13850 (define_insn "*xscvqp<su>wz_<mode>"
13851 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13854 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13855 UNSPEC_IEEE128_CONVERT))]
13856 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13857 "xscvqp<su>wz %0,%1"
13858 [(set_attr "type" "vecfloat")
13859 (set_attr "size" "128")])
13861 (define_insn "*xscvqp<su>dz_<mode>"
13862 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13865 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13866 UNSPEC_IEEE128_CONVERT))]
13867 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13868 "xscvqp<su>dz %0,%1"
13869 [(set_attr "type" "vecfloat")
13870 (set_attr "size" "128")])
13872 (define_insn "*xscv<su>dqp_<mode>"
13873 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13875 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13876 UNSPEC_IEEE128_CONVERT)))]
13877 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13878 "xscv<su>dqp %0,%1"
13879 [(set_attr "type" "vecfloat")
13880 (set_attr "size" "128")])
13882 (define_insn "*ieee128_mfvsrd_64bit"
13883 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13884 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13885 UNSPEC_IEEE128_MOVE))]
13886 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13891 [(set_attr "type" "mftgpr,fpstore,veclogical")])
13894 (define_insn "*ieee128_mfvsrd_32bit"
13895 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13896 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13897 UNSPEC_IEEE128_MOVE))]
13898 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13902 [(set_attr "type" "fpstore,veclogical")])
13904 (define_insn "*ieee128_mfvsrwz"
13905 [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13906 (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13907 UNSPEC_IEEE128_MOVE))]
13908 "TARGET_FLOAT128_HW"
13912 [(set_attr "type" "mftgpr,fpstore")])
13914 ;; 0 says do sign-extension, 1 says zero-extension
13915 (define_insn "*ieee128_mtvsrw"
13916 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13917 (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13918 (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13919 UNSPEC_IEEE128_MOVE))]
13920 "TARGET_FLOAT128_HW"
13926 [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13929 (define_insn "*ieee128_mtvsrd_64bit"
13930 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13931 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13932 UNSPEC_IEEE128_MOVE))]
13933 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13938 [(set_attr "type" "mffgpr,fpload,veclogical")])
13940 (define_insn "*ieee128_mtvsrd_32bit"
13941 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
13942 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
13943 UNSPEC_IEEE128_MOVE))]
13944 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13948 [(set_attr "type" "fpload,veclogical")])
13950 ;; IEEE 128-bit instructions with round to odd semantics
13951 (define_insn "*trunc<mode>df2_odd"
13952 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13953 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13954 UNSPEC_ROUND_TO_ODD))]
13955 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13957 [(set_attr "type" "vecfloat")
13958 (set_attr "size" "128")])
13960 ;; IEEE 128-bit comparisons
13961 (define_insn "*cmp<mode>_hw"
13962 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13963 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13964 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13965 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13966 "xscmpuqp %0,%1,%2"
13967 [(set_attr "type" "veccmp")
13968 (set_attr "size" "128")])
13972 (include "sync.md")
13973 (include "vector.md")
13975 (include "altivec.md")
13978 (include "paired.md")
13979 (include "crypto.md")