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
153 ;; UNSPEC_VOLATILE usage
156 (define_c_enum "unspecv"
158 UNSPECV_LL ; load-locked
159 UNSPECV_SC ; store-conditional
160 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
161 UNSPECV_EH_RR ; eh_reg_restore
162 UNSPECV_ISYNC ; isync instruction
163 UNSPECV_MFTB ; move from time base
164 UNSPECV_NLGR ; non-local goto receiver
165 UNSPECV_MFFS ; Move from FPSCR
166 UNSPECV_MTFSF ; Move to FPSCR Fields
167 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
171 ;; Define an insn type attribute. This is used in function unit delay
175 add,logical,shift,insert,
177 exts,cntlz,popcnt,isel,
178 load,store,fpload,fpstore,vecload,vecstore,
180 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
181 cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
182 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
184 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
185 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
187 (const_string "integer"))
189 ;; What data size does this instruction work on?
190 ;; This is used for insert, mul.
191 (define_attr "size" "8,16,32,64" (const_string "32"))
193 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
194 ;; This is used for add, logical, shift, exts, mul.
195 (define_attr "dot" "no,yes" (const_string "no"))
197 ;; Does this instruction sign-extend its result?
198 ;; This is used for load insns.
199 (define_attr "sign_extend" "no,yes" (const_string "no"))
201 ;; Does this instruction use indexed (that is, reg+reg) addressing?
202 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
203 ;; it is automatically set based on that. If a load or store instruction
204 ;; has fewer than two operands it needs to set this attribute manually
205 ;; or the compiler will crash.
206 (define_attr "indexed" "no,yes"
207 (if_then_else (ior (match_operand 0 "indexed_address_mem")
208 (match_operand 1 "indexed_address_mem"))
210 (const_string "no")))
212 ;; Does this instruction use update addressing?
213 ;; This is used for load and store insns. See the comments for "indexed".
214 (define_attr "update" "no,yes"
215 (if_then_else (ior (match_operand 0 "update_address_mem")
216 (match_operand 1 "update_address_mem"))
218 (const_string "no")))
220 ;; Is this instruction using operands[2] as shift amount, and can that be a
222 ;; This is used for shift insns.
223 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
225 ;; Is this instruction using a shift amount from a register?
226 ;; This is used for shift insns.
227 (define_attr "var_shift" "no,yes"
228 (if_then_else (and (eq_attr "type" "shift")
229 (eq_attr "maybe_var_shift" "yes"))
230 (if_then_else (match_operand 2 "gpc_reg_operand")
233 (const_string "no")))
235 ;; Is copying of this instruction disallowed?
236 (define_attr "cannot_copy" "no,yes" (const_string "no"))
238 ;; Define floating point instruction sub-types for use with Xfpu.md
239 (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"))
241 ;; Length (in bytes).
242 ; '(pc)' in the following doesn't include the instruction itself; it is
243 ; calculated as if the instruction had zero size.
244 (define_attr "length" ""
245 (if_then_else (eq_attr "type" "branch")
246 (if_then_else (and (ge (minus (match_dup 0) (pc))
248 (lt (minus (match_dup 0) (pc))
254 ;; Processor type -- this attribute must exactly match the processor_type
255 ;; enumeration in rs6000-opts.h.
257 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
258 ppc750,ppc7400,ppc7450,
259 ppc403,ppc405,ppc440,ppc476,
260 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
261 power4,power5,power6,power7,power8,power9,
262 rs64a,mpccore,cell,ppca2,titan"
263 (const (symbol_ref "rs6000_cpu_attr")))
266 ;; If this instruction is microcoded on the CELL processor
267 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
268 (define_attr "cell_micro" "not,conditional,always"
269 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
270 (eq_attr "dot" "yes"))
271 (and (eq_attr "type" "load")
272 (eq_attr "sign_extend" "yes"))
273 (and (eq_attr "type" "shift")
274 (eq_attr "var_shift" "yes")))
275 (const_string "always")
276 (const_string "not")))
278 (automata_option "ndfa")
291 (include "e300c2c3.md")
292 (include "e500mc.md")
293 (include "e500mc64.md")
296 (include "power4.md")
297 (include "power5.md")
298 (include "power6.md")
299 (include "power7.md")
300 (include "power8.md")
306 (include "predicates.md")
307 (include "constraints.md")
309 (include "darwin.md")
314 ; This mode iterator allows :GPR to be used to indicate the allowable size
315 ; of whole values in GPRs.
316 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
318 ; Any supported integer mode.
319 (define_mode_iterator INT [QI HI SI DI TI PTI])
321 ; Any supported integer mode that fits in one register.
322 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
324 ; Everything we can extend QImode to.
325 (define_mode_iterator EXTQI [HI SI (DI "TARGET_POWERPC64")])
327 ; Everything we can extend HImode to.
328 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
330 ; Everything we can extend SImode to.
331 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
333 ; QImode or HImode for small atomic ops
334 (define_mode_iterator QHI [QI HI])
336 ; QImode, HImode, SImode for fused ops only for GPR loads
337 (define_mode_iterator QHSI [QI HI SI])
339 ; HImode or SImode for sign extended fusion ops
340 (define_mode_iterator HSI [HI SI])
342 ; SImode or DImode, even if DImode doesn't fit in GPRs.
343 (define_mode_iterator SDI [SI DI])
345 ; Types that can be fused with an ADDIS instruction to load or store a GPR
346 ; register that has reg+offset addressing.
347 (define_mode_iterator GPR_FUSION [QI
350 (DI "TARGET_POWERPC64")
352 (DF "TARGET_POWERPC64")])
354 ; Types that can be fused with an ADDIS instruction to load or store a FPR
355 ; register that has reg+offset addressing.
356 (define_mode_iterator FPR_FUSION [DI SF DF])
358 ; The size of a pointer. Also, the size of the value that a record-condition
359 ; (one with a '.') will compare; and the size used for arithmetic carries.
360 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
362 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
363 ; PTImode is GPR only)
364 (define_mode_iterator TI2 [TI PTI])
366 ; Any hardware-supported floating-point mode
367 (define_mode_iterator FP [
368 (SF "TARGET_HARD_FLOAT
369 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
370 (DF "TARGET_HARD_FLOAT
371 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
372 (TF "TARGET_HARD_FLOAT
373 && (TARGET_FPRS || TARGET_E500_DOUBLE)
374 && TARGET_LONG_DOUBLE_128")
375 (IF "TARGET_FLOAT128")
376 (KF "TARGET_FLOAT128")
380 ; Any fma capable floating-point mode.
381 (define_mode_iterator FMA_F [
382 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
383 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
384 || VECTOR_UNIT_VSX_P (DFmode)")
385 (V2SF "TARGET_PAIRED_FLOAT")
386 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
387 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
388 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
389 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
392 ; Floating point move iterators to combine binary and decimal moves
393 (define_mode_iterator FMOVE32 [SF SD])
394 (define_mode_iterator FMOVE64 [DF DD])
395 (define_mode_iterator FMOVE64X [DI DF DD])
396 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
397 (IF "TARGET_LONG_DOUBLE_128")
398 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
400 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
401 (IF "FLOAT128_2REG_P (IFmode)")
402 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
404 ; Iterators for 128 bit types for direct move
405 (define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE")
413 (KF "FLOAT128_VECTOR_P (KFmode)")
414 (TF "FLOAT128_VECTOR_P (TFmode)")])
416 ; Iterator for 128-bit VSX types for pack/unpack
417 (define_mode_iterator FMOVE128_VSX [V1TI KF])
419 ; Whether a floating point move is ok, don't allow SD without hardware FP
420 (define_mode_attr fmove_ok [(SF "")
422 (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
425 ; Convert REAL_VALUE to the appropriate bits
426 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
427 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
428 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
429 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
431 ; Definitions for load to 32-bit fpr register
432 (define_mode_attr f32_lr [(SF "f") (SD "wz")])
433 (define_mode_attr f32_lr2 [(SF "wb") (SD "wn")])
434 (define_mode_attr f32_lm [(SF "m") (SD "Z")])
435 (define_mode_attr f32_lm2 [(SF "o") (SD "wn")])
436 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
437 (define_mode_attr f32_li2 [(SF "lxssp %0,%1") (SD "lfiwzx %0,%y1")])
438 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
440 ; Definitions for store from 32-bit fpr register
441 (define_mode_attr f32_sr [(SF "f") (SD "wx")])
442 (define_mode_attr f32_sr2 [(SF "wb") (SD "wn")])
443 (define_mode_attr f32_sm [(SF "m") (SD "Z")])
444 (define_mode_attr f32_sm2 [(SF "o") (SD "wn")])
445 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
446 (define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")])
447 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")])
449 ; Definitions for 32-bit fpr direct move
450 ; At present, the decimal modes are not allowed in the traditional altivec
451 ; registers, so restrict the constraints to just the traditional FPRs.
452 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
454 ; Definitions for 32-bit VSX
455 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
457 ; Definitions for 32-bit use of altivec registers
458 (define_mode_attr f32_av [(SF "wu") (SD "wn")])
460 ; Definitions for 64-bit VSX
461 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
463 ; Definitions for 64-bit direct move
464 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
466 ; Definitions for 64-bit use of altivec registers
467 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
469 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
470 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
472 ; These modes do not fit in integer registers in 32-bit mode.
473 ; but on e500v2, the gpr are 64 bit registers
474 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
476 ; Iterator for reciprocal estimate instructions
477 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
479 ; Iterator for just SF/DF
480 (define_mode_iterator SFDF [SF DF])
482 ; Iterator for 128-bit floating point that uses the IBM double-double format
483 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
484 (TF "FLOAT128_IBM_P (TFmode)")])
486 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
487 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
488 (TF "FLOAT128_IEEE_P (TFmode)")])
490 ; Iterator for 128-bit floating point
491 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128")
492 (IF "TARGET_FLOAT128")
493 (TF "TARGET_LONG_DOUBLE_128")])
495 ; SF/DF suffix for traditional floating instructions
496 (define_mode_attr Ftrad [(SF "s") (DF "")])
498 ; SF/DF suffix for VSX instructions
499 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
501 ; SF/DF constraint for arithmetic on traditional floating point registers
502 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
504 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
505 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
506 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
508 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
510 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
511 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
512 ; instructions added in ISA 2.07 (power8)
513 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
515 ; SF/DF constraint for arithmetic on altivec registers
516 (define_mode_attr Fa [(SF "wu") (DF "wv")])
518 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
519 (define_mode_attr Fs [(SF "s") (DF "d")])
522 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
523 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
525 ; Conditional returns.
526 (define_code_iterator any_return [return simple_return])
527 (define_code_attr return_pred [(return "direct_return ()")
528 (simple_return "1")])
529 (define_code_attr return_str [(return "") (simple_return "simple_")])
532 (define_code_iterator iorxor [ior xor])
534 ; Signed/unsigned variants of ops.
535 (define_code_iterator any_extend [sign_extend zero_extend])
536 (define_code_iterator any_fix [fix unsigned_fix])
537 (define_code_iterator any_float [float unsigned_float])
539 (define_code_attr u [(sign_extend "")
542 (define_code_attr su [(sign_extend "s")
547 (unsigned_float "u")])
549 (define_code_attr az [(sign_extend "a")
554 (unsigned_float "z")])
556 (define_code_attr uns [(fix "")
559 (unsigned_float "uns")])
561 ; Various instructions that come in SI and DI forms.
562 ; A generic w/d attribute, for things like cmpw/cmpd.
563 (define_mode_attr wd [(QI "b")
572 ;; How many bits in this mode?
573 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
576 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
578 ;; ISEL/ISEL64 target selection
579 (define_mode_attr sel [(SI "") (DI "64")])
581 ;; Bitmask for shift instructions
582 (define_mode_attr hH [(SI "h") (DI "H")])
584 ;; A mode twice the size of the given mode
585 (define_mode_attr dmode [(SI "di") (DI "ti")])
586 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
588 ;; Suffix for reload patterns
589 (define_mode_attr ptrsize [(SI "32bit")
592 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
593 (DI "TARGET_64BIT")])
595 (define_mode_attr mptrsize [(SI "si")
598 (define_mode_attr ptrload [(SI "lwz")
601 (define_mode_attr ptrm [(SI "m")
604 (define_mode_attr rreg [(SF "f")
611 (define_mode_attr rreg2 [(SF "f")
614 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
615 (DF "TARGET_FCFID")])
617 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
618 (DF "TARGET_E500_DOUBLE")])
620 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
621 (DF "TARGET_DOUBLE_FLOAT")])
623 ;; Mode iterator for logical operations on 128-bit types
624 (define_mode_iterator BOOL_128 [TI
626 (V16QI "TARGET_ALTIVEC")
627 (V8HI "TARGET_ALTIVEC")
628 (V4SI "TARGET_ALTIVEC")
629 (V4SF "TARGET_ALTIVEC")
630 (V2DI "TARGET_ALTIVEC")
631 (V2DF "TARGET_ALTIVEC")
632 (V1TI "TARGET_ALTIVEC")])
634 ;; For the GPRs we use 3 constraints for register outputs, two that are the
635 ;; same as the output register, and a third where the output register is an
636 ;; early clobber, so we don't have to deal with register overlaps. For the
637 ;; vector types, we prefer to use the vector registers. For TI mode, allow
640 ;; Mode attribute for boolean operation register constraints for output
641 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
643 (V16QI "wa,v,&?r,?r,?r")
644 (V8HI "wa,v,&?r,?r,?r")
645 (V4SI "wa,v,&?r,?r,?r")
646 (V4SF "wa,v,&?r,?r,?r")
647 (V2DI "wa,v,&?r,?r,?r")
648 (V2DF "wa,v,&?r,?r,?r")
649 (V1TI "wa,v,&?r,?r,?r")])
651 ;; Mode attribute for boolean operation register constraints for operand1
652 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
660 (V1TI "wa,v,r,0,r")])
662 ;; Mode attribute for boolean operation register constraints for operand2
663 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
671 (V1TI "wa,v,r,r,0")])
673 ;; Mode attribute for boolean operation register constraints for operand1
674 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
675 ;; is used for operand1 or operand2
676 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
684 (V1TI "wa,v,r,0,0")])
686 ;; Reload iterator for creating the function to allocate a base register to
687 ;; supplement addressing modes.
688 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
689 SF SD SI DF DD DI TI PTI KF IF TF])
692 ;; Start with fixed-point load and store insns. Here we put only the more
693 ;; complex forms. Basic data transfer is done later.
695 (define_insn "zero_extendqi<mode>2"
696 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
697 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
702 [(set_attr "type" "load,shift")])
704 (define_insn_and_split "*zero_extendqi<mode>2_dot"
705 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
706 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
708 (clobber (match_scratch:EXTQI 0 "=r,r"))]
709 "rs6000_gen_cell_microcode"
713 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
715 (zero_extend:EXTQI (match_dup 1)))
717 (compare:CC (match_dup 0)
720 [(set_attr "type" "logical")
721 (set_attr "dot" "yes")
722 (set_attr "length" "4,8")])
724 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
725 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
726 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
728 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
729 (zero_extend:EXTQI (match_dup 1)))]
730 "rs6000_gen_cell_microcode"
734 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
736 (zero_extend:EXTQI (match_dup 1)))
738 (compare:CC (match_dup 0)
741 [(set_attr "type" "logical")
742 (set_attr "dot" "yes")
743 (set_attr "length" "4,8")])
746 (define_insn "zero_extendhi<mode>2"
747 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
748 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
752 rlwinm %0,%1,0,0xffff"
753 [(set_attr "type" "load,shift")])
755 (define_insn_and_split "*zero_extendhi<mode>2_dot"
756 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
757 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
759 (clobber (match_scratch:EXTHI 0 "=r,r"))]
760 "rs6000_gen_cell_microcode"
764 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
766 (zero_extend:EXTHI (match_dup 1)))
768 (compare:CC (match_dup 0)
771 [(set_attr "type" "logical")
772 (set_attr "dot" "yes")
773 (set_attr "length" "4,8")])
775 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
776 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
777 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
779 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
780 (zero_extend:EXTHI (match_dup 1)))]
781 "rs6000_gen_cell_microcode"
785 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
787 (zero_extend:EXTHI (match_dup 1)))
789 (compare:CC (match_dup 0)
792 [(set_attr "type" "logical")
793 (set_attr "dot" "yes")
794 (set_attr "length" "4,8")])
797 (define_insn "zero_extendsi<mode>2"
798 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
799 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
807 [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
809 (define_insn_and_split "*zero_extendsi<mode>2_dot"
810 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
811 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
813 (clobber (match_scratch:EXTSI 0 "=r,r"))]
814 "rs6000_gen_cell_microcode"
818 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
820 (zero_extend:DI (match_dup 1)))
822 (compare:CC (match_dup 0)
825 [(set_attr "type" "shift")
826 (set_attr "dot" "yes")
827 (set_attr "length" "4,8")])
829 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
830 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
831 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
833 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
834 (zero_extend:EXTSI (match_dup 1)))]
835 "rs6000_gen_cell_microcode"
839 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
841 (zero_extend:EXTSI (match_dup 1)))
843 (compare:CC (match_dup 0)
846 [(set_attr "type" "shift")
847 (set_attr "dot" "yes")
848 (set_attr "length" "4,8")])
851 (define_insn "extendqi<mode>2"
852 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
853 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
856 [(set_attr "type" "exts")])
858 (define_insn_and_split "*extendqi<mode>2_dot"
859 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
860 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
862 (clobber (match_scratch:EXTQI 0 "=r,r"))]
863 "rs6000_gen_cell_microcode"
867 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
869 (sign_extend:EXTQI (match_dup 1)))
871 (compare:CC (match_dup 0)
874 [(set_attr "type" "exts")
875 (set_attr "dot" "yes")
876 (set_attr "length" "4,8")])
878 (define_insn_and_split "*extendqi<mode>2_dot2"
879 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
880 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
882 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
883 (sign_extend:EXTQI (match_dup 1)))]
884 "rs6000_gen_cell_microcode"
888 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
890 (sign_extend:EXTQI (match_dup 1)))
892 (compare:CC (match_dup 0)
895 [(set_attr "type" "exts")
896 (set_attr "dot" "yes")
897 (set_attr "length" "4,8")])
900 (define_expand "extendhi<mode>2"
901 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
902 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
906 (define_insn "*extendhi<mode>2"
907 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
908 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
909 "rs6000_gen_cell_microcode"
913 [(set_attr "type" "load,exts")
914 (set_attr "sign_extend" "yes")])
916 (define_insn "*extendhi<mode>2_noload"
917 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
918 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
919 "!rs6000_gen_cell_microcode"
921 [(set_attr "type" "exts")])
923 (define_insn_and_split "*extendhi<mode>2_dot"
924 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
925 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
927 (clobber (match_scratch:EXTHI 0 "=r,r"))]
928 "rs6000_gen_cell_microcode"
932 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
934 (sign_extend:EXTHI (match_dup 1)))
936 (compare:CC (match_dup 0)
939 [(set_attr "type" "exts")
940 (set_attr "dot" "yes")
941 (set_attr "length" "4,8")])
943 (define_insn_and_split "*extendhi<mode>2_dot2"
944 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
945 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
947 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
948 (sign_extend:EXTHI (match_dup 1)))]
949 "rs6000_gen_cell_microcode"
953 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
955 (sign_extend:EXTHI (match_dup 1)))
957 (compare:CC (match_dup 0)
960 [(set_attr "type" "exts")
961 (set_attr "dot" "yes")
962 (set_attr "length" "4,8")])
965 (define_insn "extendsi<mode>2"
966 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
967 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
975 [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
976 (set_attr "sign_extend" "yes")])
978 (define_insn_and_split "*extendsi<mode>2_dot"
979 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
980 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
982 (clobber (match_scratch:EXTSI 0 "=r,r"))]
983 "rs6000_gen_cell_microcode"
987 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
989 (sign_extend:EXTSI (match_dup 1)))
991 (compare:CC (match_dup 0)
994 [(set_attr "type" "exts")
995 (set_attr "dot" "yes")
996 (set_attr "length" "4,8")])
998 (define_insn_and_split "*extendsi<mode>2_dot2"
999 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1000 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1002 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1003 (sign_extend:EXTSI (match_dup 1)))]
1004 "rs6000_gen_cell_microcode"
1008 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1010 (sign_extend:EXTSI (match_dup 1)))
1012 (compare:CC (match_dup 0)
1015 [(set_attr "type" "exts")
1016 (set_attr "dot" "yes")
1017 (set_attr "length" "4,8")])
1019 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1021 (define_insn "*macchwc"
1022 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1023 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1024 (match_operand:SI 2 "gpc_reg_operand" "r")
1027 (match_operand:HI 1 "gpc_reg_operand" "r")))
1028 (match_operand:SI 4 "gpc_reg_operand" "0"))
1030 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1031 (plus:SI (mult:SI (ashiftrt:SI
1039 [(set_attr "type" "halfmul")])
1041 (define_insn "*macchw"
1042 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1043 (plus:SI (mult:SI (ashiftrt:SI
1044 (match_operand:SI 2 "gpc_reg_operand" "r")
1047 (match_operand:HI 1 "gpc_reg_operand" "r")))
1048 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1051 [(set_attr "type" "halfmul")])
1053 (define_insn "*macchwuc"
1054 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1055 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1056 (match_operand:SI 2 "gpc_reg_operand" "r")
1059 (match_operand:HI 1 "gpc_reg_operand" "r")))
1060 (match_operand:SI 4 "gpc_reg_operand" "0"))
1062 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1063 (plus:SI (mult:SI (lshiftrt:SI
1071 [(set_attr "type" "halfmul")])
1073 (define_insn "*macchwu"
1074 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1075 (plus:SI (mult:SI (lshiftrt:SI
1076 (match_operand:SI 2 "gpc_reg_operand" "r")
1079 (match_operand:HI 1 "gpc_reg_operand" "r")))
1080 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1083 [(set_attr "type" "halfmul")])
1085 (define_insn "*machhwc"
1086 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1087 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1088 (match_operand:SI 1 "gpc_reg_operand" "%r")
1091 (match_operand:SI 2 "gpc_reg_operand" "r")
1093 (match_operand:SI 4 "gpc_reg_operand" "0"))
1095 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1096 (plus:SI (mult:SI (ashiftrt:SI
1105 [(set_attr "type" "halfmul")])
1107 (define_insn "*machhw"
1108 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1109 (plus:SI (mult:SI (ashiftrt:SI
1110 (match_operand:SI 1 "gpc_reg_operand" "%r")
1113 (match_operand:SI 2 "gpc_reg_operand" "r")
1115 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1118 [(set_attr "type" "halfmul")])
1120 (define_insn "*machhwuc"
1121 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1122 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1123 (match_operand:SI 1 "gpc_reg_operand" "%r")
1126 (match_operand:SI 2 "gpc_reg_operand" "r")
1128 (match_operand:SI 4 "gpc_reg_operand" "0"))
1130 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1131 (plus:SI (mult:SI (lshiftrt:SI
1140 [(set_attr "type" "halfmul")])
1142 (define_insn "*machhwu"
1143 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1144 (plus:SI (mult:SI (lshiftrt:SI
1145 (match_operand:SI 1 "gpc_reg_operand" "%r")
1148 (match_operand:SI 2 "gpc_reg_operand" "r")
1150 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1153 [(set_attr "type" "halfmul")])
1155 (define_insn "*maclhwc"
1156 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1157 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1158 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1160 (match_operand:HI 2 "gpc_reg_operand" "r")))
1161 (match_operand:SI 4 "gpc_reg_operand" "0"))
1163 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1164 (plus:SI (mult:SI (sign_extend:SI
1171 [(set_attr "type" "halfmul")])
1173 (define_insn "*maclhw"
1174 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1175 (plus:SI (mult:SI (sign_extend:SI
1176 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1178 (match_operand:HI 2 "gpc_reg_operand" "r")))
1179 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1182 [(set_attr "type" "halfmul")])
1184 (define_insn "*maclhwuc"
1185 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1186 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1187 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1189 (match_operand:HI 2 "gpc_reg_operand" "r")))
1190 (match_operand:SI 4 "gpc_reg_operand" "0"))
1192 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1193 (plus:SI (mult:SI (zero_extend:SI
1200 [(set_attr "type" "halfmul")])
1202 (define_insn "*maclhwu"
1203 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1204 (plus:SI (mult:SI (zero_extend:SI
1205 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1207 (match_operand:HI 2 "gpc_reg_operand" "r")))
1208 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1211 [(set_attr "type" "halfmul")])
1213 (define_insn "*nmacchwc"
1214 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1215 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1216 (mult:SI (ashiftrt:SI
1217 (match_operand:SI 2 "gpc_reg_operand" "r")
1220 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1222 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1223 (minus:SI (match_dup 4)
1224 (mult:SI (ashiftrt:SI
1231 [(set_attr "type" "halfmul")])
1233 (define_insn "*nmacchw"
1234 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1235 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1236 (mult:SI (ashiftrt:SI
1237 (match_operand:SI 2 "gpc_reg_operand" "r")
1240 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1243 [(set_attr "type" "halfmul")])
1245 (define_insn "*nmachhwc"
1246 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1247 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1248 (mult:SI (ashiftrt:SI
1249 (match_operand:SI 1 "gpc_reg_operand" "%r")
1252 (match_operand:SI 2 "gpc_reg_operand" "r")
1255 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1256 (minus:SI (match_dup 4)
1257 (mult:SI (ashiftrt:SI
1265 [(set_attr "type" "halfmul")])
1267 (define_insn "*nmachhw"
1268 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1269 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1270 (mult:SI (ashiftrt:SI
1271 (match_operand:SI 1 "gpc_reg_operand" "%r")
1274 (match_operand:SI 2 "gpc_reg_operand" "r")
1278 [(set_attr "type" "halfmul")])
1280 (define_insn "*nmaclhwc"
1281 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1282 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1283 (mult:SI (sign_extend:SI
1284 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1286 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1288 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1289 (minus:SI (match_dup 4)
1290 (mult:SI (sign_extend:SI
1296 [(set_attr "type" "halfmul")])
1298 (define_insn "*nmaclhw"
1299 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1300 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1301 (mult:SI (sign_extend:SI
1302 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1304 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1307 [(set_attr "type" "halfmul")])
1309 (define_insn "*mulchwc"
1310 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1311 (compare:CC (mult:SI (ashiftrt:SI
1312 (match_operand:SI 2 "gpc_reg_operand" "r")
1315 (match_operand:HI 1 "gpc_reg_operand" "r")))
1317 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1318 (mult:SI (ashiftrt:SI
1325 [(set_attr "type" "halfmul")])
1327 (define_insn "*mulchw"
1328 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1329 (mult:SI (ashiftrt:SI
1330 (match_operand:SI 2 "gpc_reg_operand" "r")
1333 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1336 [(set_attr "type" "halfmul")])
1338 (define_insn "*mulchwuc"
1339 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1340 (compare:CC (mult:SI (lshiftrt:SI
1341 (match_operand:SI 2 "gpc_reg_operand" "r")
1344 (match_operand:HI 1 "gpc_reg_operand" "r")))
1346 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1347 (mult:SI (lshiftrt:SI
1354 [(set_attr "type" "halfmul")])
1356 (define_insn "*mulchwu"
1357 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1358 (mult:SI (lshiftrt:SI
1359 (match_operand:SI 2 "gpc_reg_operand" "r")
1362 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1365 [(set_attr "type" "halfmul")])
1367 (define_insn "*mulhhwc"
1368 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1369 (compare:CC (mult:SI (ashiftrt:SI
1370 (match_operand:SI 1 "gpc_reg_operand" "%r")
1373 (match_operand:SI 2 "gpc_reg_operand" "r")
1376 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1377 (mult:SI (ashiftrt:SI
1385 [(set_attr "type" "halfmul")])
1387 (define_insn "*mulhhw"
1388 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1389 (mult:SI (ashiftrt:SI
1390 (match_operand:SI 1 "gpc_reg_operand" "%r")
1393 (match_operand:SI 2 "gpc_reg_operand" "r")
1397 [(set_attr "type" "halfmul")])
1399 (define_insn "*mulhhwuc"
1400 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1401 (compare:CC (mult:SI (lshiftrt:SI
1402 (match_operand:SI 1 "gpc_reg_operand" "%r")
1405 (match_operand:SI 2 "gpc_reg_operand" "r")
1408 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1409 (mult:SI (lshiftrt:SI
1417 [(set_attr "type" "halfmul")])
1419 (define_insn "*mulhhwu"
1420 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1421 (mult:SI (lshiftrt:SI
1422 (match_operand:SI 1 "gpc_reg_operand" "%r")
1425 (match_operand:SI 2 "gpc_reg_operand" "r")
1429 [(set_attr "type" "halfmul")])
1431 (define_insn "*mullhwc"
1432 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1433 (compare:CC (mult:SI (sign_extend:SI
1434 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1436 (match_operand:HI 2 "gpc_reg_operand" "r")))
1438 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1439 (mult:SI (sign_extend:SI
1445 [(set_attr "type" "halfmul")])
1447 (define_insn "*mullhw"
1448 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1449 (mult:SI (sign_extend:SI
1450 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1452 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1455 [(set_attr "type" "halfmul")])
1457 (define_insn "*mullhwuc"
1458 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1459 (compare:CC (mult:SI (zero_extend:SI
1460 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1462 (match_operand:HI 2 "gpc_reg_operand" "r")))
1464 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1465 (mult:SI (zero_extend:SI
1471 [(set_attr "type" "halfmul")])
1473 (define_insn "*mullhwu"
1474 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1475 (mult:SI (zero_extend:SI
1476 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1478 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1481 [(set_attr "type" "halfmul")])
1483 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1484 (define_insn "dlmzb"
1485 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1486 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1487 (match_operand:SI 2 "gpc_reg_operand" "r")]
1489 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1490 (unspec:SI [(match_dup 1)
1496 (define_expand "strlensi"
1497 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1498 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1499 (match_operand:QI 2 "const_int_operand" "")
1500 (match_operand 3 "const_int_operand" "")]
1501 UNSPEC_DLMZB_STRLEN))
1502 (clobber (match_scratch:CC 4 "=x"))]
1503 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1505 rtx result = operands[0];
1506 rtx src = operands[1];
1507 rtx search_char = operands[2];
1508 rtx align = operands[3];
1509 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1510 rtx loop_label, end_label, mem, cr0, cond;
1511 if (search_char != const0_rtx
1512 || GET_CODE (align) != CONST_INT
1513 || INTVAL (align) < 8)
1515 word1 = gen_reg_rtx (SImode);
1516 word2 = gen_reg_rtx (SImode);
1517 scratch_dlmzb = gen_reg_rtx (SImode);
1518 scratch_string = gen_reg_rtx (Pmode);
1519 loop_label = gen_label_rtx ();
1520 end_label = gen_label_rtx ();
1521 addr = force_reg (Pmode, XEXP (src, 0));
1522 emit_move_insn (scratch_string, addr);
1523 emit_label (loop_label);
1524 mem = change_address (src, SImode, scratch_string);
1525 emit_move_insn (word1, mem);
1526 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1527 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1528 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1529 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1530 emit_jump_insn (gen_rtx_SET (pc_rtx,
1531 gen_rtx_IF_THEN_ELSE (VOIDmode,
1537 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1538 emit_jump_insn (gen_rtx_SET (pc_rtx,
1539 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1541 emit_label (end_label);
1542 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1543 emit_insn (gen_subsi3 (result, scratch_string, addr));
1544 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1548 ;; Fixed-point arithmetic insns.
1550 (define_expand "add<mode>3"
1551 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1552 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1553 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1556 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1558 rtx lo0 = gen_lowpart (SImode, operands[0]);
1559 rtx lo1 = gen_lowpart (SImode, operands[1]);
1560 rtx lo2 = gen_lowpart (SImode, operands[2]);
1561 rtx hi0 = gen_highpart (SImode, operands[0]);
1562 rtx hi1 = gen_highpart (SImode, operands[1]);
1563 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1565 if (!reg_or_short_operand (lo2, SImode))
1566 lo2 = force_reg (SImode, lo2);
1567 if (!adde_operand (hi2, SImode))
1568 hi2 = force_reg (SImode, hi2);
1570 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1571 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1575 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1577 rtx tmp = ((!can_create_pseudo_p ()
1578 || rtx_equal_p (operands[0], operands[1]))
1579 ? operands[0] : gen_reg_rtx (<MODE>mode));
1581 HOST_WIDE_INT val = INTVAL (operands[2]);
1582 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1583 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1585 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1588 /* The ordering here is important for the prolog expander.
1589 When space is allocated from the stack, adding 'low' first may
1590 produce a temporary deallocation (which would be bad). */
1591 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1592 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1597 (define_insn "*add<mode>3"
1598 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1599 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1600 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1606 [(set_attr "type" "add")])
1608 (define_insn "addsi3_high"
1609 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1610 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1611 (high:SI (match_operand 2 "" ""))))]
1612 "TARGET_MACHO && !TARGET_64BIT"
1613 "addis %0,%1,ha16(%2)"
1614 [(set_attr "type" "add")])
1616 (define_insn_and_split "*add<mode>3_dot"
1617 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1618 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1619 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1621 (clobber (match_scratch:GPR 0 "=r,r"))]
1622 "<MODE>mode == Pmode"
1626 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1628 (plus:GPR (match_dup 1)
1631 (compare:CC (match_dup 0)
1634 [(set_attr "type" "add")
1635 (set_attr "dot" "yes")
1636 (set_attr "length" "4,8")])
1638 (define_insn_and_split "*add<mode>3_dot2"
1639 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1640 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1641 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1643 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1644 (plus:GPR (match_dup 1)
1646 "<MODE>mode == Pmode"
1650 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1652 (plus:GPR (match_dup 1)
1655 (compare:CC (match_dup 0)
1658 [(set_attr "type" "add")
1659 (set_attr "dot" "yes")
1660 (set_attr "length" "4,8")])
1662 (define_insn_and_split "*add<mode>3_imm_dot"
1663 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1664 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1665 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1667 (clobber (match_scratch:GPR 0 "=r,r"))
1668 (clobber (reg:GPR CA_REGNO))]
1669 "<MODE>mode == Pmode"
1673 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1675 (plus:GPR (match_dup 1)
1678 (compare:CC (match_dup 0)
1681 [(set_attr "type" "add")
1682 (set_attr "dot" "yes")
1683 (set_attr "length" "4,8")])
1685 (define_insn_and_split "*add<mode>3_imm_dot2"
1686 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1687 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1688 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1690 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1691 (plus:GPR (match_dup 1)
1693 (clobber (reg:GPR CA_REGNO))]
1694 "<MODE>mode == Pmode"
1698 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1700 (plus:GPR (match_dup 1)
1703 (compare:CC (match_dup 0)
1706 [(set_attr "type" "add")
1707 (set_attr "dot" "yes")
1708 (set_attr "length" "4,8")])
1710 ;; Split an add that we can't do in one insn into two insns, each of which
1711 ;; does one 16-bit part. This is used by combine. Note that the low-order
1712 ;; add should be last in case the result gets used in an address.
1715 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1716 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1717 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1719 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1720 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1722 HOST_WIDE_INT val = INTVAL (operands[2]);
1723 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1724 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1726 operands[4] = GEN_INT (low);
1727 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1728 operands[3] = GEN_INT (rest);
1729 else if (can_create_pseudo_p ())
1731 operands[3] = gen_reg_rtx (DImode);
1732 emit_move_insn (operands[3], operands[2]);
1733 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1741 (define_insn "add<mode>3_carry"
1742 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1743 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1744 (match_operand:P 2 "reg_or_short_operand" "rI")))
1745 (set (reg:P CA_REGNO)
1746 (ltu:P (plus:P (match_dup 1)
1751 [(set_attr "type" "add")])
1753 (define_insn "*add<mode>3_imm_carry_pos"
1754 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1755 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1756 (match_operand:P 2 "short_cint_operand" "n")))
1757 (set (reg:P CA_REGNO)
1758 (geu:P (match_dup 1)
1759 (match_operand:P 3 "const_int_operand" "n")))]
1760 "INTVAL (operands[2]) > 0
1761 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1763 [(set_attr "type" "add")])
1765 (define_insn "*add<mode>3_imm_carry_0"
1766 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1767 (match_operand:P 1 "gpc_reg_operand" "r"))
1768 (set (reg:P CA_REGNO)
1772 [(set_attr "type" "add")])
1774 (define_insn "*add<mode>3_imm_carry_m1"
1775 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1776 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1778 (set (reg:P CA_REGNO)
1783 [(set_attr "type" "add")])
1785 (define_insn "*add<mode>3_imm_carry_neg"
1786 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1787 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1788 (match_operand:P 2 "short_cint_operand" "n")))
1789 (set (reg:P CA_REGNO)
1790 (gtu:P (match_dup 1)
1791 (match_operand:P 3 "const_int_operand" "n")))]
1792 "INTVAL (operands[2]) < 0
1793 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1795 [(set_attr "type" "add")])
1798 (define_expand "add<mode>3_carry_in"
1800 (set (match_operand:GPR 0 "gpc_reg_operand")
1801 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1802 (match_operand:GPR 2 "adde_operand"))
1803 (reg:GPR CA_REGNO)))
1804 (clobber (reg:GPR CA_REGNO))])]
1807 if (operands[2] == const0_rtx)
1809 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1812 if (operands[2] == constm1_rtx)
1814 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1819 (define_insn "*add<mode>3_carry_in_internal"
1820 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1821 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1822 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1823 (reg:GPR CA_REGNO)))
1824 (clobber (reg:GPR CA_REGNO))]
1827 [(set_attr "type" "add")])
1829 (define_insn "add<mode>3_carry_in_0"
1830 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1831 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1832 (reg:GPR CA_REGNO)))
1833 (clobber (reg:GPR CA_REGNO))]
1836 [(set_attr "type" "add")])
1838 (define_insn "add<mode>3_carry_in_m1"
1839 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1840 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1843 (clobber (reg:GPR CA_REGNO))]
1846 [(set_attr "type" "add")])
1849 (define_expand "one_cmpl<mode>2"
1850 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1851 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1854 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1856 rs6000_split_logical (operands, NOT, false, false, false);
1861 (define_insn "*one_cmpl<mode>2"
1862 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1863 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1867 (define_insn_and_split "*one_cmpl<mode>2_dot"
1868 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1869 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1871 (clobber (match_scratch:GPR 0 "=r,r"))]
1872 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1876 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1878 (not:GPR (match_dup 1)))
1880 (compare:CC (match_dup 0)
1883 [(set_attr "type" "logical")
1884 (set_attr "dot" "yes")
1885 (set_attr "length" "4,8")])
1887 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1888 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1889 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1891 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1892 (not:GPR (match_dup 1)))]
1893 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1897 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1899 (not:GPR (match_dup 1)))
1901 (compare:CC (match_dup 0)
1904 [(set_attr "type" "logical")
1905 (set_attr "dot" "yes")
1906 (set_attr "length" "4,8")])
1909 (define_expand "sub<mode>3"
1910 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1911 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1912 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1915 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1917 rtx lo0 = gen_lowpart (SImode, operands[0]);
1918 rtx lo1 = gen_lowpart (SImode, operands[1]);
1919 rtx lo2 = gen_lowpart (SImode, operands[2]);
1920 rtx hi0 = gen_highpart (SImode, operands[0]);
1921 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1922 rtx hi2 = gen_highpart (SImode, operands[2]);
1924 if (!reg_or_short_operand (lo1, SImode))
1925 lo1 = force_reg (SImode, lo1);
1926 if (!adde_operand (hi1, SImode))
1927 hi1 = force_reg (SImode, hi1);
1929 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1930 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1934 if (short_cint_operand (operands[1], <MODE>mode))
1936 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1941 (define_insn "*subf<mode>3"
1942 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1943 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1944 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1947 [(set_attr "type" "add")])
1949 (define_insn_and_split "*subf<mode>3_dot"
1950 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1951 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1952 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1954 (clobber (match_scratch:GPR 0 "=r,r"))]
1955 "<MODE>mode == Pmode"
1959 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1961 (minus:GPR (match_dup 2)
1964 (compare:CC (match_dup 0)
1967 [(set_attr "type" "add")
1968 (set_attr "dot" "yes")
1969 (set_attr "length" "4,8")])
1971 (define_insn_and_split "*subf<mode>3_dot2"
1972 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1973 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1974 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1976 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1977 (minus:GPR (match_dup 2)
1979 "<MODE>mode == Pmode"
1983 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1985 (minus:GPR (match_dup 2)
1988 (compare:CC (match_dup 0)
1991 [(set_attr "type" "add")
1992 (set_attr "dot" "yes")
1993 (set_attr "length" "4,8")])
1995 (define_insn "subf<mode>3_imm"
1996 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1997 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
1998 (match_operand:GPR 1 "gpc_reg_operand" "r")))
1999 (clobber (reg:GPR CA_REGNO))]
2002 [(set_attr "type" "add")])
2005 (define_insn "subf<mode>3_carry"
2006 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2007 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2008 (match_operand:P 1 "gpc_reg_operand" "r")))
2009 (set (reg:P CA_REGNO)
2010 (leu:P (match_dup 1)
2014 [(set_attr "type" "add")])
2016 (define_insn "*subf<mode>3_imm_carry_0"
2017 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2018 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2019 (set (reg:P CA_REGNO)
2024 [(set_attr "type" "add")])
2026 (define_insn "*subf<mode>3_imm_carry_m1"
2027 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2028 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2029 (set (reg:P CA_REGNO)
2033 [(set_attr "type" "add")])
2036 (define_expand "subf<mode>3_carry_in"
2038 (set (match_operand:GPR 0 "gpc_reg_operand")
2039 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2041 (match_operand:GPR 2 "adde_operand")))
2042 (clobber (reg:GPR CA_REGNO))])]
2045 if (operands[2] == const0_rtx)
2047 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2050 if (operands[2] == constm1_rtx)
2052 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2057 (define_insn "*subf<mode>3_carry_in_internal"
2058 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2059 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2061 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2062 (clobber (reg:GPR CA_REGNO))]
2065 [(set_attr "type" "add")])
2067 (define_insn "subf<mode>3_carry_in_0"
2068 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2069 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2070 (reg:GPR CA_REGNO)))
2071 (clobber (reg:GPR CA_REGNO))]
2074 [(set_attr "type" "add")])
2076 (define_insn "subf<mode>3_carry_in_m1"
2077 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2078 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2079 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2081 (clobber (reg:GPR CA_REGNO))]
2084 [(set_attr "type" "add")])
2086 (define_insn "subf<mode>3_carry_in_xx"
2087 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2088 (plus:GPR (reg:GPR CA_REGNO)
2090 (clobber (reg:GPR CA_REGNO))]
2093 [(set_attr "type" "add")])
2096 (define_insn "neg<mode>2"
2097 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2098 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2101 [(set_attr "type" "add")])
2103 (define_insn_and_split "*neg<mode>2_dot"
2104 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2105 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2107 (clobber (match_scratch:GPR 0 "=r,r"))]
2108 "<MODE>mode == Pmode"
2112 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2114 (neg:GPR (match_dup 1)))
2116 (compare:CC (match_dup 0)
2119 [(set_attr "type" "add")
2120 (set_attr "dot" "yes")
2121 (set_attr "length" "4,8")])
2123 (define_insn_and_split "*neg<mode>2_dot2"
2124 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2125 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2127 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2128 (neg:GPR (match_dup 1)))]
2129 "<MODE>mode == Pmode"
2133 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2135 (neg:GPR (match_dup 1)))
2137 (compare:CC (match_dup 0)
2140 [(set_attr "type" "add")
2141 (set_attr "dot" "yes")
2142 (set_attr "length" "4,8")])
2145 (define_insn "clz<mode>2"
2146 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2147 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2150 [(set_attr "type" "cntlz")])
2152 (define_expand "ctz<mode>2"
2154 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2156 (and:GPR (match_dup 1)
2159 (clz:GPR (match_dup 3)))
2160 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2161 (minus:GPR (match_dup 5)
2163 (clobber (reg:GPR CA_REGNO))])]
2168 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2172 operands[2] = gen_reg_rtx (<MODE>mode);
2173 operands[3] = gen_reg_rtx (<MODE>mode);
2174 operands[4] = gen_reg_rtx (<MODE>mode);
2175 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2178 (define_insn "ctz<mode>2_hw"
2179 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2180 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2183 [(set_attr "type" "cntlz")])
2185 (define_expand "ffs<mode>2"
2187 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2189 (and:GPR (match_dup 1)
2192 (clz:GPR (match_dup 3)))
2193 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2194 (minus:GPR (match_dup 5)
2196 (clobber (reg:GPR CA_REGNO))])]
2199 operands[2] = gen_reg_rtx (<MODE>mode);
2200 operands[3] = gen_reg_rtx (<MODE>mode);
2201 operands[4] = gen_reg_rtx (<MODE>mode);
2202 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2206 (define_expand "popcount<mode>2"
2207 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2208 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2209 "TARGET_POPCNTB || TARGET_POPCNTD"
2211 rs6000_emit_popcount (operands[0], operands[1]);
2215 (define_insn "popcntb<mode>2"
2216 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2217 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2221 [(set_attr "type" "popcnt")])
2223 (define_insn "popcntd<mode>2"
2224 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2225 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2228 [(set_attr "type" "popcnt")])
2231 (define_expand "parity<mode>2"
2232 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2233 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2236 rs6000_emit_parity (operands[0], operands[1]);
2240 (define_insn "parity<mode>2_cmpb"
2241 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2242 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2243 "TARGET_CMPB && TARGET_POPCNTB"
2245 [(set_attr "type" "popcnt")])
2248 ;; Since the hardware zeros the upper part of the register, save generating the
2249 ;; AND immediate if we are converting to unsigned
2250 (define_insn "*bswaphi2_extenddi"
2251 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2253 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2256 [(set_attr "length" "4")
2257 (set_attr "type" "load")])
2259 (define_insn "*bswaphi2_extendsi"
2260 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2262 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2265 [(set_attr "length" "4")
2266 (set_attr "type" "load")])
2268 (define_expand "bswaphi2"
2269 [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2271 (match_operand:HI 1 "reg_or_mem_operand" "")))
2272 (clobber (match_scratch:SI 2 ""))])]
2275 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2276 operands[1] = force_reg (HImode, operands[1]);
2279 (define_insn "bswaphi2_internal"
2280 [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2282 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2283 (clobber (match_scratch:SI 2 "=X,X,&r"))]
2289 [(set_attr "length" "4,4,12")
2290 (set_attr "type" "load,store,*")])
2293 [(set (match_operand:HI 0 "gpc_reg_operand" "")
2294 (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2295 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2298 (and:SI (lshiftrt:SI (match_dup 4)
2302 (and:SI (ashift:SI (match_dup 4)
2304 (const_int 65280))) ;; 0xff00
2306 (ior:SI (match_dup 3)
2310 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2311 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2314 (define_insn "*bswapsi2_extenddi"
2315 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2317 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2320 [(set_attr "length" "4")
2321 (set_attr "type" "load")])
2323 (define_expand "bswapsi2"
2324 [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2326 (match_operand:SI 1 "reg_or_mem_operand" "")))]
2329 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2330 operands[1] = force_reg (SImode, operands[1]);
2333 (define_insn "*bswapsi2_internal"
2334 [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2336 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2342 [(set_attr "length" "4,4,12")
2343 (set_attr "type" "load,store,*")])
2345 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2346 ;; zero_extract insns do not change for -mlittle.
2348 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2349 (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2351 [(set (match_dup 0) ; DABC
2352 (rotate:SI (match_dup 1)
2354 (set (match_dup 0) ; DCBC
2355 (ior:SI (and:SI (ashift:SI (match_dup 1)
2357 (const_int 16711680))
2358 (and:SI (match_dup 0)
2359 (const_int -16711681))))
2360 (set (match_dup 0) ; DCBA
2361 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2364 (and:SI (match_dup 0)
2370 (define_expand "bswapdi2"
2371 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2373 (match_operand:DI 1 "reg_or_mem_operand" "")))
2374 (clobber (match_scratch:DI 2 ""))
2375 (clobber (match_scratch:DI 3 ""))])]
2378 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2379 operands[1] = force_reg (DImode, operands[1]);
2381 if (!TARGET_POWERPC64)
2383 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2384 that uses 64-bit registers needs the same scratch registers as 64-bit
2386 emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2391 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2392 (define_insn "*bswapdi2_ldbrx"
2393 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2394 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2395 (clobber (match_scratch:DI 2 "=X,X,&r"))
2396 (clobber (match_scratch:DI 3 "=X,X,&r"))]
2397 "TARGET_POWERPC64 && TARGET_LDBRX
2398 && (REG_P (operands[0]) || REG_P (operands[1]))"
2403 [(set_attr "length" "4,4,36")
2404 (set_attr "type" "load,store,*")])
2406 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2407 (define_insn "*bswapdi2_64bit"
2408 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2409 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2410 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2411 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2412 "TARGET_POWERPC64 && !TARGET_LDBRX
2413 && (REG_P (operands[0]) || REG_P (operands[1]))
2414 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2415 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2417 [(set_attr "length" "16,12,36")])
2420 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2421 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2422 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2423 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2424 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2428 rtx dest = operands[0];
2429 rtx src = operands[1];
2430 rtx op2 = operands[2];
2431 rtx op3 = operands[3];
2432 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2433 BYTES_BIG_ENDIAN ? 4 : 0);
2434 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2435 BYTES_BIG_ENDIAN ? 4 : 0);
2441 addr1 = XEXP (src, 0);
2442 if (GET_CODE (addr1) == PLUS)
2444 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2445 if (TARGET_AVOID_XFORM)
2447 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2451 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2453 else if (TARGET_AVOID_XFORM)
2455 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2460 emit_move_insn (op2, GEN_INT (4));
2461 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2464 word1 = change_address (src, SImode, addr1);
2465 word2 = change_address (src, SImode, addr2);
2467 if (BYTES_BIG_ENDIAN)
2469 emit_insn (gen_bswapsi2 (op3_32, word2));
2470 emit_insn (gen_bswapsi2 (dest_32, word1));
2474 emit_insn (gen_bswapsi2 (op3_32, word1));
2475 emit_insn (gen_bswapsi2 (dest_32, word2));
2478 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2479 emit_insn (gen_iordi3 (dest, dest, op3));
2484 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2485 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2486 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2487 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2488 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2492 rtx dest = operands[0];
2493 rtx src = operands[1];
2494 rtx op2 = operands[2];
2495 rtx op3 = operands[3];
2496 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2497 BYTES_BIG_ENDIAN ? 4 : 0);
2498 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2499 BYTES_BIG_ENDIAN ? 4 : 0);
2505 addr1 = XEXP (dest, 0);
2506 if (GET_CODE (addr1) == PLUS)
2508 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2509 if (TARGET_AVOID_XFORM)
2511 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2515 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2517 else if (TARGET_AVOID_XFORM)
2519 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2524 emit_move_insn (op2, GEN_INT (4));
2525 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2528 word1 = change_address (dest, SImode, addr1);
2529 word2 = change_address (dest, SImode, addr2);
2531 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2533 if (BYTES_BIG_ENDIAN)
2535 emit_insn (gen_bswapsi2 (word1, src_si));
2536 emit_insn (gen_bswapsi2 (word2, op3_si));
2540 emit_insn (gen_bswapsi2 (word2, src_si));
2541 emit_insn (gen_bswapsi2 (word1, op3_si));
2547 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2548 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2549 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2550 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2551 "TARGET_POWERPC64 && reload_completed"
2555 rtx dest = operands[0];
2556 rtx src = operands[1];
2557 rtx op2 = operands[2];
2558 rtx op3 = operands[3];
2559 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2560 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2561 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2562 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2563 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2565 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2566 emit_insn (gen_bswapsi2 (dest_si, src_si));
2567 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2568 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2569 emit_insn (gen_iordi3 (dest, dest, op3));
2573 (define_insn "bswapdi2_32bit"
2574 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2575 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2576 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2577 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2579 [(set_attr "length" "16,12,36")])
2582 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2583 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2584 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2585 "!TARGET_POWERPC64 && reload_completed"
2589 rtx dest = operands[0];
2590 rtx src = operands[1];
2591 rtx op2 = operands[2];
2592 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2593 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2599 addr1 = XEXP (src, 0);
2600 if (GET_CODE (addr1) == PLUS)
2602 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2603 if (TARGET_AVOID_XFORM
2604 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2606 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2610 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2612 else if (TARGET_AVOID_XFORM
2613 || REGNO (addr1) == REGNO (dest2))
2615 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2620 emit_move_insn (op2, GEN_INT (4));
2621 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2624 word1 = change_address (src, SImode, addr1);
2625 word2 = change_address (src, SImode, addr2);
2627 emit_insn (gen_bswapsi2 (dest2, word1));
2628 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2629 thus allowing us to omit an early clobber on the output. */
2630 emit_insn (gen_bswapsi2 (dest1, word2));
2635 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2636 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2637 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2638 "!TARGET_POWERPC64 && reload_completed"
2642 rtx dest = operands[0];
2643 rtx src = operands[1];
2644 rtx op2 = operands[2];
2645 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2646 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2652 addr1 = XEXP (dest, 0);
2653 if (GET_CODE (addr1) == PLUS)
2655 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2656 if (TARGET_AVOID_XFORM)
2658 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2662 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2664 else if (TARGET_AVOID_XFORM)
2666 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2671 emit_move_insn (op2, GEN_INT (4));
2672 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2675 word1 = change_address (dest, SImode, addr1);
2676 word2 = change_address (dest, SImode, addr2);
2678 emit_insn (gen_bswapsi2 (word2, src1));
2679 emit_insn (gen_bswapsi2 (word1, src2));
2684 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2685 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2686 (clobber (match_operand:SI 2 "" ""))]
2687 "!TARGET_POWERPC64 && reload_completed"
2691 rtx dest = operands[0];
2692 rtx src = operands[1];
2693 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2694 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2695 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2696 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2698 emit_insn (gen_bswapsi2 (dest1, src2));
2699 emit_insn (gen_bswapsi2 (dest2, src1));
2704 (define_insn "mul<mode>3"
2705 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2706 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2707 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2712 [(set_attr "type" "mul")
2714 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2716 (match_operand:GPR 2 "short_cint_operand" "")
2717 (const_string "16")]
2718 (const_string "<bits>")))])
2720 (define_insn_and_split "*mul<mode>3_dot"
2721 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2722 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2723 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2725 (clobber (match_scratch:GPR 0 "=r,r"))]
2726 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2730 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2732 (mult:GPR (match_dup 1)
2735 (compare:CC (match_dup 0)
2738 [(set_attr "type" "mul")
2739 (set_attr "size" "<bits>")
2740 (set_attr "dot" "yes")
2741 (set_attr "length" "4,8")])
2743 (define_insn_and_split "*mul<mode>3_dot2"
2744 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2745 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2746 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2748 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2749 (mult:GPR (match_dup 1)
2751 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2755 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2757 (mult:GPR (match_dup 1)
2760 (compare:CC (match_dup 0)
2763 [(set_attr "type" "mul")
2764 (set_attr "size" "<bits>")
2765 (set_attr "dot" "yes")
2766 (set_attr "length" "4,8")])
2769 (define_expand "<su>mul<mode>3_highpart"
2770 [(set (match_operand:GPR 0 "gpc_reg_operand")
2772 (mult:<DMODE> (any_extend:<DMODE>
2773 (match_operand:GPR 1 "gpc_reg_operand"))
2775 (match_operand:GPR 2 "gpc_reg_operand")))
2779 if (<MODE>mode == SImode && TARGET_POWERPC64)
2781 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2786 if (!WORDS_BIG_ENDIAN)
2788 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2794 (define_insn "*<su>mul<mode>3_highpart"
2795 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2797 (mult:<DMODE> (any_extend:<DMODE>
2798 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2800 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2802 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2803 "mulh<wd><u> %0,%1,%2"
2804 [(set_attr "type" "mul")
2805 (set_attr "size" "<bits>")])
2807 (define_insn "<su>mulsi3_highpart_le"
2808 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2810 (mult:DI (any_extend:DI
2811 (match_operand:SI 1 "gpc_reg_operand" "r"))
2813 (match_operand:SI 2 "gpc_reg_operand" "r")))
2815 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2817 [(set_attr "type" "mul")])
2819 (define_insn "<su>muldi3_highpart_le"
2820 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2822 (mult:TI (any_extend:TI
2823 (match_operand:DI 1 "gpc_reg_operand" "r"))
2825 (match_operand:DI 2 "gpc_reg_operand" "r")))
2827 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2829 [(set_attr "type" "mul")
2830 (set_attr "size" "64")])
2832 (define_insn "<su>mulsi3_highpart_64"
2833 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2836 (mult:DI (any_extend:DI
2837 (match_operand:SI 1 "gpc_reg_operand" "r"))
2839 (match_operand:SI 2 "gpc_reg_operand" "r")))
2843 [(set_attr "type" "mul")])
2845 (define_expand "<u>mul<mode><dmode>3"
2846 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2847 (mult:<DMODE> (any_extend:<DMODE>
2848 (match_operand:GPR 1 "gpc_reg_operand"))
2850 (match_operand:GPR 2 "gpc_reg_operand"))))]
2851 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2853 rtx l = gen_reg_rtx (<MODE>mode);
2854 rtx h = gen_reg_rtx (<MODE>mode);
2855 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2856 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2857 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2858 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2862 (define_insn "*maddld4"
2863 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2864 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2865 (match_operand:DI 2 "gpc_reg_operand" "r"))
2866 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2868 "maddld %0,%1,%2,%3"
2869 [(set_attr "type" "mul")])
2871 (define_insn "udiv<mode>3"
2872 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2873 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2874 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2877 [(set_attr "type" "div")
2878 (set_attr "size" "<bits>")])
2881 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2882 ;; modulus. If it isn't a power of two, force operands into register and do
2884 (define_expand "div<mode>3"
2885 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2886 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2887 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2890 if (CONST_INT_P (operands[2])
2891 && INTVAL (operands[2]) > 0
2892 && exact_log2 (INTVAL (operands[2])) >= 0)
2894 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2898 operands[2] = force_reg (<MODE>mode, operands[2]);
2901 (define_insn "*div<mode>3"
2902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2903 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2904 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2907 [(set_attr "type" "div")
2908 (set_attr "size" "<bits>")])
2910 (define_insn "div<mode>3_sra"
2911 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2912 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2913 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2914 (clobber (reg:GPR CA_REGNO))]
2916 "sra<wd>i %0,%1,%p2\;addze %0,%0"
2917 [(set_attr "type" "two")
2918 (set_attr "length" "8")])
2920 (define_insn_and_split "*div<mode>3_sra_dot"
2921 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2922 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2923 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2925 (clobber (match_scratch:GPR 0 "=r,r"))
2926 (clobber (reg:GPR CA_REGNO))]
2927 "<MODE>mode == Pmode"
2929 sra<wd>i %0,%1,%p2\;addze. %0,%0
2931 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2932 [(parallel [(set (match_dup 0)
2933 (div:GPR (match_dup 1)
2935 (clobber (reg:GPR CA_REGNO))])
2937 (compare:CC (match_dup 0)
2940 [(set_attr "type" "two")
2941 (set_attr "length" "8,12")
2942 (set_attr "cell_micro" "not")])
2944 (define_insn_and_split "*div<mode>3_sra_dot2"
2945 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2946 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2947 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2949 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2950 (div:GPR (match_dup 1)
2952 (clobber (reg:GPR CA_REGNO))]
2953 "<MODE>mode == Pmode"
2955 sra<wd>i %0,%1,%p2\;addze. %0,%0
2957 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2958 [(parallel [(set (match_dup 0)
2959 (div:GPR (match_dup 1)
2961 (clobber (reg:GPR CA_REGNO))])
2963 (compare:CC (match_dup 0)
2966 [(set_attr "type" "two")
2967 (set_attr "length" "8,12")
2968 (set_attr "cell_micro" "not")])
2970 (define_expand "mod<mode>3"
2971 [(set (match_operand:GPR 0 "gpc_reg_operand")
2972 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
2973 (match_operand:GPR 2 "reg_or_cint_operand")))]
2980 if (GET_CODE (operands[2]) != CONST_INT
2981 || INTVAL (operands[2]) <= 0
2982 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
2987 operands[2] = force_reg (<MODE>mode, operands[2]);
2991 temp1 = gen_reg_rtx (<MODE>mode);
2992 temp2 = gen_reg_rtx (<MODE>mode);
2994 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
2995 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
2996 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3001 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3002 ;; mod, prefer putting the result of mod into a different register
3003 (define_insn "*mod<mode>3"
3004 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3005 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3006 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3009 [(set_attr "type" "div")
3010 (set_attr "size" "<bits>")])
3013 (define_insn "umod<mode>3"
3014 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3015 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3016 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3019 [(set_attr "type" "div")
3020 (set_attr "size" "<bits>")])
3022 ;; On machines with modulo support, do a combined div/mod the old fashioned
3023 ;; method, since the multiply/subtract is faster than doing the mod instruction
3027 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3028 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3029 (match_operand:GPR 2 "gpc_reg_operand" "")))
3030 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3031 (mod:GPR (match_dup 1)
3034 && ! reg_mentioned_p (operands[0], operands[1])
3035 && ! reg_mentioned_p (operands[0], operands[2])
3036 && ! reg_mentioned_p (operands[3], operands[1])
3037 && ! reg_mentioned_p (operands[3], operands[2])"
3039 (div:GPR (match_dup 1)
3042 (mult:GPR (match_dup 0)
3045 (minus:GPR (match_dup 1)
3049 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3050 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3051 (match_operand:GPR 2 "gpc_reg_operand" "")))
3052 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3053 (umod:GPR (match_dup 1)
3056 && ! reg_mentioned_p (operands[0], operands[1])
3057 && ! reg_mentioned_p (operands[0], operands[2])
3058 && ! reg_mentioned_p (operands[3], operands[1])
3059 && ! reg_mentioned_p (operands[3], operands[2])"
3061 (div:GPR (match_dup 1)
3064 (mult:GPR (match_dup 0)
3067 (minus:GPR (match_dup 1)
3071 ;; Logical instructions
3072 ;; The logical instructions are mostly combined by using match_operator,
3073 ;; but the plain AND insns are somewhat different because there is no
3074 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3075 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3077 (define_expand "and<mode>3"
3078 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3079 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3080 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3083 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3085 rs6000_split_logical (operands, AND, false, false, false);
3089 if (CONST_INT_P (operands[2]))
3091 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3093 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3097 if (logical_const_operand (operands[2], <MODE>mode)
3098 && rs6000_gen_cell_microcode)
3100 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3104 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3106 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3110 operands[2] = force_reg (<MODE>mode, operands[2]);
3115 (define_insn "and<mode>3_imm"
3116 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3117 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3118 (match_operand:GPR 2 "logical_const_operand" "n")))
3119 (clobber (match_scratch:CC 3 "=x"))]
3120 "rs6000_gen_cell_microcode
3121 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3122 "andi%e2. %0,%1,%u2"
3123 [(set_attr "type" "logical")
3124 (set_attr "dot" "yes")])
3126 (define_insn_and_split "*and<mode>3_imm_dot"
3127 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3128 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3129 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3131 (clobber (match_scratch:GPR 0 "=r,r"))
3132 (clobber (match_scratch:CC 4 "=X,x"))]
3133 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3134 && rs6000_gen_cell_microcode
3135 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3139 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3140 [(parallel [(set (match_dup 0)
3141 (and:GPR (match_dup 1)
3143 (clobber (match_dup 4))])
3145 (compare:CC (match_dup 0)
3148 [(set_attr "type" "logical")
3149 (set_attr "dot" "yes")
3150 (set_attr "length" "4,8")])
3152 (define_insn_and_split "*and<mode>3_imm_dot2"
3153 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3154 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3155 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3157 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3158 (and:GPR (match_dup 1)
3160 (clobber (match_scratch:CC 4 "=X,x"))]
3161 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3162 && rs6000_gen_cell_microcode
3163 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3167 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3168 [(parallel [(set (match_dup 0)
3169 (and:GPR (match_dup 1)
3171 (clobber (match_dup 4))])
3173 (compare:CC (match_dup 0)
3176 [(set_attr "type" "logical")
3177 (set_attr "dot" "yes")
3178 (set_attr "length" "4,8")])
3180 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3181 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3182 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3183 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3185 (clobber (match_scratch:GPR 0 "=r,r"))]
3186 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3187 && rs6000_gen_cell_microcode"
3191 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3193 (and:GPR (match_dup 1)
3196 (compare:CC (match_dup 0)
3199 [(set_attr "type" "logical")
3200 (set_attr "dot" "yes")
3201 (set_attr "length" "4,8")])
3203 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3204 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3205 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3206 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3208 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3209 (and:GPR (match_dup 1)
3211 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3212 && rs6000_gen_cell_microcode"
3216 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3218 (and:GPR (match_dup 1)
3221 (compare:CC (match_dup 0)
3224 [(set_attr "type" "logical")
3225 (set_attr "dot" "yes")
3226 (set_attr "length" "4,8")])
3228 (define_insn "*and<mode>3_imm_dot_shifted"
3229 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3232 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3233 (match_operand:SI 4 "const_int_operand" "n"))
3234 (match_operand:GPR 2 "const_int_operand" "n"))
3236 (clobber (match_scratch:GPR 0 "=r"))]
3237 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3238 << INTVAL (operands[4])),
3240 && (<MODE>mode == Pmode
3241 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3242 && rs6000_gen_cell_microcode"
3244 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3245 return "andi%e2. %0,%1,%u2";
3247 [(set_attr "type" "logical")
3248 (set_attr "dot" "yes")])
3251 (define_insn "and<mode>3_mask"
3252 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3253 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3254 (match_operand:GPR 2 "const_int_operand" "n")))]
3255 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3257 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3259 [(set_attr "type" "shift")])
3261 (define_insn_and_split "*and<mode>3_mask_dot"
3262 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3263 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3264 (match_operand:GPR 2 "const_int_operand" "n,n"))
3266 (clobber (match_scratch:GPR 0 "=r,r"))]
3267 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3268 && rs6000_gen_cell_microcode
3269 && !logical_const_operand (operands[2], <MODE>mode)
3270 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3272 if (which_alternative == 0)
3273 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3277 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3279 (and:GPR (match_dup 1)
3282 (compare:CC (match_dup 0)
3285 [(set_attr "type" "shift")
3286 (set_attr "dot" "yes")
3287 (set_attr "length" "4,8")])
3289 (define_insn_and_split "*and<mode>3_mask_dot2"
3290 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3291 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3292 (match_operand:GPR 2 "const_int_operand" "n,n"))
3294 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3295 (and:GPR (match_dup 1)
3297 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3298 && rs6000_gen_cell_microcode
3299 && !logical_const_operand (operands[2], <MODE>mode)
3300 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3302 if (which_alternative == 0)
3303 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3307 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3309 (and:GPR (match_dup 1)
3312 (compare:CC (match_dup 0)
3315 [(set_attr "type" "shift")
3316 (set_attr "dot" "yes")
3317 (set_attr "length" "4,8")])
3320 (define_insn_and_split "*and<mode>3_2insn"
3321 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3322 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3323 (match_operand:GPR 2 "const_int_operand" "n")))]
3324 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3325 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3326 || (logical_const_operand (operands[2], <MODE>mode)
3327 && rs6000_gen_cell_microcode))"
3332 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3335 [(set_attr "type" "shift")
3336 (set_attr "length" "8")])
3338 (define_insn_and_split "*and<mode>3_2insn_dot"
3339 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3340 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3341 (match_operand:GPR 2 "const_int_operand" "n,n"))
3343 (clobber (match_scratch:GPR 0 "=r,r"))]
3344 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3345 && rs6000_gen_cell_microcode
3346 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3347 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3348 || (logical_const_operand (operands[2], <MODE>mode)
3349 && rs6000_gen_cell_microcode))"
3351 "&& reload_completed"
3354 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3357 [(set_attr "type" "shift")
3358 (set_attr "dot" "yes")
3359 (set_attr "length" "8,12")])
3361 (define_insn_and_split "*and<mode>3_2insn_dot2"
3362 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3363 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3364 (match_operand:GPR 2 "const_int_operand" "n,n"))
3366 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3367 (and:GPR (match_dup 1)
3369 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3370 && rs6000_gen_cell_microcode
3371 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3372 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3373 || (logical_const_operand (operands[2], <MODE>mode)
3374 && rs6000_gen_cell_microcode))"
3376 "&& reload_completed"
3379 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3382 [(set_attr "type" "shift")
3383 (set_attr "dot" "yes")
3384 (set_attr "length" "8,12")])
3387 (define_expand "<code><mode>3"
3388 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3389 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3390 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3393 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3395 rs6000_split_logical (operands, <CODE>, false, false, false);
3399 if (non_logical_cint_operand (operands[2], <MODE>mode))
3401 rtx tmp = ((!can_create_pseudo_p ()
3402 || rtx_equal_p (operands[0], operands[1]))
3403 ? operands[0] : gen_reg_rtx (<MODE>mode));
3405 HOST_WIDE_INT value = INTVAL (operands[2]);
3406 HOST_WIDE_INT lo = value & 0xffff;
3407 HOST_WIDE_INT hi = value - lo;
3409 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3410 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3414 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3415 operands[2] = force_reg (<MODE>mode, operands[2]);
3419 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3420 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3421 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3424 (iorxor:GPR (match_dup 1)
3427 (iorxor:GPR (match_dup 3)
3430 operands[3] = ((!can_create_pseudo_p ()
3431 || rtx_equal_p (operands[0], operands[1]))
3432 ? operands[0] : gen_reg_rtx (<MODE>mode));
3434 HOST_WIDE_INT value = INTVAL (operands[2]);
3435 HOST_WIDE_INT lo = value & 0xffff;
3436 HOST_WIDE_INT hi = value - lo;
3438 operands[4] = GEN_INT (hi);
3439 operands[5] = GEN_INT (lo);
3442 (define_insn "*bool<mode>3_imm"
3443 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3444 (match_operator:GPR 3 "boolean_or_operator"
3445 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3446 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3449 [(set_attr "type" "logical")])
3451 (define_insn "*bool<mode>3"
3452 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3453 (match_operator:GPR 3 "boolean_operator"
3454 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3455 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3458 [(set_attr "type" "logical")])
3460 (define_insn_and_split "*bool<mode>3_dot"
3461 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3462 (compare:CC (match_operator:GPR 3 "boolean_operator"
3463 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3464 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3466 (clobber (match_scratch:GPR 0 "=r,r"))]
3467 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3471 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3475 (compare:CC (match_dup 0)
3478 [(set_attr "type" "logical")
3479 (set_attr "dot" "yes")
3480 (set_attr "length" "4,8")])
3482 (define_insn_and_split "*bool<mode>3_dot2"
3483 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3484 (compare:CC (match_operator:GPR 3 "boolean_operator"
3485 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3486 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3488 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3490 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3494 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3498 (compare:CC (match_dup 0)
3501 [(set_attr "type" "logical")
3502 (set_attr "dot" "yes")
3503 (set_attr "length" "4,8")])
3506 (define_insn "*boolc<mode>3"
3507 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3508 (match_operator:GPR 3 "boolean_operator"
3509 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3510 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3513 [(set_attr "type" "logical")])
3515 (define_insn_and_split "*boolc<mode>3_dot"
3516 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3517 (compare:CC (match_operator:GPR 3 "boolean_operator"
3518 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3519 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3521 (clobber (match_scratch:GPR 0 "=r,r"))]
3522 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3526 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3530 (compare:CC (match_dup 0)
3533 [(set_attr "type" "logical")
3534 (set_attr "dot" "yes")
3535 (set_attr "length" "4,8")])
3537 (define_insn_and_split "*boolc<mode>3_dot2"
3538 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3539 (compare:CC (match_operator:GPR 3 "boolean_operator"
3540 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3541 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3543 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3545 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3549 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3553 (compare:CC (match_dup 0)
3556 [(set_attr "type" "logical")
3557 (set_attr "dot" "yes")
3558 (set_attr "length" "4,8")])
3561 (define_insn "*boolcc<mode>3"
3562 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3563 (match_operator:GPR 3 "boolean_operator"
3564 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3565 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3568 [(set_attr "type" "logical")])
3570 (define_insn_and_split "*boolcc<mode>3_dot"
3571 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3572 (compare:CC (match_operator:GPR 3 "boolean_operator"
3573 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3574 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3576 (clobber (match_scratch:GPR 0 "=r,r"))]
3577 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3581 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3585 (compare:CC (match_dup 0)
3588 [(set_attr "type" "logical")
3589 (set_attr "dot" "yes")
3590 (set_attr "length" "4,8")])
3592 (define_insn_and_split "*boolcc<mode>3_dot2"
3593 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3594 (compare:CC (match_operator:GPR 3 "boolean_operator"
3595 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3596 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3598 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3600 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3604 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3608 (compare:CC (match_dup 0)
3611 [(set_attr "type" "logical")
3612 (set_attr "dot" "yes")
3613 (set_attr "length" "4,8")])
3616 ;; TODO: Should have dots of this as well.
3617 (define_insn "*eqv<mode>3"
3618 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3619 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3620 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3623 [(set_attr "type" "logical")])
3625 ;; Rotate-and-mask and insert.
3627 (define_insn "*rotl<mode>3_mask"
3628 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3629 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3630 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3631 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3632 (match_operand:GPR 3 "const_int_operand" "n")))]
3633 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3635 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3637 [(set_attr "type" "shift")
3638 (set_attr "maybe_var_shift" "yes")])
3640 (define_insn_and_split "*rotl<mode>3_mask_dot"
3641 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3643 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3644 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3645 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3646 (match_operand:GPR 3 "const_int_operand" "n,n"))
3648 (clobber (match_scratch:GPR 0 "=r,r"))]
3649 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3650 && rs6000_gen_cell_microcode
3651 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3653 if (which_alternative == 0)
3654 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3658 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3660 (and:GPR (match_dup 4)
3663 (compare:CC (match_dup 0)
3666 [(set_attr "type" "shift")
3667 (set_attr "maybe_var_shift" "yes")
3668 (set_attr "dot" "yes")
3669 (set_attr "length" "4,8")])
3671 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3672 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3674 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3675 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3676 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3677 (match_operand:GPR 3 "const_int_operand" "n,n"))
3679 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3680 (and:GPR (match_dup 4)
3682 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3683 && rs6000_gen_cell_microcode
3684 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3686 if (which_alternative == 0)
3687 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3691 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3693 (and:GPR (match_dup 4)
3696 (compare:CC (match_dup 0)
3699 [(set_attr "type" "shift")
3700 (set_attr "maybe_var_shift" "yes")
3701 (set_attr "dot" "yes")
3702 (set_attr "length" "4,8")])
3704 ; Special case for less-than-0. We can do it with just one machine
3705 ; instruction, but the generic optimizers do not realise it is cheap.
3706 (define_insn "*lt0_disi"
3707 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3708 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3711 "rlwinm %0,%1,1,31,31"
3712 [(set_attr "type" "shift")])
3716 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3717 ; both are an AND so are the same precedence).
3718 (define_insn "*rotl<mode>3_insert"
3719 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3720 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3721 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3722 (match_operand:SI 2 "const_int_operand" "n")])
3723 (match_operand:GPR 3 "const_int_operand" "n"))
3724 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3725 (match_operand:GPR 6 "const_int_operand" "n"))))]
3726 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3727 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3729 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3731 [(set_attr "type" "insert")])
3732 ; FIXME: this needs an attr "size", so that the scheduler can see the
3733 ; difference between rlwimi and rldimi. We also might want dot forms,
3734 ; but not for rlwimi on POWER4 and similar processors.
3736 (define_insn "*rotl<mode>3_insert_2"
3737 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3738 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3739 (match_operand:GPR 6 "const_int_operand" "n"))
3740 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3741 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3742 (match_operand:SI 2 "const_int_operand" "n")])
3743 (match_operand:GPR 3 "const_int_operand" "n"))))]
3744 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3745 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3747 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3749 [(set_attr "type" "insert")])
3751 ; There are also some forms without one of the ANDs.
3752 (define_insn "*rotl<mode>3_insert_3"
3753 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3754 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3755 (match_operand:GPR 4 "const_int_operand" "n"))
3756 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3757 (match_operand:SI 2 "const_int_operand" "n"))))]
3758 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3760 if (<MODE>mode == SImode)
3761 return "rlwimi %0,%1,%h2,0,31-%h2";
3763 return "rldimi %0,%1,%H2,0";
3765 [(set_attr "type" "insert")])
3767 (define_insn "*rotl<mode>3_insert_4"
3768 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3769 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3770 (match_operand:GPR 4 "const_int_operand" "n"))
3771 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3772 (match_operand:SI 2 "const_int_operand" "n"))))]
3773 "<MODE>mode == SImode &&
3774 GET_MODE_PRECISION (<MODE>mode)
3775 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3777 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3778 - INTVAL (operands[2]));
3779 if (<MODE>mode == SImode)
3780 return "rlwimi %0,%1,%h2,32-%h2,31";
3782 return "rldimi %0,%1,%H2,64-%H2";
3784 [(set_attr "type" "insert")])
3787 ; This handles the important case of multiple-precision shifts. There is
3788 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3790 [(set (match_operand:GPR 0 "gpc_reg_operand")
3791 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3792 (match_operand:SI 3 "const_int_operand"))
3793 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3794 (match_operand:SI 4 "const_int_operand"))))]
3795 "can_create_pseudo_p ()
3796 && INTVAL (operands[3]) + INTVAL (operands[4])
3797 >= GET_MODE_PRECISION (<MODE>mode)"
3799 (lshiftrt:GPR (match_dup 2)
3802 (ior:GPR (and:GPR (match_dup 5)
3804 (ashift:GPR (match_dup 1)
3807 unsigned HOST_WIDE_INT mask = 1;
3808 mask = (mask << INTVAL (operands[3])) - 1;
3809 operands[5] = gen_reg_rtx (<MODE>mode);
3810 operands[6] = GEN_INT (mask);
3814 [(set (match_operand:GPR 0 "gpc_reg_operand")
3815 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3816 (match_operand:SI 4 "const_int_operand"))
3817 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3818 (match_operand:SI 3 "const_int_operand"))))]
3819 "can_create_pseudo_p ()
3820 && INTVAL (operands[3]) + INTVAL (operands[4])
3821 >= GET_MODE_PRECISION (<MODE>mode)"
3823 (lshiftrt:GPR (match_dup 2)
3826 (ior:GPR (and:GPR (match_dup 5)
3828 (ashift:GPR (match_dup 1)
3831 unsigned HOST_WIDE_INT mask = 1;
3832 mask = (mask << INTVAL (operands[3])) - 1;
3833 operands[5] = gen_reg_rtx (<MODE>mode);
3834 operands[6] = GEN_INT (mask);
3838 ; Another important case is setting some bits to 1; we can do that with
3839 ; an insert instruction, in many cases.
3840 (define_insn_and_split "*ior<mode>_mask"
3841 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3842 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3843 (match_operand:GPR 2 "const_int_operand" "n")))
3844 (clobber (match_scratch:GPR 3 "=r"))]
3845 "!logical_const_operand (operands[2], <MODE>mode)
3846 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3852 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3855 (and:GPR (match_dup 1)
3859 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3860 if (GET_CODE (operands[3]) == SCRATCH)
3861 operands[3] = gen_reg_rtx (<MODE>mode);
3862 operands[4] = GEN_INT (ne);
3863 operands[5] = GEN_INT (~UINTVAL (operands[2]));
3865 [(set_attr "type" "two")
3866 (set_attr "length" "8")])
3869 ;; Now the simple shifts.
3871 (define_insn "rotl<mode>3"
3872 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3873 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3874 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3876 "rotl<wd>%I2 %0,%1,%<hH>2"
3877 [(set_attr "type" "shift")
3878 (set_attr "maybe_var_shift" "yes")])
3880 (define_insn "*rotlsi3_64"
3881 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3883 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3884 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3886 "rotlw%I2 %0,%1,%h2"
3887 [(set_attr "type" "shift")
3888 (set_attr "maybe_var_shift" "yes")])
3890 (define_insn_and_split "*rotl<mode>3_dot"
3891 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3892 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3893 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3895 (clobber (match_scratch:GPR 0 "=r,r"))]
3896 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3898 rotl<wd>%I2. %0,%1,%<hH>2
3900 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3902 (rotate:GPR (match_dup 1)
3905 (compare:CC (match_dup 0)
3908 [(set_attr "type" "shift")
3909 (set_attr "maybe_var_shift" "yes")
3910 (set_attr "dot" "yes")
3911 (set_attr "length" "4,8")])
3913 (define_insn_and_split "*rotl<mode>3_dot2"
3914 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3915 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3916 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3918 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3919 (rotate:GPR (match_dup 1)
3921 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3923 rotl<wd>%I2. %0,%1,%<hH>2
3925 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3927 (rotate:GPR (match_dup 1)
3930 (compare:CC (match_dup 0)
3933 [(set_attr "type" "shift")
3934 (set_attr "maybe_var_shift" "yes")
3935 (set_attr "dot" "yes")
3936 (set_attr "length" "4,8")])
3939 (define_insn "ashl<mode>3"
3940 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3941 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3942 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3944 "sl<wd>%I2 %0,%1,%<hH>2"
3945 [(set_attr "type" "shift")
3946 (set_attr "maybe_var_shift" "yes")])
3948 (define_insn "*ashlsi3_64"
3949 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3951 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3952 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3955 [(set_attr "type" "shift")
3956 (set_attr "maybe_var_shift" "yes")])
3958 (define_insn_and_split "*ashl<mode>3_dot"
3959 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3960 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3961 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3963 (clobber (match_scratch:GPR 0 "=r,r"))]
3964 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3966 sl<wd>%I2. %0,%1,%<hH>2
3968 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3970 (ashift:GPR (match_dup 1)
3973 (compare:CC (match_dup 0)
3976 [(set_attr "type" "shift")
3977 (set_attr "maybe_var_shift" "yes")
3978 (set_attr "dot" "yes")
3979 (set_attr "length" "4,8")])
3981 (define_insn_and_split "*ashl<mode>3_dot2"
3982 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3983 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3984 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3986 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3987 (ashift:GPR (match_dup 1)
3989 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3991 sl<wd>%I2. %0,%1,%<hH>2
3993 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3995 (ashift:GPR (match_dup 1)
3998 (compare:CC (match_dup 0)
4001 [(set_attr "type" "shift")
4002 (set_attr "maybe_var_shift" "yes")
4003 (set_attr "dot" "yes")
4004 (set_attr "length" "4,8")])
4006 ;; Pretend we have a memory form of extswsli until register allocation is done
4007 ;; so that we use LWZ to load the value from memory, instead of LWA.
4008 (define_insn_and_split "ashdi3_extswsli"
4009 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4011 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4012 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4017 "&& reload_completed && MEM_P (operands[1])"
4021 (ashift:DI (sign_extend:DI (match_dup 3))
4024 operands[3] = gen_lowpart (SImode, operands[0]);
4026 [(set_attr "type" "shift")
4027 (set_attr "maybe_var_shift" "no")])
4030 (define_insn_and_split "ashdi3_extswsli_dot"
4031 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4034 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4035 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4037 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4044 "&& reload_completed
4045 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4046 || memory_operand (operands[1], SImode))"
4049 rtx dest = operands[0];
4050 rtx src = operands[1];
4051 rtx shift = operands[2];
4052 rtx cr = operands[3];
4059 src2 = gen_lowpart (SImode, dest);
4060 emit_move_insn (src2, src);
4063 if (REGNO (cr) == CR0_REGNO)
4065 emit_insn (gen_ashdi3_extswsli_dot (dest, src2, shift, cr));
4069 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4070 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4073 [(set_attr "type" "shift")
4074 (set_attr "maybe_var_shift" "no")
4075 (set_attr "dot" "yes")
4076 (set_attr "length" "4,8,8,12")])
4078 (define_insn_and_split "ashdi3_extswsli_dot2"
4079 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4082 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4083 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4085 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4086 (ashift:DI (sign_extend:DI (match_dup 1))
4094 "&& reload_completed
4095 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4096 || memory_operand (operands[1], SImode))"
4099 rtx dest = operands[0];
4100 rtx src = operands[1];
4101 rtx shift = operands[2];
4102 rtx cr = operands[3];
4109 src2 = gen_lowpart (SImode, dest);
4110 emit_move_insn (src2, src);
4113 if (REGNO (cr) == CR0_REGNO)
4115 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4119 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4120 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4123 [(set_attr "type" "shift")
4124 (set_attr "maybe_var_shift" "no")
4125 (set_attr "dot" "yes")
4126 (set_attr "length" "4,8,8,12")])
4128 (define_insn "lshr<mode>3"
4129 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4130 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4131 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4133 "sr<wd>%I2 %0,%1,%<hH>2"
4134 [(set_attr "type" "shift")
4135 (set_attr "maybe_var_shift" "yes")])
4137 (define_insn "*lshrsi3_64"
4138 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4140 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4141 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4144 [(set_attr "type" "shift")
4145 (set_attr "maybe_var_shift" "yes")])
4147 (define_insn_and_split "*lshr<mode>3_dot"
4148 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4149 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4150 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4152 (clobber (match_scratch:GPR 0 "=r,r"))]
4153 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4155 sr<wd>%I2. %0,%1,%<hH>2
4157 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4159 (lshiftrt:GPR (match_dup 1)
4162 (compare:CC (match_dup 0)
4165 [(set_attr "type" "shift")
4166 (set_attr "maybe_var_shift" "yes")
4167 (set_attr "dot" "yes")
4168 (set_attr "length" "4,8")])
4170 (define_insn_and_split "*lshr<mode>3_dot2"
4171 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4172 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4173 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4175 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4176 (lshiftrt:GPR (match_dup 1)
4178 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4180 sr<wd>%I2. %0,%1,%<hH>2
4182 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4184 (lshiftrt:GPR (match_dup 1)
4187 (compare:CC (match_dup 0)
4190 [(set_attr "type" "shift")
4191 (set_attr "maybe_var_shift" "yes")
4192 (set_attr "dot" "yes")
4193 (set_attr "length" "4,8")])
4196 (define_insn "ashr<mode>3"
4197 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4198 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4199 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4200 (clobber (reg:GPR CA_REGNO))]
4202 "sra<wd>%I2 %0,%1,%<hH>2"
4203 [(set_attr "type" "shift")
4204 (set_attr "maybe_var_shift" "yes")])
4206 (define_insn "*ashrsi3_64"
4207 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4209 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4210 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4211 (clobber (reg:SI CA_REGNO))]
4214 [(set_attr "type" "shift")
4215 (set_attr "maybe_var_shift" "yes")])
4217 (define_insn_and_split "*ashr<mode>3_dot"
4218 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4219 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4220 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4222 (clobber (match_scratch:GPR 0 "=r,r"))
4223 (clobber (reg:GPR CA_REGNO))]
4224 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4226 sra<wd>%I2. %0,%1,%<hH>2
4228 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4229 [(parallel [(set (match_dup 0)
4230 (ashiftrt:GPR (match_dup 1)
4232 (clobber (reg:GPR CA_REGNO))])
4234 (compare:CC (match_dup 0)
4237 [(set_attr "type" "shift")
4238 (set_attr "maybe_var_shift" "yes")
4239 (set_attr "dot" "yes")
4240 (set_attr "length" "4,8")])
4242 (define_insn_and_split "*ashr<mode>3_dot2"
4243 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4244 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4245 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4247 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4248 (ashiftrt:GPR (match_dup 1)
4250 (clobber (reg:GPR CA_REGNO))]
4251 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4253 sra<wd>%I2. %0,%1,%<hH>2
4255 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4256 [(parallel [(set (match_dup 0)
4257 (ashiftrt:GPR (match_dup 1)
4259 (clobber (reg:GPR CA_REGNO))])
4261 (compare:CC (match_dup 0)
4264 [(set_attr "type" "shift")
4265 (set_attr "maybe_var_shift" "yes")
4266 (set_attr "dot" "yes")
4267 (set_attr "length" "4,8")])
4269 ;; Builtins to replace a division to generate FRE reciprocal estimate
4270 ;; instructions and the necessary fixup instructions
4271 (define_expand "recip<mode>3"
4272 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4273 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4274 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4275 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4277 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4281 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4282 ;; hardware division. This is only done before register allocation and with
4283 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4285 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4286 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4287 (match_operand 2 "gpc_reg_operand" "")))]
4288 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4289 && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4290 && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4293 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4297 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4298 ;; appropriate fixup.
4299 (define_expand "rsqrt<mode>2"
4300 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4301 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4302 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4304 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4308 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4309 ;; modes here, and also add in conditional vsx/power8-vector support to access
4310 ;; values in the traditional Altivec registers if the appropriate
4311 ;; -mupper-regs-{df,sf} option is enabled.
4313 (define_expand "abs<mode>2"
4314 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4315 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4316 "TARGET_<MODE>_INSN"
4319 (define_insn "*abs<mode>2_fpr"
4320 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4321 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4326 [(set_attr "type" "fp")
4327 (set_attr "fp_type" "fp_addsub_<Fs>")])
4329 (define_insn "*nabs<mode>2_fpr"
4330 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4333 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4338 [(set_attr "type" "fp")
4339 (set_attr "fp_type" "fp_addsub_<Fs>")])
4341 (define_expand "neg<mode>2"
4342 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4343 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4344 "TARGET_<MODE>_INSN"
4347 (define_insn "*neg<mode>2_fpr"
4348 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4349 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4354 [(set_attr "type" "fp")
4355 (set_attr "fp_type" "fp_addsub_<Fs>")])
4357 (define_expand "add<mode>3"
4358 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4359 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4360 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4361 "TARGET_<MODE>_INSN"
4364 (define_insn "*add<mode>3_fpr"
4365 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4366 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4367 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4370 fadd<Ftrad> %0,%1,%2
4371 xsadd<Fvsx> %x0,%x1,%x2"
4372 [(set_attr "type" "fp")
4373 (set_attr "fp_type" "fp_addsub_<Fs>")])
4375 (define_expand "sub<mode>3"
4376 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4377 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4378 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4379 "TARGET_<MODE>_INSN"
4382 (define_insn "*sub<mode>3_fpr"
4383 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4384 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4385 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4388 fsub<Ftrad> %0,%1,%2
4389 xssub<Fvsx> %x0,%x1,%x2"
4390 [(set_attr "type" "fp")
4391 (set_attr "fp_type" "fp_addsub_<Fs>")])
4393 (define_expand "mul<mode>3"
4394 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4395 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4396 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4397 "TARGET_<MODE>_INSN"
4400 (define_insn "*mul<mode>3_fpr"
4401 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4402 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4403 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4406 fmul<Ftrad> %0,%1,%2
4407 xsmul<Fvsx> %x0,%x1,%x2"
4408 [(set_attr "type" "dmul")
4409 (set_attr "fp_type" "fp_mul_<Fs>")])
4411 (define_expand "div<mode>3"
4412 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4413 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4414 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4415 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4418 (define_insn "*div<mode>3_fpr"
4419 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4420 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4421 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4422 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4424 fdiv<Ftrad> %0,%1,%2
4425 xsdiv<Fvsx> %x0,%x1,%x2"
4426 [(set_attr "type" "<Fs>div")
4427 (set_attr "fp_type" "fp_div_<Fs>")])
4429 (define_insn "*sqrt<mode>2_internal"
4430 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4431 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4432 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4433 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4436 xssqrt<Fvsx> %x0,%x1"
4437 [(set_attr "type" "<Fs>sqrt")
4438 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4440 (define_expand "sqrt<mode>2"
4441 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4442 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4443 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4444 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4446 if (<MODE>mode == SFmode
4447 && TARGET_RECIP_PRECISION
4448 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4449 && !optimize_function_for_size_p (cfun)
4450 && flag_finite_math_only && !flag_trapping_math
4451 && flag_unsafe_math_optimizations)
4453 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4458 ;; Floating point reciprocal approximation
4459 (define_insn "fre<Fs>"
4460 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4461 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4467 [(set_attr "type" "fp")])
4469 (define_insn "*rsqrt<mode>2"
4470 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4471 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4473 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4475 frsqrte<Ftrad> %0,%1
4476 xsrsqrte<Fvsx> %x0,%x1"
4477 [(set_attr "type" "fp")])
4479 ;; Floating point comparisons
4480 (define_insn "*cmp<mode>_fpr"
4481 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4482 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4483 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4487 xscmpudp %0,%x1,%x2"
4488 [(set_attr "type" "fpcompare")])
4490 ;; Floating point conversions
4491 (define_expand "extendsfdf2"
4492 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4493 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4494 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4497 (define_insn_and_split "*extendsfdf2_fpr"
4498 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4499 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))]
4500 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4506 xscpsgndp %x0,%x1,%x1
4509 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4512 emit_note (NOTE_INSN_DELETED);
4515 [(set_attr "type" "fp,fp,fpload,fp,fp,fpload,fpload")])
4517 (define_expand "truncdfsf2"
4518 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4519 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4520 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4523 (define_insn "*truncdfsf2_fpr"
4524 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4525 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4526 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4530 [(set_attr "type" "fp")])
4532 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4533 ;; builtins.c and optabs.c that are not correct for IBM long double
4534 ;; when little-endian.
4535 (define_expand "signbit<mode>2"
4537 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "")))
4539 (subreg:DI (match_dup 2) 0))
4542 (set (match_operand:SI 0 "gpc_reg_operand" "")
4545 && (TARGET_FPRS || TARGET_E500_DOUBLE)"
4547 operands[2] = gen_reg_rtx (DFmode);
4548 operands[3] = gen_reg_rtx (DImode);
4549 if (TARGET_POWERPC64)
4551 operands[4] = gen_reg_rtx (DImode);
4552 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4553 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4554 WORDS_BIG_ENDIAN ? 4 : 0);
4558 operands[4] = gen_reg_rtx (SImode);
4559 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4560 WORDS_BIG_ENDIAN ? 0 : 4);
4561 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4565 (define_expand "copysign<mode>3"
4567 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4569 (neg:SFDF (abs:SFDF (match_dup 1))))
4570 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4571 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4575 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4576 && ((TARGET_PPC_GFXOPT
4577 && !HONOR_NANS (<MODE>mode)
4578 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4580 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4582 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4584 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4589 operands[3] = gen_reg_rtx (<MODE>mode);
4590 operands[4] = gen_reg_rtx (<MODE>mode);
4591 operands[5] = CONST0_RTX (<MODE>mode);
4594 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4595 ;; compiler from optimizing -0.0
4596 (define_insn "copysign<mode>3_fcpsgn"
4597 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4598 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4599 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4601 "TARGET_<MODE>_FPR && TARGET_CMPB"
4604 xscpsgndp %x0,%x2,%x1"
4605 [(set_attr "type" "fp")])
4607 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4608 ;; fsel instruction and some auxiliary computations. Then we just have a
4609 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4611 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4612 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4613 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4614 ;; define_splits to make them if made by combine. On VSX machines we have the
4615 ;; min/max instructions.
4617 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4618 ;; to allow either DF/SF to use only traditional registers.
4620 (define_expand "smax<mode>3"
4621 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4622 (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4623 (match_operand:SFDF 2 "gpc_reg_operand" ""))
4626 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4628 rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
4632 (define_insn "*smax<mode>3_vsx"
4633 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4634 (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4635 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4636 "TARGET_<MODE>_FPR && TARGET_VSX"
4637 "xsmaxdp %x0,%x1,%x2"
4638 [(set_attr "type" "fp")])
4640 (define_expand "smin<mode>3"
4641 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4642 (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4643 (match_operand:SFDF 2 "gpc_reg_operand" ""))
4646 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4648 rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
4652 (define_insn "*smin<mode>3_vsx"
4653 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4654 (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4655 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4656 "TARGET_<MODE>_FPR && TARGET_VSX"
4657 "xsmindp %x0,%x1,%x2"
4658 [(set_attr "type" "fp")])
4661 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4662 (match_operator:SFDF 3 "min_max_operator"
4663 [(match_operand:SFDF 1 "gpc_reg_operand" "")
4664 (match_operand:SFDF 2 "gpc_reg_operand" "")]))]
4665 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math
4669 rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1],
4675 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4676 (match_operator:SF 3 "min_max_operator"
4677 [(match_operand:SF 1 "gpc_reg_operand" "")
4678 (match_operand:SF 2 "gpc_reg_operand" "")]))]
4679 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
4680 && TARGET_SINGLE_FLOAT && !flag_trapping_math"
4683 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4684 operands[1], operands[2]);
4688 (define_expand "mov<mode>cc"
4689 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4690 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4691 (match_operand:GPR 2 "gpc_reg_operand" "")
4692 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4696 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4702 ;; We use the BASE_REGS for the isel input operands because, if rA is
4703 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4704 ;; because we may switch the operands and rB may end up being rA.
4706 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4707 ;; leave out the mode in operand 4 and use one pattern, but reload can
4708 ;; change the mode underneath our feet and then gets confused trying
4709 ;; to reload the value.
4710 (define_insn "isel_signed_<mode>"
4711 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4713 (match_operator 1 "scc_comparison_operator"
4714 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4716 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4717 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4720 { return output_isel (operands); }"
4721 [(set_attr "type" "isel")
4722 (set_attr "length" "4")])
4724 (define_insn "isel_unsigned_<mode>"
4725 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4727 (match_operator 1 "scc_comparison_operator"
4728 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4730 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4731 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4734 { return output_isel (operands); }"
4735 [(set_attr "type" "isel")
4736 (set_attr "length" "4")])
4738 ;; These patterns can be useful for combine; they let combine know that
4739 ;; isel can handle reversed comparisons so long as the operands are
4742 (define_insn "*isel_reversed_signed_<mode>"
4743 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4745 (match_operator 1 "scc_rev_comparison_operator"
4746 [(match_operand:CC 4 "cc_reg_operand" "y")
4748 (match_operand:GPR 2 "gpc_reg_operand" "b")
4749 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4752 { return output_isel (operands); }"
4753 [(set_attr "type" "isel")
4754 (set_attr "length" "4")])
4756 (define_insn "*isel_reversed_unsigned_<mode>"
4757 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4759 (match_operator 1 "scc_rev_comparison_operator"
4760 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4762 (match_operand:GPR 2 "gpc_reg_operand" "b")
4763 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4766 { return output_isel (operands); }"
4767 [(set_attr "type" "isel")
4768 (set_attr "length" "4")])
4770 (define_expand "movsfcc"
4771 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4772 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4773 (match_operand:SF 2 "gpc_reg_operand" "")
4774 (match_operand:SF 3 "gpc_reg_operand" "")))]
4775 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4778 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4784 (define_insn "*fselsfsf4"
4785 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4786 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4787 (match_operand:SF 4 "zero_fp_constant" "F"))
4788 (match_operand:SF 2 "gpc_reg_operand" "f")
4789 (match_operand:SF 3 "gpc_reg_operand" "f")))]
4790 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4792 [(set_attr "type" "fp")])
4794 (define_insn "*fseldfsf4"
4795 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4796 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4797 (match_operand:DF 4 "zero_fp_constant" "F"))
4798 (match_operand:SF 2 "gpc_reg_operand" "f")
4799 (match_operand:SF 3 "gpc_reg_operand" "f")))]
4800 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4802 [(set_attr "type" "fp")])
4804 ;; The conditional move instructions allow us to perform max and min
4805 ;; operations even when
4808 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4809 (match_operator:DF 3 "min_max_operator"
4810 [(match_operand:DF 1 "gpc_reg_operand" "")
4811 (match_operand:DF 2 "gpc_reg_operand" "")]))]
4812 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4813 && !flag_trapping_math"
4816 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4817 operands[1], operands[2]);
4821 (define_expand "movdfcc"
4822 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4823 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4824 (match_operand:DF 2 "gpc_reg_operand" "")
4825 (match_operand:DF 3 "gpc_reg_operand" "")))]
4826 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4829 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4835 (define_insn "*fseldfdf4"
4836 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4837 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4838 (match_operand:DF 4 "zero_fp_constant" "F"))
4839 (match_operand:DF 2 "gpc_reg_operand" "d")
4840 (match_operand:DF 3 "gpc_reg_operand" "d")))]
4841 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4843 [(set_attr "type" "fp")])
4845 (define_insn "*fselsfdf4"
4846 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4847 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4848 (match_operand:SF 4 "zero_fp_constant" "F"))
4849 (match_operand:DF 2 "gpc_reg_operand" "d")
4850 (match_operand:DF 3 "gpc_reg_operand" "d")))]
4851 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4853 [(set_attr "type" "fp")])
4855 ;; Conversions to and from floating-point.
4857 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4858 ; don't want to support putting SImode in FPR registers.
4859 (define_insn "lfiwax"
4860 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4861 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4863 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4868 [(set_attr "type" "fpload,fpload,mffgpr")])
4870 ; This split must be run before register allocation because it allocates the
4871 ; memory slot that is needed to move values to/from the FPR. We don't allocate
4872 ; it earlier to allow for the combiner to merge insns together where it might
4873 ; not be needed and also in case the insns are deleted as dead code.
4875 (define_insn_and_split "floatsi<mode>2_lfiwax"
4876 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4877 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4878 (clobber (match_scratch:DI 2 "=wj"))]
4879 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4880 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4886 rtx dest = operands[0];
4887 rtx src = operands[1];
4890 if (!MEM_P (src) && TARGET_POWERPC64
4891 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4892 tmp = convert_to_mode (DImode, src, false);
4896 if (GET_CODE (tmp) == SCRATCH)
4897 tmp = gen_reg_rtx (DImode);
4900 src = rs6000_address_for_fpconvert (src);
4901 emit_insn (gen_lfiwax (tmp, src));
4905 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4906 emit_move_insn (stack, src);
4907 emit_insn (gen_lfiwax (tmp, stack));
4910 emit_insn (gen_floatdi<mode>2 (dest, tmp));
4913 [(set_attr "length" "12")
4914 (set_attr "type" "fpload")])
4916 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
4917 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4920 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4921 (clobber (match_scratch:DI 2 "=0,d"))]
4922 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4929 operands[1] = rs6000_address_for_fpconvert (operands[1]);
4930 if (GET_CODE (operands[2]) == SCRATCH)
4931 operands[2] = gen_reg_rtx (DImode);
4932 emit_insn (gen_lfiwax (operands[2], operands[1]));
4933 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4936 [(set_attr "length" "8")
4937 (set_attr "type" "fpload")])
4939 (define_insn "lfiwzx"
4940 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4941 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4943 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
4948 [(set_attr "type" "fpload,fpload,mftgpr")])
4950 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
4951 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4952 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4953 (clobber (match_scratch:DI 2 "=wj"))]
4954 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4961 rtx dest = operands[0];
4962 rtx src = operands[1];
4965 if (!MEM_P (src) && TARGET_POWERPC64
4966 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4967 tmp = convert_to_mode (DImode, src, true);
4971 if (GET_CODE (tmp) == SCRATCH)
4972 tmp = gen_reg_rtx (DImode);
4975 src = rs6000_address_for_fpconvert (src);
4976 emit_insn (gen_lfiwzx (tmp, src));
4980 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4981 emit_move_insn (stack, src);
4982 emit_insn (gen_lfiwzx (tmp, stack));
4985 emit_insn (gen_floatdi<mode>2 (dest, tmp));
4988 [(set_attr "length" "12")
4989 (set_attr "type" "fpload")])
4991 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
4992 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4993 (unsigned_float:SFDF
4995 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4996 (clobber (match_scratch:DI 2 "=0,d"))]
4997 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5004 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5005 if (GET_CODE (operands[2]) == SCRATCH)
5006 operands[2] = gen_reg_rtx (DImode);
5007 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5008 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5011 [(set_attr "length" "8")
5012 (set_attr "type" "fpload")])
5014 ; For each of these conversions, there is a define_expand, a define_insn
5015 ; with a '#' template, and a define_split (with C code). The idea is
5016 ; to allow constant folding with the template of the define_insn,
5017 ; then to have the insns split later (between sched1 and final).
5019 (define_expand "floatsidf2"
5020 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5021 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5024 (clobber (match_dup 4))
5025 (clobber (match_dup 5))
5026 (clobber (match_dup 6))])]
5028 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5031 if (TARGET_E500_DOUBLE)
5033 if (!REG_P (operands[1]))
5034 operands[1] = force_reg (SImode, operands[1]);
5035 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5038 else if (TARGET_LFIWAX && TARGET_FCFID)
5040 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5043 else if (TARGET_FCFID)
5045 rtx dreg = operands[1];
5047 dreg = force_reg (SImode, dreg);
5048 dreg = convert_to_mode (DImode, dreg, false);
5049 emit_insn (gen_floatdidf2 (operands[0], dreg));
5053 if (!REG_P (operands[1]))
5054 operands[1] = force_reg (SImode, operands[1]);
5055 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5056 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5057 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5058 operands[5] = gen_reg_rtx (DFmode);
5059 operands[6] = gen_reg_rtx (SImode);
5062 (define_insn_and_split "*floatsidf2_internal"
5063 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5064 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5065 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5066 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5067 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5068 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5069 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5070 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5076 rtx lowword, highword;
5077 gcc_assert (MEM_P (operands[4]));
5078 highword = adjust_address (operands[4], SImode, 0);
5079 lowword = adjust_address (operands[4], SImode, 4);
5080 if (! WORDS_BIG_ENDIAN)
5081 std::swap (lowword, highword);
5083 emit_insn (gen_xorsi3 (operands[6], operands[1],
5084 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5085 emit_move_insn (lowword, operands[6]);
5086 emit_move_insn (highword, operands[2]);
5087 emit_move_insn (operands[5], operands[4]);
5088 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5091 [(set_attr "length" "24")
5092 (set_attr "type" "fp")])
5094 ;; If we don't have a direct conversion to single precision, don't enable this
5095 ;; conversion for 32-bit without fast math, because we don't have the insn to
5096 ;; generate the fixup swizzle to avoid double rounding problems.
5097 (define_expand "floatunssisf2"
5098 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5099 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5100 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5103 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5104 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5105 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5110 if (!REG_P (operands[1]))
5111 operands[1] = force_reg (SImode, operands[1]);
5113 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5115 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5120 rtx dreg = operands[1];
5122 dreg = force_reg (SImode, dreg);
5123 dreg = convert_to_mode (DImode, dreg, true);
5124 emit_insn (gen_floatdisf2 (operands[0], dreg));
5129 (define_expand "floatunssidf2"
5130 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5131 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5134 (clobber (match_dup 4))
5135 (clobber (match_dup 5))])]
5137 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5140 if (TARGET_E500_DOUBLE)
5142 if (!REG_P (operands[1]))
5143 operands[1] = force_reg (SImode, operands[1]);
5144 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5147 else if (TARGET_LFIWZX && TARGET_FCFID)
5149 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5152 else if (TARGET_FCFID)
5154 rtx dreg = operands[1];
5156 dreg = force_reg (SImode, dreg);
5157 dreg = convert_to_mode (DImode, dreg, true);
5158 emit_insn (gen_floatdidf2 (operands[0], dreg));
5162 if (!REG_P (operands[1]))
5163 operands[1] = force_reg (SImode, operands[1]);
5164 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5165 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5166 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5167 operands[5] = gen_reg_rtx (DFmode);
5170 (define_insn_and_split "*floatunssidf2_internal"
5171 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5172 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5173 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5174 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5175 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5176 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5177 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5178 && !(TARGET_FCFID && TARGET_POWERPC64)"
5184 rtx lowword, highword;
5185 gcc_assert (MEM_P (operands[4]));
5186 highword = adjust_address (operands[4], SImode, 0);
5187 lowword = adjust_address (operands[4], SImode, 4);
5188 if (! WORDS_BIG_ENDIAN)
5189 std::swap (lowword, highword);
5191 emit_move_insn (lowword, operands[1]);
5192 emit_move_insn (highword, operands[2]);
5193 emit_move_insn (operands[5], operands[4]);
5194 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5197 [(set_attr "length" "20")
5198 (set_attr "type" "fp")])
5200 (define_expand "fix_trunc<mode>si2"
5201 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5202 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5203 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5206 if (!<E500_CONVERT>)
5211 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5214 tmp = gen_reg_rtx (DImode);
5215 stack = rs6000_allocate_stack_temp (DImode, true, false);
5216 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5223 ; Like the convert to float patterns, this insn must be split before
5224 ; register allocation so that it can allocate the memory slot if it
5226 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5227 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5228 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5229 (clobber (match_scratch:DI 2 "=d"))]
5230 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5231 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5232 && TARGET_STFIWX && can_create_pseudo_p ()"
5237 rtx dest = operands[0];
5238 rtx src = operands[1];
5239 rtx tmp = operands[2];
5241 if (GET_CODE (tmp) == SCRATCH)
5242 tmp = gen_reg_rtx (DImode);
5244 emit_insn (gen_fctiwz_<mode> (tmp, src));
5247 dest = rs6000_address_for_fpconvert (dest);
5248 emit_insn (gen_stfiwx (dest, tmp));
5251 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5253 dest = gen_lowpart (DImode, dest);
5254 emit_move_insn (dest, tmp);
5259 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5260 emit_insn (gen_stfiwx (stack, tmp));
5261 emit_move_insn (dest, stack);
5265 [(set_attr "length" "12")
5266 (set_attr "type" "fp")])
5268 (define_insn_and_split "fix_trunc<mode>si2_internal"
5269 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5270 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5271 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5272 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5273 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5280 gcc_assert (MEM_P (operands[3]));
5281 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5283 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5284 emit_move_insn (operands[3], operands[2]);
5285 emit_move_insn (operands[0], lowword);
5288 [(set_attr "length" "16")
5289 (set_attr "type" "fp")])
5291 (define_expand "fix_trunc<mode>di2"
5292 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5293 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5294 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5298 (define_insn "*fix_trunc<mode>di2_fctidz"
5299 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5300 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5301 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5306 [(set_attr "type" "fp")])
5308 (define_expand "fixuns_trunc<mode>si2"
5309 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5310 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5312 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5316 if (!<E500_CONVERT>)
5318 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5323 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5324 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5325 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5326 (clobber (match_scratch:DI 2 "=d"))]
5327 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5328 && TARGET_STFIWX && can_create_pseudo_p ()"
5333 rtx dest = operands[0];
5334 rtx src = operands[1];
5335 rtx tmp = operands[2];
5337 if (GET_CODE (tmp) == SCRATCH)
5338 tmp = gen_reg_rtx (DImode);
5340 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5343 dest = rs6000_address_for_fpconvert (dest);
5344 emit_insn (gen_stfiwx (dest, tmp));
5347 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5349 dest = gen_lowpart (DImode, dest);
5350 emit_move_insn (dest, tmp);
5355 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5356 emit_insn (gen_stfiwx (stack, tmp));
5357 emit_move_insn (dest, stack);
5361 [(set_attr "length" "12")
5362 (set_attr "type" "fp")])
5364 (define_expand "fixuns_trunc<mode>di2"
5365 [(set (match_operand:DI 0 "register_operand" "")
5366 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5367 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5370 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5371 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5372 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5373 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5378 [(set_attr "type" "fp")])
5380 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5381 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5382 ; because the first makes it clear that operand 0 is not live
5383 ; before the instruction.
5384 (define_insn "fctiwz_<mode>"
5385 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5386 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5388 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5392 [(set_attr "type" "fp")])
5394 (define_insn "fctiwuz_<mode>"
5395 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5396 (unspec:DI [(unsigned_fix:SI
5397 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5399 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5403 [(set_attr "type" "fp")])
5405 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5406 ;; since the friz instruction does not truncate the value if the floating
5407 ;; point value is < LONG_MIN or > LONG_MAX.
5408 (define_insn "*friz"
5409 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5410 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5411 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5412 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5416 [(set_attr "type" "fp")])
5418 ;; Since FCTIWZ doesn't sign extend the upper bits, we have to do a store and a
5419 ;; load to properly sign extend the value, but at least doing a store, load
5420 ;; into a GPR to sign extend, a store from the GPR and a load back into the FPR
5421 ;; if we have 32-bit memory ops
5422 (define_insn_and_split "*round32<mode>2_fprs"
5423 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5425 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5426 (clobber (match_scratch:DI 2 "=d"))
5427 (clobber (match_scratch:DI 3 "=d"))]
5428 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5429 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5430 && can_create_pseudo_p ()"
5435 rtx dest = operands[0];
5436 rtx src = operands[1];
5437 rtx tmp1 = operands[2];
5438 rtx tmp2 = operands[3];
5439 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5441 if (GET_CODE (tmp1) == SCRATCH)
5442 tmp1 = gen_reg_rtx (DImode);
5443 if (GET_CODE (tmp2) == SCRATCH)
5444 tmp2 = gen_reg_rtx (DImode);
5446 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5447 emit_insn (gen_stfiwx (stack, tmp1));
5448 emit_insn (gen_lfiwax (tmp2, stack));
5449 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5452 [(set_attr "type" "fpload")
5453 (set_attr "length" "16")])
5455 (define_insn_and_split "*roundu32<mode>2_fprs"
5456 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5457 (unsigned_float:SFDF
5458 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5459 (clobber (match_scratch:DI 2 "=d"))
5460 (clobber (match_scratch:DI 3 "=d"))]
5461 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5462 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU
5463 && can_create_pseudo_p ()"
5468 rtx dest = operands[0];
5469 rtx src = operands[1];
5470 rtx tmp1 = operands[2];
5471 rtx tmp2 = operands[3];
5472 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5474 if (GET_CODE (tmp1) == SCRATCH)
5475 tmp1 = gen_reg_rtx (DImode);
5476 if (GET_CODE (tmp2) == SCRATCH)
5477 tmp2 = gen_reg_rtx (DImode);
5479 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5480 emit_insn (gen_stfiwx (stack, tmp1));
5481 emit_insn (gen_lfiwzx (tmp2, stack));
5482 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5485 [(set_attr "type" "fpload")
5486 (set_attr "length" "16")])
5488 ;; No VSX equivalent to fctid
5489 (define_insn "lrint<mode>di2"
5490 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5491 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5493 "TARGET_<MODE>_FPR && TARGET_FPRND"
5495 [(set_attr "type" "fp")])
5497 (define_insn "btrunc<mode>2"
5498 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5499 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5501 "TARGET_<MODE>_FPR && TARGET_FPRND"
5505 [(set_attr "type" "fp")
5506 (set_attr "fp_type" "fp_addsub_<Fs>")])
5508 (define_insn "ceil<mode>2"
5509 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5510 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5512 "TARGET_<MODE>_FPR && TARGET_FPRND"
5516 [(set_attr "type" "fp")
5517 (set_attr "fp_type" "fp_addsub_<Fs>")])
5519 (define_insn "floor<mode>2"
5520 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5521 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5523 "TARGET_<MODE>_FPR && TARGET_FPRND"
5527 [(set_attr "type" "fp")
5528 (set_attr "fp_type" "fp_addsub_<Fs>")])
5530 ;; No VSX equivalent to frin
5531 (define_insn "round<mode>2"
5532 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5533 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5535 "TARGET_<MODE>_FPR && TARGET_FPRND"
5537 [(set_attr "type" "fp")
5538 (set_attr "fp_type" "fp_addsub_<Fs>")])
5540 (define_insn "*xsrdpi<mode>2"
5541 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5542 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5544 "TARGET_<MODE>_FPR && TARGET_VSX"
5546 [(set_attr "type" "fp")
5547 (set_attr "fp_type" "fp_addsub_<Fs>")])
5549 (define_expand "lround<mode>di2"
5551 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5553 (set (match_operand:DI 0 "gpc_reg_operand" "")
5554 (unspec:DI [(match_dup 2)]
5556 "TARGET_<MODE>_FPR && TARGET_VSX"
5558 operands[2] = gen_reg_rtx (<MODE>mode);
5561 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5562 (define_insn "stfiwx"
5563 [(set (match_operand:SI 0 "memory_operand" "=Z")
5564 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
5568 [(set_attr "type" "fpstore")])
5570 ;; If we don't have a direct conversion to single precision, don't enable this
5571 ;; conversion for 32-bit without fast math, because we don't have the insn to
5572 ;; generate the fixup swizzle to avoid double rounding problems.
5573 (define_expand "floatsisf2"
5574 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5575 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5576 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5579 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5580 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5581 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5586 if (!REG_P (operands[1]))
5587 operands[1] = force_reg (SImode, operands[1]);
5589 else if (TARGET_FCFIDS && TARGET_LFIWAX)
5591 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5594 else if (TARGET_FCFID && TARGET_LFIWAX)
5596 rtx dfreg = gen_reg_rtx (DFmode);
5597 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5598 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5603 rtx dreg = operands[1];
5605 dreg = force_reg (SImode, dreg);
5606 dreg = convert_to_mode (DImode, dreg, false);
5607 emit_insn (gen_floatdisf2 (operands[0], dreg));
5612 (define_expand "floatdidf2"
5613 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5614 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5615 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5618 (define_insn "*floatdidf2_fpr"
5619 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5620 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5621 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5625 [(set_attr "type" "fp")])
5627 ; Allow the combiner to merge source memory operands to the conversion so that
5628 ; the optimizer/register allocator doesn't try to load the value too early in a
5629 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5630 ; hit. We will split after reload to avoid the trip through the GPRs
5632 (define_insn_and_split "*floatdidf2_mem"
5633 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5634 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5635 (clobber (match_scratch:DI 2 "=d,wi"))]
5636 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5638 "&& reload_completed"
5639 [(set (match_dup 2) (match_dup 1))
5640 (set (match_dup 0) (float:DF (match_dup 2)))]
5642 [(set_attr "length" "8")
5643 (set_attr "type" "fpload")])
5645 (define_expand "floatunsdidf2"
5646 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5648 (match_operand:DI 1 "gpc_reg_operand" "")))]
5649 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5652 (define_insn "*floatunsdidf2_fcfidu"
5653 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5654 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5655 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5659 [(set_attr "type" "fp")
5660 (set_attr "length" "4")])
5662 (define_insn_and_split "*floatunsdidf2_mem"
5663 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5664 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5665 (clobber (match_scratch:DI 2 "=d,wi"))]
5666 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5668 "&& reload_completed"
5669 [(set (match_dup 2) (match_dup 1))
5670 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5672 [(set_attr "length" "8")
5673 (set_attr "type" "fpload")])
5675 (define_expand "floatdisf2"
5676 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5677 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5678 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5679 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5684 rtx val = operands[1];
5685 if (!flag_unsafe_math_optimizations)
5687 rtx label = gen_label_rtx ();
5688 val = gen_reg_rtx (DImode);
5689 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5692 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5697 (define_insn "floatdisf2_fcfids"
5698 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5699 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5700 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5701 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5705 [(set_attr "type" "fp")])
5707 (define_insn_and_split "*floatdisf2_mem"
5708 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5709 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5710 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5711 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5712 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5714 "&& reload_completed"
5718 emit_move_insn (operands[2], operands[1]);
5719 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5722 [(set_attr "length" "8")])
5724 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5725 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5726 ;; from double rounding.
5727 ;; Instead of creating a new cpu type for two FP operations, just use fp
5728 (define_insn_and_split "floatdisf2_internal1"
5729 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5730 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5731 (clobber (match_scratch:DF 2 "=d"))]
5732 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5735 "&& reload_completed"
5737 (float:DF (match_dup 1)))
5739 (float_truncate:SF (match_dup 2)))]
5741 [(set_attr "length" "8")
5742 (set_attr "type" "fp")])
5744 ;; Twiddles bits to avoid double rounding.
5745 ;; Bits that might be truncated when converting to DFmode are replaced
5746 ;; by a bit that won't be lost at that stage, but is below the SFmode
5747 ;; rounding position.
5748 (define_expand "floatdisf2_internal2"
5749 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5751 (clobber (reg:DI CA_REGNO))])
5752 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5754 (set (match_dup 3) (plus:DI (match_dup 3)
5756 (set (match_dup 0) (plus:DI (match_dup 0)
5758 (set (match_dup 4) (compare:CCUNS (match_dup 3)
5760 (set (match_dup 0) (ior:DI (match_dup 0)
5762 (set (match_dup 0) (and:DI (match_dup 0)
5764 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5765 (label_ref (match_operand:DI 2 "" ""))
5767 (set (match_dup 0) (match_dup 1))]
5768 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5772 operands[3] = gen_reg_rtx (DImode);
5773 operands[4] = gen_reg_rtx (CCUNSmode);
5776 (define_expand "floatunsdisf2"
5777 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5778 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5779 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5780 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5783 (define_insn "floatunsdisf2_fcfidus"
5784 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5785 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5786 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5787 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5791 [(set_attr "type" "fp")])
5793 (define_insn_and_split "*floatunsdisf2_mem"
5794 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5795 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5796 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5797 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5798 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5800 "&& reload_completed"
5804 emit_move_insn (operands[2], operands[1]);
5805 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
5808 [(set_attr "length" "8")
5809 (set_attr "type" "fpload")])
5811 ;; Define the TImode operations that can be done in a small number
5812 ;; of instructions. The & constraints are to prevent the register
5813 ;; allocator from allocating registers that overlap with the inputs
5814 ;; (for example, having an input in 7,8 and an output in 6,7). We
5815 ;; also allow for the output being the same as one of the inputs.
5817 (define_expand "addti3"
5818 [(set (match_operand:TI 0 "gpc_reg_operand" "")
5819 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
5820 (match_operand:TI 2 "reg_or_short_operand" "")))]
5823 rtx lo0 = gen_lowpart (DImode, operands[0]);
5824 rtx lo1 = gen_lowpart (DImode, operands[1]);
5825 rtx lo2 = gen_lowpart (DImode, operands[2]);
5826 rtx hi0 = gen_highpart (DImode, operands[0]);
5827 rtx hi1 = gen_highpart (DImode, operands[1]);
5828 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
5830 if (!reg_or_short_operand (lo2, DImode))
5831 lo2 = force_reg (DImode, lo2);
5832 if (!adde_operand (hi2, DImode))
5833 hi2 = force_reg (DImode, hi2);
5835 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
5836 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
5840 (define_expand "subti3"
5841 [(set (match_operand:TI 0 "gpc_reg_operand" "")
5842 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
5843 (match_operand:TI 2 "gpc_reg_operand" "")))]
5846 rtx lo0 = gen_lowpart (DImode, operands[0]);
5847 rtx lo1 = gen_lowpart (DImode, operands[1]);
5848 rtx lo2 = gen_lowpart (DImode, operands[2]);
5849 rtx hi0 = gen_highpart (DImode, operands[0]);
5850 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
5851 rtx hi2 = gen_highpart (DImode, operands[2]);
5853 if (!reg_or_short_operand (lo1, DImode))
5854 lo1 = force_reg (DImode, lo1);
5855 if (!adde_operand (hi1, DImode))
5856 hi1 = force_reg (DImode, hi1);
5858 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
5859 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
5863 ;; 128-bit logical operations expanders
5865 (define_expand "and<mode>3"
5866 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5867 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5868 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5872 (define_expand "ior<mode>3"
5873 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5874 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5875 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5879 (define_expand "xor<mode>3"
5880 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5881 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5882 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5886 (define_expand "one_cmpl<mode>2"
5887 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5888 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5892 (define_expand "nor<mode>3"
5893 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5895 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5896 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5900 (define_expand "andc<mode>3"
5901 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5903 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5904 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5908 ;; Power8 vector logical instructions.
5909 (define_expand "eqv<mode>3"
5910 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5912 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5913 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5914 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5917 ;; Rewrite nand into canonical form
5918 (define_expand "nand<mode>3"
5919 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5921 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5922 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5923 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5926 ;; The canonical form is to have the negated element first, so we need to
5927 ;; reverse arguments.
5928 (define_expand "orc<mode>3"
5929 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5931 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5932 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5933 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5936 ;; 128-bit logical operations insns and split operations
5937 (define_insn_and_split "*and<mode>3_internal"
5938 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5940 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
5941 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
5944 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
5945 return "xxland %x0,%x1,%x2";
5947 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
5948 return "vand %0,%1,%2";
5952 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
5955 rs6000_split_logical (operands, AND, false, false, false);
5960 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5961 (const_string "vecsimple")
5962 (const_string "integer")))
5963 (set (attr "length")
5965 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5968 (match_test "TARGET_POWERPC64")
5970 (const_string "16"))))])
5973 (define_insn_and_split "*bool<mode>3_internal"
5974 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5975 (match_operator:BOOL_128 3 "boolean_or_operator"
5976 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
5977 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
5980 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
5981 return "xxl%q3 %x0,%x1,%x2";
5983 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
5984 return "v%q3 %0,%1,%2";
5988 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
5991 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
5996 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5997 (const_string "vecsimple")
5998 (const_string "integer")))
5999 (set (attr "length")
6001 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6004 (match_test "TARGET_POWERPC64")
6006 (const_string "16"))))])
6009 (define_insn_and_split "*boolc<mode>3_internal1"
6010 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6011 (match_operator:BOOL_128 3 "boolean_operator"
6013 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6014 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6015 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6017 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6018 return "xxl%q3 %x0,%x1,%x2";
6020 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6021 return "v%q3 %0,%1,%2";
6025 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6026 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6029 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6034 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6035 (const_string "vecsimple")
6036 (const_string "integer")))
6037 (set (attr "length")
6039 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6042 (match_test "TARGET_POWERPC64")
6044 (const_string "16"))))])
6046 (define_insn_and_split "*boolc<mode>3_internal2"
6047 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6048 (match_operator:TI2 3 "boolean_operator"
6050 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6051 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6052 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6054 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6057 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6060 [(set_attr "type" "integer")
6061 (set (attr "length")
6063 (match_test "TARGET_POWERPC64")
6065 (const_string "16")))])
6068 (define_insn_and_split "*boolcc<mode>3_internal1"
6069 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6070 (match_operator:BOOL_128 3 "boolean_operator"
6072 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6074 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6075 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6077 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6078 return "xxl%q3 %x0,%x1,%x2";
6080 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6081 return "v%q3 %0,%1,%2";
6085 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6086 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6089 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6094 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6095 (const_string "vecsimple")
6096 (const_string "integer")))
6097 (set (attr "length")
6099 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6102 (match_test "TARGET_POWERPC64")
6104 (const_string "16"))))])
6106 (define_insn_and_split "*boolcc<mode>3_internal2"
6107 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6108 (match_operator:TI2 3 "boolean_operator"
6110 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6112 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6113 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6115 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6118 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6121 [(set_attr "type" "integer")
6122 (set (attr "length")
6124 (match_test "TARGET_POWERPC64")
6126 (const_string "16")))])
6130 (define_insn_and_split "*eqv<mode>3_internal1"
6131 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6134 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6135 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6138 if (vsx_register_operand (operands[0], <MODE>mode))
6139 return "xxleqv %x0,%x1,%x2";
6143 "TARGET_P8_VECTOR && reload_completed
6144 && int_reg_operand (operands[0], <MODE>mode)"
6147 rs6000_split_logical (operands, XOR, true, false, false);
6152 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6153 (const_string "vecsimple")
6154 (const_string "integer")))
6155 (set (attr "length")
6157 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6160 (match_test "TARGET_POWERPC64")
6162 (const_string "16"))))])
6164 (define_insn_and_split "*eqv<mode>3_internal2"
6165 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6168 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6169 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6172 "reload_completed && !TARGET_P8_VECTOR"
6175 rs6000_split_logical (operands, XOR, true, false, false);
6178 [(set_attr "type" "integer")
6179 (set (attr "length")
6181 (match_test "TARGET_POWERPC64")
6183 (const_string "16")))])
6185 ;; 128-bit one's complement
6186 (define_insn_and_split "*one_cmpl<mode>3_internal"
6187 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6189 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6192 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6193 return "xxlnor %x0,%x1,%x1";
6195 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6196 return "vnor %0,%1,%1";
6200 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6203 rs6000_split_logical (operands, NOT, false, false, false);
6208 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6209 (const_string "vecsimple")
6210 (const_string "integer")))
6211 (set (attr "length")
6213 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6216 (match_test "TARGET_POWERPC64")
6218 (const_string "16"))))])
6221 ;; Now define ways of moving data around.
6223 ;; Set up a register with a value from the GOT table
6225 (define_expand "movsi_got"
6226 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6227 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6228 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6229 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6232 if (GET_CODE (operands[1]) == CONST)
6234 rtx offset = const0_rtx;
6235 HOST_WIDE_INT value;
6237 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6238 value = INTVAL (offset);
6241 rtx tmp = (!can_create_pseudo_p ()
6243 : gen_reg_rtx (Pmode));
6244 emit_insn (gen_movsi_got (tmp, operands[1]));
6245 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6250 operands[2] = rs6000_got_register (operands[1]);
6253 (define_insn "*movsi_got_internal"
6254 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6255 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6256 (match_operand:SI 2 "gpc_reg_operand" "b")]
6258 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6259 "lwz %0,%a1@got(%2)"
6260 [(set_attr "type" "load")])
6262 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6263 ;; didn't get allocated to a hard register.
6265 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6266 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6267 (match_operand:SI 2 "memory_operand" "")]
6269 "DEFAULT_ABI == ABI_V4
6271 && (reload_in_progress || reload_completed)"
6272 [(set (match_dup 0) (match_dup 2))
6273 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6277 ;; For SI, we special-case integers that can't be loaded in one insn. We
6278 ;; do the load 16-bits at a time. We could do this by loading from memory,
6279 ;; and this is even supposed to be faster, but it is simpler not to get
6280 ;; integers in the TOC.
6281 (define_insn "movsi_low"
6282 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6283 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6284 (match_operand 2 "" ""))))]
6285 "TARGET_MACHO && ! TARGET_64BIT"
6286 "lwz %0,lo16(%2)(%1)"
6287 [(set_attr "type" "load")
6288 (set_attr "length" "4")])
6290 (define_insn "*movsi_internal1"
6291 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6292 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6293 "!TARGET_SINGLE_FPU &&
6294 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6307 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6308 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6310 (define_insn "*movsi_internal1_single"
6311 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6312 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6313 "TARGET_SINGLE_FPU &&
6314 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6329 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6330 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6332 ;; Split a load of a large constant into the appropriate two-insn
6336 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6337 (match_operand:SI 1 "const_int_operand" ""))]
6338 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6339 && (INTVAL (operands[1]) & 0xffff) != 0"
6343 (ior:SI (match_dup 0)
6347 if (rs6000_emit_set_const (operands[0], operands[1]))
6353 (define_insn "*mov<mode>_internal2"
6354 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6355 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6357 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6363 [(set_attr "type" "cmp,logical,cmp")
6364 (set_attr "dot" "yes")
6365 (set_attr "length" "4,4,8")])
6368 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6369 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6371 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6373 [(set (match_dup 0) (match_dup 1))
6375 (compare:CC (match_dup 0)
6379 (define_insn "*movhi_internal"
6380 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6381 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6382 "gpc_reg_operand (operands[0], HImode)
6383 || gpc_reg_operand (operands[1], HImode)"
6392 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6394 (define_expand "mov<mode>"
6395 [(set (match_operand:INT 0 "general_operand" "")
6396 (match_operand:INT 1 "any_operand" ""))]
6398 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6400 (define_insn "*movqi_internal"
6401 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6402 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6403 "gpc_reg_operand (operands[0], QImode)
6404 || gpc_reg_operand (operands[1], QImode)"
6413 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6415 ;; Here is how to move condition codes around. When we store CC data in
6416 ;; an integer register or memory, we store just the high-order 4 bits.
6417 ;; This lets us not shift in the most common case of CR0.
6418 (define_expand "movcc"
6419 [(set (match_operand:CC 0 "nonimmediate_operand" "")
6420 (match_operand:CC 1 "nonimmediate_operand" ""))]
6424 (define_insn "*movcc_internal1"
6425 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6426 (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6427 "register_operand (operands[0], CCmode)
6428 || register_operand (operands[1], CCmode)"
6432 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6435 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6443 (cond [(eq_attr "alternative" "0,3")
6444 (const_string "cr_logical")
6445 (eq_attr "alternative" "1,2")
6446 (const_string "mtcr")
6447 (eq_attr "alternative" "6,7")
6448 (const_string "integer")
6449 (eq_attr "alternative" "8")
6450 (const_string "mfjmpr")
6451 (eq_attr "alternative" "9")
6452 (const_string "mtjmpr")
6453 (eq_attr "alternative" "10")
6454 (const_string "load")
6455 (eq_attr "alternative" "11")
6456 (const_string "store")
6457 (match_test "TARGET_MFCRF")
6458 (const_string "mfcrf")
6460 (const_string "mfcr")))
6461 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6463 ;; For floating-point, we normally deal with the floating-point registers
6464 ;; unless -msoft-float is used. The sole exception is that parameter passing
6465 ;; can produce floating-point values in fixed-point registers. Unless the
6466 ;; value is a simple constant or already in memory, we deal with this by
6467 ;; allocating memory and copying the value explicitly via that memory location.
6469 ;; Move 32-bit binary/decimal floating point
6470 (define_expand "mov<mode>"
6471 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6472 (match_operand:FMOVE32 1 "any_operand" ""))]
6474 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6477 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6478 (match_operand:FMOVE32 1 "const_double_operand" ""))]
6480 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6481 || (GET_CODE (operands[0]) == SUBREG
6482 && GET_CODE (SUBREG_REG (operands[0])) == REG
6483 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6484 [(set (match_dup 2) (match_dup 3))]
6489 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6491 if (! TARGET_POWERPC64)
6492 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6494 operands[2] = gen_lowpart (SImode, operands[0]);
6496 operands[3] = gen_int_mode (l, SImode);
6499 (define_insn "mov<mode>_hardfloat"
6500 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_lr2>,<f32_sm>,<f32_sm2>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h")
6501 (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,j,<f32_lm>,<f32_lm2>,<f32_sr>,<f32_sr2>,Z,<f32_av>,r,<f32_dm>,r,h,0"))]
6502 "(gpc_reg_operand (operands[0], <MODE>mode)
6503 || gpc_reg_operand (operands[1], <MODE>mode))
6504 && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6510 xscpsgndp %x0,%x1,%x1
6524 [(set_attr "type" "*,load,store,fp,fp,vecsimple,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*")
6525 (set_attr "length" "4")])
6527 (define_insn "*mov<mode>_softfloat"
6528 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6529 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6530 "(gpc_reg_operand (operands[0], <MODE>mode)
6531 || gpc_reg_operand (operands[1], <MODE>mode))
6532 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6544 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6545 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6548 ;; Move 64-bit binary/decimal floating point
6549 (define_expand "mov<mode>"
6550 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6551 (match_operand:FMOVE64 1 "any_operand" ""))]
6553 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6556 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6557 (match_operand:FMOVE64 1 "const_int_operand" ""))]
6558 "! TARGET_POWERPC64 && reload_completed
6559 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6560 || (GET_CODE (operands[0]) == SUBREG
6561 && GET_CODE (SUBREG_REG (operands[0])) == REG
6562 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6563 [(set (match_dup 2) (match_dup 4))
6564 (set (match_dup 3) (match_dup 1))]
6567 int endian = (WORDS_BIG_ENDIAN == 0);
6568 HOST_WIDE_INT value = INTVAL (operands[1]);
6570 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6571 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6572 operands[4] = GEN_INT (value >> 32);
6573 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6577 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6578 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6579 "! TARGET_POWERPC64 && reload_completed
6580 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6581 || (GET_CODE (operands[0]) == SUBREG
6582 && GET_CODE (SUBREG_REG (operands[0])) == REG
6583 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6584 [(set (match_dup 2) (match_dup 4))
6585 (set (match_dup 3) (match_dup 5))]
6588 int endian = (WORDS_BIG_ENDIAN == 0);
6591 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6593 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6594 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6595 operands[4] = gen_int_mode (l[endian], SImode);
6596 operands[5] = gen_int_mode (l[1 - endian], SImode);
6600 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6601 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6602 "TARGET_POWERPC64 && reload_completed
6603 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6604 || (GET_CODE (operands[0]) == SUBREG
6605 && GET_CODE (SUBREG_REG (operands[0])) == REG
6606 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6607 [(set (match_dup 2) (match_dup 3))]
6610 int endian = (WORDS_BIG_ENDIAN == 0);
6614 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6616 operands[2] = gen_lowpart (DImode, operands[0]);
6617 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
6618 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6619 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6621 operands[3] = gen_int_mode (val, DImode);
6624 ;; Don't have reload use general registers to load a constant. It is
6625 ;; less efficient than loading the constant into an FP register, since
6626 ;; it will probably be used there.
6628 ;; The move constraints are ordered to prefer floating point registers before
6629 ;; general purpose registers to avoid doing a store and a load to get the value
6630 ;; into a floating point register when it is needed for a floating point
6631 ;; operation. Prefer traditional floating point registers over VSX registers,
6632 ;; since the D-form version of the memory instructions does not need a GPR for
6633 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6636 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6637 ;; except for 0.0 which can be created on VSX with an xor instruction.
6639 (define_insn "*mov<mode>_hardfloat32"
6640 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,o,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6641 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,o,<f64_p9>,<f64_vsx>,j,j,r,Y,r"))]
6642 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6643 && (gpc_reg_operand (operands[0], <MODE>mode)
6644 || gpc_reg_operand (operands[1], <MODE>mode))"
6659 [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,two,store,load,two")
6660 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6662 (define_insn "*mov<mode>_softfloat32"
6663 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6664 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6666 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
6667 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6668 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6669 && (gpc_reg_operand (operands[0], <MODE>mode)
6670 || gpc_reg_operand (operands[1], <MODE>mode))"
6672 [(set_attr "type" "store,load,two,*,*,*")
6673 (set_attr "length" "8,8,8,8,12,16")])
6675 ; ld/std require word-aligned displacements -> 'Y' constraint.
6676 ; List Y->r and r->Y before r->r for reload.
6677 (define_insn "*mov<mode>_hardfloat64"
6678 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,o,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
6679 (match_operand:FMOVE64 1 "input_operand" "d,m,d,o,<f64_p9>,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
6680 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6681 && (gpc_reg_operand (operands[0], <MODE>mode)
6682 || gpc_reg_operand (operands[1], <MODE>mode))"
6704 [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6705 (set_attr "length" "4")])
6707 (define_insn "*mov<mode>_softfloat64"
6708 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6709 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6710 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6711 && (gpc_reg_operand (operands[0], <MODE>mode)
6712 || gpc_reg_operand (operands[1], <MODE>mode))"
6723 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6724 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6726 (define_expand "mov<mode>"
6727 [(set (match_operand:FMOVE128 0 "general_operand" "")
6728 (match_operand:FMOVE128 1 "any_operand" ""))]
6730 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6732 ;; It's important to list Y->r and r->Y before r->r because otherwise
6733 ;; reload, given m->r, will try to pick r->r and reload it, which
6734 ;; doesn't make progress.
6736 ;; We can't split little endian direct moves of TDmode, because the words are
6737 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
6738 ;; problematical. Don't allow direct move for this case.
6740 (define_insn_and_split "*mov<mode>_64bit_dm"
6741 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r,r,wm")
6742 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,j,r,jY,r,wm,r"))]
6743 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6744 && FLOAT128_2REG_P (<MODE>mode)
6745 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6746 && (gpc_reg_operand (operands[0], <MODE>mode)
6747 || gpc_reg_operand (operands[1], <MODE>mode))"
6749 "&& reload_completed"
6751 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6752 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6754 (define_insn_and_split "*movtd_64bit_nodm"
6755 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
6756 (match_operand:TD 1 "input_operand" "d,m,d,j,r,jY,r"))]
6757 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6758 && (gpc_reg_operand (operands[0], TDmode)
6759 || gpc_reg_operand (operands[1], TDmode))"
6761 "&& reload_completed"
6763 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6764 [(set_attr "length" "8,8,8,8,12,12,8")])
6766 (define_insn_and_split "*mov<mode>_32bit"
6767 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
6768 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,j,r,jY,r"))]
6769 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
6770 && (FLOAT128_2REG_P (<MODE>mode)
6771 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
6772 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
6773 && (gpc_reg_operand (operands[0], <MODE>mode)
6774 || gpc_reg_operand (operands[1], <MODE>mode))"
6776 "&& reload_completed"
6778 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6779 [(set_attr "length" "8,8,8,8,20,20,16")])
6781 (define_insn_and_split "*mov<mode>_softfloat"
6782 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
6783 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
6784 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
6785 && (gpc_reg_operand (operands[0], <MODE>mode)
6786 || gpc_reg_operand (operands[1], <MODE>mode))"
6788 "&& reload_completed"
6790 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6791 [(set_attr "length" "20,20,16")])
6793 (define_expand "extenddf<mode>2"
6794 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6795 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
6796 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
6797 && TARGET_LONG_DOUBLE_128"
6799 if (FLOAT128_IEEE_P (<MODE>mode))
6800 rs6000_expand_float128_convert (operands[0], operands[1], false);
6801 else if (TARGET_E500_DOUBLE)
6803 gcc_assert (<MODE>mode == TFmode);
6804 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
6806 else if (TARGET_VSX)
6808 if (<MODE>mode == TFmode)
6809 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
6810 else if (<MODE>mode == IFmode)
6811 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
6817 rtx zero = gen_reg_rtx (DFmode);
6818 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
6820 if (<MODE>mode == TFmode)
6821 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
6822 else if (<MODE>mode == IFmode)
6823 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
6830 ;; Allow memory operands for the source to be created by the combiner.
6831 (define_insn_and_split "extenddf<mode>2_fprs"
6832 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
6833 (float_extend:IBM128
6834 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
6835 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
6836 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6837 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6839 "&& reload_completed"
6840 [(set (match_dup 3) (match_dup 1))
6841 (set (match_dup 4) (match_dup 2))]
6843 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6844 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6846 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6847 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6850 (define_insn_and_split "extenddf<mode>2_vsx"
6851 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
6852 (float_extend:IBM128
6853 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
6854 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
6856 "&& reload_completed"
6857 [(set (match_dup 2) (match_dup 1))
6858 (set (match_dup 3) (match_dup 4))]
6860 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6861 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6863 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6864 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6865 operands[4] = CONST0_RTX (DFmode);
6868 (define_expand "extendsf<mode>2"
6869 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6870 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
6872 && (TARGET_FPRS || TARGET_E500_DOUBLE)
6873 && TARGET_LONG_DOUBLE_128"
6875 if (FLOAT128_IEEE_P (<MODE>mode))
6876 rs6000_expand_float128_convert (operands[0], operands[1], false);
6879 rtx tmp = gen_reg_rtx (DFmode);
6880 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
6881 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
6886 (define_expand "trunc<mode>df2"
6887 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6888 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6890 && (TARGET_FPRS || TARGET_E500_DOUBLE)
6891 && TARGET_LONG_DOUBLE_128"
6893 if (FLOAT128_IEEE_P (<MODE>mode))
6895 rs6000_expand_float128_convert (operands[0], operands[1], false);
6900 (define_insn_and_split "trunc<mode>df2_internal1"
6901 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
6903 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
6904 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
6905 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
6909 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
6912 emit_note (NOTE_INSN_DELETED);
6915 [(set_attr "type" "fp")])
6917 (define_insn "trunc<mode>df2_internal2"
6918 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6919 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
6920 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
6921 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
6923 [(set_attr "type" "fp")
6924 (set_attr "fp_type" "fp_addsub_d")])
6926 (define_expand "trunc<mode>sf2"
6927 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6928 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6930 && (TARGET_FPRS || TARGET_E500_DOUBLE)
6931 && TARGET_LONG_DOUBLE_128"
6933 if (FLOAT128_IEEE_P (<MODE>mode))
6934 rs6000_expand_float128_convert (operands[0], operands[1], false);
6935 else if (TARGET_E500_DOUBLE)
6937 gcc_assert (<MODE>mode == TFmode);
6938 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
6940 else if (<MODE>mode == TFmode)
6941 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
6942 else if (<MODE>mode == IFmode)
6943 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
6949 (define_insn_and_split "trunc<mode>sf2_fprs"
6950 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6951 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
6952 (clobber (match_scratch:DF 2 "=d"))]
6953 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6954 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6956 "&& reload_completed"
6958 (float_truncate:DF (match_dup 1)))
6960 (float_truncate:SF (match_dup 2)))]
6963 (define_expand "floatsi<mode>2"
6964 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6965 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
6967 && (TARGET_FPRS || TARGET_E500_DOUBLE)
6968 && TARGET_LONG_DOUBLE_128"
6970 if (FLOAT128_IEEE_P (<MODE>mode))
6971 rs6000_expand_float128_convert (operands[0], operands[1], false);
6974 rtx tmp = gen_reg_rtx (DFmode);
6975 expand_float (tmp, operands[1], false);
6976 if (<MODE>mode == TFmode)
6977 emit_insn (gen_extenddftf2 (operands[0], tmp));
6978 else if (<MODE>mode == IFmode)
6979 emit_insn (gen_extenddfif2 (operands[0], tmp));
6986 ; fadd, but rounding towards zero.
6987 ; This is probably not the optimal code sequence.
6988 (define_insn "fix_trunc_helper<mode>"
6989 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6990 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
6991 UNSPEC_FIX_TRUNC_TF))
6992 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
6993 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6994 && FLOAT128_IBM_P (<MODE>mode)"
6995 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
6996 [(set_attr "type" "fp")
6997 (set_attr "length" "20")])
6999 (define_expand "fix_trunc<mode>si2"
7000 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7001 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7003 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7005 if (FLOAT128_IEEE_P (<MODE>mode))
7006 rs6000_expand_float128_convert (operands[0], operands[1], false);
7007 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7008 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7009 else if (<MODE>mode == TFmode)
7010 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7011 else if (<MODE>mode == IFmode)
7012 emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7018 (define_expand "fix_trunc<mode>si2_fprs"
7019 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7020 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7021 (clobber (match_dup 2))
7022 (clobber (match_dup 3))
7023 (clobber (match_dup 4))
7024 (clobber (match_dup 5))])]
7025 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7027 operands[2] = gen_reg_rtx (DFmode);
7028 operands[3] = gen_reg_rtx (DFmode);
7029 operands[4] = gen_reg_rtx (DImode);
7030 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7033 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7034 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7035 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7036 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7037 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7038 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7039 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7040 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7046 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7049 gcc_assert (MEM_P (operands[5]));
7050 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7052 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7053 emit_move_insn (operands[5], operands[4]);
7054 emit_move_insn (operands[0], lowword);
7058 (define_expand "fix_trunc<mode>di2"
7059 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7060 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7063 rs6000_expand_float128_convert (operands[0], operands[1], false);
7067 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7068 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7069 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7072 rs6000_expand_float128_convert (operands[0], operands[1], true);
7076 (define_expand "floatdi<mode>2"
7077 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7078 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7081 rs6000_expand_float128_convert (operands[0], operands[1], false);
7085 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7086 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7087 (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7090 rs6000_expand_float128_convert (operands[0], operands[1], true);
7094 (define_expand "neg<mode>2"
7095 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7096 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7097 "FLOAT128_IEEE_P (<MODE>mode)
7098 || (FLOAT128_IBM_P (<MODE>mode)
7099 && TARGET_HARD_FLOAT
7100 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7103 if (FLOAT128_IEEE_P (<MODE>mode))
7105 if (TARGET_FLOAT128_HW)
7107 if (<MODE>mode == TFmode)
7108 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7109 else if (<MODE>mode == KFmode)
7110 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7114 else if (TARGET_FLOAT128)
7116 if (<MODE>mode == TFmode)
7117 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7118 else if (<MODE>mode == KFmode)
7119 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7125 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7126 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7128 operands[1], <MODE>mode);
7130 if (target && !rtx_equal_p (target, operands[0]))
7131 emit_move_insn (operands[0], target);
7137 (define_insn "neg<mode>2_internal"
7138 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7139 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7140 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7143 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7144 return \"fneg %L0,%L1\;fneg %0,%1\";
7146 return \"fneg %0,%1\;fneg %L0,%L1\";
7148 [(set_attr "type" "fp")
7149 (set_attr "length" "8")])
7151 (define_expand "abs<mode>2"
7152 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7153 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7154 "FLOAT128_IEEE_P (<MODE>mode)
7155 || (FLOAT128_IBM_P (<MODE>mode)
7156 && TARGET_HARD_FLOAT
7157 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7162 if (FLOAT128_IEEE_P (<MODE>mode))
7164 if (TARGET_FLOAT128_HW)
7166 if (<MODE>mode == TFmode)
7167 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7168 else if (<MODE>mode == KFmode)
7169 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7174 else if (TARGET_FLOAT128)
7176 if (<MODE>mode == TFmode)
7177 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7178 else if (<MODE>mode == KFmode)
7179 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7188 label = gen_label_rtx ();
7189 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7191 if (flag_finite_math_only && !flag_trapping_math)
7192 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7194 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7196 else if (<MODE>mode == TFmode)
7197 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7198 else if (<MODE>mode == TFmode)
7199 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7206 (define_expand "abs<mode>2_internal"
7207 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7208 (match_operand:IBM128 1 "gpc_reg_operand" ""))
7209 (set (match_dup 3) (match_dup 5))
7210 (set (match_dup 5) (abs:DF (match_dup 5)))
7211 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7212 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7213 (label_ref (match_operand 2 "" ""))
7215 (set (match_dup 6) (neg:DF (match_dup 6)))]
7216 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7217 && TARGET_LONG_DOUBLE_128"
7220 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7221 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7222 operands[3] = gen_reg_rtx (DFmode);
7223 operands[4] = gen_reg_rtx (CCFPmode);
7224 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7225 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7229 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7232 (define_expand "ieee_128bit_negative_zero"
7233 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7236 rtvec v = rtvec_alloc (16);
7239 for (i = 0; i < 16; i++)
7240 RTVEC_ELT (v, i) = const0_rtx;
7242 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7243 RTVEC_ELT (v, high) = GEN_INT (0x80);
7245 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7249 ;; IEEE 128-bit negate
7251 ;; We have 2 insns here for negate and absolute value. The first uses
7252 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7253 ;; insns, and second insn after the first split pass loads up the bit to
7254 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
7255 ;; neg/abs to create the constant just once.
7257 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7258 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7259 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7260 (clobber (match_scratch:V16QI 2 "=v"))]
7261 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7264 [(parallel [(set (match_dup 0)
7265 (neg:IEEE128 (match_dup 1)))
7266 (use (match_dup 2))])]
7268 if (GET_CODE (operands[2]) == SCRATCH)
7269 operands[2] = gen_reg_rtx (V16QImode);
7271 operands[3] = gen_reg_rtx (V16QImode);
7272 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7274 [(set_attr "length" "8")
7275 (set_attr "type" "vecsimple")])
7277 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7278 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7279 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7280 (use (match_operand:V16QI 2 "register_operand" "=v"))]
7281 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7282 "xxlxor %x0,%x1,%x2"
7283 [(set_attr "type" "vecsimple")])
7285 ;; IEEE 128-bit absolute value
7286 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7287 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7288 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7289 (clobber (match_scratch:V16QI 2 "=v"))]
7290 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7293 [(parallel [(set (match_dup 0)
7294 (abs:IEEE128 (match_dup 1)))
7295 (use (match_dup 2))])]
7297 if (GET_CODE (operands[2]) == SCRATCH)
7298 operands[2] = gen_reg_rtx (V16QImode);
7300 operands[3] = gen_reg_rtx (V16QImode);
7301 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7303 [(set_attr "length" "8")
7304 (set_attr "type" "vecsimple")])
7306 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7307 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7308 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7309 (use (match_operand:V16QI 2 "register_operand" "=v"))]
7310 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7311 "xxlandc %x0,%x1,%x2"
7312 [(set_attr "type" "vecsimple")])
7314 ;; IEEE 128-bit negative absolute value
7315 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7316 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7319 (match_operand:IEEE128 1 "register_operand" "wa"))))
7320 (clobber (match_scratch:V16QI 2 "=v"))]
7321 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7324 [(parallel [(set (match_dup 0)
7325 (abs:IEEE128 (match_dup 1)))
7326 (use (match_dup 2))])]
7328 if (GET_CODE (operands[2]) == SCRATCH)
7329 operands[2] = gen_reg_rtx (V16QImode);
7331 operands[3] = gen_reg_rtx (V16QImode);
7332 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7334 [(set_attr "length" "8")
7335 (set_attr "type" "vecsimple")])
7337 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7338 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7341 (match_operand:IEEE128 1 "register_operand" "wa"))))
7342 (use (match_operand:V16QI 2 "register_operand" "=v"))]
7343 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7345 [(set_attr "type" "vecsimple")])
7347 ;; Float128 conversion functions. These expand to library function calls.
7348 ;; We use expand to convert from IBM double double to IEEE 128-bit
7349 ;; and trunc for the opposite.
7350 (define_expand "extendiftf2"
7351 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7352 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7355 rs6000_expand_float128_convert (operands[0], operands[1], false);
7359 (define_expand "extendifkf2"
7360 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7361 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7364 rs6000_expand_float128_convert (operands[0], operands[1], false);
7368 (define_expand "extendtfkf2"
7369 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7370 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7373 rs6000_expand_float128_convert (operands[0], operands[1], false);
7377 (define_expand "trunciftf2"
7378 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7379 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7382 rs6000_expand_float128_convert (operands[0], operands[1], false);
7386 (define_expand "truncifkf2"
7387 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7388 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7391 rs6000_expand_float128_convert (operands[0], operands[1], false);
7395 (define_expand "trunckftf2"
7396 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7397 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7400 rs6000_expand_float128_convert (operands[0], operands[1], false);
7404 (define_expand "trunctfif2"
7405 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7406 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7409 rs6000_expand_float128_convert (operands[0], operands[1], false);
7414 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
7415 ;; must have 3 arguments, and scratch register constraint must be a single
7418 ;; Reload patterns to support gpr load/store with misaligned mem.
7419 ;; and multiple gpr load/store at offset >= 0xfffc
7420 (define_expand "reload_<mode>_store"
7421 [(parallel [(match_operand 0 "memory_operand" "=m")
7422 (match_operand 1 "gpc_reg_operand" "r")
7423 (match_operand:GPR 2 "register_operand" "=&b")])]
7426 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7430 (define_expand "reload_<mode>_load"
7431 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7432 (match_operand 1 "memory_operand" "m")
7433 (match_operand:GPR 2 "register_operand" "=b")])]
7436 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7441 ;; Reload patterns for various types using the vector registers. We may need
7442 ;; an additional base register to convert the reg+offset addressing to reg+reg
7443 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7444 ;; index register for gpr registers.
7445 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7446 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7447 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7448 (match_operand:P 2 "register_operand" "=b")])]
7451 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7455 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7456 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7457 (match_operand:RELOAD 1 "memory_operand" "m")
7458 (match_operand:P 2 "register_operand" "=b")])]
7461 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7466 ;; Reload sometimes tries to move the address to a GPR, and can generate
7467 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
7468 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7470 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7471 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7472 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7473 (match_operand:P 2 "reg_or_cint_operand" "rI"))
7475 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7477 "&& reload_completed"
7479 (plus:P (match_dup 1)
7482 (and:P (match_dup 0)
7485 ;; Power8 merge instructions to allow direct move to/from floating point
7486 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
7487 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
7488 ;; value, since it is allocated in reload and not all of the flow information
7489 ;; is setup for it. We have two patterns to do the two moves between gprs and
7490 ;; fprs. There isn't a dependancy between the two, but we could potentially
7491 ;; schedule other instructions between the two instructions. TFmode is
7492 ;; currently limited to traditional FPR registers. If/when this is changed, we
7493 ;; will need to revist %L to make sure it works with VSX registers, or add an
7494 ;; %x version of %L.
7496 (define_insn "p8_fmrgow_<mode>"
7497 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7498 (unspec:FMOVE64X [(match_operand:TF 1 "register_operand" "d")]
7499 UNSPEC_P8V_FMRGOW))]
7500 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7502 [(set_attr "type" "vecperm")])
7504 (define_insn "p8_mtvsrwz_1"
7505 [(set (match_operand:TF 0 "register_operand" "=d")
7506 (unspec:TF [(match_operand:SI 1 "register_operand" "r")]
7507 UNSPEC_P8V_MTVSRWZ))]
7508 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7510 [(set_attr "type" "mftgpr")])
7512 (define_insn "p8_mtvsrwz_2"
7513 [(set (match_operand:TF 0 "register_operand" "+d")
7514 (unspec:TF [(match_dup 0)
7515 (match_operand:SI 1 "register_operand" "r")]
7516 UNSPEC_P8V_MTVSRWZ))]
7517 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7519 [(set_attr "type" "mftgpr")])
7521 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7522 [(set (match_operand:FMOVE64X 0 "register_operand" "=ws")
7523 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7524 UNSPEC_P8V_RELOAD_FROM_GPR))
7525 (clobber (match_operand:TF 2 "register_operand" "=d"))]
7526 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7528 "&& reload_completed"
7531 rtx dest = operands[0];
7532 rtx src = operands[1];
7533 rtx tmp = operands[2];
7534 rtx gpr_hi_reg = gen_highpart (SImode, src);
7535 rtx gpr_lo_reg = gen_lowpart (SImode, src);
7537 emit_insn (gen_p8_mtvsrwz_1 (tmp, gpr_hi_reg));
7538 emit_insn (gen_p8_mtvsrwz_2 (tmp, gpr_lo_reg));
7539 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp));
7542 [(set_attr "length" "12")
7543 (set_attr "type" "three")])
7545 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7546 (define_insn "p8_mtvsrd_1"
7547 [(set (match_operand:TF 0 "register_operand" "=ws")
7548 (unspec:TF [(match_operand:DI 1 "register_operand" "r")]
7549 UNSPEC_P8V_MTVSRD))]
7550 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7552 [(set_attr "type" "mftgpr")])
7554 (define_insn "p8_mtvsrd_2"
7555 [(set (match_operand:TF 0 "register_operand" "+ws")
7556 (unspec:TF [(match_dup 0)
7557 (match_operand:DI 1 "register_operand" "r")]
7558 UNSPEC_P8V_MTVSRD))]
7559 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7561 [(set_attr "type" "mftgpr")])
7563 (define_insn "p8_xxpermdi_<mode>"
7564 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7565 (unspec:FMOVE128_GPR [(match_operand:TF 1 "register_operand" "ws")]
7566 UNSPEC_P8V_XXPERMDI))]
7567 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7568 "xxpermdi %x0,%1,%L1,0"
7569 [(set_attr "type" "vecperm")])
7571 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7572 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7573 (unspec:FMOVE128_GPR
7574 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7575 UNSPEC_P8V_RELOAD_FROM_GPR))
7576 (clobber (match_operand:TF 2 "register_operand" "=ws"))]
7577 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7579 "&& reload_completed"
7582 rtx dest = operands[0];
7583 rtx src = operands[1];
7584 rtx tmp = operands[2];
7585 rtx gpr_hi_reg = gen_highpart (DImode, src);
7586 rtx gpr_lo_reg = gen_lowpart (DImode, src);
7588 emit_insn (gen_p8_mtvsrd_1 (tmp, gpr_hi_reg));
7589 emit_insn (gen_p8_mtvsrd_2 (tmp, gpr_lo_reg));
7590 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp));
7593 [(set_attr "length" "12")
7594 (set_attr "type" "three")])
7597 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7598 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7600 && (int_reg_operand (operands[0], <MODE>mode)
7601 || int_reg_operand (operands[1], <MODE>mode))
7602 && (!TARGET_DIRECT_MOVE_128
7603 || (!vsx_register_operand (operands[0], <MODE>mode)
7604 && !vsx_register_operand (operands[1], <MODE>mode)))"
7606 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7608 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
7609 ;; type is stored internally as double precision in the VSX registers, we have
7610 ;; to convert it from the vector format.
7612 (define_insn_and_split "reload_vsx_from_gprsf"
7613 [(set (match_operand:SF 0 "register_operand" "=wa")
7614 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7615 UNSPEC_P8V_RELOAD_FROM_GPR))
7616 (clobber (match_operand:DI 2 "register_operand" "=r"))]
7617 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7619 "&& reload_completed"
7622 rtx op0 = operands[0];
7623 rtx op1 = operands[1];
7624 rtx op2 = operands[2];
7625 /* Also use the destination register to hold the unconverted DImode value.
7626 This is conceptually a separate value from OP0, so we use gen_rtx_REG
7627 rather than simplify_gen_subreg. */
7628 rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
7629 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7631 /* Move SF value to upper 32-bits for xscvspdpn. */
7632 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7633 emit_move_insn (op0_di, op2);
7634 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0_di));
7637 [(set_attr "length" "8")
7638 (set_attr "type" "two")])
7640 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7641 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7642 ;; and then doing a move of that.
7643 (define_insn "p8_mfvsrd_3_<mode>"
7644 [(set (match_operand:DF 0 "register_operand" "=r")
7645 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7646 UNSPEC_P8V_RELOAD_FROM_VSX))]
7647 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7649 [(set_attr "type" "mftgpr")])
7651 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7652 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7653 (unspec:FMOVE128_GPR
7654 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7655 UNSPEC_P8V_RELOAD_FROM_VSX))
7656 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7657 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7659 "&& reload_completed"
7662 rtx dest = operands[0];
7663 rtx src = operands[1];
7664 rtx tmp = operands[2];
7665 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7666 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7668 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7669 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7670 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7673 [(set_attr "length" "12")
7674 (set_attr "type" "three")])
7676 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
7677 ;; type is stored internally as double precision, we have to convert it to the
7680 (define_insn_and_split "reload_gpr_from_vsxsf"
7681 [(set (match_operand:SF 0 "register_operand" "=r")
7682 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7683 UNSPEC_P8V_RELOAD_FROM_VSX))
7684 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7685 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7687 "&& reload_completed"
7690 rtx op0 = operands[0];
7691 rtx op1 = operands[1];
7692 rtx op2 = operands[2];
7693 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7695 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7696 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7697 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7700 [(set_attr "length" "12")
7701 (set_attr "type" "three")])
7703 (define_insn "p8_mfvsrd_4_disf"
7704 [(set (match_operand:DI 0 "register_operand" "=r")
7705 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7706 UNSPEC_P8V_RELOAD_FROM_VSX))]
7707 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7709 [(set_attr "type" "mftgpr")])
7712 ;; Next come the multi-word integer load and store and the load and store
7715 ;; List r->r after r->Y, otherwise reload will try to reload a
7716 ;; non-offsettable address by using r->r which won't make progress.
7717 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7718 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7719 (define_insn "*movdi_internal32"
7720 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
7721 (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
7723 && (gpc_reg_operand (operands[0], DImode)
7724 || gpc_reg_operand (operands[1], DImode))"
7733 [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
7736 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7737 (match_operand:DI 1 "const_int_operand" ""))]
7738 "! TARGET_POWERPC64 && reload_completed
7739 && gpr_or_gpr_p (operands[0], operands[1])
7740 && !direct_move_p (operands[0], operands[1])"
7741 [(set (match_dup 2) (match_dup 4))
7742 (set (match_dup 3) (match_dup 1))]
7745 HOST_WIDE_INT value = INTVAL (operands[1]);
7746 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7748 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7750 operands[4] = GEN_INT (value >> 32);
7751 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7755 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7756 (match_operand:DIFD 1 "input_operand" ""))]
7757 "reload_completed && !TARGET_POWERPC64
7758 && gpr_or_gpr_p (operands[0], operands[1])
7759 && !direct_move_p (operands[0], operands[1])"
7761 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7763 (define_insn "*movdi_internal64"
7764 [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi")
7765 (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))]
7767 && (gpc_reg_operand (operands[0], DImode)
7768 || gpc_reg_operand (operands[1], DImode))"
7787 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
7788 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
7790 ; Some DImode loads are best done as a load of -1 followed by a mask
7793 [(set (match_operand:DI 0 "gpc_reg_operand")
7794 (match_operand:DI 1 "const_int_operand"))]
7796 && num_insns_constant (operands[1], DImode) > 1
7797 && rs6000_is_valid_and_mask (operands[1], DImode)"
7801 (and:DI (match_dup 0)
7805 ;; Split a load of a large constant into the appropriate five-instruction
7806 ;; sequence. Handle anything in a constant number of insns.
7807 ;; When non-easy constants can go in the TOC, this should use
7808 ;; easy_fp_constant predicate.
7810 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7811 (match_operand:DI 1 "const_int_operand" ""))]
7812 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7813 [(set (match_dup 0) (match_dup 2))
7814 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7817 if (rs6000_emit_set_const (operands[0], operands[1]))
7824 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7825 (match_operand:DI 1 "const_scalar_int_operand" ""))]
7826 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7827 [(set (match_dup 0) (match_dup 2))
7828 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7831 if (rs6000_emit_set_const (operands[0], operands[1]))
7837 ;; TImode/PTImode is similar, except that we usually want to compute the
7838 ;; address into a register and use lsi/stsi (the exception is during reload).
7840 (define_insn "*mov<mode>_string"
7841 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
7842 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
7844 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
7845 && (gpc_reg_operand (operands[0], <MODE>mode)
7846 || gpc_reg_operand (operands[1], <MODE>mode))"
7849 switch (which_alternative)
7855 return \"stswi %1,%P0,16\";
7859 /* If the address is not used in the output, we can use lsi. Otherwise,
7860 fall through to generating four loads. */
7862 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
7863 return \"lswi %0,%P1,16\";
7864 /* ... fall through ... */
7871 [(set_attr "type" "store,store,load,load,*,*")
7872 (set_attr "update" "yes")
7873 (set_attr "indexed" "yes")
7874 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
7875 (const_string "always")
7876 (const_string "conditional")))])
7878 (define_insn "*mov<mode>_ppc64"
7879 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
7880 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
7881 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
7882 && (gpc_reg_operand (operands[0], <MODE>mode)
7883 || gpc_reg_operand (operands[1], <MODE>mode)))"
7885 return rs6000_output_move_128bit (operands);
7887 [(set_attr "type" "store,store,load,load,*,*")
7888 (set_attr "length" "8")])
7891 [(set (match_operand:TI2 0 "int_reg_operand" "")
7892 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
7894 && (VECTOR_MEM_NONE_P (<MODE>mode)
7895 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
7896 [(set (match_dup 2) (match_dup 4))
7897 (set (match_dup 3) (match_dup 5))]
7900 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7902 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7904 if (CONST_WIDE_INT_P (operands[1]))
7906 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
7907 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
7909 else if (CONST_INT_P (operands[1]))
7911 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
7912 operands[5] = operands[1];
7919 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
7920 (match_operand:TI2 1 "input_operand" ""))]
7922 && gpr_or_gpr_p (operands[0], operands[1])
7923 && !direct_move_p (operands[0], operands[1])
7924 && !quad_load_store_p (operands[0], operands[1])"
7926 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7928 (define_expand "load_multiple"
7929 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7930 (match_operand:SI 1 "" ""))
7931 (use (match_operand:SI 2 "" ""))])]
7932 "TARGET_STRING && !TARGET_POWERPC64"
7940 /* Support only loading a constant number of fixed-point registers from
7941 memory and only bother with this if more than two; the machine
7942 doesn't support more than eight. */
7943 if (GET_CODE (operands[2]) != CONST_INT
7944 || INTVAL (operands[2]) <= 2
7945 || INTVAL (operands[2]) > 8
7946 || GET_CODE (operands[1]) != MEM
7947 || GET_CODE (operands[0]) != REG
7948 || REGNO (operands[0]) >= 32)
7951 count = INTVAL (operands[2]);
7952 regno = REGNO (operands[0]);
7954 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
7955 op1 = replace_equiv_address (operands[1],
7956 force_reg (SImode, XEXP (operands[1], 0)));
7958 for (i = 0; i < count; i++)
7959 XVECEXP (operands[3], 0, i)
7960 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
7961 adjust_address_nv (op1, SImode, i * 4));
7964 (define_insn "*ldmsi8"
7965 [(match_parallel 0 "load_multiple_operation"
7966 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7967 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7968 (set (match_operand:SI 3 "gpc_reg_operand" "")
7969 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7970 (set (match_operand:SI 4 "gpc_reg_operand" "")
7971 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7972 (set (match_operand:SI 5 "gpc_reg_operand" "")
7973 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7974 (set (match_operand:SI 6 "gpc_reg_operand" "")
7975 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7976 (set (match_operand:SI 7 "gpc_reg_operand" "")
7977 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
7978 (set (match_operand:SI 8 "gpc_reg_operand" "")
7979 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
7980 (set (match_operand:SI 9 "gpc_reg_operand" "")
7981 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
7982 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
7984 { return rs6000_output_load_multiple (operands); }"
7985 [(set_attr "type" "load")
7986 (set_attr "update" "yes")
7987 (set_attr "indexed" "yes")
7988 (set_attr "length" "32")])
7990 (define_insn "*ldmsi7"
7991 [(match_parallel 0 "load_multiple_operation"
7992 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7993 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7994 (set (match_operand:SI 3 "gpc_reg_operand" "")
7995 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7996 (set (match_operand:SI 4 "gpc_reg_operand" "")
7997 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7998 (set (match_operand:SI 5 "gpc_reg_operand" "")
7999 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8000 (set (match_operand:SI 6 "gpc_reg_operand" "")
8001 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8002 (set (match_operand:SI 7 "gpc_reg_operand" "")
8003 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8004 (set (match_operand:SI 8 "gpc_reg_operand" "")
8005 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8006 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8008 { return rs6000_output_load_multiple (operands); }"
8009 [(set_attr "type" "load")
8010 (set_attr "update" "yes")
8011 (set_attr "indexed" "yes")
8012 (set_attr "length" "32")])
8014 (define_insn "*ldmsi6"
8015 [(match_parallel 0 "load_multiple_operation"
8016 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8017 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8018 (set (match_operand:SI 3 "gpc_reg_operand" "")
8019 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8020 (set (match_operand:SI 4 "gpc_reg_operand" "")
8021 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8022 (set (match_operand:SI 5 "gpc_reg_operand" "")
8023 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8024 (set (match_operand:SI 6 "gpc_reg_operand" "")
8025 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8026 (set (match_operand:SI 7 "gpc_reg_operand" "")
8027 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8028 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8030 { return rs6000_output_load_multiple (operands); }"
8031 [(set_attr "type" "load")
8032 (set_attr "update" "yes")
8033 (set_attr "indexed" "yes")
8034 (set_attr "length" "32")])
8036 (define_insn "*ldmsi5"
8037 [(match_parallel 0 "load_multiple_operation"
8038 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8039 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8040 (set (match_operand:SI 3 "gpc_reg_operand" "")
8041 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8042 (set (match_operand:SI 4 "gpc_reg_operand" "")
8043 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8044 (set (match_operand:SI 5 "gpc_reg_operand" "")
8045 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8046 (set (match_operand:SI 6 "gpc_reg_operand" "")
8047 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8048 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8050 { return rs6000_output_load_multiple (operands); }"
8051 [(set_attr "type" "load")
8052 (set_attr "update" "yes")
8053 (set_attr "indexed" "yes")
8054 (set_attr "length" "32")])
8056 (define_insn "*ldmsi4"
8057 [(match_parallel 0 "load_multiple_operation"
8058 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8059 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8060 (set (match_operand:SI 3 "gpc_reg_operand" "")
8061 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8062 (set (match_operand:SI 4 "gpc_reg_operand" "")
8063 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8064 (set (match_operand:SI 5 "gpc_reg_operand" "")
8065 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8066 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8068 { return rs6000_output_load_multiple (operands); }"
8069 [(set_attr "type" "load")
8070 (set_attr "update" "yes")
8071 (set_attr "indexed" "yes")
8072 (set_attr "length" "32")])
8074 (define_insn "*ldmsi3"
8075 [(match_parallel 0 "load_multiple_operation"
8076 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8077 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8078 (set (match_operand:SI 3 "gpc_reg_operand" "")
8079 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8080 (set (match_operand:SI 4 "gpc_reg_operand" "")
8081 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8082 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8084 { return rs6000_output_load_multiple (operands); }"
8085 [(set_attr "type" "load")
8086 (set_attr "update" "yes")
8087 (set_attr "indexed" "yes")
8088 (set_attr "length" "32")])
8090 (define_expand "store_multiple"
8091 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8092 (match_operand:SI 1 "" ""))
8093 (clobber (scratch:SI))
8094 (use (match_operand:SI 2 "" ""))])]
8095 "TARGET_STRING && !TARGET_POWERPC64"
8104 /* Support only storing a constant number of fixed-point registers to
8105 memory and only bother with this if more than two; the machine
8106 doesn't support more than eight. */
8107 if (GET_CODE (operands[2]) != CONST_INT
8108 || INTVAL (operands[2]) <= 2
8109 || INTVAL (operands[2]) > 8
8110 || GET_CODE (operands[0]) != MEM
8111 || GET_CODE (operands[1]) != REG
8112 || REGNO (operands[1]) >= 32)
8115 count = INTVAL (operands[2]);
8116 regno = REGNO (operands[1]);
8118 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8119 to = force_reg (SImode, XEXP (operands[0], 0));
8120 op0 = replace_equiv_address (operands[0], to);
8122 XVECEXP (operands[3], 0, 0)
8123 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8124 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8125 gen_rtx_SCRATCH (SImode));
8127 for (i = 1; i < count; i++)
8128 XVECEXP (operands[3], 0, i + 1)
8129 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8130 gen_rtx_REG (SImode, regno + i));
8133 (define_insn "*stmsi8"
8134 [(match_parallel 0 "store_multiple_operation"
8135 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8136 (match_operand:SI 2 "gpc_reg_operand" "r"))
8137 (clobber (match_scratch:SI 3 "=X"))
8138 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8139 (match_operand:SI 4 "gpc_reg_operand" "r"))
8140 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8141 (match_operand:SI 5 "gpc_reg_operand" "r"))
8142 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8143 (match_operand:SI 6 "gpc_reg_operand" "r"))
8144 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8145 (match_operand:SI 7 "gpc_reg_operand" "r"))
8146 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8147 (match_operand:SI 8 "gpc_reg_operand" "r"))
8148 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8149 (match_operand:SI 9 "gpc_reg_operand" "r"))
8150 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8151 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8152 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8154 [(set_attr "type" "store")
8155 (set_attr "update" "yes")
8156 (set_attr "indexed" "yes")
8157 (set_attr "cell_micro" "always")])
8159 (define_insn "*stmsi7"
8160 [(match_parallel 0 "store_multiple_operation"
8161 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8162 (match_operand:SI 2 "gpc_reg_operand" "r"))
8163 (clobber (match_scratch:SI 3 "=X"))
8164 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8165 (match_operand:SI 4 "gpc_reg_operand" "r"))
8166 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8167 (match_operand:SI 5 "gpc_reg_operand" "r"))
8168 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8169 (match_operand:SI 6 "gpc_reg_operand" "r"))
8170 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8171 (match_operand:SI 7 "gpc_reg_operand" "r"))
8172 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8173 (match_operand:SI 8 "gpc_reg_operand" "r"))
8174 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8175 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8176 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8178 [(set_attr "type" "store")
8179 (set_attr "update" "yes")
8180 (set_attr "indexed" "yes")
8181 (set_attr "cell_micro" "always")])
8183 (define_insn "*stmsi6"
8184 [(match_parallel 0 "store_multiple_operation"
8185 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8186 (match_operand:SI 2 "gpc_reg_operand" "r"))
8187 (clobber (match_scratch:SI 3 "=X"))
8188 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8189 (match_operand:SI 4 "gpc_reg_operand" "r"))
8190 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8191 (match_operand:SI 5 "gpc_reg_operand" "r"))
8192 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8193 (match_operand:SI 6 "gpc_reg_operand" "r"))
8194 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8195 (match_operand:SI 7 "gpc_reg_operand" "r"))
8196 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8197 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8198 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8200 [(set_attr "type" "store")
8201 (set_attr "update" "yes")
8202 (set_attr "indexed" "yes")
8203 (set_attr "cell_micro" "always")])
8205 (define_insn "*stmsi5"
8206 [(match_parallel 0 "store_multiple_operation"
8207 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8208 (match_operand:SI 2 "gpc_reg_operand" "r"))
8209 (clobber (match_scratch:SI 3 "=X"))
8210 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8211 (match_operand:SI 4 "gpc_reg_operand" "r"))
8212 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8213 (match_operand:SI 5 "gpc_reg_operand" "r"))
8214 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8215 (match_operand:SI 6 "gpc_reg_operand" "r"))
8216 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8217 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8218 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8220 [(set_attr "type" "store")
8221 (set_attr "update" "yes")
8222 (set_attr "indexed" "yes")
8223 (set_attr "cell_micro" "always")])
8225 (define_insn "*stmsi4"
8226 [(match_parallel 0 "store_multiple_operation"
8227 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8228 (match_operand:SI 2 "gpc_reg_operand" "r"))
8229 (clobber (match_scratch:SI 3 "=X"))
8230 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8231 (match_operand:SI 4 "gpc_reg_operand" "r"))
8232 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8233 (match_operand:SI 5 "gpc_reg_operand" "r"))
8234 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8235 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8236 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8238 [(set_attr "type" "store")
8239 (set_attr "update" "yes")
8240 (set_attr "indexed" "yes")
8241 (set_attr "cell_micro" "always")])
8243 (define_insn "*stmsi3"
8244 [(match_parallel 0 "store_multiple_operation"
8245 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8246 (match_operand:SI 2 "gpc_reg_operand" "r"))
8247 (clobber (match_scratch:SI 3 "=X"))
8248 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8249 (match_operand:SI 4 "gpc_reg_operand" "r"))
8250 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8251 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8252 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8254 [(set_attr "type" "store")
8255 (set_attr "update" "yes")
8256 (set_attr "indexed" "yes")
8257 (set_attr "cell_micro" "always")])
8259 (define_expand "setmemsi"
8260 [(parallel [(set (match_operand:BLK 0 "" "")
8261 (match_operand 2 "const_int_operand" ""))
8262 (use (match_operand:SI 1 "" ""))
8263 (use (match_operand:SI 3 "" ""))])]
8267 /* If value to set is not zero, use the library routine. */
8268 if (operands[2] != const0_rtx)
8271 if (expand_block_clear (operands))
8277 ;; String/block move insn.
8278 ;; Argument 0 is the destination
8279 ;; Argument 1 is the source
8280 ;; Argument 2 is the length
8281 ;; Argument 3 is the alignment
8283 (define_expand "movmemsi"
8284 [(parallel [(set (match_operand:BLK 0 "" "")
8285 (match_operand:BLK 1 "" ""))
8286 (use (match_operand:SI 2 "" ""))
8287 (use (match_operand:SI 3 "" ""))])]
8291 if (expand_block_move (operands))
8297 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
8298 ;; register allocator doesn't have a clue about allocating 8 word registers.
8299 ;; rD/rS = r5 is preferred, efficient form.
8300 (define_expand "movmemsi_8reg"
8301 [(parallel [(set (match_operand 0 "" "")
8302 (match_operand 1 "" ""))
8303 (use (match_operand 2 "" ""))
8304 (use (match_operand 3 "" ""))
8305 (clobber (reg:SI 5))
8306 (clobber (reg:SI 6))
8307 (clobber (reg:SI 7))
8308 (clobber (reg:SI 8))
8309 (clobber (reg:SI 9))
8310 (clobber (reg:SI 10))
8311 (clobber (reg:SI 11))
8312 (clobber (reg:SI 12))
8313 (clobber (match_scratch:SI 4 ""))])]
8318 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8319 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8320 (use (match_operand:SI 2 "immediate_operand" "i"))
8321 (use (match_operand:SI 3 "immediate_operand" "i"))
8322 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8323 (clobber (reg:SI 6))
8324 (clobber (reg:SI 7))
8325 (clobber (reg:SI 8))
8326 (clobber (reg:SI 9))
8327 (clobber (reg:SI 10))
8328 (clobber (reg:SI 11))
8329 (clobber (reg:SI 12))
8330 (clobber (match_scratch:SI 5 "=X"))]
8332 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8333 || INTVAL (operands[2]) == 0)
8334 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8335 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8336 && REGNO (operands[4]) == 5"
8337 "lswi %4,%1,%2\;stswi %4,%0,%2"
8338 [(set_attr "type" "store")
8339 (set_attr "update" "yes")
8340 (set_attr "indexed" "yes")
8341 (set_attr "cell_micro" "always")
8342 (set_attr "length" "8")])
8344 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
8345 ;; register allocator doesn't have a clue about allocating 6 word registers.
8346 ;; rD/rS = r5 is preferred, efficient form.
8347 (define_expand "movmemsi_6reg"
8348 [(parallel [(set (match_operand 0 "" "")
8349 (match_operand 1 "" ""))
8350 (use (match_operand 2 "" ""))
8351 (use (match_operand 3 "" ""))
8352 (clobber (reg:SI 5))
8353 (clobber (reg:SI 6))
8354 (clobber (reg:SI 7))
8355 (clobber (reg:SI 8))
8356 (clobber (reg:SI 9))
8357 (clobber (reg:SI 10))
8358 (clobber (match_scratch:SI 4 ""))])]
8363 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8364 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8365 (use (match_operand:SI 2 "immediate_operand" "i"))
8366 (use (match_operand:SI 3 "immediate_operand" "i"))
8367 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8368 (clobber (reg:SI 6))
8369 (clobber (reg:SI 7))
8370 (clobber (reg:SI 8))
8371 (clobber (reg:SI 9))
8372 (clobber (reg:SI 10))
8373 (clobber (match_scratch:SI 5 "=X"))]
8375 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8376 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8377 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8378 && REGNO (operands[4]) == 5"
8379 "lswi %4,%1,%2\;stswi %4,%0,%2"
8380 [(set_attr "type" "store")
8381 (set_attr "update" "yes")
8382 (set_attr "indexed" "yes")
8383 (set_attr "cell_micro" "always")
8384 (set_attr "length" "8")])
8386 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8387 ;; problems with TImode.
8388 ;; rD/rS = r5 is preferred, efficient form.
8389 (define_expand "movmemsi_4reg"
8390 [(parallel [(set (match_operand 0 "" "")
8391 (match_operand 1 "" ""))
8392 (use (match_operand 2 "" ""))
8393 (use (match_operand 3 "" ""))
8394 (clobber (reg:SI 5))
8395 (clobber (reg:SI 6))
8396 (clobber (reg:SI 7))
8397 (clobber (reg:SI 8))
8398 (clobber (match_scratch:SI 4 ""))])]
8403 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8404 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8405 (use (match_operand:SI 2 "immediate_operand" "i"))
8406 (use (match_operand:SI 3 "immediate_operand" "i"))
8407 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8408 (clobber (reg:SI 6))
8409 (clobber (reg:SI 7))
8410 (clobber (reg:SI 8))
8411 (clobber (match_scratch:SI 5 "=X"))]
8413 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8414 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8415 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8416 && REGNO (operands[4]) == 5"
8417 "lswi %4,%1,%2\;stswi %4,%0,%2"
8418 [(set_attr "type" "store")
8419 (set_attr "update" "yes")
8420 (set_attr "indexed" "yes")
8421 (set_attr "cell_micro" "always")
8422 (set_attr "length" "8")])
8424 ;; Move up to 8 bytes at a time.
8425 (define_expand "movmemsi_2reg"
8426 [(parallel [(set (match_operand 0 "" "")
8427 (match_operand 1 "" ""))
8428 (use (match_operand 2 "" ""))
8429 (use (match_operand 3 "" ""))
8430 (clobber (match_scratch:DI 4 ""))
8431 (clobber (match_scratch:SI 5 ""))])]
8432 "TARGET_STRING && ! TARGET_POWERPC64"
8436 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8437 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8438 (use (match_operand:SI 2 "immediate_operand" "i"))
8439 (use (match_operand:SI 3 "immediate_operand" "i"))
8440 (clobber (match_scratch:DI 4 "=&r"))
8441 (clobber (match_scratch:SI 5 "=X"))]
8442 "TARGET_STRING && ! TARGET_POWERPC64
8443 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8444 "lswi %4,%1,%2\;stswi %4,%0,%2"
8445 [(set_attr "type" "store")
8446 (set_attr "update" "yes")
8447 (set_attr "indexed" "yes")
8448 (set_attr "cell_micro" "always")
8449 (set_attr "length" "8")])
8451 ;; Move up to 4 bytes at a time.
8452 (define_expand "movmemsi_1reg"
8453 [(parallel [(set (match_operand 0 "" "")
8454 (match_operand 1 "" ""))
8455 (use (match_operand 2 "" ""))
8456 (use (match_operand 3 "" ""))
8457 (clobber (match_scratch:SI 4 ""))
8458 (clobber (match_scratch:SI 5 ""))])]
8463 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8464 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8465 (use (match_operand:SI 2 "immediate_operand" "i"))
8466 (use (match_operand:SI 3 "immediate_operand" "i"))
8467 (clobber (match_scratch:SI 4 "=&r"))
8468 (clobber (match_scratch:SI 5 "=X"))]
8469 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8470 "lswi %4,%1,%2\;stswi %4,%0,%2"
8471 [(set_attr "type" "store")
8472 (set_attr "update" "yes")
8473 (set_attr "indexed" "yes")
8474 (set_attr "cell_micro" "always")
8475 (set_attr "length" "8")])
8477 ;; Define insns that do load or store with update. Some of these we can
8478 ;; get by using pre-decrement or pre-increment, but the hardware can also
8479 ;; do cases where the increment is not the size of the object.
8481 ;; In all these cases, we use operands 0 and 1 for the register being
8482 ;; incremented because those are the operands that local-alloc will
8483 ;; tie and these are the pair most likely to be tieable (and the ones
8484 ;; that will benefit the most).
8486 (define_insn "*movdi_update1"
8487 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8488 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8489 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8490 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8491 (plus:DI (match_dup 1) (match_dup 2)))]
8492 "TARGET_POWERPC64 && TARGET_UPDATE
8493 && (!avoiding_indexed_address_p (DImode)
8494 || !gpc_reg_operand (operands[2], DImode))"
8498 [(set_attr "type" "load")
8499 (set_attr "update" "yes")
8500 (set_attr "indexed" "yes,no")])
8502 (define_insn "movdi_<mode>_update"
8503 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8504 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8505 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8506 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8507 (plus:P (match_dup 1) (match_dup 2)))]
8508 "TARGET_POWERPC64 && TARGET_UPDATE
8509 && (!avoiding_indexed_address_p (Pmode)
8510 || !gpc_reg_operand (operands[2], Pmode)
8511 || (REG_P (operands[0])
8512 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8516 [(set_attr "type" "store")
8517 (set_attr "update" "yes")
8518 (set_attr "indexed" "yes,no")])
8520 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8521 ;; needed for stack allocation, even if the user passes -mno-update.
8522 (define_insn "movdi_<mode>_update_stack"
8523 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8524 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8525 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8526 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8527 (plus:P (match_dup 1) (match_dup 2)))]
8532 [(set_attr "type" "store")
8533 (set_attr "update" "yes")
8534 (set_attr "indexed" "yes,no")])
8536 (define_insn "*movsi_update1"
8537 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8538 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8539 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8540 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8541 (plus:SI (match_dup 1) (match_dup 2)))]
8543 && (!avoiding_indexed_address_p (SImode)
8544 || !gpc_reg_operand (operands[2], SImode))"
8548 [(set_attr "type" "load")
8549 (set_attr "update" "yes")
8550 (set_attr "indexed" "yes,no")])
8552 (define_insn "*movsi_update2"
8553 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8555 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8556 (match_operand:DI 2 "gpc_reg_operand" "r")))))
8557 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8558 (plus:DI (match_dup 1) (match_dup 2)))]
8559 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8560 && !avoiding_indexed_address_p (DImode)"
8562 [(set_attr "type" "load")
8563 (set_attr "sign_extend" "yes")
8564 (set_attr "update" "yes")
8565 (set_attr "indexed" "yes")])
8567 (define_insn "movsi_update"
8568 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8569 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8570 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8571 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8572 (plus:SI (match_dup 1) (match_dup 2)))]
8574 && (!avoiding_indexed_address_p (SImode)
8575 || !gpc_reg_operand (operands[2], SImode)
8576 || (REG_P (operands[0])
8577 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8581 [(set_attr "type" "store")
8582 (set_attr "update" "yes")
8583 (set_attr "indexed" "yes,no")])
8585 ;; This is an unconditional pattern; needed for stack allocation, even
8586 ;; if the user passes -mno-update.
8587 (define_insn "movsi_update_stack"
8588 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8589 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8590 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8591 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8592 (plus:SI (match_dup 1) (match_dup 2)))]
8597 [(set_attr "type" "store")
8598 (set_attr "update" "yes")
8599 (set_attr "indexed" "yes,no")])
8601 (define_insn "*movhi_update1"
8602 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8603 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8604 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8605 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8606 (plus:SI (match_dup 1) (match_dup 2)))]
8608 && (!avoiding_indexed_address_p (SImode)
8609 || !gpc_reg_operand (operands[2], SImode))"
8613 [(set_attr "type" "load")
8614 (set_attr "update" "yes")
8615 (set_attr "indexed" "yes,no")])
8617 (define_insn "*movhi_update2"
8618 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8620 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8621 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8622 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8623 (plus:SI (match_dup 1) (match_dup 2)))]
8625 && (!avoiding_indexed_address_p (SImode)
8626 || !gpc_reg_operand (operands[2], SImode))"
8630 [(set_attr "type" "load")
8631 (set_attr "update" "yes")
8632 (set_attr "indexed" "yes,no")])
8634 (define_insn "*movhi_update3"
8635 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8637 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8638 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8639 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8640 (plus:SI (match_dup 1) (match_dup 2)))]
8641 "TARGET_UPDATE && rs6000_gen_cell_microcode
8642 && (!avoiding_indexed_address_p (SImode)
8643 || !gpc_reg_operand (operands[2], SImode))"
8647 [(set_attr "type" "load")
8648 (set_attr "sign_extend" "yes")
8649 (set_attr "update" "yes")
8650 (set_attr "indexed" "yes,no")])
8652 (define_insn "*movhi_update4"
8653 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8654 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8655 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8656 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8657 (plus:SI (match_dup 1) (match_dup 2)))]
8659 && (!avoiding_indexed_address_p (SImode)
8660 || !gpc_reg_operand (operands[2], SImode))"
8664 [(set_attr "type" "store")
8665 (set_attr "update" "yes")
8666 (set_attr "indexed" "yes,no")])
8668 (define_insn "*movqi_update1"
8669 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8670 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8671 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8672 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8673 (plus:SI (match_dup 1) (match_dup 2)))]
8675 && (!avoiding_indexed_address_p (SImode)
8676 || !gpc_reg_operand (operands[2], SImode))"
8680 [(set_attr "type" "load")
8681 (set_attr "update" "yes")
8682 (set_attr "indexed" "yes,no")])
8684 (define_insn "*movqi_update2"
8685 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8687 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8688 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8689 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8690 (plus:SI (match_dup 1) (match_dup 2)))]
8692 && (!avoiding_indexed_address_p (SImode)
8693 || !gpc_reg_operand (operands[2], SImode))"
8697 [(set_attr "type" "load")
8698 (set_attr "update" "yes")
8699 (set_attr "indexed" "yes,no")])
8701 (define_insn "*movqi_update3"
8702 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8703 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8704 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
8705 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8706 (plus:SI (match_dup 1) (match_dup 2)))]
8708 && (!avoiding_indexed_address_p (SImode)
8709 || !gpc_reg_operand (operands[2], SImode))"
8713 [(set_attr "type" "store")
8714 (set_attr "update" "yes")
8715 (set_attr "indexed" "yes,no")])
8717 (define_insn "*movsf_update1"
8718 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
8719 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8720 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8721 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8722 (plus:SI (match_dup 1) (match_dup 2)))]
8723 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8724 && (!avoiding_indexed_address_p (SImode)
8725 || !gpc_reg_operand (operands[2], SImode))"
8729 [(set_attr "type" "fpload")
8730 (set_attr "update" "yes")
8731 (set_attr "indexed" "yes,no")])
8733 (define_insn "*movsf_update2"
8734 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8735 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8736 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
8737 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8738 (plus:SI (match_dup 1) (match_dup 2)))]
8739 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8740 && (!avoiding_indexed_address_p (SImode)
8741 || !gpc_reg_operand (operands[2], SImode))"
8745 [(set_attr "type" "fpstore")
8746 (set_attr "update" "yes")
8747 (set_attr "indexed" "yes,no")])
8749 (define_insn "*movsf_update3"
8750 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
8751 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8752 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8753 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8754 (plus:SI (match_dup 1) (match_dup 2)))]
8755 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8756 && (!avoiding_indexed_address_p (SImode)
8757 || !gpc_reg_operand (operands[2], SImode))"
8761 [(set_attr "type" "load")
8762 (set_attr "update" "yes")
8763 (set_attr "indexed" "yes,no")])
8765 (define_insn "*movsf_update4"
8766 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8767 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8768 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
8769 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8770 (plus:SI (match_dup 1) (match_dup 2)))]
8771 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8772 && (!avoiding_indexed_address_p (SImode)
8773 || !gpc_reg_operand (operands[2], SImode))"
8777 [(set_attr "type" "store")
8778 (set_attr "update" "yes")
8779 (set_attr "indexed" "yes,no")])
8781 (define_insn "*movdf_update1"
8782 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
8783 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8784 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8785 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8786 (plus:SI (match_dup 1) (match_dup 2)))]
8787 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8788 && (!avoiding_indexed_address_p (SImode)
8789 || !gpc_reg_operand (operands[2], SImode))"
8793 [(set_attr "type" "fpload")
8794 (set_attr "update" "yes")
8795 (set_attr "indexed" "yes,no")])
8797 (define_insn "*movdf_update2"
8798 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8799 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8800 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
8801 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8802 (plus:SI (match_dup 1) (match_dup 2)))]
8803 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8804 && (!avoiding_indexed_address_p (SImode)
8805 || !gpc_reg_operand (operands[2], SImode))"
8809 [(set_attr "type" "fpstore")
8810 (set_attr "update" "yes")
8811 (set_attr "indexed" "yes,no")])
8814 ;; After inserting conditional returns we can sometimes have
8815 ;; unnecessary register moves. Unfortunately we cannot have a
8816 ;; modeless peephole here, because some single SImode sets have early
8817 ;; clobber outputs. Although those sets expand to multi-ppc-insn
8818 ;; sequences, using get_attr_length here will smash the operands
8819 ;; array. Neither is there an early_cobbler_p predicate.
8820 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
8821 ;; Also this optimization interferes with scalars going into
8822 ;; altivec registers (the code does reloading through the FPRs).
8824 [(set (match_operand:DF 0 "gpc_reg_operand" "")
8825 (match_operand:DF 1 "any_operand" ""))
8826 (set (match_operand:DF 2 "gpc_reg_operand" "")
8828 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
8829 && !TARGET_UPPER_REGS_DF
8830 && peep2_reg_dead_p (2, operands[0])"
8831 [(set (match_dup 2) (match_dup 1))])
8834 [(set (match_operand:SF 0 "gpc_reg_operand" "")
8835 (match_operand:SF 1 "any_operand" ""))
8836 (set (match_operand:SF 2 "gpc_reg_operand" "")
8838 "!TARGET_UPPER_REGS_SF
8839 && peep2_reg_dead_p (2, operands[0])"
8840 [(set (match_dup 2) (match_dup 1))])
8845 ;; Mode attributes for different ABIs.
8846 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
8847 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
8848 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
8849 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
8851 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
8852 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8853 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8854 (match_operand 4 "" "g")))
8855 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8856 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8858 (clobber (reg:SI LR_REGNO))]
8859 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8861 if (TARGET_CMODEL != CMODEL_SMALL)
8862 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
8865 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
8867 "&& TARGET_TLS_MARKERS"
8869 (unspec:TLSmode [(match_dup 1)
8872 (parallel [(set (match_dup 0)
8873 (call (mem:TLSmode (match_dup 3))
8875 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8876 (clobber (reg:SI LR_REGNO))])]
8878 [(set_attr "type" "two")
8879 (set (attr "length")
8880 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8884 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
8885 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8886 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8887 (match_operand 4 "" "g")))
8888 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8889 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8891 (clobber (reg:SI LR_REGNO))]
8892 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
8896 if (TARGET_SECURE_PLT && flag_pic == 2)
8897 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
8899 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
8902 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
8904 "&& TARGET_TLS_MARKERS"
8906 (unspec:TLSmode [(match_dup 1)
8909 (parallel [(set (match_dup 0)
8910 (call (mem:TLSmode (match_dup 3))
8912 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8913 (clobber (reg:SI LR_REGNO))])]
8915 [(set_attr "type" "two")
8916 (set_attr "length" "8")])
8918 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
8919 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8920 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8921 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8923 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
8924 "addi %0,%1,%2@got@tlsgd"
8925 "&& TARGET_CMODEL != CMODEL_SMALL"
8928 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
8930 (lo_sum:TLSmode (match_dup 3)
8931 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
8934 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
8936 [(set (attr "length")
8937 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8941 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
8942 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8944 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8945 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8947 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8948 "addis %0,%1,%2@got@tlsgd@ha"
8949 [(set_attr "length" "4")])
8951 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
8952 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8953 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
8954 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
8955 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8957 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8958 "addi %0,%1,%2@got@tlsgd@l"
8959 [(set_attr "length" "4")])
8961 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
8962 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8963 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8964 (match_operand 2 "" "g")))
8965 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8967 (clobber (reg:SI LR_REGNO))]
8968 "HAVE_AS_TLS && TARGET_TLS_MARKERS
8969 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8970 "bl %z1(%3@tlsgd)\;nop"
8971 [(set_attr "type" "branch")
8972 (set_attr "length" "8")])
8974 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
8975 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8976 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8977 (match_operand 2 "" "g")))
8978 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8980 (clobber (reg:SI LR_REGNO))]
8981 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
8985 if (TARGET_SECURE_PLT && flag_pic == 2)
8986 return "bl %z1+32768(%3@tlsgd)@plt";
8987 return "bl %z1(%3@tlsgd)@plt";
8989 return "bl %z1(%3@tlsgd)";
8991 [(set_attr "type" "branch")
8992 (set_attr "length" "4")])
8994 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
8995 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8996 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
8997 (match_operand 3 "" "g")))
8998 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9000 (clobber (reg:SI LR_REGNO))]
9001 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9003 if (TARGET_CMODEL != CMODEL_SMALL)
9004 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9007 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9009 "&& TARGET_TLS_MARKERS"
9011 (unspec:TLSmode [(match_dup 1)]
9013 (parallel [(set (match_dup 0)
9014 (call (mem:TLSmode (match_dup 2))
9016 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9017 (clobber (reg:SI LR_REGNO))])]
9019 [(set_attr "type" "two")
9020 (set (attr "length")
9021 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9025 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9026 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9027 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9028 (match_operand 3 "" "g")))
9029 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9031 (clobber (reg:SI LR_REGNO))]
9032 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9036 if (TARGET_SECURE_PLT && flag_pic == 2)
9037 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9039 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9042 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9044 "&& TARGET_TLS_MARKERS"
9046 (unspec:TLSmode [(match_dup 1)]
9048 (parallel [(set (match_dup 0)
9049 (call (mem:TLSmode (match_dup 2))
9051 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9052 (clobber (reg:SI LR_REGNO))])]
9054 [(set_attr "length" "8")])
9056 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9057 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9058 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9060 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9061 "addi %0,%1,%&@got@tlsld"
9062 "&& TARGET_CMODEL != CMODEL_SMALL"
9065 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9067 (lo_sum:TLSmode (match_dup 2)
9068 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9071 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9073 [(set (attr "length")
9074 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9078 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9079 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9081 (unspec:TLSmode [(const_int 0)
9082 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9084 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9085 "addis %0,%1,%&@got@tlsld@ha"
9086 [(set_attr "length" "4")])
9088 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9089 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9090 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9091 (unspec:TLSmode [(const_int 0)
9092 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9094 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9095 "addi %0,%1,%&@got@tlsld@l"
9096 [(set_attr "length" "4")])
9098 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9099 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9100 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9101 (match_operand 2 "" "g")))
9102 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9103 (clobber (reg:SI LR_REGNO))]
9104 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9105 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9106 "bl %z1(%&@tlsld)\;nop"
9107 [(set_attr "type" "branch")
9108 (set_attr "length" "8")])
9110 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9111 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9112 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9113 (match_operand 2 "" "g")))
9114 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9115 (clobber (reg:SI LR_REGNO))]
9116 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9120 if (TARGET_SECURE_PLT && flag_pic == 2)
9121 return "bl %z1+32768(%&@tlsld)@plt";
9122 return "bl %z1(%&@tlsld)@plt";
9124 return "bl %z1(%&@tlsld)";
9126 [(set_attr "type" "branch")
9127 (set_attr "length" "4")])
9129 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9130 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9131 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9132 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9135 "addi %0,%1,%2@dtprel")
9137 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9138 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9139 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9140 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9141 UNSPEC_TLSDTPRELHA))]
9143 "addis %0,%1,%2@dtprel@ha")
9145 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9146 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9147 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9148 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9149 UNSPEC_TLSDTPRELLO))]
9151 "addi %0,%1,%2@dtprel@l")
9153 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9154 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9155 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9156 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9157 UNSPEC_TLSGOTDTPREL))]
9159 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9160 "&& TARGET_CMODEL != CMODEL_SMALL"
9163 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9165 (lo_sum:TLSmode (match_dup 3)
9166 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9169 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9171 [(set (attr "length")
9172 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9176 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9177 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9179 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9180 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9181 UNSPEC_TLSGOTDTPREL)))]
9182 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9183 "addis %0,%1,%2@got@dtprel@ha"
9184 [(set_attr "length" "4")])
9186 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9187 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9188 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9189 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9190 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9191 UNSPEC_TLSGOTDTPREL)))]
9192 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9193 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9194 [(set_attr "length" "4")])
9196 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9197 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9198 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9199 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9202 "addi %0,%1,%2@tprel")
9204 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9205 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9206 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9207 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9208 UNSPEC_TLSTPRELHA))]
9210 "addis %0,%1,%2@tprel@ha")
9212 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9213 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9214 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9215 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9216 UNSPEC_TLSTPRELLO))]
9218 "addi %0,%1,%2@tprel@l")
9220 ;; "b" output constraint here and on tls_tls input to support linker tls
9221 ;; optimization. The linker may edit the instructions emitted by a
9222 ;; tls_got_tprel/tls_tls pair to addis,addi.
9223 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9224 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9225 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9226 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9227 UNSPEC_TLSGOTTPREL))]
9229 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9230 "&& TARGET_CMODEL != CMODEL_SMALL"
9233 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9235 (lo_sum:TLSmode (match_dup 3)
9236 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9239 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9241 [(set (attr "length")
9242 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9246 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9247 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9249 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9250 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9251 UNSPEC_TLSGOTTPREL)))]
9252 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9253 "addis %0,%1,%2@got@tprel@ha"
9254 [(set_attr "length" "4")])
9256 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9257 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9258 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9259 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9260 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9261 UNSPEC_TLSGOTTPREL)))]
9262 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9263 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9264 [(set_attr "length" "4")])
9266 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9267 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9268 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9269 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9271 "TARGET_ELF && HAVE_AS_TLS"
9274 (define_expand "tls_get_tpointer"
9275 [(set (match_operand:SI 0 "gpc_reg_operand" "")
9276 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9277 "TARGET_XCOFF && HAVE_AS_TLS"
9280 emit_insn (gen_tls_get_tpointer_internal ());
9281 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9285 (define_insn "tls_get_tpointer_internal"
9287 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9288 (clobber (reg:SI LR_REGNO))]
9289 "TARGET_XCOFF && HAVE_AS_TLS"
9290 "bla __get_tpointer")
9292 (define_expand "tls_get_addr<mode>"
9293 [(set (match_operand:P 0 "gpc_reg_operand" "")
9294 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9295 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9296 "TARGET_XCOFF && HAVE_AS_TLS"
9299 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9300 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9301 emit_insn (gen_tls_get_addr_internal<mode> ());
9302 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9306 (define_insn "tls_get_addr_internal<mode>"
9308 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9312 (clobber (reg:P 11))
9313 (clobber (reg:CC CR0_REGNO))
9314 (clobber (reg:P LR_REGNO))]
9315 "TARGET_XCOFF && HAVE_AS_TLS"
9316 "bla __tls_get_addr")
9318 ;; Next come insns related to the calling sequence.
9320 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9321 ;; We move the back-chain and decrement the stack pointer.
9323 (define_expand "allocate_stack"
9324 [(set (match_operand 0 "gpc_reg_operand" "")
9325 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9327 (minus (reg 1) (match_dup 1)))]
9330 { rtx chain = gen_reg_rtx (Pmode);
9331 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9333 rtx insn, par, set, mem;
9335 emit_move_insn (chain, stack_bot);
9337 /* Check stack bounds if necessary. */
9338 if (crtl->limit_stack)
9341 available = expand_binop (Pmode, sub_optab,
9342 stack_pointer_rtx, stack_limit_rtx,
9343 NULL_RTX, 1, OPTAB_WIDEN);
9344 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9347 if (GET_CODE (operands[1]) != CONST_INT
9348 || INTVAL (operands[1]) < -32767
9349 || INTVAL (operands[1]) > 32768)
9351 neg_op0 = gen_reg_rtx (Pmode);
9353 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9355 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9358 neg_op0 = GEN_INT (- INTVAL (operands[1]));
9360 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9361 : gen_movdi_di_update_stack))
9362 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9364 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9365 it now and set the alias set/attributes. The above gen_*_update
9366 calls will generate a PARALLEL with the MEM set being the first
9368 par = PATTERN (insn);
9369 gcc_assert (GET_CODE (par) == PARALLEL);
9370 set = XVECEXP (par, 0, 0);
9371 gcc_assert (GET_CODE (set) == SET);
9372 mem = SET_DEST (set);
9373 gcc_assert (MEM_P (mem));
9374 MEM_NOTRAP_P (mem) = 1;
9375 set_mem_alias_set (mem, get_frame_alias_set ());
9377 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9381 ;; These patterns say how to save and restore the stack pointer. We need not
9382 ;; save the stack pointer at function level since we are careful to
9383 ;; preserve the backchain. At block level, we have to restore the backchain
9384 ;; when we restore the stack pointer.
9386 ;; For nonlocal gotos, we must save both the stack pointer and its
9387 ;; backchain and restore both. Note that in the nonlocal case, the
9388 ;; save area is a memory location.
9390 (define_expand "save_stack_function"
9391 [(match_operand 0 "any_operand" "")
9392 (match_operand 1 "any_operand" "")]
9396 (define_expand "restore_stack_function"
9397 [(match_operand 0 "any_operand" "")
9398 (match_operand 1 "any_operand" "")]
9402 ;; Adjust stack pointer (op0) to a new value (op1).
9403 ;; First copy old stack backchain to new location, and ensure that the
9404 ;; scheduler won't reorder the sp assignment before the backchain write.
9405 (define_expand "restore_stack_block"
9406 [(set (match_dup 2) (match_dup 3))
9407 (set (match_dup 4) (match_dup 2))
9409 (set (match_operand 0 "register_operand" "")
9410 (match_operand 1 "register_operand" ""))]
9416 operands[1] = force_reg (Pmode, operands[1]);
9417 operands[2] = gen_reg_rtx (Pmode);
9418 operands[3] = gen_frame_mem (Pmode, operands[0]);
9419 operands[4] = gen_frame_mem (Pmode, operands[1]);
9420 p = rtvec_alloc (1);
9421 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9423 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9426 (define_expand "save_stack_nonlocal"
9427 [(set (match_dup 3) (match_dup 4))
9428 (set (match_operand 0 "memory_operand" "") (match_dup 3))
9429 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9433 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9435 /* Copy the backchain to the first word, sp to the second. */
9436 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9437 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9438 operands[3] = gen_reg_rtx (Pmode);
9439 operands[4] = gen_frame_mem (Pmode, operands[1]);
9442 (define_expand "restore_stack_nonlocal"
9443 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9444 (set (match_dup 3) (match_dup 4))
9445 (set (match_dup 5) (match_dup 2))
9447 (set (match_operand 0 "register_operand" "") (match_dup 3))]
9451 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9454 /* Restore the backchain from the first word, sp from the second. */
9455 operands[2] = gen_reg_rtx (Pmode);
9456 operands[3] = gen_reg_rtx (Pmode);
9457 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9458 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9459 operands[5] = gen_frame_mem (Pmode, operands[3]);
9460 p = rtvec_alloc (1);
9461 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9463 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9466 ;; TOC register handling.
9468 ;; Code to initialize the TOC register...
9470 (define_insn "load_toc_aix_si"
9471 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9472 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9474 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9478 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9479 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9480 operands[2] = gen_rtx_REG (Pmode, 2);
9481 return \"lwz %0,%1(%2)\";
9483 [(set_attr "type" "load")
9484 (set_attr "update" "no")
9485 (set_attr "indexed" "no")])
9487 (define_insn "load_toc_aix_di"
9488 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9489 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9491 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9495 #ifdef TARGET_RELOCATABLE
9496 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9497 !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
9499 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9502 strcat (buf, \"@toc\");
9503 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9504 operands[2] = gen_rtx_REG (Pmode, 2);
9505 return \"ld %0,%1(%2)\";
9507 [(set_attr "type" "load")
9508 (set_attr "update" "no")
9509 (set_attr "indexed" "no")])
9511 (define_insn "load_toc_v4_pic_si"
9512 [(set (reg:SI LR_REGNO)
9513 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9514 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9515 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9516 [(set_attr "type" "branch")
9517 (set_attr "length" "4")])
9519 (define_expand "load_toc_v4_PIC_1"
9520 [(parallel [(set (reg:SI LR_REGNO)
9521 (match_operand:SI 0 "immediate_operand" "s"))
9522 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9523 "TARGET_ELF && DEFAULT_ABI == ABI_V4
9524 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9527 (define_insn "load_toc_v4_PIC_1_normal"
9528 [(set (reg:SI LR_REGNO)
9529 (match_operand:SI 0 "immediate_operand" "s"))
9530 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9531 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9532 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9533 "bcl 20,31,%0\\n%0:"
9534 [(set_attr "type" "branch")
9535 (set_attr "length" "4")
9536 (set_attr "cannot_copy" "yes")])
9538 (define_insn "load_toc_v4_PIC_1_476"
9539 [(set (reg:SI LR_REGNO)
9540 (match_operand:SI 0 "immediate_operand" "s"))
9541 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9542 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9543 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9547 static char templ[32];
9549 get_ppc476_thunk_name (name);
9550 sprintf (templ, \"bl %s\\n%%0:\", name);
9553 [(set_attr "type" "branch")
9554 (set_attr "length" "4")
9555 (set_attr "cannot_copy" "yes")])
9557 (define_expand "load_toc_v4_PIC_1b"
9558 [(parallel [(set (reg:SI LR_REGNO)
9559 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9560 (label_ref (match_operand 1 "" ""))]
9563 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9566 (define_insn "load_toc_v4_PIC_1b_normal"
9567 [(set (reg:SI LR_REGNO)
9568 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9569 (label_ref (match_operand 1 "" ""))]
9572 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9573 "bcl 20,31,$+8\;.long %0-$"
9574 [(set_attr "type" "branch")
9575 (set_attr "length" "8")])
9577 (define_insn "load_toc_v4_PIC_1b_476"
9578 [(set (reg:SI LR_REGNO)
9579 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9580 (label_ref (match_operand 1 "" ""))]
9583 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9587 static char templ[32];
9589 get_ppc476_thunk_name (name);
9590 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9593 [(set_attr "type" "branch")
9594 (set_attr "length" "16")])
9596 (define_insn "load_toc_v4_PIC_2"
9597 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9598 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9599 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9600 (match_operand:SI 3 "immediate_operand" "s")))))]
9601 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9603 [(set_attr "type" "load")])
9605 (define_insn "load_toc_v4_PIC_3b"
9606 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9607 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9609 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9610 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9611 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9612 "addis %0,%1,%2-%3@ha")
9614 (define_insn "load_toc_v4_PIC_3c"
9615 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9616 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9617 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9618 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9619 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9620 "addi %0,%1,%2-%3@l")
9622 ;; If the TOC is shared over a translation unit, as happens with all
9623 ;; the kinds of PIC that we support, we need to restore the TOC
9624 ;; pointer only when jumping over units of translation.
9625 ;; On Darwin, we need to reload the picbase.
9627 (define_expand "builtin_setjmp_receiver"
9628 [(use (label_ref (match_operand 0 "" "")))]
9629 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9630 || (TARGET_TOC && TARGET_MINIMAL_TOC)
9631 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9635 if (DEFAULT_ABI == ABI_DARWIN)
9637 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9638 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9642 crtl->uses_pic_offset_table = 1;
9643 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9644 CODE_LABEL_NUMBER (operands[0]));
9645 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9647 emit_insn (gen_load_macho_picbase (tmplabrtx));
9648 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9649 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9653 rs6000_emit_load_toc_table (FALSE);
9658 (define_insn "*largetoc_high"
9659 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9661 (unspec [(match_operand:DI 1 "" "")
9662 (match_operand:DI 2 "gpc_reg_operand" "b")]
9664 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9665 "addis %0,%2,%1@toc@ha")
9667 (define_insn "*largetoc_high_aix<mode>"
9668 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9670 (unspec [(match_operand:P 1 "" "")
9671 (match_operand:P 2 "gpc_reg_operand" "b")]
9673 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9674 "addis %0,%1@u(%2)")
9676 (define_insn "*largetoc_high_plus"
9677 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9680 (unspec [(match_operand:DI 1 "" "")
9681 (match_operand:DI 2 "gpc_reg_operand" "b")]
9683 (match_operand:DI 3 "add_cint_operand" "n"))))]
9684 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9685 "addis %0,%2,%1+%3@toc@ha")
9687 (define_insn "*largetoc_high_plus_aix<mode>"
9688 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9691 (unspec [(match_operand:P 1 "" "")
9692 (match_operand:P 2 "gpc_reg_operand" "b")]
9694 (match_operand:P 3 "add_cint_operand" "n"))))]
9695 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9696 "addis %0,%1+%3@u(%2)")
9698 (define_insn "*largetoc_low"
9699 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9700 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9701 (match_operand:DI 2 "" "")))]
9702 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9705 (define_insn "*largetoc_low_aix<mode>"
9706 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9707 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9708 (match_operand:P 2 "" "")))]
9709 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9712 (define_insn_and_split "*tocref<mode>"
9713 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9714 (match_operand:P 1 "small_toc_ref" "R"))]
9717 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
9718 [(set (match_dup 0) (high:P (match_dup 1)))
9719 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
9721 ;; Elf specific ways of loading addresses for non-PIC code.
9722 ;; The output of this could be r0, but we make a very strong
9723 ;; preference for a base register because it will usually
9725 (define_insn "elf_high"
9726 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
9727 (high:SI (match_operand 1 "" "")))]
9728 "TARGET_ELF && ! TARGET_64BIT"
9731 (define_insn "elf_low"
9732 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9733 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9734 (match_operand 2 "" "")))]
9735 "TARGET_ELF && ! TARGET_64BIT"
9738 ;; Call and call_value insns
9739 (define_expand "call"
9740 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
9741 (match_operand 1 "" ""))
9742 (use (match_operand 2 "" ""))
9743 (clobber (reg:SI LR_REGNO))])]
9748 if (MACHOPIC_INDIRECT)
9749 operands[0] = machopic_indirect_call_target (operands[0]);
9752 gcc_assert (GET_CODE (operands[0]) == MEM);
9753 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
9755 operands[0] = XEXP (operands[0], 0);
9757 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9759 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
9763 if (GET_CODE (operands[0]) != SYMBOL_REF
9764 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
9766 if (INTVAL (operands[2]) & CALL_LONG)
9767 operands[0] = rs6000_longcall_ref (operands[0]);
9769 switch (DEFAULT_ABI)
9773 operands[0] = force_reg (Pmode, operands[0]);
9782 (define_expand "call_value"
9783 [(parallel [(set (match_operand 0 "" "")
9784 (call (mem:SI (match_operand 1 "address_operand" ""))
9785 (match_operand 2 "" "")))
9786 (use (match_operand 3 "" ""))
9787 (clobber (reg:SI LR_REGNO))])]
9792 if (MACHOPIC_INDIRECT)
9793 operands[1] = machopic_indirect_call_target (operands[1]);
9796 gcc_assert (GET_CODE (operands[1]) == MEM);
9797 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
9799 operands[1] = XEXP (operands[1], 0);
9801 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9803 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
9807 if (GET_CODE (operands[1]) != SYMBOL_REF
9808 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
9810 if (INTVAL (operands[3]) & CALL_LONG)
9811 operands[1] = rs6000_longcall_ref (operands[1]);
9813 switch (DEFAULT_ABI)
9817 operands[1] = force_reg (Pmode, operands[1]);
9826 ;; Call to function in current module. No TOC pointer reload needed.
9827 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
9828 ;; either the function was not prototyped, or it was prototyped as a
9829 ;; variable argument function. It is > 0 if FP registers were passed
9830 ;; and < 0 if they were not.
9832 (define_insn "*call_local32"
9833 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
9834 (match_operand 1 "" "g,g"))
9835 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9836 (clobber (reg:SI LR_REGNO))]
9837 "(INTVAL (operands[2]) & CALL_LONG) == 0"
9840 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9841 output_asm_insn (\"crxor 6,6,6\", operands);
9843 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9844 output_asm_insn (\"creqv 6,6,6\", operands);
9846 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9848 [(set_attr "type" "branch")
9849 (set_attr "length" "4,8")])
9851 (define_insn "*call_local64"
9852 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
9853 (match_operand 1 "" "g,g"))
9854 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9855 (clobber (reg:SI LR_REGNO))]
9856 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
9859 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9860 output_asm_insn (\"crxor 6,6,6\", operands);
9862 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9863 output_asm_insn (\"creqv 6,6,6\", operands);
9865 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9867 [(set_attr "type" "branch")
9868 (set_attr "length" "4,8")])
9870 (define_insn "*call_value_local32"
9871 [(set (match_operand 0 "" "")
9872 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
9873 (match_operand 2 "" "g,g")))
9874 (use (match_operand:SI 3 "immediate_operand" "O,n"))
9875 (clobber (reg:SI LR_REGNO))]
9876 "(INTVAL (operands[3]) & CALL_LONG) == 0"
9879 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9880 output_asm_insn (\"crxor 6,6,6\", operands);
9882 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9883 output_asm_insn (\"creqv 6,6,6\", operands);
9885 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9887 [(set_attr "type" "branch")
9888 (set_attr "length" "4,8")])
9891 (define_insn "*call_value_local64"
9892 [(set (match_operand 0 "" "")
9893 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
9894 (match_operand 2 "" "g,g")))
9895 (use (match_operand:SI 3 "immediate_operand" "O,n"))
9896 (clobber (reg:SI LR_REGNO))]
9897 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
9900 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9901 output_asm_insn (\"crxor 6,6,6\", operands);
9903 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9904 output_asm_insn (\"creqv 6,6,6\", operands);
9906 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9908 [(set_attr "type" "branch")
9909 (set_attr "length" "4,8")])
9912 ;; A function pointer under System V is just a normal pointer
9913 ;; operands[0] is the function pointer
9914 ;; operands[1] is the stack size to clean up
9915 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
9916 ;; which indicates how to set cr1
9918 (define_insn "*call_indirect_nonlocal_sysv<mode>"
9919 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
9920 (match_operand 1 "" "g,g,g,g"))
9921 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
9922 (clobber (reg:SI LR_REGNO))]
9923 "DEFAULT_ABI == ABI_V4
9924 || DEFAULT_ABI == ABI_DARWIN"
9926 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9927 output_asm_insn ("crxor 6,6,6", operands);
9929 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9930 output_asm_insn ("creqv 6,6,6", operands);
9934 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
9935 (set_attr "length" "4,4,8,8")])
9937 (define_insn_and_split "*call_nonlocal_sysv<mode>"
9938 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9939 (match_operand 1 "" "g,g"))
9940 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9941 (clobber (reg:SI LR_REGNO))]
9942 "(DEFAULT_ABI == ABI_DARWIN
9943 || (DEFAULT_ABI == ABI_V4
9944 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
9946 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9947 output_asm_insn ("crxor 6,6,6", operands);
9949 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9950 output_asm_insn ("creqv 6,6,6", operands);
9953 return output_call(insn, operands, 0, 2);
9955 if (DEFAULT_ABI == ABI_V4 && flag_pic)
9957 gcc_assert (!TARGET_SECURE_PLT);
9958 return "bl %z0@plt";
9964 "DEFAULT_ABI == ABI_V4
9965 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9966 && (INTVAL (operands[2]) & CALL_LONG) == 0"
9967 [(parallel [(call (mem:SI (match_dup 0))
9971 (clobber (reg:SI LR_REGNO))])]
9973 operands[3] = pic_offset_table_rtx;
9975 [(set_attr "type" "branch,branch")
9976 (set_attr "length" "4,8")])
9978 (define_insn "*call_nonlocal_sysv_secure<mode>"
9979 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9980 (match_operand 1 "" "g,g"))
9981 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9982 (use (match_operand:SI 3 "register_operand" "r,r"))
9983 (clobber (reg:SI LR_REGNO))]
9984 "(DEFAULT_ABI == ABI_V4
9985 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9986 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
9988 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9989 output_asm_insn ("crxor 6,6,6", operands);
9991 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9992 output_asm_insn ("creqv 6,6,6", operands);
9995 /* The magic 32768 offset here and in the other sysv call insns
9996 corresponds to the offset of r30 in .got2, as given by LCTOC1.
9997 See sysv4.h:toc_section. */
9998 return "bl %z0+32768@plt";
10000 return "bl %z0@plt";
10002 [(set_attr "type" "branch,branch")
10003 (set_attr "length" "4,8")])
10005 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10006 [(set (match_operand 0 "" "")
10007 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10008 (match_operand 2 "" "g,g,g,g")))
10009 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10010 (clobber (reg:SI LR_REGNO))]
10011 "DEFAULT_ABI == ABI_V4
10012 || DEFAULT_ABI == ABI_DARWIN"
10014 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10015 output_asm_insn ("crxor 6,6,6", operands);
10017 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10018 output_asm_insn ("creqv 6,6,6", operands);
10022 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10023 (set_attr "length" "4,4,8,8")])
10025 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10026 [(set (match_operand 0 "" "")
10027 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10028 (match_operand 2 "" "g,g")))
10029 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10030 (clobber (reg:SI LR_REGNO))]
10031 "(DEFAULT_ABI == ABI_DARWIN
10032 || (DEFAULT_ABI == ABI_V4
10033 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10035 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10036 output_asm_insn ("crxor 6,6,6", operands);
10038 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10039 output_asm_insn ("creqv 6,6,6", operands);
10042 return output_call(insn, operands, 1, 3);
10044 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10046 gcc_assert (!TARGET_SECURE_PLT);
10047 return "bl %z1@plt";
10053 "DEFAULT_ABI == ABI_V4
10054 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10055 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10056 [(parallel [(set (match_dup 0)
10057 (call (mem:SI (match_dup 1))
10059 (use (match_dup 3))
10060 (use (match_dup 4))
10061 (clobber (reg:SI LR_REGNO))])]
10063 operands[4] = pic_offset_table_rtx;
10065 [(set_attr "type" "branch,branch")
10066 (set_attr "length" "4,8")])
10068 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10069 [(set (match_operand 0 "" "")
10070 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10071 (match_operand 2 "" "g,g")))
10072 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10073 (use (match_operand:SI 4 "register_operand" "r,r"))
10074 (clobber (reg:SI LR_REGNO))]
10075 "(DEFAULT_ABI == ABI_V4
10076 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10077 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10079 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10080 output_asm_insn ("crxor 6,6,6", operands);
10082 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10083 output_asm_insn ("creqv 6,6,6", operands);
10086 return "bl %z1+32768@plt";
10088 return "bl %z1@plt";
10090 [(set_attr "type" "branch,branch")
10091 (set_attr "length" "4,8")])
10094 ;; Call to AIX abi function in the same module.
10096 (define_insn "*call_local_aix<mode>"
10097 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10098 (match_operand 1 "" "g"))
10099 (clobber (reg:P LR_REGNO))]
10100 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10102 [(set_attr "type" "branch")
10103 (set_attr "length" "4")])
10105 (define_insn "*call_value_local_aix<mode>"
10106 [(set (match_operand 0 "" "")
10107 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10108 (match_operand 2 "" "g")))
10109 (clobber (reg:P LR_REGNO))]
10110 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10112 [(set_attr "type" "branch")
10113 (set_attr "length" "4")])
10115 ;; Call to AIX abi function which may be in another module.
10116 ;; Restore the TOC pointer (r2) after the call.
10118 (define_insn "*call_nonlocal_aix<mode>"
10119 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10120 (match_operand 1 "" "g"))
10121 (clobber (reg:P LR_REGNO))]
10122 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10124 [(set_attr "type" "branch")
10125 (set_attr "length" "8")])
10127 (define_insn "*call_value_nonlocal_aix<mode>"
10128 [(set (match_operand 0 "" "")
10129 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10130 (match_operand 2 "" "g")))
10131 (clobber (reg:P LR_REGNO))]
10132 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10134 [(set_attr "type" "branch")
10135 (set_attr "length" "8")])
10137 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10138 ;; Operand0 is the addresss of the function to call
10139 ;; Operand2 is the location in the function descriptor to load r2 from
10140 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10142 (define_insn "*call_indirect_aix<mode>"
10143 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10144 (match_operand 1 "" "g,g"))
10145 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10146 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10147 (clobber (reg:P LR_REGNO))]
10148 "DEFAULT_ABI == ABI_AIX"
10149 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10150 [(set_attr "type" "jmpreg")
10151 (set_attr "length" "12")])
10153 (define_insn "*call_value_indirect_aix<mode>"
10154 [(set (match_operand 0 "" "")
10155 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10156 (match_operand 2 "" "g,g")))
10157 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10158 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10159 (clobber (reg:P LR_REGNO))]
10160 "DEFAULT_ABI == ABI_AIX"
10161 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10162 [(set_attr "type" "jmpreg")
10163 (set_attr "length" "12")])
10165 ;; Call to indirect functions with the ELFv2 ABI.
10166 ;; Operand0 is the addresss of the function to call
10167 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10169 (define_insn "*call_indirect_elfv2<mode>"
10170 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10171 (match_operand 1 "" "g,g"))
10172 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10173 (clobber (reg:P LR_REGNO))]
10174 "DEFAULT_ABI == ABI_ELFv2"
10175 "b%T0l\;<ptrload> 2,%2(1)"
10176 [(set_attr "type" "jmpreg")
10177 (set_attr "length" "8")])
10179 (define_insn "*call_value_indirect_elfv2<mode>"
10180 [(set (match_operand 0 "" "")
10181 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10182 (match_operand 2 "" "g,g")))
10183 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10184 (clobber (reg:P LR_REGNO))]
10185 "DEFAULT_ABI == ABI_ELFv2"
10186 "b%T1l\;<ptrload> 2,%3(1)"
10187 [(set_attr "type" "jmpreg")
10188 (set_attr "length" "8")])
10191 ;; Call subroutine returning any type.
10192 (define_expand "untyped_call"
10193 [(parallel [(call (match_operand 0 "" "")
10195 (match_operand 1 "" "")
10196 (match_operand 2 "" "")])]
10202 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10204 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10206 rtx set = XVECEXP (operands[2], 0, i);
10207 emit_move_insn (SET_DEST (set), SET_SRC (set));
10210 /* The optimizer does not know that the call sets the function value
10211 registers we stored in the result block. We avoid problems by
10212 claiming that all hard registers are used and clobbered at this
10214 emit_insn (gen_blockage ());
10219 ;; sibling call patterns
10220 (define_expand "sibcall"
10221 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10222 (match_operand 1 "" ""))
10223 (use (match_operand 2 "" ""))
10224 (use (reg:SI LR_REGNO))
10230 if (MACHOPIC_INDIRECT)
10231 operands[0] = machopic_indirect_call_target (operands[0]);
10234 gcc_assert (GET_CODE (operands[0]) == MEM);
10235 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10237 operands[0] = XEXP (operands[0], 0);
10239 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10241 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10246 (define_expand "sibcall_value"
10247 [(parallel [(set (match_operand 0 "register_operand" "")
10248 (call (mem:SI (match_operand 1 "address_operand" ""))
10249 (match_operand 2 "" "")))
10250 (use (match_operand 3 "" ""))
10251 (use (reg:SI LR_REGNO))
10257 if (MACHOPIC_INDIRECT)
10258 operands[1] = machopic_indirect_call_target (operands[1]);
10261 gcc_assert (GET_CODE (operands[1]) == MEM);
10262 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10264 operands[1] = XEXP (operands[1], 0);
10266 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10268 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10273 ;; this and similar patterns must be marked as using LR, otherwise
10274 ;; dataflow will try to delete the store into it. This is true
10275 ;; even when the actual reg to jump to is in CTR, when LR was
10276 ;; saved and restored around the PIC-setting BCL.
10277 (define_insn "*sibcall_local32"
10278 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10279 (match_operand 1 "" "g,g"))
10280 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10281 (use (reg:SI LR_REGNO))
10283 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10286 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10287 output_asm_insn (\"crxor 6,6,6\", operands);
10289 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10290 output_asm_insn (\"creqv 6,6,6\", operands);
10292 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10294 [(set_attr "type" "branch")
10295 (set_attr "length" "4,8")])
10297 (define_insn "*sibcall_local64"
10298 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10299 (match_operand 1 "" "g,g"))
10300 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10301 (use (reg:SI LR_REGNO))
10303 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10306 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10307 output_asm_insn (\"crxor 6,6,6\", operands);
10309 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10310 output_asm_insn (\"creqv 6,6,6\", operands);
10312 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10314 [(set_attr "type" "branch")
10315 (set_attr "length" "4,8")])
10317 (define_insn "*sibcall_value_local32"
10318 [(set (match_operand 0 "" "")
10319 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10320 (match_operand 2 "" "g,g")))
10321 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10322 (use (reg:SI LR_REGNO))
10324 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10327 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10328 output_asm_insn (\"crxor 6,6,6\", operands);
10330 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10331 output_asm_insn (\"creqv 6,6,6\", operands);
10333 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10335 [(set_attr "type" "branch")
10336 (set_attr "length" "4,8")])
10338 (define_insn "*sibcall_value_local64"
10339 [(set (match_operand 0 "" "")
10340 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10341 (match_operand 2 "" "g,g")))
10342 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10343 (use (reg:SI LR_REGNO))
10345 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10348 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10349 output_asm_insn (\"crxor 6,6,6\", operands);
10351 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10352 output_asm_insn (\"creqv 6,6,6\", operands);
10354 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10356 [(set_attr "type" "branch")
10357 (set_attr "length" "4,8")])
10359 (define_insn "*sibcall_nonlocal_sysv<mode>"
10360 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10361 (match_operand 1 "" ""))
10362 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10363 (use (reg:SI LR_REGNO))
10365 "(DEFAULT_ABI == ABI_DARWIN
10366 || DEFAULT_ABI == ABI_V4)
10367 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10370 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10371 output_asm_insn (\"crxor 6,6,6\", operands);
10373 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10374 output_asm_insn (\"creqv 6,6,6\", operands);
10376 if (which_alternative >= 2)
10378 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10380 gcc_assert (!TARGET_SECURE_PLT);
10381 return \"b %z0@plt\";
10386 [(set_attr "type" "branch")
10387 (set_attr "length" "4,8,4,8")])
10389 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10390 [(set (match_operand 0 "" "")
10391 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10392 (match_operand 2 "" "")))
10393 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10394 (use (reg:SI LR_REGNO))
10396 "(DEFAULT_ABI == ABI_DARWIN
10397 || DEFAULT_ABI == ABI_V4)
10398 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10401 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10402 output_asm_insn (\"crxor 6,6,6\", operands);
10404 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10405 output_asm_insn (\"creqv 6,6,6\", operands);
10407 if (which_alternative >= 2)
10409 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10411 gcc_assert (!TARGET_SECURE_PLT);
10412 return \"b %z1@plt\";
10417 [(set_attr "type" "branch")
10418 (set_attr "length" "4,8,4,8")])
10420 ;; AIX ABI sibling call patterns.
10422 (define_insn "*sibcall_aix<mode>"
10423 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10424 (match_operand 1 "" "g,g"))
10426 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10430 [(set_attr "type" "branch")
10431 (set_attr "length" "4")])
10433 (define_insn "*sibcall_value_aix<mode>"
10434 [(set (match_operand 0 "" "")
10435 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10436 (match_operand 2 "" "g,g")))
10438 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10442 [(set_attr "type" "branch")
10443 (set_attr "length" "4")])
10445 (define_expand "sibcall_epilogue"
10446 [(use (const_int 0))]
10449 if (!TARGET_SCHED_PROLOG)
10450 emit_insn (gen_blockage ());
10451 rs6000_emit_epilogue (TRUE);
10455 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10456 ;; all of memory. This blocks insns from being moved across this point.
10458 (define_insn "blockage"
10459 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10463 (define_expand "probe_stack_address"
10464 [(use (match_operand 0 "address_operand"))]
10467 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10468 MEM_VOLATILE_P (operands[0]) = 1;
10471 emit_insn (gen_probe_stack_di (operands[0]));
10473 emit_insn (gen_probe_stack_si (operands[0]));
10477 (define_insn "probe_stack_<mode>"
10478 [(set (match_operand:P 0 "memory_operand" "=m")
10479 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10482 operands[1] = gen_rtx_REG (Pmode, 0);
10483 return "st<wd>%U0%X0 %1,%0";
10485 [(set_attr "type" "store")
10486 (set (attr "update")
10487 (if_then_else (match_operand 0 "update_address_mem")
10488 (const_string "yes")
10489 (const_string "no")))
10490 (set (attr "indexed")
10491 (if_then_else (match_operand 0 "indexed_address_mem")
10492 (const_string "yes")
10493 (const_string "no")))
10494 (set_attr "length" "4")])
10496 (define_insn "probe_stack_range<P:mode>"
10497 [(set (match_operand:P 0 "register_operand" "=r")
10498 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10499 (match_operand:P 2 "register_operand" "r")]
10500 UNSPECV_PROBE_STACK_RANGE))]
10502 "* return output_probe_stack_range (operands[0], operands[2]);"
10503 [(set_attr "type" "three")])
10505 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
10506 ;; signed & unsigned, and one type of branch.
10508 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10509 ;; insns, and branches.
10511 (define_expand "cbranch<mode>4"
10512 [(use (match_operator 0 "rs6000_cbranch_operator"
10513 [(match_operand:GPR 1 "gpc_reg_operand" "")
10514 (match_operand:GPR 2 "reg_or_short_operand" "")]))
10515 (use (match_operand 3 ""))]
10519 /* Take care of the possibility that operands[2] might be negative but
10520 this might be a logical operation. That insn doesn't exist. */
10521 if (GET_CODE (operands[2]) == CONST_INT
10522 && INTVAL (operands[2]) < 0)
10524 operands[2] = force_reg (<MODE>mode, operands[2]);
10525 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10526 GET_MODE (operands[0]),
10527 operands[1], operands[2]);
10530 rs6000_emit_cbranch (<MODE>mode, operands);
10534 (define_expand "cbranch<mode>4"
10535 [(use (match_operator 0 "rs6000_cbranch_operator"
10536 [(match_operand:FP 1 "gpc_reg_operand" "")
10537 (match_operand:FP 2 "gpc_reg_operand" "")]))
10538 (use (match_operand 3 ""))]
10542 rs6000_emit_cbranch (<MODE>mode, operands);
10546 (define_expand "cstore<mode>4_signed"
10547 [(use (match_operator 1 "signed_comparison_operator"
10548 [(match_operand:P 2 "gpc_reg_operand")
10549 (match_operand:P 3 "gpc_reg_operand")]))
10550 (clobber (match_operand:P 0 "gpc_reg_operand"))]
10553 enum rtx_code cond_code = GET_CODE (operands[1]);
10555 rtx op0 = operands[0];
10556 rtx op1 = operands[2];
10557 rtx op2 = operands[3];
10559 if (cond_code == GE || cond_code == LT)
10561 cond_code = swap_condition (cond_code);
10562 std::swap (op1, op2);
10565 rtx tmp1 = gen_reg_rtx (<MODE>mode);
10566 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10567 rtx tmp3 = gen_reg_rtx (<MODE>mode);
10569 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10570 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10571 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10573 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10575 if (cond_code == LE)
10576 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
10579 rtx tmp4 = gen_reg_rtx (<MODE>mode);
10580 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
10581 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
10587 (define_expand "cstore<mode>4_unsigned"
10588 [(use (match_operator 1 "unsigned_comparison_operator"
10589 [(match_operand:P 2 "gpc_reg_operand")
10590 (match_operand:P 3 "reg_or_short_operand")]))
10591 (clobber (match_operand:P 0 "gpc_reg_operand"))]
10594 enum rtx_code cond_code = GET_CODE (operands[1]);
10596 rtx op0 = operands[0];
10597 rtx op1 = operands[2];
10598 rtx op2 = operands[3];
10600 if (cond_code == GEU || cond_code == LTU)
10602 cond_code = swap_condition (cond_code);
10603 std::swap (op1, op2);
10606 if (!gpc_reg_operand (op1, <MODE>mode))
10607 op1 = force_reg (<MODE>mode, op1);
10608 if (!reg_or_short_operand (op2, <MODE>mode))
10609 op2 = force_reg (<MODE>mode, op2);
10611 rtx tmp = gen_reg_rtx (<MODE>mode);
10612 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10614 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10615 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10617 if (cond_code == LEU)
10618 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10620 emit_insn (gen_neg<mode>2 (op0, tmp2));
10625 (define_expand "cstore_si_as_di"
10626 [(use (match_operator 1 "unsigned_comparison_operator"
10627 [(match_operand:SI 2 "gpc_reg_operand")
10628 (match_operand:SI 3 "reg_or_short_operand")]))
10629 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10632 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10633 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10635 operands[2] = force_reg (SImode, operands[2]);
10636 operands[3] = force_reg (SImode, operands[3]);
10637 rtx op1 = gen_reg_rtx (DImode);
10638 rtx op2 = gen_reg_rtx (DImode);
10639 convert_move (op1, operands[2], uns_flag);
10640 convert_move (op2, operands[3], uns_flag);
10642 if (cond_code == GT || cond_code == LE)
10644 cond_code = swap_condition (cond_code);
10645 std::swap (op1, op2);
10648 rtx tmp = gen_reg_rtx (DImode);
10649 rtx tmp2 = gen_reg_rtx (DImode);
10650 emit_insn (gen_subdi3 (tmp, op1, op2));
10651 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
10657 gcc_unreachable ();
10662 tmp3 = gen_reg_rtx (DImode);
10663 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
10667 convert_move (operands[0], tmp3, 1);
10672 (define_expand "cstore<mode>4_signed_imm"
10673 [(use (match_operator 1 "signed_comparison_operator"
10674 [(match_operand:GPR 2 "gpc_reg_operand")
10675 (match_operand:GPR 3 "immediate_operand")]))
10676 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10679 bool invert = false;
10681 enum rtx_code cond_code = GET_CODE (operands[1]);
10683 rtx op0 = operands[0];
10684 rtx op1 = operands[2];
10685 HOST_WIDE_INT val = INTVAL (operands[3]);
10687 if (cond_code == GE || cond_code == GT)
10689 cond_code = reverse_condition (cond_code);
10693 if (cond_code == LE)
10696 rtx tmp = gen_reg_rtx (<MODE>mode);
10697 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10698 rtx x = gen_reg_rtx (<MODE>mode);
10700 emit_insn (gen_and<mode>3 (x, op1, tmp));
10702 emit_insn (gen_ior<mode>3 (x, op1, tmp));
10706 rtx tmp = gen_reg_rtx (<MODE>mode);
10707 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10711 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10712 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10717 (define_expand "cstore<mode>4_unsigned_imm"
10718 [(use (match_operator 1 "unsigned_comparison_operator"
10719 [(match_operand:GPR 2 "gpc_reg_operand")
10720 (match_operand:GPR 3 "immediate_operand")]))
10721 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10724 bool invert = false;
10726 enum rtx_code cond_code = GET_CODE (operands[1]);
10728 rtx op0 = operands[0];
10729 rtx op1 = operands[2];
10730 HOST_WIDE_INT val = INTVAL (operands[3]);
10732 if (cond_code == GEU || cond_code == GTU)
10734 cond_code = reverse_condition (cond_code);
10738 if (cond_code == LEU)
10741 rtx tmp = gen_reg_rtx (<MODE>mode);
10742 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10743 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10744 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
10745 rtx x = gen_reg_rtx (<MODE>mode);
10747 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
10749 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
10753 rtx tmp = gen_reg_rtx (<MODE>mode);
10754 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10758 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10759 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10764 (define_expand "cstore<mode>4"
10765 [(use (match_operator 1 "rs6000_cbranch_operator"
10766 [(match_operand:GPR 2 "gpc_reg_operand")
10767 (match_operand:GPR 3 "reg_or_short_operand")]))
10768 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10771 /* Use ISEL if the user asked for it. */
10773 rs6000_emit_sISEL (<MODE>mode, operands);
10775 /* Expanding EQ and NE directly to some machine instructions does not help
10776 but does hurt combine. So don't. */
10777 else if (GET_CODE (operands[1]) == EQ)
10778 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
10779 else if (<MODE>mode == Pmode
10780 && GET_CODE (operands[1]) == NE)
10781 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
10782 else if (GET_CODE (operands[1]) == NE)
10784 rtx tmp = gen_reg_rtx (<MODE>mode);
10785 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
10786 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
10789 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
10790 etc. combinations magically work out just right. */
10791 else if (<MODE>mode == Pmode
10792 && unsigned_comparison_operator (operands[1], VOIDmode))
10793 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
10794 operands[2], operands[3]));
10796 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
10797 else if (<MODE>mode == SImode && Pmode == DImode)
10798 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
10799 operands[2], operands[3]));
10801 /* For signed comparisons against a constant, we can do some simple
10803 else if (signed_comparison_operator (operands[1], VOIDmode)
10804 && CONST_INT_P (operands[3]))
10805 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
10806 operands[2], operands[3]));
10808 /* And similarly for unsigned comparisons. */
10809 else if (unsigned_comparison_operator (operands[1], VOIDmode)
10810 && CONST_INT_P (operands[3]))
10811 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
10812 operands[2], operands[3]));
10814 /* We also do not want to use mfcr for signed comparisons. */
10815 else if (<MODE>mode == Pmode
10816 && signed_comparison_operator (operands[1], VOIDmode))
10817 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
10818 operands[2], operands[3]));
10820 /* Everything else, use the mfcr brute force. */
10822 rs6000_emit_sCOND (<MODE>mode, operands);
10827 (define_expand "cstore<mode>4"
10828 [(use (match_operator 1 "rs6000_cbranch_operator"
10829 [(match_operand:FP 2 "gpc_reg_operand")
10830 (match_operand:FP 3 "gpc_reg_operand")]))
10831 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10834 rs6000_emit_sCOND (<MODE>mode, operands);
10839 (define_expand "stack_protect_set"
10840 [(match_operand 0 "memory_operand" "")
10841 (match_operand 1 "memory_operand" "")]
10844 #ifdef TARGET_THREAD_SSP_OFFSET
10845 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10846 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10847 operands[1] = gen_rtx_MEM (Pmode, addr);
10850 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10852 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10856 (define_insn "stack_protect_setsi"
10857 [(set (match_operand:SI 0 "memory_operand" "=m")
10858 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
10859 (set (match_scratch:SI 2 "=&r") (const_int 0))]
10861 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
10862 [(set_attr "type" "three")
10863 (set_attr "length" "12")])
10865 (define_insn "stack_protect_setdi"
10866 [(set (match_operand:DI 0 "memory_operand" "=Y")
10867 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
10868 (set (match_scratch:DI 2 "=&r") (const_int 0))]
10870 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
10871 [(set_attr "type" "three")
10872 (set_attr "length" "12")])
10874 (define_expand "stack_protect_test"
10875 [(match_operand 0 "memory_operand" "")
10876 (match_operand 1 "memory_operand" "")
10877 (match_operand 2 "" "")]
10880 rtx test, op0, op1;
10881 #ifdef TARGET_THREAD_SSP_OFFSET
10882 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10883 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10884 operands[1] = gen_rtx_MEM (Pmode, addr);
10887 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
10888 test = gen_rtx_EQ (VOIDmode, op0, op1);
10889 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
10893 (define_insn "stack_protect_testsi"
10894 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10895 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
10896 (match_operand:SI 2 "memory_operand" "m,m")]
10898 (set (match_scratch:SI 4 "=r,r") (const_int 0))
10899 (clobber (match_scratch:SI 3 "=&r,&r"))]
10902 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10903 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
10904 [(set_attr "length" "16,20")])
10906 (define_insn "stack_protect_testdi"
10907 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10908 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
10909 (match_operand:DI 2 "memory_operand" "Y,Y")]
10911 (set (match_scratch:DI 4 "=r,r") (const_int 0))
10912 (clobber (match_scratch:DI 3 "=&r,&r"))]
10915 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10916 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
10917 [(set_attr "length" "16,20")])
10920 ;; Here are the actual compare insns.
10921 (define_insn "*cmp<mode>_signed"
10922 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
10923 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
10924 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
10926 "cmp<wd>%I2 %0,%1,%2"
10927 [(set_attr "type" "cmp")])
10929 (define_insn "*cmp<mode>_unsigned"
10930 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
10931 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
10932 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
10934 "cmpl<wd>%I2 %0,%1,%2"
10935 [(set_attr "type" "cmp")])
10937 ;; If we are comparing a register for equality with a large constant,
10938 ;; we can do this with an XOR followed by a compare. But this is profitable
10939 ;; only if the large constant is only used for the comparison (and in this
10940 ;; case we already have a register to reuse as scratch).
10942 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
10943 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
10946 [(set (match_operand:SI 0 "register_operand")
10947 (match_operand:SI 1 "logical_const_operand" ""))
10948 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
10950 (match_operand:SI 2 "logical_const_operand" "")]))
10951 (set (match_operand:CC 4 "cc_reg_operand" "")
10952 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
10955 (if_then_else (match_operator 6 "equality_operator"
10956 [(match_dup 4) (const_int 0)])
10957 (match_operand 7 "" "")
10958 (match_operand 8 "" "")))]
10959 "peep2_reg_dead_p (3, operands[0])
10960 && peep2_reg_dead_p (4, operands[4])
10961 && REGNO (operands[0]) != REGNO (operands[5])"
10962 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
10963 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
10964 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
10967 /* Get the constant we are comparing against, and see what it looks like
10968 when sign-extended from 16 to 32 bits. Then see what constant we could
10969 XOR with SEXTC to get the sign-extended value. */
10970 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
10972 operands[1], operands[2]);
10973 HOST_WIDE_INT c = INTVAL (cnst);
10974 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
10975 HOST_WIDE_INT xorv = c ^ sextc;
10977 operands[9] = GEN_INT (xorv);
10978 operands[10] = GEN_INT (sextc);
10981 ;; The following two insns don't exist as single insns, but if we provide
10982 ;; them, we can swap an add and compare, which will enable us to overlap more
10983 ;; of the required delay between a compare and branch. We generate code for
10984 ;; them by splitting.
10987 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
10988 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
10989 (match_operand:SI 2 "short_cint_operand" "i")))
10990 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
10991 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
10994 [(set_attr "length" "8")])
10997 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
10998 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
10999 (match_operand:SI 2 "u_short_cint_operand" "i")))
11000 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11001 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11004 [(set_attr "length" "8")])
11007 [(set (match_operand:CC 3 "cc_reg_operand" "")
11008 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11009 (match_operand:SI 2 "short_cint_operand" "")))
11010 (set (match_operand:SI 0 "gpc_reg_operand" "")
11011 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11013 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11014 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11017 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11018 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11019 (match_operand:SI 2 "u_short_cint_operand" "")))
11020 (set (match_operand:SI 0 "gpc_reg_operand" "")
11021 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11023 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11024 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11026 ;; Only need to compare second words if first words equal
11027 (define_insn "*cmp<mode>_internal1"
11028 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11029 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11030 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11031 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11032 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11033 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11034 [(set_attr "type" "fpcompare")
11035 (set_attr "length" "12")])
11037 (define_insn_and_split "*cmp<mode>_internal2"
11038 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11039 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11040 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11041 (clobber (match_scratch:DF 3 "=d"))
11042 (clobber (match_scratch:DF 4 "=d"))
11043 (clobber (match_scratch:DF 5 "=d"))
11044 (clobber (match_scratch:DF 6 "=d"))
11045 (clobber (match_scratch:DF 7 "=d"))
11046 (clobber (match_scratch:DF 8 "=d"))
11047 (clobber (match_scratch:DF 9 "=d"))
11048 (clobber (match_scratch:DF 10 "=d"))
11049 (clobber (match_scratch:GPR 11 "=b"))]
11050 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11051 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11053 "&& reload_completed"
11054 [(set (match_dup 3) (match_dup 14))
11055 (set (match_dup 4) (match_dup 15))
11056 (set (match_dup 9) (abs:DF (match_dup 5)))
11057 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11058 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11059 (label_ref (match_dup 12))
11061 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11062 (set (pc) (label_ref (match_dup 13)))
11064 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11065 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11066 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11067 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11070 REAL_VALUE_TYPE rv;
11071 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11072 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11074 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11075 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11076 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11077 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11078 operands[12] = gen_label_rtx ();
11079 operands[13] = gen_label_rtx ();
11081 operands[14] = force_const_mem (DFmode,
11082 const_double_from_real_value (rv, DFmode));
11083 operands[15] = force_const_mem (DFmode,
11084 const_double_from_real_value (dconst0,
11089 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11090 operands[14] = gen_const_mem (DFmode, tocref);
11091 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11092 operands[15] = gen_const_mem (DFmode, tocref);
11093 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11094 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11098 ;; Now we have the scc insns. We can do some combinations because of the
11099 ;; way the machine works.
11101 ;; Note that this is probably faster if we can put an insn between the
11102 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11103 ;; cases the insns below which don't use an intermediate CR field will
11104 ;; be used instead.
11106 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11107 (match_operator:SI 1 "scc_comparison_operator"
11108 [(match_operand 2 "cc_reg_operand" "y")
11111 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11112 [(set (attr "type")
11113 (cond [(match_test "TARGET_MFCRF")
11114 (const_string "mfcrf")
11116 (const_string "mfcr")))
11117 (set_attr "length" "8")])
11119 ;; Same as above, but get the GT bit.
11120 (define_insn "move_from_CR_gt_bit"
11121 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11122 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11123 "TARGET_HARD_FLOAT && !TARGET_FPRS"
11124 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11125 [(set_attr "type" "mfcr")
11126 (set_attr "length" "8")])
11128 ;; Same as above, but get the OV/ORDERED bit.
11129 (define_insn "move_from_CR_ov_bit"
11130 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11131 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11134 "mfcr %0\;rlwinm %0,%0,%t1,1"
11135 [(set_attr "type" "mfcr")
11136 (set_attr "length" "8")])
11139 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11140 (match_operator:DI 1 "scc_comparison_operator"
11141 [(match_operand 2 "cc_reg_operand" "y")
11144 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11145 [(set (attr "type")
11146 (cond [(match_test "TARGET_MFCRF")
11147 (const_string "mfcrf")
11149 (const_string "mfcr")))
11150 (set_attr "length" "8")])
11153 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11154 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11155 [(match_operand 2 "cc_reg_operand" "y,y")
11158 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11159 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11162 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11164 [(set_attr "type" "shift")
11165 (set_attr "dot" "yes")
11166 (set_attr "length" "8,16")])
11169 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11170 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11171 [(match_operand 2 "cc_reg_operand" "")
11174 (set (match_operand:SI 3 "gpc_reg_operand" "")
11175 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11176 "TARGET_32BIT && reload_completed"
11177 [(set (match_dup 3)
11178 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11180 (compare:CC (match_dup 3)
11185 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11186 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11187 [(match_operand 2 "cc_reg_operand" "y")
11189 (match_operand:SI 3 "const_int_operand" "n")))]
11193 int is_bit = ccr_bit (operands[1], 1);
11194 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11197 if (is_bit >= put_bit)
11198 count = is_bit - put_bit;
11200 count = 32 - (put_bit - is_bit);
11202 operands[4] = GEN_INT (count);
11203 operands[5] = GEN_INT (put_bit);
11205 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11207 [(set (attr "type")
11208 (cond [(match_test "TARGET_MFCRF")
11209 (const_string "mfcrf")
11211 (const_string "mfcr")))
11212 (set_attr "length" "8")])
11215 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11217 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11218 [(match_operand 2 "cc_reg_operand" "y,y")
11220 (match_operand:SI 3 "const_int_operand" "n,n"))
11222 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11223 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11228 int is_bit = ccr_bit (operands[1], 1);
11229 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11232 /* Force split for non-cc0 compare. */
11233 if (which_alternative == 1)
11236 if (is_bit >= put_bit)
11237 count = is_bit - put_bit;
11239 count = 32 - (put_bit - is_bit);
11241 operands[5] = GEN_INT (count);
11242 operands[6] = GEN_INT (put_bit);
11244 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11246 [(set_attr "type" "shift")
11247 (set_attr "dot" "yes")
11248 (set_attr "length" "8,16")])
11251 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11253 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11254 [(match_operand 2 "cc_reg_operand" "")
11256 (match_operand:SI 3 "const_int_operand" ""))
11258 (set (match_operand:SI 4 "gpc_reg_operand" "")
11259 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11262 [(set (match_dup 4)
11263 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11266 (compare:CC (match_dup 4)
11270 ;; There is a 3 cycle delay between consecutive mfcr instructions
11271 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
11274 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11275 (match_operator:SI 1 "scc_comparison_operator"
11276 [(match_operand 2 "cc_reg_operand" "y")
11278 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
11279 (match_operator:SI 4 "scc_comparison_operator"
11280 [(match_operand 5 "cc_reg_operand" "y")
11282 "REGNO (operands[2]) != REGNO (operands[5])"
11283 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11284 [(set_attr "type" "mfcr")
11285 (set_attr "length" "12")])
11288 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11289 (match_operator:DI 1 "scc_comparison_operator"
11290 [(match_operand 2 "cc_reg_operand" "y")
11292 (set (match_operand:DI 3 "gpc_reg_operand" "=r")
11293 (match_operator:DI 4 "scc_comparison_operator"
11294 [(match_operand 5 "cc_reg_operand" "y")
11296 "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
11297 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11298 [(set_attr "type" "mfcr")
11299 (set_attr "length" "12")])
11302 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11305 (define_insn_and_split "eq<mode>3"
11306 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11307 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11308 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11309 (clobber (match_scratch:GPR 3 "=r"))
11310 (clobber (match_scratch:GPR 4 "=r"))]
11314 [(set (match_dup 4)
11315 (clz:GPR (match_dup 3)))
11317 (lshiftrt:GPR (match_dup 4)
11320 operands[3] = rs6000_emit_eqne (<MODE>mode,
11321 operands[1], operands[2], operands[3]);
11323 if (GET_CODE (operands[4]) == SCRATCH)
11324 operands[4] = gen_reg_rtx (<MODE>mode);
11326 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11328 [(set (attr "length")
11329 (if_then_else (match_test "operands[2] == const0_rtx")
11331 (const_string "12")))])
11333 (define_insn_and_split "ne<mode>3"
11334 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11335 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11336 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11337 (clobber (match_scratch:P 3 "=r"))
11338 (clobber (match_scratch:P 4 "=r"))
11339 (clobber (reg:P CA_REGNO))]
11343 [(parallel [(set (match_dup 4)
11344 (plus:P (match_dup 3)
11346 (set (reg:P CA_REGNO)
11347 (ne:P (match_dup 3)
11349 (parallel [(set (match_dup 0)
11350 (plus:P (plus:P (not:P (match_dup 4))
11353 (clobber (reg:P CA_REGNO))])]
11355 operands[3] = rs6000_emit_eqne (<MODE>mode,
11356 operands[1], operands[2], operands[3]);
11358 if (GET_CODE (operands[4]) == SCRATCH)
11359 operands[4] = gen_reg_rtx (<MODE>mode);
11361 [(set (attr "length")
11362 (if_then_else (match_test "operands[2] == const0_rtx")
11364 (const_string "12")))])
11366 (define_insn_and_split "*neg_eq_<mode>"
11367 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11368 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11369 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11370 (clobber (match_scratch:P 3 "=r"))
11371 (clobber (match_scratch:P 4 "=r"))
11372 (clobber (reg:P CA_REGNO))]
11376 [(parallel [(set (match_dup 4)
11377 (plus:P (match_dup 3)
11379 (set (reg:P CA_REGNO)
11380 (ne:P (match_dup 3)
11382 (parallel [(set (match_dup 0)
11383 (plus:P (reg:P CA_REGNO)
11385 (clobber (reg:P CA_REGNO))])]
11387 operands[3] = rs6000_emit_eqne (<MODE>mode,
11388 operands[1], operands[2], operands[3]);
11390 if (GET_CODE (operands[4]) == SCRATCH)
11391 operands[4] = gen_reg_rtx (<MODE>mode);
11393 [(set (attr "length")
11394 (if_then_else (match_test "operands[2] == const0_rtx")
11396 (const_string "12")))])
11398 (define_insn_and_split "*neg_ne_<mode>"
11399 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11400 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11401 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11402 (clobber (match_scratch:P 3 "=r"))
11403 (clobber (match_scratch:P 4 "=r"))
11404 (clobber (reg:P CA_REGNO))]
11408 [(parallel [(set (match_dup 4)
11409 (neg:P (match_dup 3)))
11410 (set (reg:P CA_REGNO)
11411 (eq:P (match_dup 3)
11413 (parallel [(set (match_dup 0)
11414 (plus:P (reg:P CA_REGNO)
11416 (clobber (reg:P CA_REGNO))])]
11418 operands[3] = rs6000_emit_eqne (<MODE>mode,
11419 operands[1], operands[2], operands[3]);
11421 if (GET_CODE (operands[4]) == SCRATCH)
11422 operands[4] = gen_reg_rtx (<MODE>mode);
11424 [(set (attr "length")
11425 (if_then_else (match_test "operands[2] == const0_rtx")
11427 (const_string "12")))])
11429 (define_insn_and_split "*plus_eq_<mode>"
11430 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11431 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11432 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11433 (match_operand:P 3 "gpc_reg_operand" "r")))
11434 (clobber (match_scratch:P 4 "=r"))
11435 (clobber (match_scratch:P 5 "=r"))
11436 (clobber (reg:P CA_REGNO))]
11440 [(parallel [(set (match_dup 5)
11441 (neg:P (match_dup 4)))
11442 (set (reg:P CA_REGNO)
11443 (eq:P (match_dup 4)
11445 (parallel [(set (match_dup 0)
11446 (plus:P (match_dup 3)
11448 (clobber (reg:P CA_REGNO))])]
11450 operands[4] = rs6000_emit_eqne (<MODE>mode,
11451 operands[1], operands[2], operands[4]);
11453 if (GET_CODE (operands[5]) == SCRATCH)
11454 operands[5] = gen_reg_rtx (<MODE>mode);
11456 [(set (attr "length")
11457 (if_then_else (match_test "operands[2] == const0_rtx")
11459 (const_string "12")))])
11461 (define_insn_and_split "*plus_ne_<mode>"
11462 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11463 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11464 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11465 (match_operand:P 3 "gpc_reg_operand" "r")))
11466 (clobber (match_scratch:P 4 "=r"))
11467 (clobber (match_scratch:P 5 "=r"))
11468 (clobber (reg:P CA_REGNO))]
11472 [(parallel [(set (match_dup 5)
11473 (plus:P (match_dup 4)
11475 (set (reg:P CA_REGNO)
11476 (ne:P (match_dup 4)
11478 (parallel [(set (match_dup 0)
11479 (plus:P (match_dup 3)
11481 (clobber (reg:P CA_REGNO))])]
11483 operands[4] = rs6000_emit_eqne (<MODE>mode,
11484 operands[1], operands[2], operands[4]);
11486 if (GET_CODE (operands[5]) == SCRATCH)
11487 operands[5] = gen_reg_rtx (<MODE>mode);
11489 [(set (attr "length")
11490 (if_then_else (match_test "operands[2] == const0_rtx")
11492 (const_string "12")))])
11494 (define_insn_and_split "*minus_eq_<mode>"
11495 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11496 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11497 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11498 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11499 (clobber (match_scratch:P 4 "=r"))
11500 (clobber (match_scratch:P 5 "=r"))
11501 (clobber (reg:P CA_REGNO))]
11505 [(parallel [(set (match_dup 5)
11506 (plus:P (match_dup 4)
11508 (set (reg:P CA_REGNO)
11509 (ne:P (match_dup 4)
11511 (parallel [(set (match_dup 0)
11512 (plus:P (plus:P (match_dup 3)
11515 (clobber (reg:P CA_REGNO))])]
11517 operands[4] = rs6000_emit_eqne (<MODE>mode,
11518 operands[1], operands[2], operands[4]);
11520 if (GET_CODE (operands[5]) == SCRATCH)
11521 operands[5] = gen_reg_rtx (<MODE>mode);
11523 [(set (attr "length")
11524 (if_then_else (match_test "operands[2] == const0_rtx")
11526 (const_string "12")))])
11528 (define_insn_and_split "*minus_ne_<mode>"
11529 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11530 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11531 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11532 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11533 (clobber (match_scratch:P 4 "=r"))
11534 (clobber (match_scratch:P 5 "=r"))
11535 (clobber (reg:P CA_REGNO))]
11539 [(parallel [(set (match_dup 5)
11540 (neg:P (match_dup 4)))
11541 (set (reg:P CA_REGNO)
11542 (eq:P (match_dup 4)
11544 (parallel [(set (match_dup 0)
11545 (plus:P (plus:P (match_dup 3)
11548 (clobber (reg:P CA_REGNO))])]
11550 operands[4] = rs6000_emit_eqne (<MODE>mode,
11551 operands[1], operands[2], operands[4]);
11553 if (GET_CODE (operands[5]) == SCRATCH)
11554 operands[5] = gen_reg_rtx (<MODE>mode);
11556 [(set (attr "length")
11557 (if_then_else (match_test "operands[2] == const0_rtx")
11559 (const_string "12")))])
11561 (define_insn_and_split "*eqsi3_ext<mode>"
11562 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11563 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11564 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11565 (clobber (match_scratch:SI 3 "=r"))
11566 (clobber (match_scratch:SI 4 "=r"))]
11570 [(set (match_dup 4)
11571 (clz:SI (match_dup 3)))
11574 (lshiftrt:SI (match_dup 4)
11577 operands[3] = rs6000_emit_eqne (SImode,
11578 operands[1], operands[2], operands[3]);
11580 if (GET_CODE (operands[4]) == SCRATCH)
11581 operands[4] = gen_reg_rtx (SImode);
11583 [(set (attr "length")
11584 (if_then_else (match_test "operands[2] == const0_rtx")
11586 (const_string "12")))])
11588 (define_insn_and_split "*nesi3_ext<mode>"
11589 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11590 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11591 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11592 (clobber (match_scratch:SI 3 "=r"))
11593 (clobber (match_scratch:SI 4 "=r"))
11594 (clobber (match_scratch:EXTSI 5 "=r"))]
11598 [(set (match_dup 4)
11599 (clz:SI (match_dup 3)))
11602 (lshiftrt:SI (match_dup 4)
11605 (xor:EXTSI (match_dup 5)
11608 operands[3] = rs6000_emit_eqne (SImode,
11609 operands[1], operands[2], operands[3]);
11611 if (GET_CODE (operands[4]) == SCRATCH)
11612 operands[4] = gen_reg_rtx (SImode);
11613 if (GET_CODE (operands[5]) == SCRATCH)
11614 operands[5] = gen_reg_rtx (<MODE>mode);
11616 [(set (attr "length")
11617 (if_then_else (match_test "operands[2] == const0_rtx")
11618 (const_string "12")
11619 (const_string "16")))])
11621 ;; Define both directions of branch and return. If we need a reload
11622 ;; register, we'd rather use CR0 since it is much easier to copy a
11623 ;; register CC value to there.
11627 (if_then_else (match_operator 1 "branch_comparison_operator"
11629 "cc_reg_operand" "y")
11631 (label_ref (match_operand 0 "" ""))
11636 return output_cbranch (operands[1], \"%l0\", 0, insn);
11638 [(set_attr "type" "branch")])
11642 (if_then_else (match_operator 0 "branch_comparison_operator"
11644 "cc_reg_operand" "y")
11651 return output_cbranch (operands[0], NULL, 0, insn);
11653 [(set_attr "type" "jmpreg")
11654 (set_attr "length" "4")])
11658 (if_then_else (match_operator 1 "branch_comparison_operator"
11660 "cc_reg_operand" "y")
11663 (label_ref (match_operand 0 "" ""))))]
11667 return output_cbranch (operands[1], \"%l0\", 1, insn);
11669 [(set_attr "type" "branch")])
11673 (if_then_else (match_operator 0 "branch_comparison_operator"
11675 "cc_reg_operand" "y")
11682 return output_cbranch (operands[0], NULL, 1, insn);
11684 [(set_attr "type" "jmpreg")
11685 (set_attr "length" "4")])
11687 ;; Logic on condition register values.
11689 ; This pattern matches things like
11690 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11691 ; (eq:SI (reg:CCFP 68) (const_int 0)))
11693 ; which are generated by the branch logic.
11694 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11696 (define_insn "*cceq_ior_compare"
11697 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11698 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11699 [(match_operator:SI 2
11700 "branch_positive_comparison_operator"
11702 "cc_reg_operand" "y,y")
11704 (match_operator:SI 4
11705 "branch_positive_comparison_operator"
11707 "cc_reg_operand" "0,y")
11711 "cr%q1 %E0,%j2,%j4"
11712 [(set_attr "type" "cr_logical,delayed_cr")])
11714 ; Why is the constant -1 here, but 1 in the previous pattern?
11715 ; Because ~1 has all but the low bit set.
11717 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11718 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11719 [(not:SI (match_operator:SI 2
11720 "branch_positive_comparison_operator"
11722 "cc_reg_operand" "y,y")
11724 (match_operator:SI 4
11725 "branch_positive_comparison_operator"
11727 "cc_reg_operand" "0,y")
11731 "cr%q1 %E0,%j2,%j4"
11732 [(set_attr "type" "cr_logical,delayed_cr")])
11734 (define_insn "*cceq_rev_compare"
11735 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11736 (compare:CCEQ (match_operator:SI 1
11737 "branch_positive_comparison_operator"
11739 "cc_reg_operand" "0,y")
11744 [(set_attr "type" "cr_logical,delayed_cr")])
11746 ;; If we are comparing the result of two comparisons, this can be done
11747 ;; using creqv or crxor.
11749 (define_insn_and_split ""
11750 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
11751 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
11752 [(match_operand 2 "cc_reg_operand" "y")
11754 (match_operator 3 "branch_comparison_operator"
11755 [(match_operand 4 "cc_reg_operand" "y")
11760 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
11764 int positive_1, positive_2;
11766 positive_1 = branch_positive_comparison_operator (operands[1],
11767 GET_MODE (operands[1]));
11768 positive_2 = branch_positive_comparison_operator (operands[3],
11769 GET_MODE (operands[3]));
11772 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
11773 GET_CODE (operands[1])),
11775 operands[2], const0_rtx);
11776 else if (GET_MODE (operands[1]) != SImode)
11777 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
11778 operands[2], const0_rtx);
11781 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
11782 GET_CODE (operands[3])),
11784 operands[4], const0_rtx);
11785 else if (GET_MODE (operands[3]) != SImode)
11786 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
11787 operands[4], const0_rtx);
11789 if (positive_1 == positive_2)
11791 operands[1] = gen_rtx_NOT (SImode, operands[1]);
11792 operands[5] = constm1_rtx;
11796 operands[5] = const1_rtx;
11800 ;; Unconditional branch and return.
11802 (define_insn "jump"
11804 (label_ref (match_operand 0 "" "")))]
11807 [(set_attr "type" "branch")])
11809 (define_insn "<return_str>return"
11813 [(set_attr "type" "jmpreg")])
11815 (define_expand "indirect_jump"
11816 [(set (pc) (match_operand 0 "register_operand" ""))])
11818 (define_insn "*indirect_jump<mode>"
11819 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
11824 [(set_attr "type" "jmpreg")])
11826 ;; Table jump for switch statements:
11827 (define_expand "tablejump"
11828 [(use (match_operand 0 "" ""))
11829 (use (label_ref (match_operand 1 "" "")))]
11834 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
11836 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
11840 (define_expand "tablejumpsi"
11841 [(set (match_dup 3)
11842 (plus:SI (match_operand:SI 0 "" "")
11844 (parallel [(set (pc) (match_dup 3))
11845 (use (label_ref (match_operand 1 "" "")))])]
11848 { operands[0] = force_reg (SImode, operands[0]);
11849 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
11850 operands[3] = gen_reg_rtx (SImode);
11853 (define_expand "tablejumpdi"
11854 [(set (match_dup 4)
11855 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
11857 (plus:DI (match_dup 4)
11859 (parallel [(set (pc) (match_dup 3))
11860 (use (label_ref (match_operand 1 "" "")))])]
11863 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
11864 operands[3] = gen_reg_rtx (DImode);
11865 operands[4] = gen_reg_rtx (DImode);
11868 (define_insn "*tablejump<mode>_internal1"
11870 (match_operand:P 0 "register_operand" "c,*l"))
11871 (use (label_ref (match_operand 1 "" "")))]
11876 [(set_attr "type" "jmpreg")])
11879 [(unspec [(const_int 0)] UNSPEC_NOP)]
11883 (define_insn "group_ending_nop"
11884 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
11888 if (rs6000_cpu_attr == CPU_POWER6)
11889 return \"ori 1,1,0\";
11890 return \"ori 2,2,0\";
11893 ;; Define the subtract-one-and-jump insns, starting with the template
11894 ;; so loop.c knows what to generate.
11896 (define_expand "doloop_end"
11897 [(use (match_operand 0 "" "")) ; loop pseudo
11898 (use (match_operand 1 "" ""))] ; label
11904 if (GET_MODE (operands[0]) != DImode)
11906 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
11910 if (GET_MODE (operands[0]) != SImode)
11912 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
11917 (define_expand "ctr<mode>"
11918 [(parallel [(set (pc)
11919 (if_then_else (ne (match_operand:P 0 "register_operand" "")
11921 (label_ref (match_operand 1 "" ""))
11924 (plus:P (match_dup 0)
11926 (clobber (match_scratch:CC 2 ""))
11927 (clobber (match_scratch:P 3 ""))])]
11931 ;; We need to be able to do this for any operand, including MEM, or we
11932 ;; will cause reload to blow up since we don't allow output reloads on
11934 ;; For the length attribute to be calculated correctly, the
11935 ;; label MUST be operand 0.
11937 (define_insn "*ctr<mode>_internal1"
11939 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11941 (label_ref (match_operand 0 "" ""))
11943 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11944 (plus:P (match_dup 1)
11946 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11947 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11951 if (which_alternative != 0)
11953 else if (get_attr_length (insn) == 4)
11954 return \"bdnz %l0\";
11956 return \"bdz $+8\;b %l0\";
11958 [(set_attr "type" "branch")
11959 (set_attr "length" "*,16,20,20")])
11961 (define_insn "*ctr<mode>_internal2"
11963 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11966 (label_ref (match_operand 0 "" ""))))
11967 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11968 (plus:P (match_dup 1)
11970 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11971 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11975 if (which_alternative != 0)
11977 else if (get_attr_length (insn) == 4)
11978 return \"bdz %l0\";
11980 return \"bdnz $+8\;b %l0\";
11982 [(set_attr "type" "branch")
11983 (set_attr "length" "*,16,20,20")])
11985 ;; Similar but use EQ
11987 (define_insn "*ctr<mode>_internal5"
11989 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11991 (label_ref (match_operand 0 "" ""))
11993 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11994 (plus:P (match_dup 1)
11996 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11997 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12001 if (which_alternative != 0)
12003 else if (get_attr_length (insn) == 4)
12004 return \"bdz %l0\";
12006 return \"bdnz $+8\;b %l0\";
12008 [(set_attr "type" "branch")
12009 (set_attr "length" "*,16,20,20")])
12011 (define_insn "*ctr<mode>_internal6"
12013 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12016 (label_ref (match_operand 0 "" ""))))
12017 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
12018 (plus:P (match_dup 1)
12020 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12021 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12025 if (which_alternative != 0)
12027 else if (get_attr_length (insn) == 4)
12028 return \"bdnz %l0\";
12030 return \"bdz $+8\;b %l0\";
12032 [(set_attr "type" "branch")
12033 (set_attr "length" "*,16,20,20")])
12035 ;; Now the splitters if we could not allocate the CTR register
12039 (if_then_else (match_operator 2 "comparison_operator"
12040 [(match_operand:P 1 "gpc_reg_operand" "")
12042 (match_operand 5 "" "")
12043 (match_operand 6 "" "")))
12044 (set (match_operand:P 0 "gpc_reg_operand" "")
12045 (plus:P (match_dup 1) (const_int -1)))
12046 (clobber (match_scratch:CC 3 ""))
12047 (clobber (match_scratch:P 4 ""))]
12049 [(set (match_dup 3)
12050 (compare:CC (match_dup 1)
12053 (plus:P (match_dup 1)
12055 (set (pc) (if_then_else (match_dup 7)
12059 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12060 operands[3], const0_rtx); }")
12064 (if_then_else (match_operator 2 "comparison_operator"
12065 [(match_operand:P 1 "gpc_reg_operand" "")
12067 (match_operand 5 "" "")
12068 (match_operand 6 "" "")))
12069 (set (match_operand:P 0 "nonimmediate_operand" "")
12070 (plus:P (match_dup 1) (const_int -1)))
12071 (clobber (match_scratch:CC 3 ""))
12072 (clobber (match_scratch:P 4 ""))]
12073 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12074 [(set (match_dup 3)
12075 (compare:CC (match_dup 1)
12078 (plus:P (match_dup 1)
12082 (set (pc) (if_then_else (match_dup 7)
12086 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12087 operands[3], const0_rtx); }")
12089 (define_insn "trap"
12090 [(trap_if (const_int 1) (const_int 0))]
12093 [(set_attr "type" "trap")])
12095 (define_expand "ctrap<mode>4"
12096 [(trap_if (match_operator 0 "ordered_comparison_operator"
12097 [(match_operand:GPR 1 "register_operand")
12098 (match_operand:GPR 2 "reg_or_short_operand")])
12099 (match_operand 3 "zero_constant" ""))]
12104 [(trap_if (match_operator 0 "ordered_comparison_operator"
12105 [(match_operand:GPR 1 "register_operand" "r")
12106 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12109 "t<wd>%V0%I2 %1,%2"
12110 [(set_attr "type" "trap")])
12112 ;; Insns related to generating the function prologue and epilogue.
12114 (define_expand "prologue"
12115 [(use (const_int 0))]
12118 rs6000_emit_prologue ();
12119 if (!TARGET_SCHED_PROLOG)
12120 emit_insn (gen_blockage ());
12124 (define_insn "*movesi_from_cr_one"
12125 [(match_parallel 0 "mfcr_operation"
12126 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12127 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12128 (match_operand 3 "immediate_operand" "n")]
12129 UNSPEC_MOVESI_FROM_CR))])]
12135 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12137 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12138 operands[4] = GEN_INT (mask);
12139 output_asm_insn (\"mfcr %1,%4\", operands);
12143 [(set_attr "type" "mfcrf")])
12145 (define_insn "movesi_from_cr"
12146 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12147 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12148 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12149 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12150 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12151 UNSPEC_MOVESI_FROM_CR))]
12154 [(set_attr "type" "mfcr")])
12156 (define_insn "*crsave"
12157 [(match_parallel 0 "crsave_operation"
12158 [(set (match_operand:SI 1 "memory_operand" "=m")
12159 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12162 [(set_attr "type" "store")])
12164 (define_insn "*stmw"
12165 [(match_parallel 0 "stmw_operation"
12166 [(set (match_operand:SI 1 "memory_operand" "=m")
12167 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12170 [(set_attr "type" "store")
12171 (set_attr "update" "yes")
12172 (set_attr "indexed" "yes")])
12174 ; The following comment applies to:
12178 ; return_and_restore_gpregs*
12179 ; return_and_restore_fpregs*
12180 ; return_and_restore_fpregs_aix*
12182 ; The out-of-line save / restore functions expects one input argument.
12183 ; Since those are not standard call_insn's, we must avoid using
12184 ; MATCH_OPERAND for that argument. That way the register rename
12185 ; optimization will not try to rename this register.
12186 ; Each pattern is repeated for each possible register number used in
12187 ; various ABIs (r11, r1, and for some functions r12)
12189 (define_insn "*save_gpregs_<mode>_r11"
12190 [(match_parallel 0 "any_parallel_operand"
12191 [(clobber (reg:P 65))
12192 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12194 (set (match_operand:P 2 "memory_operand" "=m")
12195 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12198 [(set_attr "type" "branch")
12199 (set_attr "length" "4")])
12201 (define_insn "*save_gpregs_<mode>_r12"
12202 [(match_parallel 0 "any_parallel_operand"
12203 [(clobber (reg:P 65))
12204 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12206 (set (match_operand:P 2 "memory_operand" "=m")
12207 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12210 [(set_attr "type" "branch")
12211 (set_attr "length" "4")])
12213 (define_insn "*save_gpregs_<mode>_r1"
12214 [(match_parallel 0 "any_parallel_operand"
12215 [(clobber (reg:P 65))
12216 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12218 (set (match_operand:P 2 "memory_operand" "=m")
12219 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12222 [(set_attr "type" "branch")
12223 (set_attr "length" "4")])
12225 (define_insn "*save_fpregs_<mode>_r11"
12226 [(match_parallel 0 "any_parallel_operand"
12227 [(clobber (reg:P 65))
12228 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12230 (set (match_operand:DF 2 "memory_operand" "=m")
12231 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12234 [(set_attr "type" "branch")
12235 (set_attr "length" "4")])
12237 (define_insn "*save_fpregs_<mode>_r12"
12238 [(match_parallel 0 "any_parallel_operand"
12239 [(clobber (reg:P 65))
12240 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12242 (set (match_operand:DF 2 "memory_operand" "=m")
12243 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12246 [(set_attr "type" "branch")
12247 (set_attr "length" "4")])
12249 (define_insn "*save_fpregs_<mode>_r1"
12250 [(match_parallel 0 "any_parallel_operand"
12251 [(clobber (reg:P 65))
12252 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12254 (set (match_operand:DF 2 "memory_operand" "=m")
12255 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12258 [(set_attr "type" "branch")
12259 (set_attr "length" "4")])
12261 ; This is to explain that changes to the stack pointer should
12262 ; not be moved over loads from or stores to stack memory.
12263 (define_insn "stack_tie"
12264 [(match_parallel 0 "tie_operand"
12265 [(set (mem:BLK (reg 1)) (const_int 0))])]
12268 [(set_attr "length" "0")])
12270 (define_expand "epilogue"
12271 [(use (const_int 0))]
12274 if (!TARGET_SCHED_PROLOG)
12275 emit_insn (gen_blockage ());
12276 rs6000_emit_epilogue (FALSE);
12280 ; On some processors, doing the mtcrf one CC register at a time is
12281 ; faster (like on the 604e). On others, doing them all at once is
12282 ; faster; for instance, on the 601 and 750.
12284 (define_expand "movsi_to_cr_one"
12285 [(set (match_operand:CC 0 "cc_reg_operand" "")
12286 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12287 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12289 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12291 (define_insn "*movsi_to_cr"
12292 [(match_parallel 0 "mtcrf_operation"
12293 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12294 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12295 (match_operand 3 "immediate_operand" "n")]
12296 UNSPEC_MOVESI_TO_CR))])]
12302 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12303 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12304 operands[4] = GEN_INT (mask);
12305 return \"mtcrf %4,%2\";
12307 [(set_attr "type" "mtcr")])
12309 (define_insn "*mtcrfsi"
12310 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12311 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12312 (match_operand 2 "immediate_operand" "n")]
12313 UNSPEC_MOVESI_TO_CR))]
12314 "GET_CODE (operands[0]) == REG
12315 && CR_REGNO_P (REGNO (operands[0]))
12316 && GET_CODE (operands[2]) == CONST_INT
12317 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12319 [(set_attr "type" "mtcr")])
12321 ; The load-multiple instructions have similar properties.
12322 ; Note that "load_multiple" is a name known to the machine-independent
12323 ; code that actually corresponds to the PowerPC load-string.
12325 (define_insn "*lmw"
12326 [(match_parallel 0 "lmw_operation"
12327 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12328 (match_operand:SI 2 "memory_operand" "m"))])]
12331 [(set_attr "type" "load")
12332 (set_attr "update" "yes")
12333 (set_attr "indexed" "yes")
12334 (set_attr "cell_micro" "always")])
12336 (define_insn "*return_internal_<mode>"
12338 (use (match_operand:P 0 "register_operand" "lc"))]
12341 [(set_attr "type" "jmpreg")])
12343 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12344 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
12346 ; The following comment applies to:
12350 ; return_and_restore_gpregs*
12351 ; return_and_restore_fpregs*
12352 ; return_and_restore_fpregs_aix*
12354 ; The out-of-line save / restore functions expects one input argument.
12355 ; Since those are not standard call_insn's, we must avoid using
12356 ; MATCH_OPERAND for that argument. That way the register rename
12357 ; optimization will not try to rename this register.
12358 ; Each pattern is repeated for each possible register number used in
12359 ; various ABIs (r11, r1, and for some functions r12)
12361 (define_insn "*restore_gpregs_<mode>_r11"
12362 [(match_parallel 0 "any_parallel_operand"
12363 [(clobber (match_operand:P 1 "register_operand" "=l"))
12364 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12366 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12367 (match_operand:P 4 "memory_operand" "m"))])]
12370 [(set_attr "type" "branch")
12371 (set_attr "length" "4")])
12373 (define_insn "*restore_gpregs_<mode>_r12"
12374 [(match_parallel 0 "any_parallel_operand"
12375 [(clobber (match_operand:P 1 "register_operand" "=l"))
12376 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12378 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12379 (match_operand:P 4 "memory_operand" "m"))])]
12382 [(set_attr "type" "branch")
12383 (set_attr "length" "4")])
12385 (define_insn "*restore_gpregs_<mode>_r1"
12386 [(match_parallel 0 "any_parallel_operand"
12387 [(clobber (match_operand:P 1 "register_operand" "=l"))
12388 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12390 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12391 (match_operand:P 4 "memory_operand" "m"))])]
12394 [(set_attr "type" "branch")
12395 (set_attr "length" "4")])
12397 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12398 [(match_parallel 0 "any_parallel_operand"
12400 (clobber (match_operand:P 1 "register_operand" "=l"))
12401 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12403 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12404 (match_operand:P 4 "memory_operand" "m"))])]
12407 [(set_attr "type" "branch")
12408 (set_attr "length" "4")])
12410 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12411 [(match_parallel 0 "any_parallel_operand"
12413 (clobber (match_operand:P 1 "register_operand" "=l"))
12414 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12416 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12417 (match_operand:P 4 "memory_operand" "m"))])]
12420 [(set_attr "type" "branch")
12421 (set_attr "length" "4")])
12423 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12424 [(match_parallel 0 "any_parallel_operand"
12426 (clobber (match_operand:P 1 "register_operand" "=l"))
12427 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12429 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12430 (match_operand:P 4 "memory_operand" "m"))])]
12433 [(set_attr "type" "branch")
12434 (set_attr "length" "4")])
12436 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12437 [(match_parallel 0 "any_parallel_operand"
12439 (clobber (match_operand:P 1 "register_operand" "=l"))
12440 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12442 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12443 (match_operand:DF 4 "memory_operand" "m"))])]
12446 [(set_attr "type" "branch")
12447 (set_attr "length" "4")])
12449 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12450 [(match_parallel 0 "any_parallel_operand"
12452 (clobber (match_operand:P 1 "register_operand" "=l"))
12453 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12455 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12456 (match_operand:DF 4 "memory_operand" "m"))])]
12459 [(set_attr "type" "branch")
12460 (set_attr "length" "4")])
12462 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12463 [(match_parallel 0 "any_parallel_operand"
12465 (clobber (match_operand:P 1 "register_operand" "=l"))
12466 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12468 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12469 (match_operand:DF 4 "memory_operand" "m"))])]
12472 [(set_attr "type" "branch")
12473 (set_attr "length" "4")])
12475 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12476 [(match_parallel 0 "any_parallel_operand"
12478 (use (match_operand:P 1 "register_operand" "l"))
12479 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12481 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12482 (match_operand:DF 4 "memory_operand" "m"))])]
12485 [(set_attr "type" "branch")
12486 (set_attr "length" "4")])
12488 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12489 [(match_parallel 0 "any_parallel_operand"
12491 (use (match_operand:P 1 "register_operand" "l"))
12492 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12494 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12495 (match_operand:DF 4 "memory_operand" "m"))])]
12498 [(set_attr "type" "branch")
12499 (set_attr "length" "4")])
12501 ; This is used in compiling the unwind routines.
12502 (define_expand "eh_return"
12503 [(use (match_operand 0 "general_operand" ""))]
12508 emit_insn (gen_eh_set_lr_si (operands[0]));
12510 emit_insn (gen_eh_set_lr_di (operands[0]));
12514 ; We can't expand this before we know where the link register is stored.
12515 (define_insn "eh_set_lr_<mode>"
12516 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12518 (clobber (match_scratch:P 1 "=&b"))]
12523 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12524 (clobber (match_scratch 1 ""))]
12529 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12533 (define_insn "prefetch"
12534 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12535 (match_operand:SI 1 "const_int_operand" "n")
12536 (match_operand:SI 2 "const_int_operand" "n"))]
12540 if (GET_CODE (operands[0]) == REG)
12541 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12542 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12544 [(set_attr "type" "load")])
12546 ;; Handle -fsplit-stack.
12548 (define_expand "split_stack_prologue"
12552 rs6000_expand_split_stack_prologue ();
12556 (define_expand "load_split_stack_limit"
12557 [(set (match_operand 0)
12558 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12561 emit_insn (gen_rtx_SET (operands[0],
12562 gen_rtx_UNSPEC (Pmode,
12563 gen_rtvec (1, const0_rtx),
12564 UNSPEC_STACK_CHECK)));
12568 (define_insn "load_split_stack_limit_di"
12569 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12570 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12572 "ld %0,-0x7040(13)"
12573 [(set_attr "type" "load")
12574 (set_attr "update" "no")
12575 (set_attr "indexed" "no")])
12577 (define_insn "load_split_stack_limit_si"
12578 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12579 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12581 "lwz %0,-0x7020(2)"
12582 [(set_attr "type" "load")
12583 (set_attr "update" "no")
12584 (set_attr "indexed" "no")])
12586 ;; A return instruction which the middle-end doesn't see.
12587 (define_insn "split_stack_return"
12588 [(unspec_volatile [(const_int 0)] UNSPECV_SPLIT_STACK_RETURN)]
12591 [(set_attr "type" "jmpreg")])
12593 ;; If there are operand 0 bytes available on the stack, jump to
12595 (define_expand "split_stack_space_check"
12596 [(set (match_dup 2)
12597 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12599 (minus (reg STACK_POINTER_REGNUM)
12600 (match_operand 0)))
12601 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12602 (set (pc) (if_then_else
12603 (geu (match_dup 4) (const_int 0))
12604 (label_ref (match_operand 1))
12608 rs6000_split_stack_space_check (operands[0], operands[1]);
12612 (define_insn "bpermd_<mode>"
12613 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12614 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12615 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12618 [(set_attr "type" "popcnt")])
12621 ;; Builtin fma support. Handle
12622 ;; Note that the conditions for expansion are in the FMA_F iterator.
12624 (define_expand "fma<mode>4"
12625 [(set (match_operand:FMA_F 0 "register_operand" "")
12627 (match_operand:FMA_F 1 "register_operand" "")
12628 (match_operand:FMA_F 2 "register_operand" "")
12629 (match_operand:FMA_F 3 "register_operand" "")))]
12633 (define_insn "*fma<mode>4_fpr"
12634 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12636 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12637 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12638 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12639 "TARGET_<MODE>_FPR"
12641 fmadd<Ftrad> %0,%1,%2,%3
12642 xsmadda<Fvsx> %x0,%x1,%x2
12643 xsmaddm<Fvsx> %x0,%x1,%x3"
12644 [(set_attr "type" "fp")
12645 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12647 ; Altivec only has fma and nfms.
12648 (define_expand "fms<mode>4"
12649 [(set (match_operand:FMA_F 0 "register_operand" "")
12651 (match_operand:FMA_F 1 "register_operand" "")
12652 (match_operand:FMA_F 2 "register_operand" "")
12653 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12654 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12657 (define_insn "*fms<mode>4_fpr"
12658 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12660 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12661 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12662 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12663 "TARGET_<MODE>_FPR"
12665 fmsub<Ftrad> %0,%1,%2,%3
12666 xsmsuba<Fvsx> %x0,%x1,%x2
12667 xsmsubm<Fvsx> %x0,%x1,%x3"
12668 [(set_attr "type" "fp")
12669 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12671 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12672 (define_expand "fnma<mode>4"
12673 [(set (match_operand:FMA_F 0 "register_operand" "")
12676 (match_operand:FMA_F 1 "register_operand" "")
12677 (match_operand:FMA_F 2 "register_operand" "")
12678 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12679 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12682 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12683 (define_expand "fnms<mode>4"
12684 [(set (match_operand:FMA_F 0 "register_operand" "")
12687 (match_operand:FMA_F 1 "register_operand" "")
12688 (match_operand:FMA_F 2 "register_operand" "")
12689 (match_operand:FMA_F 3 "register_operand" ""))))]
12690 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12693 ; Not an official optab name, but used from builtins.
12694 (define_expand "nfma<mode>4"
12695 [(set (match_operand:FMA_F 0 "register_operand" "")
12698 (match_operand:FMA_F 1 "register_operand" "")
12699 (match_operand:FMA_F 2 "register_operand" "")
12700 (match_operand:FMA_F 3 "register_operand" ""))))]
12701 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12704 (define_insn "*nfma<mode>4_fpr"
12705 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12708 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12709 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12710 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12711 "TARGET_<MODE>_FPR"
12713 fnmadd<Ftrad> %0,%1,%2,%3
12714 xsnmadda<Fvsx> %x0,%x1,%x2
12715 xsnmaddm<Fvsx> %x0,%x1,%x3"
12716 [(set_attr "type" "fp")
12717 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12719 ; Not an official optab name, but used from builtins.
12720 (define_expand "nfms<mode>4"
12721 [(set (match_operand:FMA_F 0 "register_operand" "")
12724 (match_operand:FMA_F 1 "register_operand" "")
12725 (match_operand:FMA_F 2 "register_operand" "")
12726 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12730 (define_insn "*nfmssf4_fpr"
12731 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12734 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12735 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12737 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
12738 "TARGET_<MODE>_FPR"
12740 fnmsub<Ftrad> %0,%1,%2,%3
12741 xsnmsuba<Fvsx> %x0,%x1,%x2
12742 xsnmsubm<Fvsx> %x0,%x1,%x3"
12743 [(set_attr "type" "fp")
12744 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12747 (define_expand "rs6000_get_timebase"
12748 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
12751 if (TARGET_POWERPC64)
12752 emit_insn (gen_rs6000_mftb_di (operands[0]));
12754 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
12758 (define_insn "rs6000_get_timebase_ppc32"
12759 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12760 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
12761 (clobber (match_scratch:SI 1 "=r"))
12762 (clobber (match_scratch:CC 2 "=y"))]
12763 "!TARGET_POWERPC64"
12765 if (WORDS_BIG_ENDIAN)
12768 return "mfspr %0,269\;"
12776 return "mftbu %0\;"
12785 return "mfspr %L0,269\;"
12793 return "mftbu %L0\;"
12800 [(set_attr "length" "20")])
12802 (define_insn "rs6000_mftb_<mode>"
12803 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12804 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
12808 return "mfspr %0,268";
12814 (define_insn "rs6000_mffs"
12815 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
12816 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
12817 "TARGET_HARD_FLOAT && TARGET_FPRS"
12820 (define_insn "rs6000_mtfsf"
12821 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
12822 (match_operand:DF 1 "gpc_reg_operand" "d")]
12824 "TARGET_HARD_FLOAT && TARGET_FPRS"
12828 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
12829 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
12830 ;; register that is being loaded. The fused ops must be physically adjacent.
12832 ;; There are two parts to addis fusion. The support for fused TOCs occur
12833 ;; before register allocation, and is meant to reduce the lifetime for the
12834 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
12835 ;; to use the register that is being load. The peephole2 then gathers any
12836 ;; other fused possibilities that it can find after register allocation. If
12837 ;; power9 fusion is selected, we also fuse floating point loads/stores.
12839 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
12840 ;; before register allocation, so that we can avoid allocating a temporary base
12841 ;; register that won't be used, and that we try to load into base registers,
12842 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
12843 ;; (addis followed by load) even on power8.
12846 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
12847 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
12848 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
12849 [(parallel [(set (match_dup 0) (match_dup 2))
12850 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12851 (use (match_dup 3))
12852 (clobber (scratch:DI))])]
12854 operands[2] = fusion_wrap_memory_address (operands[1]);
12855 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
12858 (define_insn "*toc_fusionload_<mode>"
12859 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
12860 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
12861 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12862 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
12863 (clobber (match_scratch:DI 3 "=X,&b"))]
12864 "TARGET_TOC_FUSION_INT"
12866 if (base_reg_operand (operands[0], <MODE>mode))
12867 return emit_fusion_gpr_load (operands[0], operands[1]);
12869 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
12871 [(set_attr "type" "load")
12872 (set_attr "length" "8")])
12874 (define_insn "*toc_fusionload_di"
12875 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
12876 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
12877 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12878 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
12879 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
12880 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
12881 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
12883 if (base_reg_operand (operands[0], DImode))
12884 return emit_fusion_gpr_load (operands[0], operands[1]);
12886 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
12888 [(set_attr "type" "load")
12889 (set_attr "length" "8")])
12892 ;; Find cases where the addis that feeds into a load instruction is either used
12893 ;; once or is the same as the target register, and replace it with the fusion
12897 [(set (match_operand:P 0 "base_reg_operand" "")
12898 (match_operand:P 1 "fusion_gpr_addis" ""))
12899 (set (match_operand:INT1 2 "base_reg_operand" "")
12900 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
12902 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
12906 expand_fusion_gpr_load (operands);
12910 ;; Fusion insn, created by the define_peephole2 above (and eventually by
12913 (define_insn "fusion_gpr_load_<mode>"
12914 [(set (match_operand:INT1 0 "base_reg_operand" "=&b")
12915 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "")]
12916 UNSPEC_FUSION_GPR))]
12919 return emit_fusion_gpr_load (operands[0], operands[1]);
12921 [(set_attr "type" "load")
12922 (set_attr "length" "8")])
12925 ;; ISA 3.0 (power9) fusion support
12926 ;; Merge addis with floating load/store to FPRs (or GPRs).
12928 [(set (match_operand:P 0 "base_reg_operand" "")
12929 (match_operand:P 1 "fusion_gpr_addis" ""))
12930 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
12931 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
12932 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
12933 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
12936 expand_fusion_p9_load (operands);
12941 [(set (match_operand:P 0 "base_reg_operand" "")
12942 (match_operand:P 1 "fusion_gpr_addis" ""))
12943 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
12944 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
12945 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
12946 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
12949 expand_fusion_p9_store (operands);
12954 [(set (match_operand:SDI 0 "int_reg_operand" "")
12955 (match_operand:SDI 1 "upper16_cint_operand" ""))
12957 (ior:SDI (match_dup 0)
12958 (match_operand:SDI 2 "u_short_cint_operand" "")))]
12960 [(set (match_dup 0)
12961 (unspec:SDI [(match_dup 1)
12962 (match_dup 2)] UNSPEC_FUSION_P9))])
12965 [(set (match_operand:SDI 0 "int_reg_operand" "")
12966 (match_operand:SDI 1 "upper16_cint_operand" ""))
12967 (set (match_operand:SDI 2 "int_reg_operand" "")
12968 (ior:SDI (match_dup 0)
12969 (match_operand:SDI 3 "u_short_cint_operand" "")))]
12971 && !rtx_equal_p (operands[0], operands[2])
12972 && peep2_reg_dead_p (2, operands[0])"
12973 [(set (match_dup 2)
12974 (unspec:SDI [(match_dup 1)
12975 (match_dup 3)] UNSPEC_FUSION_P9))])
12977 ;; Fusion insns, created by the define_peephole2 above (and eventually by
12978 ;; reload). Because we want to eventually have secondary_reload generate
12979 ;; these, they have to have a single alternative that gives the register
12980 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
12981 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
12982 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
12984 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
12986 (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
12989 /* This insn is a secondary reload insn, which cannot have alternatives.
12990 If we are not loading up register 0, use the power8 fusion instead. */
12991 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
12992 return emit_fusion_gpr_load (operands[0], operands[1]);
12994 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
12996 [(set_attr "type" "load")
12997 (set_attr "length" "8")])
12999 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13000 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13002 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13004 (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
13007 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13009 [(set_attr "type" "store")
13010 (set_attr "length" "8")])
13012 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
13013 [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
13015 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13017 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13020 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13022 [(set_attr "type" "fpload")
13023 (set_attr "length" "8")])
13025 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
13026 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13028 [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
13030 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13033 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13035 [(set_attr "type" "fpstore")
13036 (set_attr "length" "8")])
13038 (define_insn "*fusion_p9_<mode>_constant"
13039 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13040 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13041 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13042 UNSPEC_FUSION_P9))]
13045 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13046 return "ori %0,%0,%2";
13048 [(set_attr "type" "two")
13049 (set_attr "length" "8")])
13052 ;; Miscellaneous ISA 2.06 (power7) instructions
13053 (define_insn "addg6s"
13054 [(set (match_operand:SI 0 "register_operand" "=r")
13055 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13056 (match_operand:SI 2 "register_operand" "r")]
13060 [(set_attr "type" "integer")
13061 (set_attr "length" "4")])
13063 (define_insn "cdtbcd"
13064 [(set (match_operand:SI 0 "register_operand" "=r")
13065 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13069 [(set_attr "type" "integer")
13070 (set_attr "length" "4")])
13072 (define_insn "cbcdtd"
13073 [(set (match_operand:SI 0 "register_operand" "=r")
13074 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13078 [(set_attr "type" "integer")
13079 (set_attr "length" "4")])
13081 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13086 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13087 (UNSPEC_DIVEO "eo")
13088 (UNSPEC_DIVEU "eu")
13089 (UNSPEC_DIVEUO "euo")])
13091 (define_insn "div<div_extend>_<mode>"
13092 [(set (match_operand:GPR 0 "register_operand" "=r")
13093 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13094 (match_operand:GPR 2 "register_operand" "r")]
13095 UNSPEC_DIV_EXTEND))]
13097 "div<wd><div_extend> %0,%1,%2"
13098 [(set_attr "type" "div")
13099 (set_attr "size" "<bits>")])
13102 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13104 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13105 (define_mode_attr FP128_64 [(TF "DF")
13110 (define_expand "unpack<mode>"
13111 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13113 [(match_operand:FMOVE128 1 "register_operand" "")
13114 (match_operand:QI 2 "const_0_to_1_operand" "")]
13115 UNSPEC_UNPACK_128BIT))]
13116 "FLOAT128_2REG_P (<MODE>mode)"
13119 (define_insn_and_split "unpack<mode>_dm"
13120 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13122 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13123 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13124 UNSPEC_UNPACK_128BIT))]
13125 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13127 "&& reload_completed"
13128 [(set (match_dup 0) (match_dup 3))]
13130 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13132 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13134 emit_note (NOTE_INSN_DELETED);
13138 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13140 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13141 (set_attr "length" "4")])
13143 (define_insn_and_split "unpack<mode>_nodm"
13144 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13146 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13147 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13148 UNSPEC_UNPACK_128BIT))]
13149 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13151 "&& reload_completed"
13152 [(set (match_dup 0) (match_dup 3))]
13154 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13156 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13158 emit_note (NOTE_INSN_DELETED);
13162 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13164 [(set_attr "type" "fp,fpstore")
13165 (set_attr "length" "4")])
13167 (define_insn_and_split "pack<mode>"
13168 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13170 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13171 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13172 UNSPEC_PACK_128BIT))]
13173 "FLOAT128_2REG_P (<MODE>mode)"
13177 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13178 [(set (match_dup 3) (match_dup 1))
13179 (set (match_dup 4) (match_dup 2))]
13181 unsigned dest_hi = REGNO (operands[0]);
13182 unsigned dest_lo = dest_hi + 1;
13184 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13185 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13187 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13188 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13190 [(set_attr "type" "fp,fp")
13191 (set_attr "length" "4,8")])
13193 (define_insn "unpack<mode>"
13194 [(set (match_operand:DI 0 "register_operand" "=d,d")
13195 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13196 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13197 UNSPEC_UNPACK_128BIT))]
13198 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13200 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13201 return ASM_COMMENT_START " xxpermdi to same register";
13203 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13204 return "xxpermdi %x0,%x1,%x1,%3";
13206 [(set_attr "type" "vecperm")])
13208 (define_insn "pack<mode>"
13209 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13210 (unspec:FMOVE128_VSX
13211 [(match_operand:DI 1 "register_operand" "d")
13212 (match_operand:DI 2 "register_operand" "d")]
13213 UNSPEC_PACK_128BIT))]
13215 "xxpermdi %x0,%x1,%x2,0"
13216 [(set_attr "type" "vecperm")])
13220 ;; ISA 2.08 IEEE 128-bit floating point support.
13222 (define_insn "add<mode>3"
13223 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13225 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13226 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13227 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13229 [(set_attr "type" "vecfloat")])
13231 (define_insn "sub<mode>3"
13232 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13234 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13235 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13236 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13238 [(set_attr "type" "vecfloat")])
13240 (define_insn "mul<mode>3"
13241 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13243 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13244 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13245 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13247 [(set_attr "type" "vecfloat")])
13249 (define_insn "div<mode>3"
13250 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13252 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13253 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13254 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13256 [(set_attr "type" "vecdiv")])
13258 (define_insn "sqrt<mode>2"
13259 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13261 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13262 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13264 [(set_attr "type" "vecdiv")])
13266 (define_insn "copysign<mode>3"
13267 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13269 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13270 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13272 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13273 "xscpsgnqp %0,%2,%1"
13274 [(set_attr "type" "vecsimple")])
13276 (define_insn "neg<mode>2_hw"
13277 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13279 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13280 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13282 [(set_attr "type" "vecfloat")])
13285 (define_insn "abs<mode>2_hw"
13286 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13288 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13289 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13291 [(set_attr "type" "vecfloat")])
13294 (define_insn "*nabs<mode>2_hw"
13295 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13298 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13299 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13301 [(set_attr "type" "vecfloat")])
13303 ;; Initially don't worry about doing fusion
13304 (define_insn "*fma<mode>4_hw"
13305 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13307 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13308 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13309 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13310 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13311 "xsmaddqp %0,%1,%2"
13312 [(set_attr "type" "vecfloat")])
13314 (define_insn "*fms<mode>4_hw"
13315 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13317 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13318 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13320 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13321 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13322 "xsmsubqp %0,%1,%2"
13323 [(set_attr "type" "vecfloat")])
13325 (define_insn "*nfma<mode>4_hw"
13326 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13329 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13330 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13331 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13332 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13333 "xsnmaddqp %0,%1,%2"
13334 [(set_attr "type" "vecfloat")])
13336 (define_insn "*nfms<mode>4_hw"
13337 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13340 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13341 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13343 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13344 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13345 "xsnmsubqp %0,%1,%2"
13346 [(set_attr "type" "vecfloat")])
13348 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13349 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13350 (float_extend:IEEE128
13351 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13352 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13354 [(set_attr "type" "vecfloat")])
13356 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13357 ;; point is a simple copy.
13358 (define_insn_and_split "extendkftf2"
13359 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13360 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13361 "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13365 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13368 emit_note (NOTE_INSN_DELETED);
13371 [(set_attr "type" "*,vecsimple")
13372 (set_attr "length" "0,4")])
13374 (define_insn_and_split "trunctfkf2"
13375 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13376 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13377 "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13381 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13384 emit_note (NOTE_INSN_DELETED);
13387 [(set_attr "type" "*,vecsimple")
13388 (set_attr "length" "0,4")])
13390 (define_insn "trunc<mode>df2_hw"
13391 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13393 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13394 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13396 [(set_attr "type" "vecfloat")])
13398 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13399 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13401 (define_insn_and_split "trunc<mode>sf2_hw"
13402 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13404 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13405 (clobber (match_scratch:DF 2 "=v"))]
13406 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13409 [(set (match_dup 2)
13410 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13412 (float_truncate:SF (match_dup 2)))]
13414 if (GET_CODE (operands[2]) == SCRATCH)
13415 operands[2] = gen_reg_rtx (DFmode);
13417 [(set_attr "type" "vecfloat")
13418 (set_attr "length" "8")])
13420 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13421 ;; allowed in the traditional floating point registers. Use V2DImode so that
13422 ;; we can get a value in an Altivec register.
13424 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13425 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13426 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13427 (clobber (match_scratch:V2DI 2 "=v,v"))]
13428 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13433 convert_float128_to_int (operands, <CODE>);
13436 [(set_attr "length" "8")
13437 (set_attr "type" "mftgpr,fpstore")])
13439 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13440 [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13441 (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13442 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13443 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13448 convert_float128_to_int (operands, <CODE>);
13451 [(set_attr "length" "8")
13452 (set_attr "type" "mftgpr,vecsimple,fpstore")])
13454 (define_insn_and_split "float<uns>_<mode>si2_hw"
13455 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13456 (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13457 (clobber (match_scratch:V2DI 2 "=v,v"))]
13458 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13463 convert_int_to_float128 (operands, <CODE>);
13466 [(set_attr "length" "8")
13467 (set_attr "type" "vecfloat")])
13469 (define_insn_and_split "float<uns>_<mode>di2_hw"
13470 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13471 (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13472 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13473 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13478 convert_int_to_float128 (operands, <CODE>);
13481 [(set_attr "length" "8")
13482 (set_attr "type" "vecfloat")])
13484 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13485 (define_insn "*xscvqp<su>wz_<mode>"
13486 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13489 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13490 UNSPEC_IEEE128_CONVERT))]
13491 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13492 "xscvqp<su>wz %0,%1"
13493 [(set_attr "type" "vecfloat")])
13495 (define_insn "*xscvqp<su>dz_<mode>"
13496 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13499 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13500 UNSPEC_IEEE128_CONVERT))]
13501 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13502 "xscvqp<su>dz %0,%1"
13503 [(set_attr "type" "vecfloat")])
13505 (define_insn "*xscv<su>dqp_<mode>"
13506 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13508 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13509 UNSPEC_IEEE128_CONVERT)))]
13510 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13511 "xscv<su>dqp %0,%1"
13512 [(set_attr "type" "vecfloat")])
13514 (define_insn "*ieee128_mfvsrd_64bit"
13515 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13516 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13517 UNSPEC_IEEE128_MOVE))]
13518 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13523 [(set_attr "type" "mftgpr,vecsimple,fpstore")])
13526 (define_insn "*ieee128_mfvsrd_32bit"
13527 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13528 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13529 UNSPEC_IEEE128_MOVE))]
13530 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13534 [(set_attr "type" "vecsimple,fpstore")])
13536 (define_insn "*ieee128_mfvsrwz"
13537 [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13538 (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13539 UNSPEC_IEEE128_MOVE))]
13540 "TARGET_FLOAT128_HW"
13544 [(set_attr "type" "mftgpr,fpstore")])
13546 ;; 0 says do sign-extension, 1 says zero-extension
13547 (define_insn "*ieee128_mtvsrw"
13548 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13549 (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13550 (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13551 UNSPEC_IEEE128_MOVE))]
13552 "TARGET_FLOAT128_HW"
13558 [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13561 (define_insn "*ieee128_mtvsrd_64bit"
13562 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13563 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13564 UNSPEC_IEEE128_MOVE))]
13565 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13570 [(set_attr "type" "mffgpr,fpload,vecsimple")])
13572 (define_insn "*ieee128_mtvsrd_32bit"
13573 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
13574 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
13575 UNSPEC_IEEE128_MOVE))]
13576 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13580 [(set_attr "type" "fpload,vecsimple")])
13582 ;; IEEE 128-bit instructions with round to odd semantics
13583 (define_insn "*trunc<mode>df2_odd"
13584 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13585 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13586 UNSPEC_ROUND_TO_ODD))]
13587 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13589 [(set_attr "type" "vecfloat")])
13591 ;; IEEE 128-bit comparisons
13592 (define_insn "*cmp<mode>_hw"
13593 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13594 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13595 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13596 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13597 "xscmpuqp %0,%1,%2"
13598 [(set_attr "type" "fpcompare")])
13602 (include "sync.md")
13603 (include "vector.md")
13605 (include "altivec.md")
13608 (include "paired.md")
13609 (include "crypto.md")