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 [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 ; Whether 0.0 has an all-zero bit pattern
432 (define_mode_attr zero_fp [(SF "j")
441 ; Definitions for load to 32-bit fpr register
442 (define_mode_attr f32_lr [(SF "f") (SD "wz")])
443 (define_mode_attr f32_lr2 [(SF "wb") (SD "wn")])
444 (define_mode_attr f32_lm [(SF "m") (SD "Z")])
445 (define_mode_attr f32_lm2 [(SF "o") (SD "wn")])
446 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
447 (define_mode_attr f32_li2 [(SF "lxssp %0,%1") (SD "lfiwzx %0,%y1")])
448 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
450 ; Definitions for store from 32-bit fpr register
451 (define_mode_attr f32_sr [(SF "f") (SD "wx")])
452 (define_mode_attr f32_sr2 [(SF "wb") (SD "wn")])
453 (define_mode_attr f32_sm [(SF "m") (SD "Z")])
454 (define_mode_attr f32_sm2 [(SF "o") (SD "wn")])
455 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
456 (define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")])
457 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")])
459 ; Definitions for 32-bit fpr direct move
460 ; At present, the decimal modes are not allowed in the traditional altivec
461 ; registers, so restrict the constraints to just the traditional FPRs.
462 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
464 ; Definitions for 32-bit VSX
465 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
467 ; Definitions for 32-bit use of altivec registers
468 (define_mode_attr f32_av [(SF "wu") (SD "wn")])
470 ; Definitions for 64-bit VSX
471 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
473 ; Definitions for 64-bit direct move
474 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
476 ; Definitions for 64-bit use of altivec registers
477 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
479 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
480 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
482 ; These modes do not fit in integer registers in 32-bit mode.
483 ; but on e500v2, the gpr are 64 bit registers
484 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
486 ; Iterator for reciprocal estimate instructions
487 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
489 ; Iterator for just SF/DF
490 (define_mode_iterator SFDF [SF DF])
492 ; Iterator for 128-bit floating point that uses the IBM double-double format
493 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
494 (TF "FLOAT128_IBM_P (TFmode)")])
496 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
497 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
498 (TF "FLOAT128_IEEE_P (TFmode)")])
500 ; Iterator for 128-bit floating point
501 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128")
502 (IF "TARGET_FLOAT128")
503 (TF "TARGET_LONG_DOUBLE_128")])
505 ; SF/DF suffix for traditional floating instructions
506 (define_mode_attr Ftrad [(SF "s") (DF "")])
508 ; SF/DF suffix for VSX instructions
509 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
511 ; SF/DF constraint for arithmetic on traditional floating point registers
512 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
514 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
515 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
516 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
518 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
520 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
521 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
522 ; instructions added in ISA 2.07 (power8)
523 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
525 ; SF/DF constraint for arithmetic on altivec registers
526 (define_mode_attr Fa [(SF "wu") (DF "wv")])
528 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
529 (define_mode_attr Fs [(SF "s") (DF "d")])
532 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
533 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
535 ; Conditional returns.
536 (define_code_iterator any_return [return simple_return])
537 (define_code_attr return_pred [(return "direct_return ()")
538 (simple_return "1")])
539 (define_code_attr return_str [(return "") (simple_return "simple_")])
542 (define_code_iterator iorxor [ior xor])
544 ; Signed/unsigned variants of ops.
545 (define_code_iterator any_extend [sign_extend zero_extend])
546 (define_code_iterator any_fix [fix unsigned_fix])
547 (define_code_iterator any_float [float unsigned_float])
549 (define_code_attr u [(sign_extend "")
552 (define_code_attr su [(sign_extend "s")
557 (unsigned_float "u")])
559 (define_code_attr az [(sign_extend "a")
564 (unsigned_float "z")])
566 (define_code_attr uns [(fix "")
569 (unsigned_float "uns")])
571 ; Various instructions that come in SI and DI forms.
572 ; A generic w/d attribute, for things like cmpw/cmpd.
573 (define_mode_attr wd [(QI "b")
582 ;; How many bits in this mode?
583 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
586 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
588 ;; ISEL/ISEL64 target selection
589 (define_mode_attr sel [(SI "") (DI "64")])
591 ;; Bitmask for shift instructions
592 (define_mode_attr hH [(SI "h") (DI "H")])
594 ;; A mode twice the size of the given mode
595 (define_mode_attr dmode [(SI "di") (DI "ti")])
596 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
598 ;; Suffix for reload patterns
599 (define_mode_attr ptrsize [(SI "32bit")
602 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
603 (DI "TARGET_64BIT")])
605 (define_mode_attr mptrsize [(SI "si")
608 (define_mode_attr ptrload [(SI "lwz")
611 (define_mode_attr ptrm [(SI "m")
614 (define_mode_attr rreg [(SF "f")
621 (define_mode_attr rreg2 [(SF "f")
624 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
625 (DF "TARGET_FCFID")])
627 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
628 (DF "TARGET_E500_DOUBLE")])
630 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
631 (DF "TARGET_DOUBLE_FLOAT")])
633 ;; Mode iterator for logical operations on 128-bit types
634 (define_mode_iterator BOOL_128 [TI
636 (V16QI "TARGET_ALTIVEC")
637 (V8HI "TARGET_ALTIVEC")
638 (V4SI "TARGET_ALTIVEC")
639 (V4SF "TARGET_ALTIVEC")
640 (V2DI "TARGET_ALTIVEC")
641 (V2DF "TARGET_ALTIVEC")
642 (V1TI "TARGET_ALTIVEC")])
644 ;; For the GPRs we use 3 constraints for register outputs, two that are the
645 ;; same as the output register, and a third where the output register is an
646 ;; early clobber, so we don't have to deal with register overlaps. For the
647 ;; vector types, we prefer to use the vector registers. For TI mode, allow
650 ;; Mode attribute for boolean operation register constraints for output
651 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
653 (V16QI "wa,v,&?r,?r,?r")
654 (V8HI "wa,v,&?r,?r,?r")
655 (V4SI "wa,v,&?r,?r,?r")
656 (V4SF "wa,v,&?r,?r,?r")
657 (V2DI "wa,v,&?r,?r,?r")
658 (V2DF "wa,v,&?r,?r,?r")
659 (V1TI "wa,v,&?r,?r,?r")])
661 ;; Mode attribute for boolean operation register constraints for operand1
662 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
670 (V1TI "wa,v,r,0,r")])
672 ;; Mode attribute for boolean operation register constraints for operand2
673 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
681 (V1TI "wa,v,r,r,0")])
683 ;; Mode attribute for boolean operation register constraints for operand1
684 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
685 ;; is used for operand1 or operand2
686 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
694 (V1TI "wa,v,r,0,0")])
696 ;; Reload iterator for creating the function to allocate a base register to
697 ;; supplement addressing modes.
698 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
699 SF SD SI DF DD DI TI PTI KF IF TF])
702 ;; Start with fixed-point load and store insns. Here we put only the more
703 ;; complex forms. Basic data transfer is done later.
705 (define_insn "zero_extendqi<mode>2"
706 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
707 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
712 [(set_attr "type" "load,shift")])
714 (define_insn_and_split "*zero_extendqi<mode>2_dot"
715 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
716 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
718 (clobber (match_scratch:EXTQI 0 "=r,r"))]
719 "rs6000_gen_cell_microcode"
723 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
725 (zero_extend:EXTQI (match_dup 1)))
727 (compare:CC (match_dup 0)
730 [(set_attr "type" "logical")
731 (set_attr "dot" "yes")
732 (set_attr "length" "4,8")])
734 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
735 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
736 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
738 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
739 (zero_extend:EXTQI (match_dup 1)))]
740 "rs6000_gen_cell_microcode"
744 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
746 (zero_extend:EXTQI (match_dup 1)))
748 (compare:CC (match_dup 0)
751 [(set_attr "type" "logical")
752 (set_attr "dot" "yes")
753 (set_attr "length" "4,8")])
756 (define_insn "zero_extendhi<mode>2"
757 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
758 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
762 rlwinm %0,%1,0,0xffff"
763 [(set_attr "type" "load,shift")])
765 (define_insn_and_split "*zero_extendhi<mode>2_dot"
766 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
767 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
769 (clobber (match_scratch:EXTHI 0 "=r,r"))]
770 "rs6000_gen_cell_microcode"
774 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
776 (zero_extend:EXTHI (match_dup 1)))
778 (compare:CC (match_dup 0)
781 [(set_attr "type" "logical")
782 (set_attr "dot" "yes")
783 (set_attr "length" "4,8")])
785 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
786 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
787 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
789 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
790 (zero_extend:EXTHI (match_dup 1)))]
791 "rs6000_gen_cell_microcode"
795 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
797 (zero_extend:EXTHI (match_dup 1)))
799 (compare:CC (match_dup 0)
802 [(set_attr "type" "logical")
803 (set_attr "dot" "yes")
804 (set_attr "length" "4,8")])
807 (define_insn "zero_extendsi<mode>2"
808 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
809 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
817 [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
819 (define_insn_and_split "*zero_extendsi<mode>2_dot"
820 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
821 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
823 (clobber (match_scratch:EXTSI 0 "=r,r"))]
824 "rs6000_gen_cell_microcode"
828 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
830 (zero_extend:DI (match_dup 1)))
832 (compare:CC (match_dup 0)
835 [(set_attr "type" "shift")
836 (set_attr "dot" "yes")
837 (set_attr "length" "4,8")])
839 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
840 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
841 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
843 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
844 (zero_extend:EXTSI (match_dup 1)))]
845 "rs6000_gen_cell_microcode"
849 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
851 (zero_extend:EXTSI (match_dup 1)))
853 (compare:CC (match_dup 0)
856 [(set_attr "type" "shift")
857 (set_attr "dot" "yes")
858 (set_attr "length" "4,8")])
861 (define_insn "extendqi<mode>2"
862 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
863 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
866 [(set_attr "type" "exts")])
868 (define_insn_and_split "*extendqi<mode>2_dot"
869 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
870 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
872 (clobber (match_scratch:EXTQI 0 "=r,r"))]
873 "rs6000_gen_cell_microcode"
877 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
879 (sign_extend:EXTQI (match_dup 1)))
881 (compare:CC (match_dup 0)
884 [(set_attr "type" "exts")
885 (set_attr "dot" "yes")
886 (set_attr "length" "4,8")])
888 (define_insn_and_split "*extendqi<mode>2_dot2"
889 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
890 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
892 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
893 (sign_extend:EXTQI (match_dup 1)))]
894 "rs6000_gen_cell_microcode"
898 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
900 (sign_extend:EXTQI (match_dup 1)))
902 (compare:CC (match_dup 0)
905 [(set_attr "type" "exts")
906 (set_attr "dot" "yes")
907 (set_attr "length" "4,8")])
910 (define_expand "extendhi<mode>2"
911 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
912 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
916 (define_insn "*extendhi<mode>2"
917 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
918 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
919 "rs6000_gen_cell_microcode"
923 [(set_attr "type" "load,exts")
924 (set_attr "sign_extend" "yes")])
926 (define_insn "*extendhi<mode>2_noload"
927 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
928 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
929 "!rs6000_gen_cell_microcode"
931 [(set_attr "type" "exts")])
933 (define_insn_and_split "*extendhi<mode>2_dot"
934 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
935 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
937 (clobber (match_scratch:EXTHI 0 "=r,r"))]
938 "rs6000_gen_cell_microcode"
942 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
944 (sign_extend:EXTHI (match_dup 1)))
946 (compare:CC (match_dup 0)
949 [(set_attr "type" "exts")
950 (set_attr "dot" "yes")
951 (set_attr "length" "4,8")])
953 (define_insn_and_split "*extendhi<mode>2_dot2"
954 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
955 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
957 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
958 (sign_extend:EXTHI (match_dup 1)))]
959 "rs6000_gen_cell_microcode"
963 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
965 (sign_extend:EXTHI (match_dup 1)))
967 (compare:CC (match_dup 0)
970 [(set_attr "type" "exts")
971 (set_attr "dot" "yes")
972 (set_attr "length" "4,8")])
975 (define_insn "extendsi<mode>2"
976 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
977 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
985 [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
986 (set_attr "sign_extend" "yes")])
988 (define_insn_and_split "*extendsi<mode>2_dot"
989 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
990 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
992 (clobber (match_scratch:EXTSI 0 "=r,r"))]
993 "rs6000_gen_cell_microcode"
997 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
999 (sign_extend:EXTSI (match_dup 1)))
1001 (compare:CC (match_dup 0)
1004 [(set_attr "type" "exts")
1005 (set_attr "dot" "yes")
1006 (set_attr "length" "4,8")])
1008 (define_insn_and_split "*extendsi<mode>2_dot2"
1009 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1010 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1012 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1013 (sign_extend:EXTSI (match_dup 1)))]
1014 "rs6000_gen_cell_microcode"
1018 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1020 (sign_extend:EXTSI (match_dup 1)))
1022 (compare:CC (match_dup 0)
1025 [(set_attr "type" "exts")
1026 (set_attr "dot" "yes")
1027 (set_attr "length" "4,8")])
1029 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1031 (define_insn "*macchwc"
1032 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1033 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1034 (match_operand:SI 2 "gpc_reg_operand" "r")
1037 (match_operand:HI 1 "gpc_reg_operand" "r")))
1038 (match_operand:SI 4 "gpc_reg_operand" "0"))
1040 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1041 (plus:SI (mult:SI (ashiftrt:SI
1049 [(set_attr "type" "halfmul")])
1051 (define_insn "*macchw"
1052 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1053 (plus:SI (mult:SI (ashiftrt:SI
1054 (match_operand:SI 2 "gpc_reg_operand" "r")
1057 (match_operand:HI 1 "gpc_reg_operand" "r")))
1058 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1061 [(set_attr "type" "halfmul")])
1063 (define_insn "*macchwuc"
1064 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1065 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1066 (match_operand:SI 2 "gpc_reg_operand" "r")
1069 (match_operand:HI 1 "gpc_reg_operand" "r")))
1070 (match_operand:SI 4 "gpc_reg_operand" "0"))
1072 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1073 (plus:SI (mult:SI (lshiftrt:SI
1081 [(set_attr "type" "halfmul")])
1083 (define_insn "*macchwu"
1084 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1085 (plus:SI (mult:SI (lshiftrt:SI
1086 (match_operand:SI 2 "gpc_reg_operand" "r")
1089 (match_operand:HI 1 "gpc_reg_operand" "r")))
1090 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1093 [(set_attr "type" "halfmul")])
1095 (define_insn "*machhwc"
1096 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1097 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1098 (match_operand:SI 1 "gpc_reg_operand" "%r")
1101 (match_operand:SI 2 "gpc_reg_operand" "r")
1103 (match_operand:SI 4 "gpc_reg_operand" "0"))
1105 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1106 (plus:SI (mult:SI (ashiftrt:SI
1115 [(set_attr "type" "halfmul")])
1117 (define_insn "*machhw"
1118 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1119 (plus:SI (mult:SI (ashiftrt:SI
1120 (match_operand:SI 1 "gpc_reg_operand" "%r")
1123 (match_operand:SI 2 "gpc_reg_operand" "r")
1125 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1128 [(set_attr "type" "halfmul")])
1130 (define_insn "*machhwuc"
1131 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1132 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1133 (match_operand:SI 1 "gpc_reg_operand" "%r")
1136 (match_operand:SI 2 "gpc_reg_operand" "r")
1138 (match_operand:SI 4 "gpc_reg_operand" "0"))
1140 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1141 (plus:SI (mult:SI (lshiftrt:SI
1150 [(set_attr "type" "halfmul")])
1152 (define_insn "*machhwu"
1153 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1154 (plus:SI (mult:SI (lshiftrt:SI
1155 (match_operand:SI 1 "gpc_reg_operand" "%r")
1158 (match_operand:SI 2 "gpc_reg_operand" "r")
1160 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1163 [(set_attr "type" "halfmul")])
1165 (define_insn "*maclhwc"
1166 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1167 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1168 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1170 (match_operand:HI 2 "gpc_reg_operand" "r")))
1171 (match_operand:SI 4 "gpc_reg_operand" "0"))
1173 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1174 (plus:SI (mult:SI (sign_extend:SI
1181 [(set_attr "type" "halfmul")])
1183 (define_insn "*maclhw"
1184 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1185 (plus:SI (mult:SI (sign_extend:SI
1186 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1188 (match_operand:HI 2 "gpc_reg_operand" "r")))
1189 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1192 [(set_attr "type" "halfmul")])
1194 (define_insn "*maclhwuc"
1195 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1196 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1197 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1199 (match_operand:HI 2 "gpc_reg_operand" "r")))
1200 (match_operand:SI 4 "gpc_reg_operand" "0"))
1202 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1203 (plus:SI (mult:SI (zero_extend:SI
1210 [(set_attr "type" "halfmul")])
1212 (define_insn "*maclhwu"
1213 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1214 (plus:SI (mult:SI (zero_extend:SI
1215 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1217 (match_operand:HI 2 "gpc_reg_operand" "r")))
1218 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1221 [(set_attr "type" "halfmul")])
1223 (define_insn "*nmacchwc"
1224 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1225 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1226 (mult:SI (ashiftrt:SI
1227 (match_operand:SI 2 "gpc_reg_operand" "r")
1230 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1232 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1233 (minus:SI (match_dup 4)
1234 (mult:SI (ashiftrt:SI
1241 [(set_attr "type" "halfmul")])
1243 (define_insn "*nmacchw"
1244 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1245 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1246 (mult:SI (ashiftrt:SI
1247 (match_operand:SI 2 "gpc_reg_operand" "r")
1250 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1253 [(set_attr "type" "halfmul")])
1255 (define_insn "*nmachhwc"
1256 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1257 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1258 (mult:SI (ashiftrt:SI
1259 (match_operand:SI 1 "gpc_reg_operand" "%r")
1262 (match_operand:SI 2 "gpc_reg_operand" "r")
1265 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1266 (minus:SI (match_dup 4)
1267 (mult:SI (ashiftrt:SI
1275 [(set_attr "type" "halfmul")])
1277 (define_insn "*nmachhw"
1278 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1279 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1280 (mult:SI (ashiftrt:SI
1281 (match_operand:SI 1 "gpc_reg_operand" "%r")
1284 (match_operand:SI 2 "gpc_reg_operand" "r")
1288 [(set_attr "type" "halfmul")])
1290 (define_insn "*nmaclhwc"
1291 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1292 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1293 (mult:SI (sign_extend:SI
1294 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1296 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1298 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1299 (minus:SI (match_dup 4)
1300 (mult:SI (sign_extend:SI
1306 [(set_attr "type" "halfmul")])
1308 (define_insn "*nmaclhw"
1309 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1310 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1311 (mult:SI (sign_extend:SI
1312 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1314 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1317 [(set_attr "type" "halfmul")])
1319 (define_insn "*mulchwc"
1320 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1321 (compare:CC (mult:SI (ashiftrt:SI
1322 (match_operand:SI 2 "gpc_reg_operand" "r")
1325 (match_operand:HI 1 "gpc_reg_operand" "r")))
1327 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1328 (mult:SI (ashiftrt:SI
1335 [(set_attr "type" "halfmul")])
1337 (define_insn "*mulchw"
1338 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1339 (mult:SI (ashiftrt:SI
1340 (match_operand:SI 2 "gpc_reg_operand" "r")
1343 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1346 [(set_attr "type" "halfmul")])
1348 (define_insn "*mulchwuc"
1349 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1350 (compare:CC (mult:SI (lshiftrt:SI
1351 (match_operand:SI 2 "gpc_reg_operand" "r")
1354 (match_operand:HI 1 "gpc_reg_operand" "r")))
1356 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1357 (mult:SI (lshiftrt:SI
1364 [(set_attr "type" "halfmul")])
1366 (define_insn "*mulchwu"
1367 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1368 (mult:SI (lshiftrt:SI
1369 (match_operand:SI 2 "gpc_reg_operand" "r")
1372 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1375 [(set_attr "type" "halfmul")])
1377 (define_insn "*mulhhwc"
1378 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1379 (compare:CC (mult:SI (ashiftrt:SI
1380 (match_operand:SI 1 "gpc_reg_operand" "%r")
1383 (match_operand:SI 2 "gpc_reg_operand" "r")
1386 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1387 (mult:SI (ashiftrt:SI
1395 [(set_attr "type" "halfmul")])
1397 (define_insn "*mulhhw"
1398 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1399 (mult:SI (ashiftrt:SI
1400 (match_operand:SI 1 "gpc_reg_operand" "%r")
1403 (match_operand:SI 2 "gpc_reg_operand" "r")
1407 [(set_attr "type" "halfmul")])
1409 (define_insn "*mulhhwuc"
1410 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1411 (compare:CC (mult:SI (lshiftrt:SI
1412 (match_operand:SI 1 "gpc_reg_operand" "%r")
1415 (match_operand:SI 2 "gpc_reg_operand" "r")
1418 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1419 (mult:SI (lshiftrt:SI
1427 [(set_attr "type" "halfmul")])
1429 (define_insn "*mulhhwu"
1430 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1431 (mult:SI (lshiftrt:SI
1432 (match_operand:SI 1 "gpc_reg_operand" "%r")
1435 (match_operand:SI 2 "gpc_reg_operand" "r")
1439 [(set_attr "type" "halfmul")])
1441 (define_insn "*mullhwc"
1442 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1443 (compare:CC (mult:SI (sign_extend:SI
1444 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1446 (match_operand:HI 2 "gpc_reg_operand" "r")))
1448 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1449 (mult:SI (sign_extend:SI
1455 [(set_attr "type" "halfmul")])
1457 (define_insn "*mullhw"
1458 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1459 (mult:SI (sign_extend:SI
1460 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1462 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1465 [(set_attr "type" "halfmul")])
1467 (define_insn "*mullhwuc"
1468 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1469 (compare:CC (mult:SI (zero_extend:SI
1470 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1472 (match_operand:HI 2 "gpc_reg_operand" "r")))
1474 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1475 (mult:SI (zero_extend:SI
1481 [(set_attr "type" "halfmul")])
1483 (define_insn "*mullhwu"
1484 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1485 (mult:SI (zero_extend:SI
1486 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1488 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1491 [(set_attr "type" "halfmul")])
1493 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1494 (define_insn "dlmzb"
1495 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1496 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1497 (match_operand:SI 2 "gpc_reg_operand" "r")]
1499 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1500 (unspec:SI [(match_dup 1)
1506 (define_expand "strlensi"
1507 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1508 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1509 (match_operand:QI 2 "const_int_operand" "")
1510 (match_operand 3 "const_int_operand" "")]
1511 UNSPEC_DLMZB_STRLEN))
1512 (clobber (match_scratch:CC 4 "=x"))]
1513 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1515 rtx result = operands[0];
1516 rtx src = operands[1];
1517 rtx search_char = operands[2];
1518 rtx align = operands[3];
1519 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1520 rtx loop_label, end_label, mem, cr0, cond;
1521 if (search_char != const0_rtx
1522 || GET_CODE (align) != CONST_INT
1523 || INTVAL (align) < 8)
1525 word1 = gen_reg_rtx (SImode);
1526 word2 = gen_reg_rtx (SImode);
1527 scratch_dlmzb = gen_reg_rtx (SImode);
1528 scratch_string = gen_reg_rtx (Pmode);
1529 loop_label = gen_label_rtx ();
1530 end_label = gen_label_rtx ();
1531 addr = force_reg (Pmode, XEXP (src, 0));
1532 emit_move_insn (scratch_string, addr);
1533 emit_label (loop_label);
1534 mem = change_address (src, SImode, scratch_string);
1535 emit_move_insn (word1, mem);
1536 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1537 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1538 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1539 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1540 emit_jump_insn (gen_rtx_SET (pc_rtx,
1541 gen_rtx_IF_THEN_ELSE (VOIDmode,
1547 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1548 emit_jump_insn (gen_rtx_SET (pc_rtx,
1549 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1551 emit_label (end_label);
1552 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1553 emit_insn (gen_subsi3 (result, scratch_string, addr));
1554 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1558 ;; Fixed-point arithmetic insns.
1560 (define_expand "add<mode>3"
1561 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1562 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1563 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1566 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1568 rtx lo0 = gen_lowpart (SImode, operands[0]);
1569 rtx lo1 = gen_lowpart (SImode, operands[1]);
1570 rtx lo2 = gen_lowpart (SImode, operands[2]);
1571 rtx hi0 = gen_highpart (SImode, operands[0]);
1572 rtx hi1 = gen_highpart (SImode, operands[1]);
1573 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1575 if (!reg_or_short_operand (lo2, SImode))
1576 lo2 = force_reg (SImode, lo2);
1577 if (!adde_operand (hi2, SImode))
1578 hi2 = force_reg (SImode, hi2);
1580 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1581 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1585 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1587 rtx tmp = ((!can_create_pseudo_p ()
1588 || rtx_equal_p (operands[0], operands[1]))
1589 ? operands[0] : gen_reg_rtx (<MODE>mode));
1591 HOST_WIDE_INT val = INTVAL (operands[2]);
1592 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1593 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1595 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1598 /* The ordering here is important for the prolog expander.
1599 When space is allocated from the stack, adding 'low' first may
1600 produce a temporary deallocation (which would be bad). */
1601 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1602 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1607 (define_insn "*add<mode>3"
1608 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1609 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1610 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1616 [(set_attr "type" "add")])
1618 (define_insn "addsi3_high"
1619 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1620 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1621 (high:SI (match_operand 2 "" ""))))]
1622 "TARGET_MACHO && !TARGET_64BIT"
1623 "addis %0,%1,ha16(%2)"
1624 [(set_attr "type" "add")])
1626 (define_insn_and_split "*add<mode>3_dot"
1627 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1628 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1629 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1631 (clobber (match_scratch:GPR 0 "=r,r"))]
1632 "<MODE>mode == Pmode"
1636 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1638 (plus:GPR (match_dup 1)
1641 (compare:CC (match_dup 0)
1644 [(set_attr "type" "add")
1645 (set_attr "dot" "yes")
1646 (set_attr "length" "4,8")])
1648 (define_insn_and_split "*add<mode>3_dot2"
1649 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1650 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1651 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1653 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1654 (plus:GPR (match_dup 1)
1656 "<MODE>mode == Pmode"
1660 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1662 (plus:GPR (match_dup 1)
1665 (compare:CC (match_dup 0)
1668 [(set_attr "type" "add")
1669 (set_attr "dot" "yes")
1670 (set_attr "length" "4,8")])
1672 (define_insn_and_split "*add<mode>3_imm_dot"
1673 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1674 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1675 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1677 (clobber (match_scratch:GPR 0 "=r,r"))
1678 (clobber (reg:GPR CA_REGNO))]
1679 "<MODE>mode == Pmode"
1683 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1685 (plus:GPR (match_dup 1)
1688 (compare:CC (match_dup 0)
1691 [(set_attr "type" "add")
1692 (set_attr "dot" "yes")
1693 (set_attr "length" "4,8")])
1695 (define_insn_and_split "*add<mode>3_imm_dot2"
1696 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1697 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1698 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1700 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1701 (plus:GPR (match_dup 1)
1703 (clobber (reg:GPR CA_REGNO))]
1704 "<MODE>mode == Pmode"
1708 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1710 (plus:GPR (match_dup 1)
1713 (compare:CC (match_dup 0)
1716 [(set_attr "type" "add")
1717 (set_attr "dot" "yes")
1718 (set_attr "length" "4,8")])
1720 ;; Split an add that we can't do in one insn into two insns, each of which
1721 ;; does one 16-bit part. This is used by combine. Note that the low-order
1722 ;; add should be last in case the result gets used in an address.
1725 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1726 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1727 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1729 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1730 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1732 HOST_WIDE_INT val = INTVAL (operands[2]);
1733 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1734 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1736 operands[4] = GEN_INT (low);
1737 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1738 operands[3] = GEN_INT (rest);
1739 else if (can_create_pseudo_p ())
1741 operands[3] = gen_reg_rtx (DImode);
1742 emit_move_insn (operands[3], operands[2]);
1743 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1751 (define_insn "add<mode>3_carry"
1752 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1753 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1754 (match_operand:P 2 "reg_or_short_operand" "rI")))
1755 (set (reg:P CA_REGNO)
1756 (ltu:P (plus:P (match_dup 1)
1761 [(set_attr "type" "add")])
1763 (define_insn "*add<mode>3_imm_carry_pos"
1764 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1765 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1766 (match_operand:P 2 "short_cint_operand" "n")))
1767 (set (reg:P CA_REGNO)
1768 (geu:P (match_dup 1)
1769 (match_operand:P 3 "const_int_operand" "n")))]
1770 "INTVAL (operands[2]) > 0
1771 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1773 [(set_attr "type" "add")])
1775 (define_insn "*add<mode>3_imm_carry_0"
1776 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1777 (match_operand:P 1 "gpc_reg_operand" "r"))
1778 (set (reg:P CA_REGNO)
1782 [(set_attr "type" "add")])
1784 (define_insn "*add<mode>3_imm_carry_m1"
1785 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1786 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1788 (set (reg:P CA_REGNO)
1793 [(set_attr "type" "add")])
1795 (define_insn "*add<mode>3_imm_carry_neg"
1796 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1797 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1798 (match_operand:P 2 "short_cint_operand" "n")))
1799 (set (reg:P CA_REGNO)
1800 (gtu:P (match_dup 1)
1801 (match_operand:P 3 "const_int_operand" "n")))]
1802 "INTVAL (operands[2]) < 0
1803 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1805 [(set_attr "type" "add")])
1808 (define_expand "add<mode>3_carry_in"
1810 (set (match_operand:GPR 0 "gpc_reg_operand")
1811 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1812 (match_operand:GPR 2 "adde_operand"))
1813 (reg:GPR CA_REGNO)))
1814 (clobber (reg:GPR CA_REGNO))])]
1817 if (operands[2] == const0_rtx)
1819 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1822 if (operands[2] == constm1_rtx)
1824 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1829 (define_insn "*add<mode>3_carry_in_internal"
1830 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1831 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1832 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1833 (reg:GPR CA_REGNO)))
1834 (clobber (reg:GPR CA_REGNO))]
1837 [(set_attr "type" "add")])
1839 (define_insn "add<mode>3_carry_in_0"
1840 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1841 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1842 (reg:GPR CA_REGNO)))
1843 (clobber (reg:GPR CA_REGNO))]
1846 [(set_attr "type" "add")])
1848 (define_insn "add<mode>3_carry_in_m1"
1849 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1850 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1853 (clobber (reg:GPR CA_REGNO))]
1856 [(set_attr "type" "add")])
1859 (define_expand "one_cmpl<mode>2"
1860 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1861 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1864 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1866 rs6000_split_logical (operands, NOT, false, false, false);
1871 (define_insn "*one_cmpl<mode>2"
1872 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1873 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1877 (define_insn_and_split "*one_cmpl<mode>2_dot"
1878 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1879 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1881 (clobber (match_scratch:GPR 0 "=r,r"))]
1882 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1886 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1888 (not:GPR (match_dup 1)))
1890 (compare:CC (match_dup 0)
1893 [(set_attr "type" "logical")
1894 (set_attr "dot" "yes")
1895 (set_attr "length" "4,8")])
1897 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1898 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1899 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1901 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1902 (not:GPR (match_dup 1)))]
1903 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1907 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1909 (not:GPR (match_dup 1)))
1911 (compare:CC (match_dup 0)
1914 [(set_attr "type" "logical")
1915 (set_attr "dot" "yes")
1916 (set_attr "length" "4,8")])
1919 (define_expand "sub<mode>3"
1920 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1921 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1922 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1925 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1927 rtx lo0 = gen_lowpart (SImode, operands[0]);
1928 rtx lo1 = gen_lowpart (SImode, operands[1]);
1929 rtx lo2 = gen_lowpart (SImode, operands[2]);
1930 rtx hi0 = gen_highpart (SImode, operands[0]);
1931 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1932 rtx hi2 = gen_highpart (SImode, operands[2]);
1934 if (!reg_or_short_operand (lo1, SImode))
1935 lo1 = force_reg (SImode, lo1);
1936 if (!adde_operand (hi1, SImode))
1937 hi1 = force_reg (SImode, hi1);
1939 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1940 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1944 if (short_cint_operand (operands[1], <MODE>mode))
1946 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1951 (define_insn "*subf<mode>3"
1952 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1953 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1954 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1957 [(set_attr "type" "add")])
1959 (define_insn_and_split "*subf<mode>3_dot"
1960 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1961 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1962 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1964 (clobber (match_scratch:GPR 0 "=r,r"))]
1965 "<MODE>mode == Pmode"
1969 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1971 (minus:GPR (match_dup 2)
1974 (compare:CC (match_dup 0)
1977 [(set_attr "type" "add")
1978 (set_attr "dot" "yes")
1979 (set_attr "length" "4,8")])
1981 (define_insn_and_split "*subf<mode>3_dot2"
1982 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1983 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1984 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1986 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1987 (minus:GPR (match_dup 2)
1989 "<MODE>mode == Pmode"
1993 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1995 (minus:GPR (match_dup 2)
1998 (compare:CC (match_dup 0)
2001 [(set_attr "type" "add")
2002 (set_attr "dot" "yes")
2003 (set_attr "length" "4,8")])
2005 (define_insn "subf<mode>3_imm"
2006 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2007 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2008 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2009 (clobber (reg:GPR CA_REGNO))]
2012 [(set_attr "type" "add")])
2015 (define_insn "subf<mode>3_carry"
2016 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2017 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2018 (match_operand:P 1 "gpc_reg_operand" "r")))
2019 (set (reg:P CA_REGNO)
2020 (leu:P (match_dup 1)
2024 [(set_attr "type" "add")])
2026 (define_insn "*subf<mode>3_imm_carry_0"
2027 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2028 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2029 (set (reg:P CA_REGNO)
2034 [(set_attr "type" "add")])
2036 (define_insn "*subf<mode>3_imm_carry_m1"
2037 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2038 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2039 (set (reg:P CA_REGNO)
2043 [(set_attr "type" "add")])
2046 (define_expand "subf<mode>3_carry_in"
2048 (set (match_operand:GPR 0 "gpc_reg_operand")
2049 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2051 (match_operand:GPR 2 "adde_operand")))
2052 (clobber (reg:GPR CA_REGNO))])]
2055 if (operands[2] == const0_rtx)
2057 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2060 if (operands[2] == constm1_rtx)
2062 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2067 (define_insn "*subf<mode>3_carry_in_internal"
2068 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2069 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2071 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2072 (clobber (reg:GPR CA_REGNO))]
2075 [(set_attr "type" "add")])
2077 (define_insn "subf<mode>3_carry_in_0"
2078 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2079 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2080 (reg:GPR CA_REGNO)))
2081 (clobber (reg:GPR CA_REGNO))]
2084 [(set_attr "type" "add")])
2086 (define_insn "subf<mode>3_carry_in_m1"
2087 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2088 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2089 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2091 (clobber (reg:GPR CA_REGNO))]
2094 [(set_attr "type" "add")])
2096 (define_insn "subf<mode>3_carry_in_xx"
2097 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2098 (plus:GPR (reg:GPR CA_REGNO)
2100 (clobber (reg:GPR CA_REGNO))]
2103 [(set_attr "type" "add")])
2106 (define_insn "neg<mode>2"
2107 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2108 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2111 [(set_attr "type" "add")])
2113 (define_insn_and_split "*neg<mode>2_dot"
2114 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2115 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2117 (clobber (match_scratch:GPR 0 "=r,r"))]
2118 "<MODE>mode == Pmode"
2122 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2124 (neg:GPR (match_dup 1)))
2126 (compare:CC (match_dup 0)
2129 [(set_attr "type" "add")
2130 (set_attr "dot" "yes")
2131 (set_attr "length" "4,8")])
2133 (define_insn_and_split "*neg<mode>2_dot2"
2134 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2135 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2137 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2138 (neg:GPR (match_dup 1)))]
2139 "<MODE>mode == Pmode"
2143 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2145 (neg:GPR (match_dup 1)))
2147 (compare:CC (match_dup 0)
2150 [(set_attr "type" "add")
2151 (set_attr "dot" "yes")
2152 (set_attr "length" "4,8")])
2155 (define_insn "clz<mode>2"
2156 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2157 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2160 [(set_attr "type" "cntlz")])
2162 (define_expand "ctz<mode>2"
2164 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2166 (and:GPR (match_dup 1)
2169 (clz:GPR (match_dup 3)))
2170 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2171 (minus:GPR (match_dup 5)
2173 (clobber (reg:GPR CA_REGNO))])]
2178 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2182 operands[2] = gen_reg_rtx (<MODE>mode);
2183 operands[3] = gen_reg_rtx (<MODE>mode);
2184 operands[4] = gen_reg_rtx (<MODE>mode);
2185 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2188 (define_insn "ctz<mode>2_hw"
2189 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2190 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2193 [(set_attr "type" "cntlz")])
2195 (define_expand "ffs<mode>2"
2197 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2199 (and:GPR (match_dup 1)
2202 (clz:GPR (match_dup 3)))
2203 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2204 (minus:GPR (match_dup 5)
2206 (clobber (reg:GPR CA_REGNO))])]
2209 operands[2] = gen_reg_rtx (<MODE>mode);
2210 operands[3] = gen_reg_rtx (<MODE>mode);
2211 operands[4] = gen_reg_rtx (<MODE>mode);
2212 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2216 (define_expand "popcount<mode>2"
2217 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2218 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2219 "TARGET_POPCNTB || TARGET_POPCNTD"
2221 rs6000_emit_popcount (operands[0], operands[1]);
2225 (define_insn "popcntb<mode>2"
2226 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2227 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2231 [(set_attr "type" "popcnt")])
2233 (define_insn "popcntd<mode>2"
2234 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2235 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2238 [(set_attr "type" "popcnt")])
2241 (define_expand "parity<mode>2"
2242 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2243 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2246 rs6000_emit_parity (operands[0], operands[1]);
2250 (define_insn "parity<mode>2_cmpb"
2251 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2252 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2253 "TARGET_CMPB && TARGET_POPCNTB"
2255 [(set_attr "type" "popcnt")])
2258 ;; Since the hardware zeros the upper part of the register, save generating the
2259 ;; AND immediate if we are converting to unsigned
2260 (define_insn "*bswaphi2_extenddi"
2261 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2263 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2266 [(set_attr "length" "4")
2267 (set_attr "type" "load")])
2269 (define_insn "*bswaphi2_extendsi"
2270 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2272 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2275 [(set_attr "length" "4")
2276 (set_attr "type" "load")])
2278 (define_expand "bswaphi2"
2279 [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2281 (match_operand:HI 1 "reg_or_mem_operand" "")))
2282 (clobber (match_scratch:SI 2 ""))])]
2285 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2286 operands[1] = force_reg (HImode, operands[1]);
2289 (define_insn "bswaphi2_internal"
2290 [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2292 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2293 (clobber (match_scratch:SI 2 "=X,X,&r"))]
2299 [(set_attr "length" "4,4,12")
2300 (set_attr "type" "load,store,*")])
2303 [(set (match_operand:HI 0 "gpc_reg_operand" "")
2304 (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2305 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2308 (and:SI (lshiftrt:SI (match_dup 4)
2312 (and:SI (ashift:SI (match_dup 4)
2314 (const_int 65280))) ;; 0xff00
2316 (ior:SI (match_dup 3)
2320 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2321 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2324 (define_insn "*bswapsi2_extenddi"
2325 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2327 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2330 [(set_attr "length" "4")
2331 (set_attr "type" "load")])
2333 (define_expand "bswapsi2"
2334 [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2336 (match_operand:SI 1 "reg_or_mem_operand" "")))]
2339 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2340 operands[1] = force_reg (SImode, operands[1]);
2343 (define_insn "*bswapsi2_internal"
2344 [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2346 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2352 [(set_attr "length" "4,4,12")
2353 (set_attr "type" "load,store,*")])
2355 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2356 ;; zero_extract insns do not change for -mlittle.
2358 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2359 (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2361 [(set (match_dup 0) ; DABC
2362 (rotate:SI (match_dup 1)
2364 (set (match_dup 0) ; DCBC
2365 (ior:SI (and:SI (ashift:SI (match_dup 1)
2367 (const_int 16711680))
2368 (and:SI (match_dup 0)
2369 (const_int -16711681))))
2370 (set (match_dup 0) ; DCBA
2371 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2374 (and:SI (match_dup 0)
2380 (define_expand "bswapdi2"
2381 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2383 (match_operand:DI 1 "reg_or_mem_operand" "")))
2384 (clobber (match_scratch:DI 2 ""))
2385 (clobber (match_scratch:DI 3 ""))])]
2388 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2389 operands[1] = force_reg (DImode, operands[1]);
2391 if (!TARGET_POWERPC64)
2393 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2394 that uses 64-bit registers needs the same scratch registers as 64-bit
2396 emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2401 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2402 (define_insn "*bswapdi2_ldbrx"
2403 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2404 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2405 (clobber (match_scratch:DI 2 "=X,X,&r"))
2406 (clobber (match_scratch:DI 3 "=X,X,&r"))]
2407 "TARGET_POWERPC64 && TARGET_LDBRX
2408 && (REG_P (operands[0]) || REG_P (operands[1]))"
2413 [(set_attr "length" "4,4,36")
2414 (set_attr "type" "load,store,*")])
2416 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2417 (define_insn "*bswapdi2_64bit"
2418 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2419 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2420 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2421 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2422 "TARGET_POWERPC64 && !TARGET_LDBRX
2423 && (REG_P (operands[0]) || REG_P (operands[1]))
2424 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2425 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2427 [(set_attr "length" "16,12,36")])
2430 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2431 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2432 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2433 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2434 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2438 rtx dest = operands[0];
2439 rtx src = operands[1];
2440 rtx op2 = operands[2];
2441 rtx op3 = operands[3];
2442 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2443 BYTES_BIG_ENDIAN ? 4 : 0);
2444 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2445 BYTES_BIG_ENDIAN ? 4 : 0);
2451 addr1 = XEXP (src, 0);
2452 if (GET_CODE (addr1) == PLUS)
2454 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2455 if (TARGET_AVOID_XFORM)
2457 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2461 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2463 else if (TARGET_AVOID_XFORM)
2465 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2470 emit_move_insn (op2, GEN_INT (4));
2471 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2474 word1 = change_address (src, SImode, addr1);
2475 word2 = change_address (src, SImode, addr2);
2477 if (BYTES_BIG_ENDIAN)
2479 emit_insn (gen_bswapsi2 (op3_32, word2));
2480 emit_insn (gen_bswapsi2 (dest_32, word1));
2484 emit_insn (gen_bswapsi2 (op3_32, word1));
2485 emit_insn (gen_bswapsi2 (dest_32, word2));
2488 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2489 emit_insn (gen_iordi3 (dest, dest, op3));
2494 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2495 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2496 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2497 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2498 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2502 rtx dest = operands[0];
2503 rtx src = operands[1];
2504 rtx op2 = operands[2];
2505 rtx op3 = operands[3];
2506 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2507 BYTES_BIG_ENDIAN ? 4 : 0);
2508 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2509 BYTES_BIG_ENDIAN ? 4 : 0);
2515 addr1 = XEXP (dest, 0);
2516 if (GET_CODE (addr1) == PLUS)
2518 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2519 if (TARGET_AVOID_XFORM)
2521 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2525 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2527 else if (TARGET_AVOID_XFORM)
2529 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2534 emit_move_insn (op2, GEN_INT (4));
2535 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2538 word1 = change_address (dest, SImode, addr1);
2539 word2 = change_address (dest, SImode, addr2);
2541 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2543 if (BYTES_BIG_ENDIAN)
2545 emit_insn (gen_bswapsi2 (word1, src_si));
2546 emit_insn (gen_bswapsi2 (word2, op3_si));
2550 emit_insn (gen_bswapsi2 (word2, src_si));
2551 emit_insn (gen_bswapsi2 (word1, op3_si));
2557 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2558 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2559 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2560 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2561 "TARGET_POWERPC64 && reload_completed"
2565 rtx dest = operands[0];
2566 rtx src = operands[1];
2567 rtx op2 = operands[2];
2568 rtx op3 = operands[3];
2569 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2570 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2571 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2572 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2573 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2575 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2576 emit_insn (gen_bswapsi2 (dest_si, src_si));
2577 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2578 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2579 emit_insn (gen_iordi3 (dest, dest, op3));
2583 (define_insn "bswapdi2_32bit"
2584 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2585 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2586 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2587 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2589 [(set_attr "length" "16,12,36")])
2592 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2593 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2594 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2595 "!TARGET_POWERPC64 && reload_completed"
2599 rtx dest = operands[0];
2600 rtx src = operands[1];
2601 rtx op2 = operands[2];
2602 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2603 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2609 addr1 = XEXP (src, 0);
2610 if (GET_CODE (addr1) == PLUS)
2612 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2613 if (TARGET_AVOID_XFORM
2614 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2616 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2620 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2622 else if (TARGET_AVOID_XFORM
2623 || REGNO (addr1) == REGNO (dest2))
2625 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2630 emit_move_insn (op2, GEN_INT (4));
2631 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2634 word1 = change_address (src, SImode, addr1);
2635 word2 = change_address (src, SImode, addr2);
2637 emit_insn (gen_bswapsi2 (dest2, word1));
2638 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2639 thus allowing us to omit an early clobber on the output. */
2640 emit_insn (gen_bswapsi2 (dest1, word2));
2645 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2646 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2647 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2648 "!TARGET_POWERPC64 && reload_completed"
2652 rtx dest = operands[0];
2653 rtx src = operands[1];
2654 rtx op2 = operands[2];
2655 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2656 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2662 addr1 = XEXP (dest, 0);
2663 if (GET_CODE (addr1) == PLUS)
2665 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2666 if (TARGET_AVOID_XFORM)
2668 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2672 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2674 else if (TARGET_AVOID_XFORM)
2676 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2681 emit_move_insn (op2, GEN_INT (4));
2682 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2685 word1 = change_address (dest, SImode, addr1);
2686 word2 = change_address (dest, SImode, addr2);
2688 emit_insn (gen_bswapsi2 (word2, src1));
2689 emit_insn (gen_bswapsi2 (word1, src2));
2694 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2695 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2696 (clobber (match_operand:SI 2 "" ""))]
2697 "!TARGET_POWERPC64 && reload_completed"
2701 rtx dest = operands[0];
2702 rtx src = operands[1];
2703 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2704 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2705 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2706 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2708 emit_insn (gen_bswapsi2 (dest1, src2));
2709 emit_insn (gen_bswapsi2 (dest2, src1));
2714 (define_insn "mul<mode>3"
2715 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2716 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2717 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2722 [(set_attr "type" "mul")
2724 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2726 (match_operand:GPR 2 "short_cint_operand" "")
2727 (const_string "16")]
2728 (const_string "<bits>")))])
2730 (define_insn_and_split "*mul<mode>3_dot"
2731 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2732 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2733 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2735 (clobber (match_scratch:GPR 0 "=r,r"))]
2736 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2740 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2742 (mult:GPR (match_dup 1)
2745 (compare:CC (match_dup 0)
2748 [(set_attr "type" "mul")
2749 (set_attr "size" "<bits>")
2750 (set_attr "dot" "yes")
2751 (set_attr "length" "4,8")])
2753 (define_insn_and_split "*mul<mode>3_dot2"
2754 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2755 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2756 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2758 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2759 (mult:GPR (match_dup 1)
2761 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2765 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2767 (mult:GPR (match_dup 1)
2770 (compare:CC (match_dup 0)
2773 [(set_attr "type" "mul")
2774 (set_attr "size" "<bits>")
2775 (set_attr "dot" "yes")
2776 (set_attr "length" "4,8")])
2779 (define_expand "<su>mul<mode>3_highpart"
2780 [(set (match_operand:GPR 0 "gpc_reg_operand")
2782 (mult:<DMODE> (any_extend:<DMODE>
2783 (match_operand:GPR 1 "gpc_reg_operand"))
2785 (match_operand:GPR 2 "gpc_reg_operand")))
2789 if (<MODE>mode == SImode && TARGET_POWERPC64)
2791 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2796 if (!WORDS_BIG_ENDIAN)
2798 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2804 (define_insn "*<su>mul<mode>3_highpart"
2805 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2807 (mult:<DMODE> (any_extend:<DMODE>
2808 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2810 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2812 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2813 "mulh<wd><u> %0,%1,%2"
2814 [(set_attr "type" "mul")
2815 (set_attr "size" "<bits>")])
2817 (define_insn "<su>mulsi3_highpart_le"
2818 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2820 (mult:DI (any_extend:DI
2821 (match_operand:SI 1 "gpc_reg_operand" "r"))
2823 (match_operand:SI 2 "gpc_reg_operand" "r")))
2825 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2827 [(set_attr "type" "mul")])
2829 (define_insn "<su>muldi3_highpart_le"
2830 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2832 (mult:TI (any_extend:TI
2833 (match_operand:DI 1 "gpc_reg_operand" "r"))
2835 (match_operand:DI 2 "gpc_reg_operand" "r")))
2837 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2839 [(set_attr "type" "mul")
2840 (set_attr "size" "64")])
2842 (define_insn "<su>mulsi3_highpart_64"
2843 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2846 (mult:DI (any_extend:DI
2847 (match_operand:SI 1 "gpc_reg_operand" "r"))
2849 (match_operand:SI 2 "gpc_reg_operand" "r")))
2853 [(set_attr "type" "mul")])
2855 (define_expand "<u>mul<mode><dmode>3"
2856 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2857 (mult:<DMODE> (any_extend:<DMODE>
2858 (match_operand:GPR 1 "gpc_reg_operand"))
2860 (match_operand:GPR 2 "gpc_reg_operand"))))]
2861 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2863 rtx l = gen_reg_rtx (<MODE>mode);
2864 rtx h = gen_reg_rtx (<MODE>mode);
2865 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2866 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2867 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2868 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2872 (define_insn "*maddld4"
2873 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2874 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2875 (match_operand:DI 2 "gpc_reg_operand" "r"))
2876 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2878 "maddld %0,%1,%2,%3"
2879 [(set_attr "type" "mul")])
2881 (define_insn "udiv<mode>3"
2882 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2883 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2884 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2887 [(set_attr "type" "div")
2888 (set_attr "size" "<bits>")])
2891 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2892 ;; modulus. If it isn't a power of two, force operands into register and do
2894 (define_expand "div<mode>3"
2895 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2896 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2897 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2900 if (CONST_INT_P (operands[2])
2901 && INTVAL (operands[2]) > 0
2902 && exact_log2 (INTVAL (operands[2])) >= 0)
2904 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2908 operands[2] = force_reg (<MODE>mode, operands[2]);
2911 (define_insn "*div<mode>3"
2912 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2913 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2914 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2917 [(set_attr "type" "div")
2918 (set_attr "size" "<bits>")])
2920 (define_insn "div<mode>3_sra"
2921 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2922 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2923 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2924 (clobber (reg:GPR CA_REGNO))]
2926 "sra<wd>i %0,%1,%p2\;addze %0,%0"
2927 [(set_attr "type" "two")
2928 (set_attr "length" "8")])
2930 (define_insn_and_split "*div<mode>3_sra_dot"
2931 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2932 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2933 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2935 (clobber (match_scratch:GPR 0 "=r,r"))
2936 (clobber (reg:GPR CA_REGNO))]
2937 "<MODE>mode == Pmode"
2939 sra<wd>i %0,%1,%p2\;addze. %0,%0
2941 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2942 [(parallel [(set (match_dup 0)
2943 (div:GPR (match_dup 1)
2945 (clobber (reg:GPR CA_REGNO))])
2947 (compare:CC (match_dup 0)
2950 [(set_attr "type" "two")
2951 (set_attr "length" "8,12")
2952 (set_attr "cell_micro" "not")])
2954 (define_insn_and_split "*div<mode>3_sra_dot2"
2955 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2956 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2957 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2959 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2960 (div:GPR (match_dup 1)
2962 (clobber (reg:GPR CA_REGNO))]
2963 "<MODE>mode == Pmode"
2965 sra<wd>i %0,%1,%p2\;addze. %0,%0
2967 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2968 [(parallel [(set (match_dup 0)
2969 (div:GPR (match_dup 1)
2971 (clobber (reg:GPR CA_REGNO))])
2973 (compare:CC (match_dup 0)
2976 [(set_attr "type" "two")
2977 (set_attr "length" "8,12")
2978 (set_attr "cell_micro" "not")])
2980 (define_expand "mod<mode>3"
2981 [(set (match_operand:GPR 0 "gpc_reg_operand")
2982 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
2983 (match_operand:GPR 2 "reg_or_cint_operand")))]
2990 if (GET_CODE (operands[2]) != CONST_INT
2991 || INTVAL (operands[2]) <= 0
2992 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
2997 operands[2] = force_reg (<MODE>mode, operands[2]);
3001 temp1 = gen_reg_rtx (<MODE>mode);
3002 temp2 = gen_reg_rtx (<MODE>mode);
3004 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3005 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3006 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3011 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3012 ;; mod, prefer putting the result of mod into a different register
3013 (define_insn "*mod<mode>3"
3014 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3015 (mod: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>")])
3023 (define_insn "umod<mode>3"
3024 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3025 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3026 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3029 [(set_attr "type" "div")
3030 (set_attr "size" "<bits>")])
3032 ;; On machines with modulo support, do a combined div/mod the old fashioned
3033 ;; method, since the multiply/subtract is faster than doing the mod instruction
3037 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3038 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3039 (match_operand:GPR 2 "gpc_reg_operand" "")))
3040 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3041 (mod:GPR (match_dup 1)
3044 && ! reg_mentioned_p (operands[0], operands[1])
3045 && ! reg_mentioned_p (operands[0], operands[2])
3046 && ! reg_mentioned_p (operands[3], operands[1])
3047 && ! reg_mentioned_p (operands[3], operands[2])"
3049 (div:GPR (match_dup 1)
3052 (mult:GPR (match_dup 0)
3055 (minus:GPR (match_dup 1)
3059 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3060 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3061 (match_operand:GPR 2 "gpc_reg_operand" "")))
3062 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3063 (umod:GPR (match_dup 1)
3066 && ! reg_mentioned_p (operands[0], operands[1])
3067 && ! reg_mentioned_p (operands[0], operands[2])
3068 && ! reg_mentioned_p (operands[3], operands[1])
3069 && ! reg_mentioned_p (operands[3], operands[2])"
3071 (div:GPR (match_dup 1)
3074 (mult:GPR (match_dup 0)
3077 (minus:GPR (match_dup 1)
3081 ;; Logical instructions
3082 ;; The logical instructions are mostly combined by using match_operator,
3083 ;; but the plain AND insns are somewhat different because there is no
3084 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3085 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3087 (define_expand "and<mode>3"
3088 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3089 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3090 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3093 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3095 rs6000_split_logical (operands, AND, false, false, false);
3099 if (CONST_INT_P (operands[2]))
3101 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3103 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3107 if (logical_const_operand (operands[2], <MODE>mode)
3108 && rs6000_gen_cell_microcode)
3110 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3114 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3116 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3120 operands[2] = force_reg (<MODE>mode, operands[2]);
3125 (define_insn "and<mode>3_imm"
3126 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3127 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3128 (match_operand:GPR 2 "logical_const_operand" "n")))
3129 (clobber (match_scratch:CC 3 "=x"))]
3130 "rs6000_gen_cell_microcode
3131 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3132 "andi%e2. %0,%1,%u2"
3133 [(set_attr "type" "logical")
3134 (set_attr "dot" "yes")])
3136 (define_insn_and_split "*and<mode>3_imm_dot"
3137 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3138 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3139 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3141 (clobber (match_scratch:GPR 0 "=r,r"))
3142 (clobber (match_scratch:CC 4 "=X,x"))]
3143 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3144 && rs6000_gen_cell_microcode
3145 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3149 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3150 [(parallel [(set (match_dup 0)
3151 (and:GPR (match_dup 1)
3153 (clobber (match_dup 4))])
3155 (compare:CC (match_dup 0)
3158 [(set_attr "type" "logical")
3159 (set_attr "dot" "yes")
3160 (set_attr "length" "4,8")])
3162 (define_insn_and_split "*and<mode>3_imm_dot2"
3163 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3164 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3165 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3167 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3168 (and:GPR (match_dup 1)
3170 (clobber (match_scratch:CC 4 "=X,x"))]
3171 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3172 && rs6000_gen_cell_microcode
3173 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3177 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3178 [(parallel [(set (match_dup 0)
3179 (and:GPR (match_dup 1)
3181 (clobber (match_dup 4))])
3183 (compare:CC (match_dup 0)
3186 [(set_attr "type" "logical")
3187 (set_attr "dot" "yes")
3188 (set_attr "length" "4,8")])
3190 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3191 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3192 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3193 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3195 (clobber (match_scratch:GPR 0 "=r,r"))]
3196 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3197 && rs6000_gen_cell_microcode"
3201 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3203 (and:GPR (match_dup 1)
3206 (compare:CC (match_dup 0)
3209 [(set_attr "type" "logical")
3210 (set_attr "dot" "yes")
3211 (set_attr "length" "4,8")])
3213 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3214 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3215 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3216 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3218 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3219 (and:GPR (match_dup 1)
3221 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3222 && rs6000_gen_cell_microcode"
3226 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3228 (and:GPR (match_dup 1)
3231 (compare:CC (match_dup 0)
3234 [(set_attr "type" "logical")
3235 (set_attr "dot" "yes")
3236 (set_attr "length" "4,8")])
3238 (define_insn "*and<mode>3_imm_dot_shifted"
3239 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3242 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3243 (match_operand:SI 4 "const_int_operand" "n"))
3244 (match_operand:GPR 2 "const_int_operand" "n"))
3246 (clobber (match_scratch:GPR 0 "=r"))]
3247 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3248 << INTVAL (operands[4])),
3250 && (<MODE>mode == Pmode
3251 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3252 && rs6000_gen_cell_microcode"
3254 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3255 return "andi%e2. %0,%1,%u2";
3257 [(set_attr "type" "logical")
3258 (set_attr "dot" "yes")])
3261 (define_insn "and<mode>3_mask"
3262 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3263 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3264 (match_operand:GPR 2 "const_int_operand" "n")))]
3265 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3267 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3269 [(set_attr "type" "shift")])
3271 (define_insn_and_split "*and<mode>3_mask_dot"
3272 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3273 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3274 (match_operand:GPR 2 "const_int_operand" "n,n"))
3276 (clobber (match_scratch:GPR 0 "=r,r"))]
3277 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3278 && rs6000_gen_cell_microcode
3279 && !logical_const_operand (operands[2], <MODE>mode)
3280 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3282 if (which_alternative == 0)
3283 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3287 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3289 (and:GPR (match_dup 1)
3292 (compare:CC (match_dup 0)
3295 [(set_attr "type" "shift")
3296 (set_attr "dot" "yes")
3297 (set_attr "length" "4,8")])
3299 (define_insn_and_split "*and<mode>3_mask_dot2"
3300 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3301 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3302 (match_operand:GPR 2 "const_int_operand" "n,n"))
3304 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3305 (and:GPR (match_dup 1)
3307 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3308 && rs6000_gen_cell_microcode
3309 && !logical_const_operand (operands[2], <MODE>mode)
3310 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3312 if (which_alternative == 0)
3313 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3317 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3319 (and:GPR (match_dup 1)
3322 (compare:CC (match_dup 0)
3325 [(set_attr "type" "shift")
3326 (set_attr "dot" "yes")
3327 (set_attr "length" "4,8")])
3330 (define_insn_and_split "*and<mode>3_2insn"
3331 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3332 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3333 (match_operand:GPR 2 "const_int_operand" "n")))]
3334 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3335 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3336 || (logical_const_operand (operands[2], <MODE>mode)
3337 && rs6000_gen_cell_microcode))"
3342 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3345 [(set_attr "type" "shift")
3346 (set_attr "length" "8")])
3348 (define_insn_and_split "*and<mode>3_2insn_dot"
3349 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3350 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3351 (match_operand:GPR 2 "const_int_operand" "n,n"))
3353 (clobber (match_scratch:GPR 0 "=r,r"))]
3354 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3355 && rs6000_gen_cell_microcode
3356 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3357 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3358 || (logical_const_operand (operands[2], <MODE>mode)
3359 && rs6000_gen_cell_microcode))"
3361 "&& reload_completed"
3364 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3367 [(set_attr "type" "shift")
3368 (set_attr "dot" "yes")
3369 (set_attr "length" "8,12")])
3371 (define_insn_and_split "*and<mode>3_2insn_dot2"
3372 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3373 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3374 (match_operand:GPR 2 "const_int_operand" "n,n"))
3376 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3377 (and:GPR (match_dup 1)
3379 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3380 && rs6000_gen_cell_microcode
3381 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3382 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3383 || (logical_const_operand (operands[2], <MODE>mode)
3384 && rs6000_gen_cell_microcode))"
3386 "&& reload_completed"
3389 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3392 [(set_attr "type" "shift")
3393 (set_attr "dot" "yes")
3394 (set_attr "length" "8,12")])
3397 (define_expand "<code><mode>3"
3398 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3399 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3400 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3403 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3405 rs6000_split_logical (operands, <CODE>, false, false, false);
3409 if (non_logical_cint_operand (operands[2], <MODE>mode))
3411 rtx tmp = ((!can_create_pseudo_p ()
3412 || rtx_equal_p (operands[0], operands[1]))
3413 ? operands[0] : gen_reg_rtx (<MODE>mode));
3415 HOST_WIDE_INT value = INTVAL (operands[2]);
3416 HOST_WIDE_INT lo = value & 0xffff;
3417 HOST_WIDE_INT hi = value - lo;
3419 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3420 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3424 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3425 operands[2] = force_reg (<MODE>mode, operands[2]);
3429 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3430 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3431 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3434 (iorxor:GPR (match_dup 1)
3437 (iorxor:GPR (match_dup 3)
3440 operands[3] = ((!can_create_pseudo_p ()
3441 || rtx_equal_p (operands[0], operands[1]))
3442 ? operands[0] : gen_reg_rtx (<MODE>mode));
3444 HOST_WIDE_INT value = INTVAL (operands[2]);
3445 HOST_WIDE_INT lo = value & 0xffff;
3446 HOST_WIDE_INT hi = value - lo;
3448 operands[4] = GEN_INT (hi);
3449 operands[5] = GEN_INT (lo);
3452 (define_insn "*bool<mode>3_imm"
3453 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3454 (match_operator:GPR 3 "boolean_or_operator"
3455 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3456 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3459 [(set_attr "type" "logical")])
3461 (define_insn "*bool<mode>3"
3462 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3463 (match_operator:GPR 3 "boolean_operator"
3464 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3465 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3468 [(set_attr "type" "logical")])
3470 (define_insn_and_split "*bool<mode>3_dot"
3471 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3472 (compare:CC (match_operator:GPR 3 "boolean_operator"
3473 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3474 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3476 (clobber (match_scratch:GPR 0 "=r,r"))]
3477 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3481 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3485 (compare:CC (match_dup 0)
3488 [(set_attr "type" "logical")
3489 (set_attr "dot" "yes")
3490 (set_attr "length" "4,8")])
3492 (define_insn_and_split "*bool<mode>3_dot2"
3493 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3494 (compare:CC (match_operator:GPR 3 "boolean_operator"
3495 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3496 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3498 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3500 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3504 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3508 (compare:CC (match_dup 0)
3511 [(set_attr "type" "logical")
3512 (set_attr "dot" "yes")
3513 (set_attr "length" "4,8")])
3516 (define_insn "*boolc<mode>3"
3517 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3518 (match_operator:GPR 3 "boolean_operator"
3519 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3520 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3523 [(set_attr "type" "logical")])
3525 (define_insn_and_split "*boolc<mode>3_dot"
3526 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3527 (compare:CC (match_operator:GPR 3 "boolean_operator"
3528 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3529 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3531 (clobber (match_scratch:GPR 0 "=r,r"))]
3532 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3536 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3540 (compare:CC (match_dup 0)
3543 [(set_attr "type" "logical")
3544 (set_attr "dot" "yes")
3545 (set_attr "length" "4,8")])
3547 (define_insn_and_split "*boolc<mode>3_dot2"
3548 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3549 (compare:CC (match_operator:GPR 3 "boolean_operator"
3550 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3551 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3553 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3555 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3559 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3563 (compare:CC (match_dup 0)
3566 [(set_attr "type" "logical")
3567 (set_attr "dot" "yes")
3568 (set_attr "length" "4,8")])
3571 (define_insn "*boolcc<mode>3"
3572 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3573 (match_operator:GPR 3 "boolean_operator"
3574 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3575 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3578 [(set_attr "type" "logical")])
3580 (define_insn_and_split "*boolcc<mode>3_dot"
3581 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3582 (compare:CC (match_operator:GPR 3 "boolean_operator"
3583 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3584 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3586 (clobber (match_scratch:GPR 0 "=r,r"))]
3587 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3591 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3595 (compare:CC (match_dup 0)
3598 [(set_attr "type" "logical")
3599 (set_attr "dot" "yes")
3600 (set_attr "length" "4,8")])
3602 (define_insn_and_split "*boolcc<mode>3_dot2"
3603 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3604 (compare:CC (match_operator:GPR 3 "boolean_operator"
3605 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3606 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3608 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3610 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3614 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3618 (compare:CC (match_dup 0)
3621 [(set_attr "type" "logical")
3622 (set_attr "dot" "yes")
3623 (set_attr "length" "4,8")])
3626 ;; TODO: Should have dots of this as well.
3627 (define_insn "*eqv<mode>3"
3628 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3629 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3630 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3633 [(set_attr "type" "logical")])
3635 ;; Rotate-and-mask and insert.
3637 (define_insn "*rotl<mode>3_mask"
3638 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3639 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3640 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3641 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3642 (match_operand:GPR 3 "const_int_operand" "n")))]
3643 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3645 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3647 [(set_attr "type" "shift")
3648 (set_attr "maybe_var_shift" "yes")])
3650 (define_insn_and_split "*rotl<mode>3_mask_dot"
3651 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3653 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3654 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3655 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3656 (match_operand:GPR 3 "const_int_operand" "n,n"))
3658 (clobber (match_scratch:GPR 0 "=r,r"))]
3659 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3660 && rs6000_gen_cell_microcode
3661 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3663 if (which_alternative == 0)
3664 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3668 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3670 (and:GPR (match_dup 4)
3673 (compare:CC (match_dup 0)
3676 [(set_attr "type" "shift")
3677 (set_attr "maybe_var_shift" "yes")
3678 (set_attr "dot" "yes")
3679 (set_attr "length" "4,8")])
3681 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3682 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3684 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3685 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3686 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3687 (match_operand:GPR 3 "const_int_operand" "n,n"))
3689 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3690 (and:GPR (match_dup 4)
3692 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3693 && rs6000_gen_cell_microcode
3694 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3696 if (which_alternative == 0)
3697 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3701 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3703 (and:GPR (match_dup 4)
3706 (compare:CC (match_dup 0)
3709 [(set_attr "type" "shift")
3710 (set_attr "maybe_var_shift" "yes")
3711 (set_attr "dot" "yes")
3712 (set_attr "length" "4,8")])
3714 ; Special case for less-than-0. We can do it with just one machine
3715 ; instruction, but the generic optimizers do not realise it is cheap.
3716 (define_insn "*lt0_disi"
3717 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3718 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3721 "rlwinm %0,%1,1,31,31"
3722 [(set_attr "type" "shift")])
3726 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3727 ; both are an AND so are the same precedence).
3728 (define_insn "*rotl<mode>3_insert"
3729 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3730 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3731 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3732 (match_operand:SI 2 "const_int_operand" "n")])
3733 (match_operand:GPR 3 "const_int_operand" "n"))
3734 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3735 (match_operand:GPR 6 "const_int_operand" "n"))))]
3736 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3737 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3739 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3741 [(set_attr "type" "insert")])
3742 ; FIXME: this needs an attr "size", so that the scheduler can see the
3743 ; difference between rlwimi and rldimi. We also might want dot forms,
3744 ; but not for rlwimi on POWER4 and similar processors.
3746 (define_insn "*rotl<mode>3_insert_2"
3747 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3748 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3749 (match_operand:GPR 6 "const_int_operand" "n"))
3750 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3751 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3752 (match_operand:SI 2 "const_int_operand" "n")])
3753 (match_operand:GPR 3 "const_int_operand" "n"))))]
3754 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3755 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3757 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3759 [(set_attr "type" "insert")])
3761 ; There are also some forms without one of the ANDs.
3762 (define_insn "*rotl<mode>3_insert_3"
3763 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3764 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3765 (match_operand:GPR 4 "const_int_operand" "n"))
3766 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3767 (match_operand:SI 2 "const_int_operand" "n"))))]
3768 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3770 if (<MODE>mode == SImode)
3771 return "rlwimi %0,%1,%h2,0,31-%h2";
3773 return "rldimi %0,%1,%H2,0";
3775 [(set_attr "type" "insert")])
3777 (define_insn "*rotl<mode>3_insert_4"
3778 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3779 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3780 (match_operand:GPR 4 "const_int_operand" "n"))
3781 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3782 (match_operand:SI 2 "const_int_operand" "n"))))]
3783 "<MODE>mode == SImode &&
3784 GET_MODE_PRECISION (<MODE>mode)
3785 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3787 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3788 - INTVAL (operands[2]));
3789 if (<MODE>mode == SImode)
3790 return "rlwimi %0,%1,%h2,32-%h2,31";
3792 return "rldimi %0,%1,%H2,64-%H2";
3794 [(set_attr "type" "insert")])
3797 ; This handles the important case of multiple-precision shifts. There is
3798 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3800 [(set (match_operand:GPR 0 "gpc_reg_operand")
3801 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3802 (match_operand:SI 3 "const_int_operand"))
3803 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3804 (match_operand:SI 4 "const_int_operand"))))]
3805 "can_create_pseudo_p ()
3806 && INTVAL (operands[3]) + INTVAL (operands[4])
3807 >= GET_MODE_PRECISION (<MODE>mode)"
3809 (lshiftrt:GPR (match_dup 2)
3812 (ior:GPR (and:GPR (match_dup 5)
3814 (ashift:GPR (match_dup 1)
3817 unsigned HOST_WIDE_INT mask = 1;
3818 mask = (mask << INTVAL (operands[3])) - 1;
3819 operands[5] = gen_reg_rtx (<MODE>mode);
3820 operands[6] = GEN_INT (mask);
3824 [(set (match_operand:GPR 0 "gpc_reg_operand")
3825 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3826 (match_operand:SI 4 "const_int_operand"))
3827 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3828 (match_operand:SI 3 "const_int_operand"))))]
3829 "can_create_pseudo_p ()
3830 && INTVAL (operands[3]) + INTVAL (operands[4])
3831 >= GET_MODE_PRECISION (<MODE>mode)"
3833 (lshiftrt:GPR (match_dup 2)
3836 (ior:GPR (and:GPR (match_dup 5)
3838 (ashift:GPR (match_dup 1)
3841 unsigned HOST_WIDE_INT mask = 1;
3842 mask = (mask << INTVAL (operands[3])) - 1;
3843 operands[5] = gen_reg_rtx (<MODE>mode);
3844 operands[6] = GEN_INT (mask);
3848 ; Another important case is setting some bits to 1; we can do that with
3849 ; an insert instruction, in many cases.
3850 (define_insn_and_split "*ior<mode>_mask"
3851 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3852 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3853 (match_operand:GPR 2 "const_int_operand" "n")))
3854 (clobber (match_scratch:GPR 3 "=r"))]
3855 "!logical_const_operand (operands[2], <MODE>mode)
3856 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3862 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3865 (and:GPR (match_dup 1)
3869 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3870 if (GET_CODE (operands[3]) == SCRATCH)
3871 operands[3] = gen_reg_rtx (<MODE>mode);
3872 operands[4] = GEN_INT (ne);
3873 operands[5] = GEN_INT (~UINTVAL (operands[2]));
3875 [(set_attr "type" "two")
3876 (set_attr "length" "8")])
3879 ;; Now the simple shifts.
3881 (define_insn "rotl<mode>3"
3882 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3883 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3884 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3886 "rotl<wd>%I2 %0,%1,%<hH>2"
3887 [(set_attr "type" "shift")
3888 (set_attr "maybe_var_shift" "yes")])
3890 (define_insn "*rotlsi3_64"
3891 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3893 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3894 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3896 "rotlw%I2 %0,%1,%h2"
3897 [(set_attr "type" "shift")
3898 (set_attr "maybe_var_shift" "yes")])
3900 (define_insn_and_split "*rotl<mode>3_dot"
3901 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3902 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3903 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3905 (clobber (match_scratch:GPR 0 "=r,r"))]
3906 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3908 rotl<wd>%I2. %0,%1,%<hH>2
3910 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3912 (rotate:GPR (match_dup 1)
3915 (compare:CC (match_dup 0)
3918 [(set_attr "type" "shift")
3919 (set_attr "maybe_var_shift" "yes")
3920 (set_attr "dot" "yes")
3921 (set_attr "length" "4,8")])
3923 (define_insn_and_split "*rotl<mode>3_dot2"
3924 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3925 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3926 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3928 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3929 (rotate:GPR (match_dup 1)
3931 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3933 rotl<wd>%I2. %0,%1,%<hH>2
3935 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3937 (rotate:GPR (match_dup 1)
3940 (compare:CC (match_dup 0)
3943 [(set_attr "type" "shift")
3944 (set_attr "maybe_var_shift" "yes")
3945 (set_attr "dot" "yes")
3946 (set_attr "length" "4,8")])
3949 (define_insn "ashl<mode>3"
3950 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3951 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3952 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3954 "sl<wd>%I2 %0,%1,%<hH>2"
3955 [(set_attr "type" "shift")
3956 (set_attr "maybe_var_shift" "yes")])
3958 (define_insn "*ashlsi3_64"
3959 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3961 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3962 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3965 [(set_attr "type" "shift")
3966 (set_attr "maybe_var_shift" "yes")])
3968 (define_insn_and_split "*ashl<mode>3_dot"
3969 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3970 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3971 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3973 (clobber (match_scratch:GPR 0 "=r,r"))]
3974 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3976 sl<wd>%I2. %0,%1,%<hH>2
3978 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3980 (ashift:GPR (match_dup 1)
3983 (compare:CC (match_dup 0)
3986 [(set_attr "type" "shift")
3987 (set_attr "maybe_var_shift" "yes")
3988 (set_attr "dot" "yes")
3989 (set_attr "length" "4,8")])
3991 (define_insn_and_split "*ashl<mode>3_dot2"
3992 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3993 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3994 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3996 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3997 (ashift:GPR (match_dup 1)
3999 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4001 sl<wd>%I2. %0,%1,%<hH>2
4003 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4005 (ashift:GPR (match_dup 1)
4008 (compare:CC (match_dup 0)
4011 [(set_attr "type" "shift")
4012 (set_attr "maybe_var_shift" "yes")
4013 (set_attr "dot" "yes")
4014 (set_attr "length" "4,8")])
4016 ;; Pretend we have a memory form of extswsli until register allocation is done
4017 ;; so that we use LWZ to load the value from memory, instead of LWA.
4018 (define_insn_and_split "ashdi3_extswsli"
4019 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4021 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4022 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4027 "&& reload_completed && MEM_P (operands[1])"
4031 (ashift:DI (sign_extend:DI (match_dup 3))
4034 operands[3] = gen_lowpart (SImode, operands[0]);
4036 [(set_attr "type" "shift")
4037 (set_attr "maybe_var_shift" "no")])
4040 (define_insn_and_split "ashdi3_extswsli_dot"
4041 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4044 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4045 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4047 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4054 "&& reload_completed
4055 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4056 || memory_operand (operands[1], SImode))"
4059 rtx dest = operands[0];
4060 rtx src = operands[1];
4061 rtx shift = operands[2];
4062 rtx cr = operands[3];
4069 src2 = gen_lowpart (SImode, dest);
4070 emit_move_insn (src2, src);
4073 if (REGNO (cr) == CR0_REGNO)
4075 emit_insn (gen_ashdi3_extswsli_dot (dest, src2, shift, cr));
4079 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4080 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4083 [(set_attr "type" "shift")
4084 (set_attr "maybe_var_shift" "no")
4085 (set_attr "dot" "yes")
4086 (set_attr "length" "4,8,8,12")])
4088 (define_insn_and_split "ashdi3_extswsli_dot2"
4089 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4092 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4093 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4095 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4096 (ashift:DI (sign_extend:DI (match_dup 1))
4104 "&& reload_completed
4105 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4106 || memory_operand (operands[1], SImode))"
4109 rtx dest = operands[0];
4110 rtx src = operands[1];
4111 rtx shift = operands[2];
4112 rtx cr = operands[3];
4119 src2 = gen_lowpart (SImode, dest);
4120 emit_move_insn (src2, src);
4123 if (REGNO (cr) == CR0_REGNO)
4125 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4129 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4130 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4133 [(set_attr "type" "shift")
4134 (set_attr "maybe_var_shift" "no")
4135 (set_attr "dot" "yes")
4136 (set_attr "length" "4,8,8,12")])
4138 (define_insn "lshr<mode>3"
4139 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4140 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4141 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4143 "sr<wd>%I2 %0,%1,%<hH>2"
4144 [(set_attr "type" "shift")
4145 (set_attr "maybe_var_shift" "yes")])
4147 (define_insn "*lshrsi3_64"
4148 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4150 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4151 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4154 [(set_attr "type" "shift")
4155 (set_attr "maybe_var_shift" "yes")])
4157 (define_insn_and_split "*lshr<mode>3_dot"
4158 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4159 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4160 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4162 (clobber (match_scratch:GPR 0 "=r,r"))]
4163 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4165 sr<wd>%I2. %0,%1,%<hH>2
4167 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4169 (lshiftrt:GPR (match_dup 1)
4172 (compare:CC (match_dup 0)
4175 [(set_attr "type" "shift")
4176 (set_attr "maybe_var_shift" "yes")
4177 (set_attr "dot" "yes")
4178 (set_attr "length" "4,8")])
4180 (define_insn_and_split "*lshr<mode>3_dot2"
4181 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4182 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4183 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4185 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4186 (lshiftrt:GPR (match_dup 1)
4188 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4190 sr<wd>%I2. %0,%1,%<hH>2
4192 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4194 (lshiftrt:GPR (match_dup 1)
4197 (compare:CC (match_dup 0)
4200 [(set_attr "type" "shift")
4201 (set_attr "maybe_var_shift" "yes")
4202 (set_attr "dot" "yes")
4203 (set_attr "length" "4,8")])
4206 (define_insn "ashr<mode>3"
4207 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4208 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4209 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4210 (clobber (reg:GPR CA_REGNO))]
4212 "sra<wd>%I2 %0,%1,%<hH>2"
4213 [(set_attr "type" "shift")
4214 (set_attr "maybe_var_shift" "yes")])
4216 (define_insn "*ashrsi3_64"
4217 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4219 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4220 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4221 (clobber (reg:SI CA_REGNO))]
4224 [(set_attr "type" "shift")
4225 (set_attr "maybe_var_shift" "yes")])
4227 (define_insn_and_split "*ashr<mode>3_dot"
4228 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4229 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4230 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4232 (clobber (match_scratch:GPR 0 "=r,r"))
4233 (clobber (reg:GPR CA_REGNO))]
4234 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4236 sra<wd>%I2. %0,%1,%<hH>2
4238 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4239 [(parallel [(set (match_dup 0)
4240 (ashiftrt:GPR (match_dup 1)
4242 (clobber (reg:GPR CA_REGNO))])
4244 (compare:CC (match_dup 0)
4247 [(set_attr "type" "shift")
4248 (set_attr "maybe_var_shift" "yes")
4249 (set_attr "dot" "yes")
4250 (set_attr "length" "4,8")])
4252 (define_insn_and_split "*ashr<mode>3_dot2"
4253 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4254 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4255 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4257 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4258 (ashiftrt:GPR (match_dup 1)
4260 (clobber (reg:GPR CA_REGNO))]
4261 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4263 sra<wd>%I2. %0,%1,%<hH>2
4265 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4266 [(parallel [(set (match_dup 0)
4267 (ashiftrt:GPR (match_dup 1)
4269 (clobber (reg:GPR CA_REGNO))])
4271 (compare:CC (match_dup 0)
4274 [(set_attr "type" "shift")
4275 (set_attr "maybe_var_shift" "yes")
4276 (set_attr "dot" "yes")
4277 (set_attr "length" "4,8")])
4279 ;; Builtins to replace a division to generate FRE reciprocal estimate
4280 ;; instructions and the necessary fixup instructions
4281 (define_expand "recip<mode>3"
4282 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4283 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4284 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4285 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4287 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4291 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4292 ;; hardware division. This is only done before register allocation and with
4293 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4295 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4296 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4297 (match_operand 2 "gpc_reg_operand" "")))]
4298 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4299 && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4300 && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4303 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4307 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4308 ;; appropriate fixup.
4309 (define_expand "rsqrt<mode>2"
4310 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4311 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4312 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4314 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4318 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4319 ;; modes here, and also add in conditional vsx/power8-vector support to access
4320 ;; values in the traditional Altivec registers if the appropriate
4321 ;; -mupper-regs-{df,sf} option is enabled.
4323 (define_expand "abs<mode>2"
4324 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4325 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4326 "TARGET_<MODE>_INSN"
4329 (define_insn "*abs<mode>2_fpr"
4330 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4331 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4336 [(set_attr "type" "fp")
4337 (set_attr "fp_type" "fp_addsub_<Fs>")])
4339 (define_insn "*nabs<mode>2_fpr"
4340 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4343 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4348 [(set_attr "type" "fp")
4349 (set_attr "fp_type" "fp_addsub_<Fs>")])
4351 (define_expand "neg<mode>2"
4352 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4353 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4354 "TARGET_<MODE>_INSN"
4357 (define_insn "*neg<mode>2_fpr"
4358 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4359 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4364 [(set_attr "type" "fp")
4365 (set_attr "fp_type" "fp_addsub_<Fs>")])
4367 (define_expand "add<mode>3"
4368 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4369 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4370 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4371 "TARGET_<MODE>_INSN"
4374 (define_insn "*add<mode>3_fpr"
4375 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4376 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4377 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4380 fadd<Ftrad> %0,%1,%2
4381 xsadd<Fvsx> %x0,%x1,%x2"
4382 [(set_attr "type" "fp")
4383 (set_attr "fp_type" "fp_addsub_<Fs>")])
4385 (define_expand "sub<mode>3"
4386 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4387 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4388 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4389 "TARGET_<MODE>_INSN"
4392 (define_insn "*sub<mode>3_fpr"
4393 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4394 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4395 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4398 fsub<Ftrad> %0,%1,%2
4399 xssub<Fvsx> %x0,%x1,%x2"
4400 [(set_attr "type" "fp")
4401 (set_attr "fp_type" "fp_addsub_<Fs>")])
4403 (define_expand "mul<mode>3"
4404 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4405 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4406 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4407 "TARGET_<MODE>_INSN"
4410 (define_insn "*mul<mode>3_fpr"
4411 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4412 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4413 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4416 fmul<Ftrad> %0,%1,%2
4417 xsmul<Fvsx> %x0,%x1,%x2"
4418 [(set_attr "type" "dmul")
4419 (set_attr "fp_type" "fp_mul_<Fs>")])
4421 (define_expand "div<mode>3"
4422 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4423 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4424 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4425 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4428 (define_insn "*div<mode>3_fpr"
4429 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4430 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4431 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4432 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4434 fdiv<Ftrad> %0,%1,%2
4435 xsdiv<Fvsx> %x0,%x1,%x2"
4436 [(set_attr "type" "<Fs>div")
4437 (set_attr "fp_type" "fp_div_<Fs>")])
4439 (define_insn "*sqrt<mode>2_internal"
4440 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4441 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4442 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4443 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4446 xssqrt<Fvsx> %x0,%x1"
4447 [(set_attr "type" "<Fs>sqrt")
4448 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4450 (define_expand "sqrt<mode>2"
4451 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4452 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4453 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4454 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4456 if (<MODE>mode == SFmode
4457 && TARGET_RECIP_PRECISION
4458 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4459 && !optimize_function_for_size_p (cfun)
4460 && flag_finite_math_only && !flag_trapping_math
4461 && flag_unsafe_math_optimizations)
4463 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4468 ;; Floating point reciprocal approximation
4469 (define_insn "fre<Fs>"
4470 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4471 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4477 [(set_attr "type" "fp")])
4479 (define_insn "*rsqrt<mode>2"
4480 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4481 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4483 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4485 frsqrte<Ftrad> %0,%1
4486 xsrsqrte<Fvsx> %x0,%x1"
4487 [(set_attr "type" "fp")])
4489 ;; Floating point comparisons
4490 (define_insn "*cmp<mode>_fpr"
4491 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4492 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4493 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4497 xscmpudp %0,%x1,%x2"
4498 [(set_attr "type" "fpcompare")])
4500 ;; Floating point conversions
4501 (define_expand "extendsfdf2"
4502 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4503 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4504 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4507 (define_insn_and_split "*extendsfdf2_fpr"
4508 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4509 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))]
4510 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4516 xscpsgndp %x0,%x1,%x1
4519 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4522 emit_note (NOTE_INSN_DELETED);
4525 [(set_attr "type" "fp,fp,fpload,fp,fp,fpload,fpload")])
4527 (define_expand "truncdfsf2"
4528 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4529 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4530 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4533 (define_insn "*truncdfsf2_fpr"
4534 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4535 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4536 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4540 [(set_attr "type" "fp")])
4542 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4543 ;; builtins.c and optabs.c that are not correct for IBM long double
4544 ;; when little-endian.
4545 (define_expand "signbit<mode>2"
4547 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "")))
4549 (subreg:DI (match_dup 2) 0))
4552 (set (match_operand:SI 0 "gpc_reg_operand" "")
4555 && (TARGET_FPRS || TARGET_E500_DOUBLE)"
4557 operands[2] = gen_reg_rtx (DFmode);
4558 operands[3] = gen_reg_rtx (DImode);
4559 if (TARGET_POWERPC64)
4561 operands[4] = gen_reg_rtx (DImode);
4562 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4563 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4564 WORDS_BIG_ENDIAN ? 4 : 0);
4568 operands[4] = gen_reg_rtx (SImode);
4569 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4570 WORDS_BIG_ENDIAN ? 0 : 4);
4571 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4575 (define_expand "copysign<mode>3"
4577 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4579 (neg:SFDF (abs:SFDF (match_dup 1))))
4580 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4581 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4585 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4586 && ((TARGET_PPC_GFXOPT
4587 && !HONOR_NANS (<MODE>mode)
4588 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4590 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4592 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4594 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4599 operands[3] = gen_reg_rtx (<MODE>mode);
4600 operands[4] = gen_reg_rtx (<MODE>mode);
4601 operands[5] = CONST0_RTX (<MODE>mode);
4604 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4605 ;; compiler from optimizing -0.0
4606 (define_insn "copysign<mode>3_fcpsgn"
4607 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4608 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4609 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4611 "TARGET_<MODE>_FPR && TARGET_CMPB"
4614 xscpsgndp %x0,%x2,%x1"
4615 [(set_attr "type" "fp")])
4617 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4618 ;; fsel instruction and some auxiliary computations. Then we just have a
4619 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4621 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4622 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4623 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4624 ;; define_splits to make them if made by combine. On VSX machines we have the
4625 ;; min/max instructions.
4627 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4628 ;; to allow either DF/SF to use only traditional registers.
4630 (define_expand "smax<mode>3"
4631 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4632 (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4633 (match_operand:SFDF 2 "gpc_reg_operand" ""))
4636 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4638 rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
4642 (define_insn "*smax<mode>3_vsx"
4643 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4644 (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4645 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4646 "TARGET_<MODE>_FPR && TARGET_VSX"
4647 "xsmaxdp %x0,%x1,%x2"
4648 [(set_attr "type" "fp")])
4650 (define_expand "smin<mode>3"
4651 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4652 (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4653 (match_operand:SFDF 2 "gpc_reg_operand" ""))
4656 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4658 rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
4662 (define_insn "*smin<mode>3_vsx"
4663 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4664 (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4665 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4666 "TARGET_<MODE>_FPR && TARGET_VSX"
4667 "xsmindp %x0,%x1,%x2"
4668 [(set_attr "type" "fp")])
4671 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4672 (match_operator:SFDF 3 "min_max_operator"
4673 [(match_operand:SFDF 1 "gpc_reg_operand" "")
4674 (match_operand:SFDF 2 "gpc_reg_operand" "")]))]
4675 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math
4679 rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1],
4685 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4686 (match_operator:SF 3 "min_max_operator"
4687 [(match_operand:SF 1 "gpc_reg_operand" "")
4688 (match_operand:SF 2 "gpc_reg_operand" "")]))]
4689 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
4690 && TARGET_SINGLE_FLOAT && !flag_trapping_math"
4693 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4694 operands[1], operands[2]);
4698 (define_expand "mov<mode>cc"
4699 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4700 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4701 (match_operand:GPR 2 "gpc_reg_operand" "")
4702 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4706 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4712 ;; We use the BASE_REGS for the isel input operands because, if rA is
4713 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4714 ;; because we may switch the operands and rB may end up being rA.
4716 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4717 ;; leave out the mode in operand 4 and use one pattern, but reload can
4718 ;; change the mode underneath our feet and then gets confused trying
4719 ;; to reload the value.
4720 (define_insn "isel_signed_<mode>"
4721 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4723 (match_operator 1 "scc_comparison_operator"
4724 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4726 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4727 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4730 { return output_isel (operands); }"
4731 [(set_attr "type" "isel")
4732 (set_attr "length" "4")])
4734 (define_insn "isel_unsigned_<mode>"
4735 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4737 (match_operator 1 "scc_comparison_operator"
4738 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4740 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4741 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4744 { return output_isel (operands); }"
4745 [(set_attr "type" "isel")
4746 (set_attr "length" "4")])
4748 ;; These patterns can be useful for combine; they let combine know that
4749 ;; isel can handle reversed comparisons so long as the operands are
4752 (define_insn "*isel_reversed_signed_<mode>"
4753 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4755 (match_operator 1 "scc_rev_comparison_operator"
4756 [(match_operand:CC 4 "cc_reg_operand" "y")
4758 (match_operand:GPR 2 "gpc_reg_operand" "b")
4759 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4762 { return output_isel (operands); }"
4763 [(set_attr "type" "isel")
4764 (set_attr "length" "4")])
4766 (define_insn "*isel_reversed_unsigned_<mode>"
4767 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4769 (match_operator 1 "scc_rev_comparison_operator"
4770 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4772 (match_operand:GPR 2 "gpc_reg_operand" "b")
4773 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4776 { return output_isel (operands); }"
4777 [(set_attr "type" "isel")
4778 (set_attr "length" "4")])
4780 (define_expand "movsfcc"
4781 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4782 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4783 (match_operand:SF 2 "gpc_reg_operand" "")
4784 (match_operand:SF 3 "gpc_reg_operand" "")))]
4785 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4788 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4794 (define_insn "*fselsfsf4"
4795 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4796 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4797 (match_operand:SF 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_SINGLE_FLOAT"
4802 [(set_attr "type" "fp")])
4804 (define_insn "*fseldfsf4"
4805 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4806 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4807 (match_operand:DF 4 "zero_fp_constant" "F"))
4808 (match_operand:SF 2 "gpc_reg_operand" "f")
4809 (match_operand:SF 3 "gpc_reg_operand" "f")))]
4810 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4812 [(set_attr "type" "fp")])
4814 ;; The conditional move instructions allow us to perform max and min
4815 ;; operations even when
4818 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4819 (match_operator:DF 3 "min_max_operator"
4820 [(match_operand:DF 1 "gpc_reg_operand" "")
4821 (match_operand:DF 2 "gpc_reg_operand" "")]))]
4822 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4823 && !flag_trapping_math"
4826 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4827 operands[1], operands[2]);
4831 (define_expand "movdfcc"
4832 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4833 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4834 (match_operand:DF 2 "gpc_reg_operand" "")
4835 (match_operand:DF 3 "gpc_reg_operand" "")))]
4836 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4839 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4845 (define_insn "*fseldfdf4"
4846 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4847 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4848 (match_operand:DF 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"
4853 [(set_attr "type" "fp")])
4855 (define_insn "*fselsfdf4"
4856 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4857 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4858 (match_operand:SF 4 "zero_fp_constant" "F"))
4859 (match_operand:DF 2 "gpc_reg_operand" "d")
4860 (match_operand:DF 3 "gpc_reg_operand" "d")))]
4861 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4863 [(set_attr "type" "fp")])
4865 ;; Conversions to and from floating-point.
4867 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4868 ; don't want to support putting SImode in FPR registers.
4869 (define_insn "lfiwax"
4870 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4871 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4873 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4878 [(set_attr "type" "fpload,fpload,mffgpr")])
4880 ; This split must be run before register allocation because it allocates the
4881 ; memory slot that is needed to move values to/from the FPR. We don't allocate
4882 ; it earlier to allow for the combiner to merge insns together where it might
4883 ; not be needed and also in case the insns are deleted as dead code.
4885 (define_insn_and_split "floatsi<mode>2_lfiwax"
4886 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4887 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4888 (clobber (match_scratch:DI 2 "=wj"))]
4889 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4890 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4896 rtx dest = operands[0];
4897 rtx src = operands[1];
4900 if (!MEM_P (src) && TARGET_POWERPC64
4901 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4902 tmp = convert_to_mode (DImode, src, false);
4906 if (GET_CODE (tmp) == SCRATCH)
4907 tmp = gen_reg_rtx (DImode);
4910 src = rs6000_address_for_fpconvert (src);
4911 emit_insn (gen_lfiwax (tmp, src));
4915 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4916 emit_move_insn (stack, src);
4917 emit_insn (gen_lfiwax (tmp, stack));
4920 emit_insn (gen_floatdi<mode>2 (dest, tmp));
4923 [(set_attr "length" "12")
4924 (set_attr "type" "fpload")])
4926 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
4927 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4930 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4931 (clobber (match_scratch:DI 2 "=0,d"))]
4932 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4939 operands[1] = rs6000_address_for_fpconvert (operands[1]);
4940 if (GET_CODE (operands[2]) == SCRATCH)
4941 operands[2] = gen_reg_rtx (DImode);
4942 emit_insn (gen_lfiwax (operands[2], operands[1]));
4943 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4946 [(set_attr "length" "8")
4947 (set_attr "type" "fpload")])
4949 (define_insn "lfiwzx"
4950 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4951 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4953 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
4958 [(set_attr "type" "fpload,fpload,mftgpr")])
4960 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
4961 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4962 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4963 (clobber (match_scratch:DI 2 "=wj"))]
4964 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4971 rtx dest = operands[0];
4972 rtx src = operands[1];
4975 if (!MEM_P (src) && TARGET_POWERPC64
4976 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4977 tmp = convert_to_mode (DImode, src, true);
4981 if (GET_CODE (tmp) == SCRATCH)
4982 tmp = gen_reg_rtx (DImode);
4985 src = rs6000_address_for_fpconvert (src);
4986 emit_insn (gen_lfiwzx (tmp, src));
4990 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4991 emit_move_insn (stack, src);
4992 emit_insn (gen_lfiwzx (tmp, stack));
4995 emit_insn (gen_floatdi<mode>2 (dest, tmp));
4998 [(set_attr "length" "12")
4999 (set_attr "type" "fpload")])
5001 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5002 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
5003 (unsigned_float:SFDF
5005 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5006 (clobber (match_scratch:DI 2 "=0,d"))]
5007 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5014 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5015 if (GET_CODE (operands[2]) == SCRATCH)
5016 operands[2] = gen_reg_rtx (DImode);
5017 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5018 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5021 [(set_attr "length" "8")
5022 (set_attr "type" "fpload")])
5024 ; For each of these conversions, there is a define_expand, a define_insn
5025 ; with a '#' template, and a define_split (with C code). The idea is
5026 ; to allow constant folding with the template of the define_insn,
5027 ; then to have the insns split later (between sched1 and final).
5029 (define_expand "floatsidf2"
5030 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5031 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5034 (clobber (match_dup 4))
5035 (clobber (match_dup 5))
5036 (clobber (match_dup 6))])]
5038 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5041 if (TARGET_E500_DOUBLE)
5043 if (!REG_P (operands[1]))
5044 operands[1] = force_reg (SImode, operands[1]);
5045 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5048 else if (TARGET_LFIWAX && TARGET_FCFID)
5050 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5053 else if (TARGET_FCFID)
5055 rtx dreg = operands[1];
5057 dreg = force_reg (SImode, dreg);
5058 dreg = convert_to_mode (DImode, dreg, false);
5059 emit_insn (gen_floatdidf2 (operands[0], dreg));
5063 if (!REG_P (operands[1]))
5064 operands[1] = force_reg (SImode, operands[1]);
5065 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5066 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5067 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5068 operands[5] = gen_reg_rtx (DFmode);
5069 operands[6] = gen_reg_rtx (SImode);
5072 (define_insn_and_split "*floatsidf2_internal"
5073 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5074 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5075 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5076 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5077 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5078 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5079 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5080 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5086 rtx lowword, highword;
5087 gcc_assert (MEM_P (operands[4]));
5088 highword = adjust_address (operands[4], SImode, 0);
5089 lowword = adjust_address (operands[4], SImode, 4);
5090 if (! WORDS_BIG_ENDIAN)
5091 std::swap (lowword, highword);
5093 emit_insn (gen_xorsi3 (operands[6], operands[1],
5094 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5095 emit_move_insn (lowword, operands[6]);
5096 emit_move_insn (highword, operands[2]);
5097 emit_move_insn (operands[5], operands[4]);
5098 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5101 [(set_attr "length" "24")
5102 (set_attr "type" "fp")])
5104 ;; If we don't have a direct conversion to single precision, don't enable this
5105 ;; conversion for 32-bit without fast math, because we don't have the insn to
5106 ;; generate the fixup swizzle to avoid double rounding problems.
5107 (define_expand "floatunssisf2"
5108 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5109 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5110 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5113 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5114 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5115 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5120 if (!REG_P (operands[1]))
5121 operands[1] = force_reg (SImode, operands[1]);
5123 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5125 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5130 rtx dreg = operands[1];
5132 dreg = force_reg (SImode, dreg);
5133 dreg = convert_to_mode (DImode, dreg, true);
5134 emit_insn (gen_floatdisf2 (operands[0], dreg));
5139 (define_expand "floatunssidf2"
5140 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5141 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5144 (clobber (match_dup 4))
5145 (clobber (match_dup 5))])]
5147 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5150 if (TARGET_E500_DOUBLE)
5152 if (!REG_P (operands[1]))
5153 operands[1] = force_reg (SImode, operands[1]);
5154 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5157 else if (TARGET_LFIWZX && TARGET_FCFID)
5159 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5162 else if (TARGET_FCFID)
5164 rtx dreg = operands[1];
5166 dreg = force_reg (SImode, dreg);
5167 dreg = convert_to_mode (DImode, dreg, true);
5168 emit_insn (gen_floatdidf2 (operands[0], dreg));
5172 if (!REG_P (operands[1]))
5173 operands[1] = force_reg (SImode, operands[1]);
5174 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5175 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5176 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5177 operands[5] = gen_reg_rtx (DFmode);
5180 (define_insn_and_split "*floatunssidf2_internal"
5181 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5182 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5183 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5184 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5185 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5186 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5187 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5188 && !(TARGET_FCFID && TARGET_POWERPC64)"
5194 rtx lowword, highword;
5195 gcc_assert (MEM_P (operands[4]));
5196 highword = adjust_address (operands[4], SImode, 0);
5197 lowword = adjust_address (operands[4], SImode, 4);
5198 if (! WORDS_BIG_ENDIAN)
5199 std::swap (lowword, highword);
5201 emit_move_insn (lowword, operands[1]);
5202 emit_move_insn (highword, operands[2]);
5203 emit_move_insn (operands[5], operands[4]);
5204 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5207 [(set_attr "length" "20")
5208 (set_attr "type" "fp")])
5210 (define_expand "fix_trunc<mode>si2"
5211 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5212 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5213 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5216 if (!<E500_CONVERT>)
5221 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5224 tmp = gen_reg_rtx (DImode);
5225 stack = rs6000_allocate_stack_temp (DImode, true, false);
5226 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5233 ; Like the convert to float patterns, this insn must be split before
5234 ; register allocation so that it can allocate the memory slot if it
5236 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5237 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5238 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5239 (clobber (match_scratch:DI 2 "=d"))]
5240 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5241 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5242 && TARGET_STFIWX && can_create_pseudo_p ()"
5247 rtx dest = operands[0];
5248 rtx src = operands[1];
5249 rtx tmp = operands[2];
5251 if (GET_CODE (tmp) == SCRATCH)
5252 tmp = gen_reg_rtx (DImode);
5254 emit_insn (gen_fctiwz_<mode> (tmp, src));
5257 dest = rs6000_address_for_fpconvert (dest);
5258 emit_insn (gen_stfiwx (dest, tmp));
5261 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5263 dest = gen_lowpart (DImode, dest);
5264 emit_move_insn (dest, tmp);
5269 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5270 emit_insn (gen_stfiwx (stack, tmp));
5271 emit_move_insn (dest, stack);
5275 [(set_attr "length" "12")
5276 (set_attr "type" "fp")])
5278 (define_insn_and_split "fix_trunc<mode>si2_internal"
5279 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5280 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5281 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5282 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5283 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5290 gcc_assert (MEM_P (operands[3]));
5291 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5293 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5294 emit_move_insn (operands[3], operands[2]);
5295 emit_move_insn (operands[0], lowword);
5298 [(set_attr "length" "16")
5299 (set_attr "type" "fp")])
5301 (define_expand "fix_trunc<mode>di2"
5302 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5303 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5304 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5308 (define_insn "*fix_trunc<mode>di2_fctidz"
5309 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5310 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5311 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5316 [(set_attr "type" "fp")])
5318 (define_expand "fixuns_trunc<mode>si2"
5319 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5320 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5322 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5326 if (!<E500_CONVERT>)
5328 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5333 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5334 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5335 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5336 (clobber (match_scratch:DI 2 "=d"))]
5337 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5338 && TARGET_STFIWX && can_create_pseudo_p ()"
5343 rtx dest = operands[0];
5344 rtx src = operands[1];
5345 rtx tmp = operands[2];
5347 if (GET_CODE (tmp) == SCRATCH)
5348 tmp = gen_reg_rtx (DImode);
5350 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5353 dest = rs6000_address_for_fpconvert (dest);
5354 emit_insn (gen_stfiwx (dest, tmp));
5357 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5359 dest = gen_lowpart (DImode, dest);
5360 emit_move_insn (dest, tmp);
5365 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5366 emit_insn (gen_stfiwx (stack, tmp));
5367 emit_move_insn (dest, stack);
5371 [(set_attr "length" "12")
5372 (set_attr "type" "fp")])
5374 (define_expand "fixuns_trunc<mode>di2"
5375 [(set (match_operand:DI 0 "register_operand" "")
5376 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5377 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5380 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5381 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5382 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5383 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5388 [(set_attr "type" "fp")])
5390 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5391 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5392 ; because the first makes it clear that operand 0 is not live
5393 ; before the instruction.
5394 (define_insn "fctiwz_<mode>"
5395 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5396 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5398 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5402 [(set_attr "type" "fp")])
5404 (define_insn "fctiwuz_<mode>"
5405 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5406 (unspec:DI [(unsigned_fix:SI
5407 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5409 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5413 [(set_attr "type" "fp")])
5415 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5416 ;; since the friz instruction does not truncate the value if the floating
5417 ;; point value is < LONG_MIN or > LONG_MAX.
5418 (define_insn "*friz"
5419 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5420 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5421 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5422 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5426 [(set_attr "type" "fp")])
5428 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5429 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5430 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5431 ;; extend it, store it back on the stack from the GPR, load it back into the
5432 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5433 ;; disable using store and load to sign/zero extend the value.
5434 (define_insn_and_split "*round32<mode>2_fprs"
5435 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5437 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5438 (clobber (match_scratch:DI 2 "=d"))
5439 (clobber (match_scratch:DI 3 "=d"))]
5440 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5441 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5442 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5447 rtx dest = operands[0];
5448 rtx src = operands[1];
5449 rtx tmp1 = operands[2];
5450 rtx tmp2 = operands[3];
5451 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5453 if (GET_CODE (tmp1) == SCRATCH)
5454 tmp1 = gen_reg_rtx (DImode);
5455 if (GET_CODE (tmp2) == SCRATCH)
5456 tmp2 = gen_reg_rtx (DImode);
5458 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5459 emit_insn (gen_stfiwx (stack, tmp1));
5460 emit_insn (gen_lfiwax (tmp2, stack));
5461 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5464 [(set_attr "type" "fpload")
5465 (set_attr "length" "16")])
5467 (define_insn_and_split "*roundu32<mode>2_fprs"
5468 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5469 (unsigned_float:SFDF
5470 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5471 (clobber (match_scratch:DI 2 "=d"))
5472 (clobber (match_scratch:DI 3 "=d"))]
5473 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5474 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5475 && can_create_pseudo_p ()"
5480 rtx dest = operands[0];
5481 rtx src = operands[1];
5482 rtx tmp1 = operands[2];
5483 rtx tmp2 = operands[3];
5484 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5486 if (GET_CODE (tmp1) == SCRATCH)
5487 tmp1 = gen_reg_rtx (DImode);
5488 if (GET_CODE (tmp2) == SCRATCH)
5489 tmp2 = gen_reg_rtx (DImode);
5491 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5492 emit_insn (gen_stfiwx (stack, tmp1));
5493 emit_insn (gen_lfiwzx (tmp2, stack));
5494 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5497 [(set_attr "type" "fpload")
5498 (set_attr "length" "16")])
5500 ;; No VSX equivalent to fctid
5501 (define_insn "lrint<mode>di2"
5502 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5503 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5505 "TARGET_<MODE>_FPR && TARGET_FPRND"
5507 [(set_attr "type" "fp")])
5509 (define_insn "btrunc<mode>2"
5510 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5511 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5513 "TARGET_<MODE>_FPR && TARGET_FPRND"
5517 [(set_attr "type" "fp")
5518 (set_attr "fp_type" "fp_addsub_<Fs>")])
5520 (define_insn "ceil<mode>2"
5521 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5522 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5524 "TARGET_<MODE>_FPR && TARGET_FPRND"
5528 [(set_attr "type" "fp")
5529 (set_attr "fp_type" "fp_addsub_<Fs>")])
5531 (define_insn "floor<mode>2"
5532 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5533 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5535 "TARGET_<MODE>_FPR && TARGET_FPRND"
5539 [(set_attr "type" "fp")
5540 (set_attr "fp_type" "fp_addsub_<Fs>")])
5542 ;; No VSX equivalent to frin
5543 (define_insn "round<mode>2"
5544 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5545 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5547 "TARGET_<MODE>_FPR && TARGET_FPRND"
5549 [(set_attr "type" "fp")
5550 (set_attr "fp_type" "fp_addsub_<Fs>")])
5552 (define_insn "*xsrdpi<mode>2"
5553 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5554 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5556 "TARGET_<MODE>_FPR && TARGET_VSX"
5558 [(set_attr "type" "fp")
5559 (set_attr "fp_type" "fp_addsub_<Fs>")])
5561 (define_expand "lround<mode>di2"
5563 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5565 (set (match_operand:DI 0 "gpc_reg_operand" "")
5566 (unspec:DI [(match_dup 2)]
5568 "TARGET_<MODE>_FPR && TARGET_VSX"
5570 operands[2] = gen_reg_rtx (<MODE>mode);
5573 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5574 (define_insn "stfiwx"
5575 [(set (match_operand:SI 0 "memory_operand" "=Z")
5576 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
5580 [(set_attr "type" "fpstore")])
5582 ;; If we don't have a direct conversion to single precision, don't enable this
5583 ;; conversion for 32-bit without fast math, because we don't have the insn to
5584 ;; generate the fixup swizzle to avoid double rounding problems.
5585 (define_expand "floatsisf2"
5586 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5587 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5588 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5591 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5592 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5593 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5598 if (!REG_P (operands[1]))
5599 operands[1] = force_reg (SImode, operands[1]);
5601 else if (TARGET_FCFIDS && TARGET_LFIWAX)
5603 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5606 else if (TARGET_FCFID && TARGET_LFIWAX)
5608 rtx dfreg = gen_reg_rtx (DFmode);
5609 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5610 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5615 rtx dreg = operands[1];
5617 dreg = force_reg (SImode, dreg);
5618 dreg = convert_to_mode (DImode, dreg, false);
5619 emit_insn (gen_floatdisf2 (operands[0], dreg));
5624 (define_expand "floatdidf2"
5625 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5626 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5627 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5630 (define_insn "*floatdidf2_fpr"
5631 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5632 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5633 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5637 [(set_attr "type" "fp")])
5639 ; Allow the combiner to merge source memory operands to the conversion so that
5640 ; the optimizer/register allocator doesn't try to load the value too early in a
5641 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5642 ; hit. We will split after reload to avoid the trip through the GPRs
5644 (define_insn_and_split "*floatdidf2_mem"
5645 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5646 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5647 (clobber (match_scratch:DI 2 "=d,wi"))]
5648 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5650 "&& reload_completed"
5651 [(set (match_dup 2) (match_dup 1))
5652 (set (match_dup 0) (float:DF (match_dup 2)))]
5654 [(set_attr "length" "8")
5655 (set_attr "type" "fpload")])
5657 (define_expand "floatunsdidf2"
5658 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5660 (match_operand:DI 1 "gpc_reg_operand" "")))]
5661 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5664 (define_insn "*floatunsdidf2_fcfidu"
5665 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5666 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5667 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5671 [(set_attr "type" "fp")
5672 (set_attr "length" "4")])
5674 (define_insn_and_split "*floatunsdidf2_mem"
5675 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5676 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5677 (clobber (match_scratch:DI 2 "=d,wi"))]
5678 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5680 "&& reload_completed"
5681 [(set (match_dup 2) (match_dup 1))
5682 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5684 [(set_attr "length" "8")
5685 (set_attr "type" "fpload")])
5687 (define_expand "floatdisf2"
5688 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5689 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5690 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5691 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5696 rtx val = operands[1];
5697 if (!flag_unsafe_math_optimizations)
5699 rtx label = gen_label_rtx ();
5700 val = gen_reg_rtx (DImode);
5701 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5704 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5709 (define_insn "floatdisf2_fcfids"
5710 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5711 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5712 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5713 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5717 [(set_attr "type" "fp")])
5719 (define_insn_and_split "*floatdisf2_mem"
5720 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5721 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5722 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5723 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5724 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5726 "&& reload_completed"
5730 emit_move_insn (operands[2], operands[1]);
5731 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5734 [(set_attr "length" "8")])
5736 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5737 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5738 ;; from double rounding.
5739 ;; Instead of creating a new cpu type for two FP operations, just use fp
5740 (define_insn_and_split "floatdisf2_internal1"
5741 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5742 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5743 (clobber (match_scratch:DF 2 "=d"))]
5744 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5747 "&& reload_completed"
5749 (float:DF (match_dup 1)))
5751 (float_truncate:SF (match_dup 2)))]
5753 [(set_attr "length" "8")
5754 (set_attr "type" "fp")])
5756 ;; Twiddles bits to avoid double rounding.
5757 ;; Bits that might be truncated when converting to DFmode are replaced
5758 ;; by a bit that won't be lost at that stage, but is below the SFmode
5759 ;; rounding position.
5760 (define_expand "floatdisf2_internal2"
5761 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5763 (clobber (reg:DI CA_REGNO))])
5764 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5766 (set (match_dup 3) (plus:DI (match_dup 3)
5768 (set (match_dup 0) (plus:DI (match_dup 0)
5770 (set (match_dup 4) (compare:CCUNS (match_dup 3)
5772 (set (match_dup 0) (ior:DI (match_dup 0)
5774 (set (match_dup 0) (and:DI (match_dup 0)
5776 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5777 (label_ref (match_operand:DI 2 "" ""))
5779 (set (match_dup 0) (match_dup 1))]
5780 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5784 operands[3] = gen_reg_rtx (DImode);
5785 operands[4] = gen_reg_rtx (CCUNSmode);
5788 (define_expand "floatunsdisf2"
5789 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5790 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5791 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5792 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5795 (define_insn "floatunsdisf2_fcfidus"
5796 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5797 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5798 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5799 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5803 [(set_attr "type" "fp")])
5805 (define_insn_and_split "*floatunsdisf2_mem"
5806 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5807 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5808 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5809 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5810 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5812 "&& reload_completed"
5816 emit_move_insn (operands[2], operands[1]);
5817 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
5820 [(set_attr "length" "8")
5821 (set_attr "type" "fpload")])
5823 ;; Define the TImode operations that can be done in a small number
5824 ;; of instructions. The & constraints are to prevent the register
5825 ;; allocator from allocating registers that overlap with the inputs
5826 ;; (for example, having an input in 7,8 and an output in 6,7). We
5827 ;; also allow for the output being the same as one of the inputs.
5829 (define_expand "addti3"
5830 [(set (match_operand:TI 0 "gpc_reg_operand" "")
5831 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
5832 (match_operand:TI 2 "reg_or_short_operand" "")))]
5835 rtx lo0 = gen_lowpart (DImode, operands[0]);
5836 rtx lo1 = gen_lowpart (DImode, operands[1]);
5837 rtx lo2 = gen_lowpart (DImode, operands[2]);
5838 rtx hi0 = gen_highpart (DImode, operands[0]);
5839 rtx hi1 = gen_highpart (DImode, operands[1]);
5840 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
5842 if (!reg_or_short_operand (lo2, DImode))
5843 lo2 = force_reg (DImode, lo2);
5844 if (!adde_operand (hi2, DImode))
5845 hi2 = force_reg (DImode, hi2);
5847 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
5848 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
5852 (define_expand "subti3"
5853 [(set (match_operand:TI 0 "gpc_reg_operand" "")
5854 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
5855 (match_operand:TI 2 "gpc_reg_operand" "")))]
5858 rtx lo0 = gen_lowpart (DImode, operands[0]);
5859 rtx lo1 = gen_lowpart (DImode, operands[1]);
5860 rtx lo2 = gen_lowpart (DImode, operands[2]);
5861 rtx hi0 = gen_highpart (DImode, operands[0]);
5862 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
5863 rtx hi2 = gen_highpart (DImode, operands[2]);
5865 if (!reg_or_short_operand (lo1, DImode))
5866 lo1 = force_reg (DImode, lo1);
5867 if (!adde_operand (hi1, DImode))
5868 hi1 = force_reg (DImode, hi1);
5870 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
5871 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
5875 ;; 128-bit logical operations expanders
5877 (define_expand "and<mode>3"
5878 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5879 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5880 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5884 (define_expand "ior<mode>3"
5885 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5886 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5887 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5891 (define_expand "xor<mode>3"
5892 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5893 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5894 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5898 (define_expand "one_cmpl<mode>2"
5899 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5900 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5904 (define_expand "nor<mode>3"
5905 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5907 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5908 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5912 (define_expand "andc<mode>3"
5913 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5915 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5916 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5920 ;; Power8 vector logical instructions.
5921 (define_expand "eqv<mode>3"
5922 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5924 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5925 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5926 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5929 ;; Rewrite nand into canonical form
5930 (define_expand "nand<mode>3"
5931 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5933 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5934 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5935 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5938 ;; The canonical form is to have the negated element first, so we need to
5939 ;; reverse arguments.
5940 (define_expand "orc<mode>3"
5941 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5943 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5944 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5945 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5948 ;; 128-bit logical operations insns and split operations
5949 (define_insn_and_split "*and<mode>3_internal"
5950 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5952 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
5953 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
5956 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
5957 return "xxland %x0,%x1,%x2";
5959 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
5960 return "vand %0,%1,%2";
5964 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
5967 rs6000_split_logical (operands, AND, false, false, false);
5972 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5973 (const_string "vecsimple")
5974 (const_string "integer")))
5975 (set (attr "length")
5977 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5980 (match_test "TARGET_POWERPC64")
5982 (const_string "16"))))])
5985 (define_insn_and_split "*bool<mode>3_internal"
5986 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5987 (match_operator:BOOL_128 3 "boolean_or_operator"
5988 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
5989 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
5992 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
5993 return "xxl%q3 %x0,%x1,%x2";
5995 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
5996 return "v%q3 %0,%1,%2";
6000 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6003 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6008 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6009 (const_string "vecsimple")
6010 (const_string "integer")))
6011 (set (attr "length")
6013 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6016 (match_test "TARGET_POWERPC64")
6018 (const_string "16"))))])
6021 (define_insn_and_split "*boolc<mode>3_internal1"
6022 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6023 (match_operator:BOOL_128 3 "boolean_operator"
6025 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6026 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6027 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6029 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6030 return "xxl%q3 %x0,%x1,%x2";
6032 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6033 return "v%q3 %0,%1,%2";
6037 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6038 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6041 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6046 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6047 (const_string "vecsimple")
6048 (const_string "integer")))
6049 (set (attr "length")
6051 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6054 (match_test "TARGET_POWERPC64")
6056 (const_string "16"))))])
6058 (define_insn_and_split "*boolc<mode>3_internal2"
6059 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6060 (match_operator:TI2 3 "boolean_operator"
6062 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6063 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6064 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6066 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6069 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6072 [(set_attr "type" "integer")
6073 (set (attr "length")
6075 (match_test "TARGET_POWERPC64")
6077 (const_string "16")))])
6080 (define_insn_and_split "*boolcc<mode>3_internal1"
6081 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6082 (match_operator:BOOL_128 3 "boolean_operator"
6084 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6086 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6087 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6089 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6090 return "xxl%q3 %x0,%x1,%x2";
6092 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6093 return "v%q3 %0,%1,%2";
6097 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6098 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6101 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6106 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6107 (const_string "vecsimple")
6108 (const_string "integer")))
6109 (set (attr "length")
6111 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6114 (match_test "TARGET_POWERPC64")
6116 (const_string "16"))))])
6118 (define_insn_and_split "*boolcc<mode>3_internal2"
6119 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6120 (match_operator:TI2 3 "boolean_operator"
6122 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6124 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6125 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6127 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6130 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6133 [(set_attr "type" "integer")
6134 (set (attr "length")
6136 (match_test "TARGET_POWERPC64")
6138 (const_string "16")))])
6142 (define_insn_and_split "*eqv<mode>3_internal1"
6143 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6146 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6147 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6150 if (vsx_register_operand (operands[0], <MODE>mode))
6151 return "xxleqv %x0,%x1,%x2";
6155 "TARGET_P8_VECTOR && reload_completed
6156 && int_reg_operand (operands[0], <MODE>mode)"
6159 rs6000_split_logical (operands, XOR, true, false, false);
6164 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6165 (const_string "vecsimple")
6166 (const_string "integer")))
6167 (set (attr "length")
6169 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6172 (match_test "TARGET_POWERPC64")
6174 (const_string "16"))))])
6176 (define_insn_and_split "*eqv<mode>3_internal2"
6177 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6180 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6181 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6184 "reload_completed && !TARGET_P8_VECTOR"
6187 rs6000_split_logical (operands, XOR, true, false, false);
6190 [(set_attr "type" "integer")
6191 (set (attr "length")
6193 (match_test "TARGET_POWERPC64")
6195 (const_string "16")))])
6197 ;; 128-bit one's complement
6198 (define_insn_and_split "*one_cmpl<mode>3_internal"
6199 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6201 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6204 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6205 return "xxlnor %x0,%x1,%x1";
6207 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6208 return "vnor %0,%1,%1";
6212 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6215 rs6000_split_logical (operands, NOT, false, false, false);
6220 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6221 (const_string "vecsimple")
6222 (const_string "integer")))
6223 (set (attr "length")
6225 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6228 (match_test "TARGET_POWERPC64")
6230 (const_string "16"))))])
6233 ;; Now define ways of moving data around.
6235 ;; Set up a register with a value from the GOT table
6237 (define_expand "movsi_got"
6238 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6239 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6240 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6241 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6244 if (GET_CODE (operands[1]) == CONST)
6246 rtx offset = const0_rtx;
6247 HOST_WIDE_INT value;
6249 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6250 value = INTVAL (offset);
6253 rtx tmp = (!can_create_pseudo_p ()
6255 : gen_reg_rtx (Pmode));
6256 emit_insn (gen_movsi_got (tmp, operands[1]));
6257 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6262 operands[2] = rs6000_got_register (operands[1]);
6265 (define_insn "*movsi_got_internal"
6266 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6267 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6268 (match_operand:SI 2 "gpc_reg_operand" "b")]
6270 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6271 "lwz %0,%a1@got(%2)"
6272 [(set_attr "type" "load")])
6274 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6275 ;; didn't get allocated to a hard register.
6277 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6278 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6279 (match_operand:SI 2 "memory_operand" "")]
6281 "DEFAULT_ABI == ABI_V4
6283 && (reload_in_progress || reload_completed)"
6284 [(set (match_dup 0) (match_dup 2))
6285 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6289 ;; For SI, we special-case integers that can't be loaded in one insn. We
6290 ;; do the load 16-bits at a time. We could do this by loading from memory,
6291 ;; and this is even supposed to be faster, but it is simpler not to get
6292 ;; integers in the TOC.
6293 (define_insn "movsi_low"
6294 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6295 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6296 (match_operand 2 "" ""))))]
6297 "TARGET_MACHO && ! TARGET_64BIT"
6298 "lwz %0,lo16(%2)(%1)"
6299 [(set_attr "type" "load")
6300 (set_attr "length" "4")])
6302 (define_insn "*movsi_internal1"
6303 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6304 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6305 "!TARGET_SINGLE_FPU &&
6306 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6319 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6320 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6322 (define_insn "*movsi_internal1_single"
6323 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6324 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6325 "TARGET_SINGLE_FPU &&
6326 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6341 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6342 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6344 ;; Split a load of a large constant into the appropriate two-insn
6348 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6349 (match_operand:SI 1 "const_int_operand" ""))]
6350 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6351 && (INTVAL (operands[1]) & 0xffff) != 0"
6355 (ior:SI (match_dup 0)
6359 if (rs6000_emit_set_const (operands[0], operands[1]))
6365 (define_insn "*mov<mode>_internal2"
6366 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6367 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6369 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6375 [(set_attr "type" "cmp,logical,cmp")
6376 (set_attr "dot" "yes")
6377 (set_attr "length" "4,4,8")])
6380 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6381 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6383 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6385 [(set (match_dup 0) (match_dup 1))
6387 (compare:CC (match_dup 0)
6391 (define_insn "*movhi_internal"
6392 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6393 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6394 "gpc_reg_operand (operands[0], HImode)
6395 || gpc_reg_operand (operands[1], HImode)"
6404 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6406 (define_expand "mov<mode>"
6407 [(set (match_operand:INT 0 "general_operand" "")
6408 (match_operand:INT 1 "any_operand" ""))]
6410 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6412 (define_insn "*movqi_internal"
6413 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6414 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6415 "gpc_reg_operand (operands[0], QImode)
6416 || gpc_reg_operand (operands[1], QImode)"
6425 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6427 ;; Here is how to move condition codes around. When we store CC data in
6428 ;; an integer register or memory, we store just the high-order 4 bits.
6429 ;; This lets us not shift in the most common case of CR0.
6430 (define_expand "movcc"
6431 [(set (match_operand:CC 0 "nonimmediate_operand" "")
6432 (match_operand:CC 1 "nonimmediate_operand" ""))]
6436 (define_insn "*movcc_internal1"
6437 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6438 (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6439 "register_operand (operands[0], CCmode)
6440 || register_operand (operands[1], CCmode)"
6444 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6447 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6455 (cond [(eq_attr "alternative" "0,3")
6456 (const_string "cr_logical")
6457 (eq_attr "alternative" "1,2")
6458 (const_string "mtcr")
6459 (eq_attr "alternative" "6,7")
6460 (const_string "integer")
6461 (eq_attr "alternative" "8")
6462 (const_string "mfjmpr")
6463 (eq_attr "alternative" "9")
6464 (const_string "mtjmpr")
6465 (eq_attr "alternative" "10")
6466 (const_string "load")
6467 (eq_attr "alternative" "11")
6468 (const_string "store")
6469 (match_test "TARGET_MFCRF")
6470 (const_string "mfcrf")
6472 (const_string "mfcr")))
6473 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6475 ;; For floating-point, we normally deal with the floating-point registers
6476 ;; unless -msoft-float is used. The sole exception is that parameter passing
6477 ;; can produce floating-point values in fixed-point registers. Unless the
6478 ;; value is a simple constant or already in memory, we deal with this by
6479 ;; allocating memory and copying the value explicitly via that memory location.
6481 ;; Move 32-bit binary/decimal floating point
6482 (define_expand "mov<mode>"
6483 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6484 (match_operand:FMOVE32 1 "any_operand" ""))]
6486 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6489 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6490 (match_operand:FMOVE32 1 "const_double_operand" ""))]
6492 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6493 || (GET_CODE (operands[0]) == SUBREG
6494 && GET_CODE (SUBREG_REG (operands[0])) == REG
6495 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6496 [(set (match_dup 2) (match_dup 3))]
6501 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6503 if (! TARGET_POWERPC64)
6504 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6506 operands[2] = gen_lowpart (SImode, operands[0]);
6508 operands[3] = gen_int_mode (l, SImode);
6511 (define_insn "mov<mode>_hardfloat"
6512 [(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")
6513 (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,<zero_fp>,<zero_fp>,<f32_lm>,<f32_lm2>,<f32_sr>,<f32_sr2>,Z,<f32_av>,r,<f32_dm>,r,h,0"))]
6514 "(gpc_reg_operand (operands[0], <MODE>mode)
6515 || gpc_reg_operand (operands[1], <MODE>mode))
6516 && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6522 xscpsgndp %x0,%x1,%x1
6536 [(set_attr "type" "*,load,store,fp,fp,vecsimple,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mffgpr,mftgpr,mtjmpr,mfjmpr,*")
6537 (set_attr "length" "4")])
6539 (define_insn "*mov<mode>_softfloat"
6540 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6541 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6542 "(gpc_reg_operand (operands[0], <MODE>mode)
6543 || gpc_reg_operand (operands[1], <MODE>mode))
6544 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6556 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6557 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6560 ;; Move 64-bit binary/decimal floating point
6561 (define_expand "mov<mode>"
6562 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6563 (match_operand:FMOVE64 1 "any_operand" ""))]
6565 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6568 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6569 (match_operand:FMOVE64 1 "const_int_operand" ""))]
6570 "! TARGET_POWERPC64 && reload_completed
6571 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6572 || (GET_CODE (operands[0]) == SUBREG
6573 && GET_CODE (SUBREG_REG (operands[0])) == REG
6574 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6575 [(set (match_dup 2) (match_dup 4))
6576 (set (match_dup 3) (match_dup 1))]
6579 int endian = (WORDS_BIG_ENDIAN == 0);
6580 HOST_WIDE_INT value = INTVAL (operands[1]);
6582 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6583 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6584 operands[4] = GEN_INT (value >> 32);
6585 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6589 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6590 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6591 "! TARGET_POWERPC64 && reload_completed
6592 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6593 || (GET_CODE (operands[0]) == SUBREG
6594 && GET_CODE (SUBREG_REG (operands[0])) == REG
6595 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6596 [(set (match_dup 2) (match_dup 4))
6597 (set (match_dup 3) (match_dup 5))]
6600 int endian = (WORDS_BIG_ENDIAN == 0);
6603 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6605 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6606 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6607 operands[4] = gen_int_mode (l[endian], SImode);
6608 operands[5] = gen_int_mode (l[1 - endian], SImode);
6612 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6613 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6614 "TARGET_POWERPC64 && reload_completed
6615 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6616 || (GET_CODE (operands[0]) == SUBREG
6617 && GET_CODE (SUBREG_REG (operands[0])) == REG
6618 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6619 [(set (match_dup 2) (match_dup 3))]
6622 int endian = (WORDS_BIG_ENDIAN == 0);
6626 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6628 operands[2] = gen_lowpart (DImode, operands[0]);
6629 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
6630 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6631 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6633 operands[3] = gen_int_mode (val, DImode);
6636 ;; Don't have reload use general registers to load a constant. It is
6637 ;; less efficient than loading the constant into an FP register, since
6638 ;; it will probably be used there.
6640 ;; The move constraints are ordered to prefer floating point registers before
6641 ;; general purpose registers to avoid doing a store and a load to get the value
6642 ;; into a floating point register when it is needed for a floating point
6643 ;; operation. Prefer traditional floating point registers over VSX registers,
6644 ;; since the D-form version of the memory instructions does not need a GPR for
6645 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6648 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6649 ;; except for 0.0 which can be created on VSX with an xor instruction.
6651 (define_insn "*mov<mode>_hardfloat32"
6652 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,o,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6653 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,o,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
6654 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6655 && (gpc_reg_operand (operands[0], <MODE>mode)
6656 || gpc_reg_operand (operands[1], <MODE>mode))"
6671 [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,two,store,load,two")
6672 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6674 (define_insn "*mov<mode>_softfloat32"
6675 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6676 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6678 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
6679 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6680 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6681 && (gpc_reg_operand (operands[0], <MODE>mode)
6682 || gpc_reg_operand (operands[1], <MODE>mode))"
6684 [(set_attr "type" "store,load,two,*,*,*")
6685 (set_attr "length" "8,8,8,8,12,16")])
6687 ; ld/std require word-aligned displacements -> 'Y' constraint.
6688 ; List Y->r and r->Y before r->r for reload.
6689 (define_insn "*mov<mode>_hardfloat64"
6690 [(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>")
6691 (match_operand:FMOVE64 1 "input_operand" "d,m,d,o,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
6692 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6693 && (gpc_reg_operand (operands[0], <MODE>mode)
6694 || gpc_reg_operand (operands[1], <MODE>mode))"
6716 [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6717 (set_attr "length" "4")])
6719 (define_insn "*mov<mode>_softfloat64"
6720 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6721 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6722 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6723 && (gpc_reg_operand (operands[0], <MODE>mode)
6724 || gpc_reg_operand (operands[1], <MODE>mode))"
6735 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6736 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6738 (define_expand "mov<mode>"
6739 [(set (match_operand:FMOVE128 0 "general_operand" "")
6740 (match_operand:FMOVE128 1 "any_operand" ""))]
6742 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6744 ;; It's important to list Y->r and r->Y before r->r because otherwise
6745 ;; reload, given m->r, will try to pick r->r and reload it, which
6746 ;; doesn't make progress.
6748 ;; We can't split little endian direct moves of TDmode, because the words are
6749 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
6750 ;; problematical. Don't allow direct move for this case.
6752 (define_insn_and_split "*mov<mode>_64bit_dm"
6753 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
6754 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
6755 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6756 && FLOAT128_2REG_P (<MODE>mode)
6757 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6758 && (gpc_reg_operand (operands[0], <MODE>mode)
6759 || gpc_reg_operand (operands[1], <MODE>mode))"
6761 "&& reload_completed"
6763 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6764 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6766 (define_insn_and_split "*movtd_64bit_nodm"
6767 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
6768 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
6769 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6770 && (gpc_reg_operand (operands[0], TDmode)
6771 || gpc_reg_operand (operands[1], TDmode))"
6773 "&& reload_completed"
6775 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6776 [(set_attr "length" "8,8,8,12,12,8")])
6778 (define_insn_and_split "*mov<mode>_32bit"
6779 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
6780 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
6781 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
6782 && (FLOAT128_2REG_P (<MODE>mode)
6783 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
6784 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
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" "8,8,8,8,20,20,16")])
6793 (define_insn_and_split "*mov<mode>_softfloat"
6794 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
6795 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
6796 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
6797 && (gpc_reg_operand (operands[0], <MODE>mode)
6798 || gpc_reg_operand (operands[1], <MODE>mode))"
6800 "&& reload_completed"
6802 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6803 [(set_attr "length" "20,20,16")])
6805 (define_expand "extenddf<mode>2"
6806 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6807 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
6808 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
6809 && TARGET_LONG_DOUBLE_128"
6811 if (FLOAT128_IEEE_P (<MODE>mode))
6812 rs6000_expand_float128_convert (operands[0], operands[1], false);
6813 else if (TARGET_E500_DOUBLE)
6815 gcc_assert (<MODE>mode == TFmode);
6816 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
6818 else if (TARGET_VSX)
6820 if (<MODE>mode == TFmode)
6821 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
6822 else if (<MODE>mode == IFmode)
6823 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
6829 rtx zero = gen_reg_rtx (DFmode);
6830 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
6832 if (<MODE>mode == TFmode)
6833 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
6834 else if (<MODE>mode == IFmode)
6835 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
6842 ;; Allow memory operands for the source to be created by the combiner.
6843 (define_insn_and_split "extenddf<mode>2_fprs"
6844 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
6845 (float_extend:IBM128
6846 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
6847 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
6848 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6849 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6851 "&& reload_completed"
6852 [(set (match_dup 3) (match_dup 1))
6853 (set (match_dup 4) (match_dup 2))]
6855 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6856 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6858 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6859 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6862 (define_insn_and_split "extenddf<mode>2_vsx"
6863 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
6864 (float_extend:IBM128
6865 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
6866 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
6868 "&& reload_completed"
6869 [(set (match_dup 2) (match_dup 1))
6870 (set (match_dup 3) (match_dup 4))]
6872 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6873 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6875 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6876 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6877 operands[4] = CONST0_RTX (DFmode);
6880 (define_expand "extendsf<mode>2"
6881 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6882 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
6884 && (TARGET_FPRS || TARGET_E500_DOUBLE)
6885 && TARGET_LONG_DOUBLE_128"
6887 if (FLOAT128_IEEE_P (<MODE>mode))
6888 rs6000_expand_float128_convert (operands[0], operands[1], false);
6891 rtx tmp = gen_reg_rtx (DFmode);
6892 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
6893 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
6898 (define_expand "trunc<mode>df2"
6899 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6900 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6902 && (TARGET_FPRS || TARGET_E500_DOUBLE)
6903 && TARGET_LONG_DOUBLE_128"
6905 if (FLOAT128_IEEE_P (<MODE>mode))
6907 rs6000_expand_float128_convert (operands[0], operands[1], false);
6912 (define_insn_and_split "trunc<mode>df2_internal1"
6913 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
6915 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
6916 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
6917 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
6921 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
6924 emit_note (NOTE_INSN_DELETED);
6927 [(set_attr "type" "fp")])
6929 (define_insn "trunc<mode>df2_internal2"
6930 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6931 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
6932 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
6933 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
6935 [(set_attr "type" "fp")
6936 (set_attr "fp_type" "fp_addsub_d")])
6938 (define_expand "trunc<mode>sf2"
6939 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6940 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6942 && (TARGET_FPRS || TARGET_E500_DOUBLE)
6943 && TARGET_LONG_DOUBLE_128"
6945 if (FLOAT128_IEEE_P (<MODE>mode))
6946 rs6000_expand_float128_convert (operands[0], operands[1], false);
6947 else if (TARGET_E500_DOUBLE)
6949 gcc_assert (<MODE>mode == TFmode);
6950 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
6952 else if (<MODE>mode == TFmode)
6953 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
6954 else if (<MODE>mode == IFmode)
6955 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
6961 (define_insn_and_split "trunc<mode>sf2_fprs"
6962 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6963 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
6964 (clobber (match_scratch:DF 2 "=d"))]
6965 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6966 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6968 "&& reload_completed"
6970 (float_truncate:DF (match_dup 1)))
6972 (float_truncate:SF (match_dup 2)))]
6975 (define_expand "floatsi<mode>2"
6976 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6977 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
6979 && (TARGET_FPRS || TARGET_E500_DOUBLE)
6980 && TARGET_LONG_DOUBLE_128"
6982 if (FLOAT128_IEEE_P (<MODE>mode))
6983 rs6000_expand_float128_convert (operands[0], operands[1], false);
6986 rtx tmp = gen_reg_rtx (DFmode);
6987 expand_float (tmp, operands[1], false);
6988 if (<MODE>mode == TFmode)
6989 emit_insn (gen_extenddftf2 (operands[0], tmp));
6990 else if (<MODE>mode == IFmode)
6991 emit_insn (gen_extenddfif2 (operands[0], tmp));
6998 ; fadd, but rounding towards zero.
6999 ; This is probably not the optimal code sequence.
7000 (define_insn "fix_trunc_helper<mode>"
7001 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7002 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7003 UNSPEC_FIX_TRUNC_TF))
7004 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7005 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7006 && FLOAT128_IBM_P (<MODE>mode)"
7007 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7008 [(set_attr "type" "fp")
7009 (set_attr "length" "20")])
7011 (define_expand "fix_trunc<mode>si2"
7012 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7013 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7015 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7017 if (FLOAT128_IEEE_P (<MODE>mode))
7018 rs6000_expand_float128_convert (operands[0], operands[1], false);
7019 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7020 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7021 else if (<MODE>mode == TFmode)
7022 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7023 else if (<MODE>mode == IFmode)
7024 emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7030 (define_expand "fix_trunc<mode>si2_fprs"
7031 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7032 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7033 (clobber (match_dup 2))
7034 (clobber (match_dup 3))
7035 (clobber (match_dup 4))
7036 (clobber (match_dup 5))])]
7037 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7039 operands[2] = gen_reg_rtx (DFmode);
7040 operands[3] = gen_reg_rtx (DFmode);
7041 operands[4] = gen_reg_rtx (DImode);
7042 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7045 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7046 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7047 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7048 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7049 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7050 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7051 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7052 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7058 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7061 gcc_assert (MEM_P (operands[5]));
7062 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7064 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7065 emit_move_insn (operands[5], operands[4]);
7066 emit_move_insn (operands[0], lowword);
7070 (define_expand "fix_trunc<mode>di2"
7071 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7072 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7075 rs6000_expand_float128_convert (operands[0], operands[1], false);
7079 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7080 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7081 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7084 rs6000_expand_float128_convert (operands[0], operands[1], true);
7088 (define_expand "floatdi<mode>2"
7089 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7090 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7093 rs6000_expand_float128_convert (operands[0], operands[1], false);
7097 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7098 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7099 (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7102 rs6000_expand_float128_convert (operands[0], operands[1], true);
7106 (define_expand "neg<mode>2"
7107 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7108 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7109 "FLOAT128_IEEE_P (<MODE>mode)
7110 || (FLOAT128_IBM_P (<MODE>mode)
7111 && TARGET_HARD_FLOAT
7112 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7115 if (FLOAT128_IEEE_P (<MODE>mode))
7117 if (TARGET_FLOAT128_HW)
7119 if (<MODE>mode == TFmode)
7120 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7121 else if (<MODE>mode == KFmode)
7122 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7126 else if (TARGET_FLOAT128)
7128 if (<MODE>mode == TFmode)
7129 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7130 else if (<MODE>mode == KFmode)
7131 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7137 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7138 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7140 operands[1], <MODE>mode);
7142 if (target && !rtx_equal_p (target, operands[0]))
7143 emit_move_insn (operands[0], target);
7149 (define_insn "neg<mode>2_internal"
7150 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7151 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7152 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7155 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7156 return \"fneg %L0,%L1\;fneg %0,%1\";
7158 return \"fneg %0,%1\;fneg %L0,%L1\";
7160 [(set_attr "type" "fp")
7161 (set_attr "length" "8")])
7163 (define_expand "abs<mode>2"
7164 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7165 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7166 "FLOAT128_IEEE_P (<MODE>mode)
7167 || (FLOAT128_IBM_P (<MODE>mode)
7168 && TARGET_HARD_FLOAT
7169 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7174 if (FLOAT128_IEEE_P (<MODE>mode))
7176 if (TARGET_FLOAT128_HW)
7178 if (<MODE>mode == TFmode)
7179 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7180 else if (<MODE>mode == KFmode)
7181 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7186 else if (TARGET_FLOAT128)
7188 if (<MODE>mode == TFmode)
7189 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7190 else if (<MODE>mode == KFmode)
7191 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7200 label = gen_label_rtx ();
7201 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7203 if (flag_finite_math_only && !flag_trapping_math)
7204 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7206 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7208 else if (<MODE>mode == TFmode)
7209 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7210 else if (<MODE>mode == TFmode)
7211 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7218 (define_expand "abs<mode>2_internal"
7219 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7220 (match_operand:IBM128 1 "gpc_reg_operand" ""))
7221 (set (match_dup 3) (match_dup 5))
7222 (set (match_dup 5) (abs:DF (match_dup 5)))
7223 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7224 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7225 (label_ref (match_operand 2 "" ""))
7227 (set (match_dup 6) (neg:DF (match_dup 6)))]
7228 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7229 && TARGET_LONG_DOUBLE_128"
7232 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7233 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7234 operands[3] = gen_reg_rtx (DFmode);
7235 operands[4] = gen_reg_rtx (CCFPmode);
7236 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7237 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7241 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7244 (define_expand "ieee_128bit_negative_zero"
7245 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7248 rtvec v = rtvec_alloc (16);
7251 for (i = 0; i < 16; i++)
7252 RTVEC_ELT (v, i) = const0_rtx;
7254 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7255 RTVEC_ELT (v, high) = GEN_INT (0x80);
7257 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7261 ;; IEEE 128-bit negate
7263 ;; We have 2 insns here for negate and absolute value. The first uses
7264 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7265 ;; insns, and second insn after the first split pass loads up the bit to
7266 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
7267 ;; neg/abs to create the constant just once.
7269 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7270 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7271 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7272 (clobber (match_scratch:V16QI 2 "=v"))]
7273 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7276 [(parallel [(set (match_dup 0)
7277 (neg:IEEE128 (match_dup 1)))
7278 (use (match_dup 2))])]
7280 if (GET_CODE (operands[2]) == SCRATCH)
7281 operands[2] = gen_reg_rtx (V16QImode);
7283 operands[3] = gen_reg_rtx (V16QImode);
7284 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7286 [(set_attr "length" "8")
7287 (set_attr "type" "vecsimple")])
7289 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7290 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7291 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7292 (use (match_operand:V16QI 2 "register_operand" "v"))]
7293 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7294 "xxlxor %x0,%x1,%x2"
7295 [(set_attr "type" "vecsimple")])
7297 ;; IEEE 128-bit absolute value
7298 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7299 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7300 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7301 (clobber (match_scratch:V16QI 2 "=v"))]
7302 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7305 [(parallel [(set (match_dup 0)
7306 (abs:IEEE128 (match_dup 1)))
7307 (use (match_dup 2))])]
7309 if (GET_CODE (operands[2]) == SCRATCH)
7310 operands[2] = gen_reg_rtx (V16QImode);
7312 operands[3] = gen_reg_rtx (V16QImode);
7313 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7315 [(set_attr "length" "8")
7316 (set_attr "type" "vecsimple")])
7318 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7319 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7320 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7321 (use (match_operand:V16QI 2 "register_operand" "v"))]
7322 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7323 "xxlandc %x0,%x1,%x2"
7324 [(set_attr "type" "vecsimple")])
7326 ;; IEEE 128-bit negative absolute value
7327 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7328 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7331 (match_operand:IEEE128 1 "register_operand" "wa"))))
7332 (clobber (match_scratch:V16QI 2 "=v"))]
7333 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7336 [(parallel [(set (match_dup 0)
7337 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7338 (use (match_dup 2))])]
7340 if (GET_CODE (operands[2]) == SCRATCH)
7341 operands[2] = gen_reg_rtx (V16QImode);
7343 operands[3] = gen_reg_rtx (V16QImode);
7344 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7346 [(set_attr "length" "8")
7347 (set_attr "type" "vecsimple")])
7349 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7350 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7353 (match_operand:IEEE128 1 "register_operand" "wa"))))
7354 (use (match_operand:V16QI 2 "register_operand" "v"))]
7355 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7357 [(set_attr "type" "vecsimple")])
7359 ;; Float128 conversion functions. These expand to library function calls.
7360 ;; We use expand to convert from IBM double double to IEEE 128-bit
7361 ;; and trunc for the opposite.
7362 (define_expand "extendiftf2"
7363 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7364 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7367 rs6000_expand_float128_convert (operands[0], operands[1], false);
7371 (define_expand "extendifkf2"
7372 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7373 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7376 rs6000_expand_float128_convert (operands[0], operands[1], false);
7380 (define_expand "extendtfkf2"
7381 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7382 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7385 rs6000_expand_float128_convert (operands[0], operands[1], false);
7389 (define_expand "trunciftf2"
7390 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7391 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7394 rs6000_expand_float128_convert (operands[0], operands[1], false);
7398 (define_expand "truncifkf2"
7399 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7400 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7403 rs6000_expand_float128_convert (operands[0], operands[1], false);
7407 (define_expand "trunckftf2"
7408 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7409 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7412 rs6000_expand_float128_convert (operands[0], operands[1], false);
7416 (define_expand "trunctfif2"
7417 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7418 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7421 rs6000_expand_float128_convert (operands[0], operands[1], false);
7426 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
7427 ;; must have 3 arguments, and scratch register constraint must be a single
7430 ;; Reload patterns to support gpr load/store with misaligned mem.
7431 ;; and multiple gpr load/store at offset >= 0xfffc
7432 (define_expand "reload_<mode>_store"
7433 [(parallel [(match_operand 0 "memory_operand" "=m")
7434 (match_operand 1 "gpc_reg_operand" "r")
7435 (match_operand:GPR 2 "register_operand" "=&b")])]
7438 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7442 (define_expand "reload_<mode>_load"
7443 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7444 (match_operand 1 "memory_operand" "m")
7445 (match_operand:GPR 2 "register_operand" "=b")])]
7448 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7453 ;; Reload patterns for various types using the vector registers. We may need
7454 ;; an additional base register to convert the reg+offset addressing to reg+reg
7455 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7456 ;; index register for gpr registers.
7457 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7458 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7459 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7460 (match_operand:P 2 "register_operand" "=b")])]
7463 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7467 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7468 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7469 (match_operand:RELOAD 1 "memory_operand" "m")
7470 (match_operand:P 2 "register_operand" "=b")])]
7473 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7478 ;; Reload sometimes tries to move the address to a GPR, and can generate
7479 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
7480 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7482 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7483 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7484 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7485 (match_operand:P 2 "reg_or_cint_operand" "rI"))
7487 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7489 "&& reload_completed"
7491 (plus:P (match_dup 1)
7494 (and:P (match_dup 0)
7497 ;; Power8 merge instructions to allow direct move to/from floating point
7498 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
7499 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
7500 ;; value, since it is allocated in reload and not all of the flow information
7501 ;; is setup for it. We have two patterns to do the two moves between gprs and
7502 ;; fprs. There isn't a dependancy between the two, but we could potentially
7503 ;; schedule other instructions between the two instructions.
7505 (define_insn "p8_fmrgow_<mode>"
7506 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7508 (match_operand:DF 1 "register_operand" "d")
7509 (match_operand:DF 2 "register_operand" "d")]
7510 UNSPEC_P8V_FMRGOW))]
7511 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7513 [(set_attr "type" "vecperm")])
7515 (define_insn "p8_mtvsrwz"
7516 [(set (match_operand:DF 0 "register_operand" "=d")
7517 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7518 UNSPEC_P8V_MTVSRWZ))]
7519 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7521 [(set_attr "type" "mftgpr")])
7523 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7524 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7525 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7526 UNSPEC_P8V_RELOAD_FROM_GPR))
7527 (clobber (match_operand:IF 2 "register_operand" "=d"))]
7528 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7530 "&& reload_completed"
7533 rtx dest = operands[0];
7534 rtx src = operands[1];
7535 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7536 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7537 rtx gpr_hi_reg = gen_highpart (SImode, src);
7538 rtx gpr_lo_reg = gen_lowpart (SImode, src);
7540 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7541 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7542 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7545 [(set_attr "length" "12")
7546 (set_attr "type" "three")])
7548 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7549 (define_insn "p8_mtvsrd_df"
7550 [(set (match_operand:DF 0 "register_operand" "=wa")
7551 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7552 UNSPEC_P8V_MTVSRD))]
7553 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7555 [(set_attr "type" "mftgpr")])
7557 (define_insn "p8_xxpermdi_<mode>"
7558 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7559 (unspec:FMOVE128_GPR [
7560 (match_operand:DF 1 "register_operand" "wa")
7561 (match_operand:DF 2 "register_operand" "wa")]
7562 UNSPEC_P8V_XXPERMDI))]
7563 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7564 "xxpermdi %x0,%x1,%x2,0"
7565 [(set_attr "type" "vecperm")])
7567 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7568 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7569 (unspec:FMOVE128_GPR
7570 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7571 UNSPEC_P8V_RELOAD_FROM_GPR))
7572 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
7573 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7575 "&& reload_completed"
7578 rtx dest = operands[0];
7579 rtx src = operands[1];
7580 /* You might think that we could use op0 as one temp and a DF clobber
7581 as op2, but you'd be wrong. Secondary reload move patterns don't
7582 check for overlap of the clobber and the destination. */
7583 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7584 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7585 rtx gpr_hi_reg = gen_highpart (DImode, src);
7586 rtx gpr_lo_reg = gen_lowpart (DImode, src);
7588 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
7589 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
7590 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
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.
7611 (define_insn "p8_mtvsrd_sf"
7612 [(set (match_operand:SF 0 "register_operand" "=wa")
7613 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
7614 UNSPEC_P8V_MTVSRD))]
7615 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7617 [(set_attr "type" "mftgpr")])
7619 (define_insn_and_split "reload_vsx_from_gprsf"
7620 [(set (match_operand:SF 0 "register_operand" "=wa")
7621 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7622 UNSPEC_P8V_RELOAD_FROM_GPR))
7623 (clobber (match_operand:DI 2 "register_operand" "=r"))]
7624 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7626 "&& reload_completed"
7629 rtx op0 = operands[0];
7630 rtx op1 = operands[1];
7631 rtx op2 = operands[2];
7632 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7634 /* Move SF value to upper 32-bits for xscvspdpn. */
7635 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7636 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7637 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7640 [(set_attr "length" "8")
7641 (set_attr "type" "two")])
7643 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7644 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7645 ;; and then doing a move of that.
7646 (define_insn "p8_mfvsrd_3_<mode>"
7647 [(set (match_operand:DF 0 "register_operand" "=r")
7648 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7649 UNSPEC_P8V_RELOAD_FROM_VSX))]
7650 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7652 [(set_attr "type" "mftgpr")])
7654 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7655 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7656 (unspec:FMOVE128_GPR
7657 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7658 UNSPEC_P8V_RELOAD_FROM_VSX))
7659 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7660 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7662 "&& reload_completed"
7665 rtx dest = operands[0];
7666 rtx src = operands[1];
7667 rtx tmp = operands[2];
7668 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7669 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7671 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7672 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7673 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7676 [(set_attr "length" "12")
7677 (set_attr "type" "three")])
7679 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
7680 ;; type is stored internally as double precision, we have to convert it to the
7683 (define_insn_and_split "reload_gpr_from_vsxsf"
7684 [(set (match_operand:SF 0 "register_operand" "=r")
7685 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7686 UNSPEC_P8V_RELOAD_FROM_VSX))
7687 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7688 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7690 "&& reload_completed"
7693 rtx op0 = operands[0];
7694 rtx op1 = operands[1];
7695 rtx op2 = operands[2];
7696 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7698 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7699 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7700 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7703 [(set_attr "length" "12")
7704 (set_attr "type" "three")])
7706 (define_insn "p8_mfvsrd_4_disf"
7707 [(set (match_operand:DI 0 "register_operand" "=r")
7708 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7709 UNSPEC_P8V_RELOAD_FROM_VSX))]
7710 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7712 [(set_attr "type" "mftgpr")])
7715 ;; Next come the multi-word integer load and store and the load and store
7718 ;; List r->r after r->Y, otherwise reload will try to reload a
7719 ;; non-offsettable address by using r->r which won't make progress.
7720 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7721 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7722 (define_insn "*movdi_internal32"
7723 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
7724 (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
7726 && (gpc_reg_operand (operands[0], DImode)
7727 || gpc_reg_operand (operands[1], DImode))"
7736 [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
7739 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7740 (match_operand:DI 1 "const_int_operand" ""))]
7741 "! TARGET_POWERPC64 && reload_completed
7742 && gpr_or_gpr_p (operands[0], operands[1])
7743 && !direct_move_p (operands[0], operands[1])"
7744 [(set (match_dup 2) (match_dup 4))
7745 (set (match_dup 3) (match_dup 1))]
7748 HOST_WIDE_INT value = INTVAL (operands[1]);
7749 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7751 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7753 operands[4] = GEN_INT (value >> 32);
7754 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7758 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7759 (match_operand:DIFD 1 "input_operand" ""))]
7760 "reload_completed && !TARGET_POWERPC64
7761 && gpr_or_gpr_p (operands[0], operands[1])
7762 && !direct_move_p (operands[0], operands[1])"
7764 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7766 (define_insn "*movdi_internal64"
7767 [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi")
7768 (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))]
7770 && (gpc_reg_operand (operands[0], DImode)
7771 || gpc_reg_operand (operands[1], DImode))"
7790 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
7791 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
7793 ; Some DImode loads are best done as a load of -1 followed by a mask
7796 [(set (match_operand:DI 0 "gpc_reg_operand")
7797 (match_operand:DI 1 "const_int_operand"))]
7799 && num_insns_constant (operands[1], DImode) > 1
7800 && rs6000_is_valid_and_mask (operands[1], DImode)"
7804 (and:DI (match_dup 0)
7808 ;; Split a load of a large constant into the appropriate five-instruction
7809 ;; sequence. Handle anything in a constant number of insns.
7810 ;; When non-easy constants can go in the TOC, this should use
7811 ;; easy_fp_constant predicate.
7813 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7814 (match_operand:DI 1 "const_int_operand" ""))]
7815 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7816 [(set (match_dup 0) (match_dup 2))
7817 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7820 if (rs6000_emit_set_const (operands[0], operands[1]))
7827 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7828 (match_operand:DI 1 "const_scalar_int_operand" ""))]
7829 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7830 [(set (match_dup 0) (match_dup 2))
7831 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7834 if (rs6000_emit_set_const (operands[0], operands[1]))
7840 ;; TImode/PTImode is similar, except that we usually want to compute the
7841 ;; address into a register and use lsi/stsi (the exception is during reload).
7843 (define_insn "*mov<mode>_string"
7844 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
7845 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
7847 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
7848 && (gpc_reg_operand (operands[0], <MODE>mode)
7849 || gpc_reg_operand (operands[1], <MODE>mode))"
7852 switch (which_alternative)
7858 return \"stswi %1,%P0,16\";
7862 /* If the address is not used in the output, we can use lsi. Otherwise,
7863 fall through to generating four loads. */
7865 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
7866 return \"lswi %0,%P1,16\";
7867 /* ... fall through ... */
7874 [(set_attr "type" "store,store,load,load,*,*")
7875 (set_attr "update" "yes")
7876 (set_attr "indexed" "yes")
7877 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
7878 (const_string "always")
7879 (const_string "conditional")))])
7881 (define_insn "*mov<mode>_ppc64"
7882 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
7883 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
7884 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
7885 && (gpc_reg_operand (operands[0], <MODE>mode)
7886 || gpc_reg_operand (operands[1], <MODE>mode)))"
7888 return rs6000_output_move_128bit (operands);
7890 [(set_attr "type" "store,store,load,load,*,*")
7891 (set_attr "length" "8")])
7894 [(set (match_operand:TI2 0 "int_reg_operand" "")
7895 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
7897 && (VECTOR_MEM_NONE_P (<MODE>mode)
7898 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
7899 [(set (match_dup 2) (match_dup 4))
7900 (set (match_dup 3) (match_dup 5))]
7903 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7905 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7907 if (CONST_WIDE_INT_P (operands[1]))
7909 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
7910 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
7912 else if (CONST_INT_P (operands[1]))
7914 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
7915 operands[5] = operands[1];
7922 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
7923 (match_operand:TI2 1 "input_operand" ""))]
7925 && gpr_or_gpr_p (operands[0], operands[1])
7926 && !direct_move_p (operands[0], operands[1])
7927 && !quad_load_store_p (operands[0], operands[1])"
7929 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7931 (define_expand "load_multiple"
7932 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7933 (match_operand:SI 1 "" ""))
7934 (use (match_operand:SI 2 "" ""))])]
7935 "TARGET_STRING && !TARGET_POWERPC64"
7943 /* Support only loading a constant number of fixed-point registers from
7944 memory and only bother with this if more than two; the machine
7945 doesn't support more than eight. */
7946 if (GET_CODE (operands[2]) != CONST_INT
7947 || INTVAL (operands[2]) <= 2
7948 || INTVAL (operands[2]) > 8
7949 || GET_CODE (operands[1]) != MEM
7950 || GET_CODE (operands[0]) != REG
7951 || REGNO (operands[0]) >= 32)
7954 count = INTVAL (operands[2]);
7955 regno = REGNO (operands[0]);
7957 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
7958 op1 = replace_equiv_address (operands[1],
7959 force_reg (SImode, XEXP (operands[1], 0)));
7961 for (i = 0; i < count; i++)
7962 XVECEXP (operands[3], 0, i)
7963 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
7964 adjust_address_nv (op1, SImode, i * 4));
7967 (define_insn "*ldmsi8"
7968 [(match_parallel 0 "load_multiple_operation"
7969 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7970 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7971 (set (match_operand:SI 3 "gpc_reg_operand" "")
7972 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7973 (set (match_operand:SI 4 "gpc_reg_operand" "")
7974 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7975 (set (match_operand:SI 5 "gpc_reg_operand" "")
7976 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7977 (set (match_operand:SI 6 "gpc_reg_operand" "")
7978 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7979 (set (match_operand:SI 7 "gpc_reg_operand" "")
7980 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
7981 (set (match_operand:SI 8 "gpc_reg_operand" "")
7982 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
7983 (set (match_operand:SI 9 "gpc_reg_operand" "")
7984 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
7985 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
7987 { return rs6000_output_load_multiple (operands); }"
7988 [(set_attr "type" "load")
7989 (set_attr "update" "yes")
7990 (set_attr "indexed" "yes")
7991 (set_attr "length" "32")])
7993 (define_insn "*ldmsi7"
7994 [(match_parallel 0 "load_multiple_operation"
7995 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7996 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7997 (set (match_operand:SI 3 "gpc_reg_operand" "")
7998 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7999 (set (match_operand:SI 4 "gpc_reg_operand" "")
8000 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8001 (set (match_operand:SI 5 "gpc_reg_operand" "")
8002 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8003 (set (match_operand:SI 6 "gpc_reg_operand" "")
8004 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8005 (set (match_operand:SI 7 "gpc_reg_operand" "")
8006 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8007 (set (match_operand:SI 8 "gpc_reg_operand" "")
8008 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8009 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8011 { return rs6000_output_load_multiple (operands); }"
8012 [(set_attr "type" "load")
8013 (set_attr "update" "yes")
8014 (set_attr "indexed" "yes")
8015 (set_attr "length" "32")])
8017 (define_insn "*ldmsi6"
8018 [(match_parallel 0 "load_multiple_operation"
8019 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8020 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8021 (set (match_operand:SI 3 "gpc_reg_operand" "")
8022 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8023 (set (match_operand:SI 4 "gpc_reg_operand" "")
8024 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8025 (set (match_operand:SI 5 "gpc_reg_operand" "")
8026 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8027 (set (match_operand:SI 6 "gpc_reg_operand" "")
8028 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8029 (set (match_operand:SI 7 "gpc_reg_operand" "")
8030 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8031 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8033 { return rs6000_output_load_multiple (operands); }"
8034 [(set_attr "type" "load")
8035 (set_attr "update" "yes")
8036 (set_attr "indexed" "yes")
8037 (set_attr "length" "32")])
8039 (define_insn "*ldmsi5"
8040 [(match_parallel 0 "load_multiple_operation"
8041 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8042 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8043 (set (match_operand:SI 3 "gpc_reg_operand" "")
8044 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8045 (set (match_operand:SI 4 "gpc_reg_operand" "")
8046 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8047 (set (match_operand:SI 5 "gpc_reg_operand" "")
8048 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8049 (set (match_operand:SI 6 "gpc_reg_operand" "")
8050 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8051 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8053 { return rs6000_output_load_multiple (operands); }"
8054 [(set_attr "type" "load")
8055 (set_attr "update" "yes")
8056 (set_attr "indexed" "yes")
8057 (set_attr "length" "32")])
8059 (define_insn "*ldmsi4"
8060 [(match_parallel 0 "load_multiple_operation"
8061 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8062 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8063 (set (match_operand:SI 3 "gpc_reg_operand" "")
8064 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8065 (set (match_operand:SI 4 "gpc_reg_operand" "")
8066 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8067 (set (match_operand:SI 5 "gpc_reg_operand" "")
8068 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8069 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8071 { return rs6000_output_load_multiple (operands); }"
8072 [(set_attr "type" "load")
8073 (set_attr "update" "yes")
8074 (set_attr "indexed" "yes")
8075 (set_attr "length" "32")])
8077 (define_insn "*ldmsi3"
8078 [(match_parallel 0 "load_multiple_operation"
8079 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8080 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8081 (set (match_operand:SI 3 "gpc_reg_operand" "")
8082 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8083 (set (match_operand:SI 4 "gpc_reg_operand" "")
8084 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8085 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8087 { return rs6000_output_load_multiple (operands); }"
8088 [(set_attr "type" "load")
8089 (set_attr "update" "yes")
8090 (set_attr "indexed" "yes")
8091 (set_attr "length" "32")])
8093 (define_expand "store_multiple"
8094 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8095 (match_operand:SI 1 "" ""))
8096 (clobber (scratch:SI))
8097 (use (match_operand:SI 2 "" ""))])]
8098 "TARGET_STRING && !TARGET_POWERPC64"
8107 /* Support only storing a constant number of fixed-point registers to
8108 memory and only bother with this if more than two; the machine
8109 doesn't support more than eight. */
8110 if (GET_CODE (operands[2]) != CONST_INT
8111 || INTVAL (operands[2]) <= 2
8112 || INTVAL (operands[2]) > 8
8113 || GET_CODE (operands[0]) != MEM
8114 || GET_CODE (operands[1]) != REG
8115 || REGNO (operands[1]) >= 32)
8118 count = INTVAL (operands[2]);
8119 regno = REGNO (operands[1]);
8121 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8122 to = force_reg (SImode, XEXP (operands[0], 0));
8123 op0 = replace_equiv_address (operands[0], to);
8125 XVECEXP (operands[3], 0, 0)
8126 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8127 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8128 gen_rtx_SCRATCH (SImode));
8130 for (i = 1; i < count; i++)
8131 XVECEXP (operands[3], 0, i + 1)
8132 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8133 gen_rtx_REG (SImode, regno + i));
8136 (define_insn "*stmsi8"
8137 [(match_parallel 0 "store_multiple_operation"
8138 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8139 (match_operand:SI 2 "gpc_reg_operand" "r"))
8140 (clobber (match_scratch:SI 3 "=X"))
8141 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8142 (match_operand:SI 4 "gpc_reg_operand" "r"))
8143 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8144 (match_operand:SI 5 "gpc_reg_operand" "r"))
8145 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8146 (match_operand:SI 6 "gpc_reg_operand" "r"))
8147 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8148 (match_operand:SI 7 "gpc_reg_operand" "r"))
8149 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8150 (match_operand:SI 8 "gpc_reg_operand" "r"))
8151 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8152 (match_operand:SI 9 "gpc_reg_operand" "r"))
8153 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8154 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8155 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8157 [(set_attr "type" "store")
8158 (set_attr "update" "yes")
8159 (set_attr "indexed" "yes")
8160 (set_attr "cell_micro" "always")])
8162 (define_insn "*stmsi7"
8163 [(match_parallel 0 "store_multiple_operation"
8164 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8165 (match_operand:SI 2 "gpc_reg_operand" "r"))
8166 (clobber (match_scratch:SI 3 "=X"))
8167 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8168 (match_operand:SI 4 "gpc_reg_operand" "r"))
8169 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8170 (match_operand:SI 5 "gpc_reg_operand" "r"))
8171 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8172 (match_operand:SI 6 "gpc_reg_operand" "r"))
8173 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8174 (match_operand:SI 7 "gpc_reg_operand" "r"))
8175 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8176 (match_operand:SI 8 "gpc_reg_operand" "r"))
8177 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8178 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8179 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8181 [(set_attr "type" "store")
8182 (set_attr "update" "yes")
8183 (set_attr "indexed" "yes")
8184 (set_attr "cell_micro" "always")])
8186 (define_insn "*stmsi6"
8187 [(match_parallel 0 "store_multiple_operation"
8188 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8189 (match_operand:SI 2 "gpc_reg_operand" "r"))
8190 (clobber (match_scratch:SI 3 "=X"))
8191 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8192 (match_operand:SI 4 "gpc_reg_operand" "r"))
8193 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8194 (match_operand:SI 5 "gpc_reg_operand" "r"))
8195 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8196 (match_operand:SI 6 "gpc_reg_operand" "r"))
8197 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8198 (match_operand:SI 7 "gpc_reg_operand" "r"))
8199 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8200 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8201 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8203 [(set_attr "type" "store")
8204 (set_attr "update" "yes")
8205 (set_attr "indexed" "yes")
8206 (set_attr "cell_micro" "always")])
8208 (define_insn "*stmsi5"
8209 [(match_parallel 0 "store_multiple_operation"
8210 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8211 (match_operand:SI 2 "gpc_reg_operand" "r"))
8212 (clobber (match_scratch:SI 3 "=X"))
8213 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8214 (match_operand:SI 4 "gpc_reg_operand" "r"))
8215 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8216 (match_operand:SI 5 "gpc_reg_operand" "r"))
8217 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8218 (match_operand:SI 6 "gpc_reg_operand" "r"))
8219 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8220 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8221 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8223 [(set_attr "type" "store")
8224 (set_attr "update" "yes")
8225 (set_attr "indexed" "yes")
8226 (set_attr "cell_micro" "always")])
8228 (define_insn "*stmsi4"
8229 [(match_parallel 0 "store_multiple_operation"
8230 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8231 (match_operand:SI 2 "gpc_reg_operand" "r"))
8232 (clobber (match_scratch:SI 3 "=X"))
8233 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8234 (match_operand:SI 4 "gpc_reg_operand" "r"))
8235 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8236 (match_operand:SI 5 "gpc_reg_operand" "r"))
8237 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8238 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8239 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8241 [(set_attr "type" "store")
8242 (set_attr "update" "yes")
8243 (set_attr "indexed" "yes")
8244 (set_attr "cell_micro" "always")])
8246 (define_insn "*stmsi3"
8247 [(match_parallel 0 "store_multiple_operation"
8248 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8249 (match_operand:SI 2 "gpc_reg_operand" "r"))
8250 (clobber (match_scratch:SI 3 "=X"))
8251 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8252 (match_operand:SI 4 "gpc_reg_operand" "r"))
8253 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8254 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8255 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8257 [(set_attr "type" "store")
8258 (set_attr "update" "yes")
8259 (set_attr "indexed" "yes")
8260 (set_attr "cell_micro" "always")])
8262 (define_expand "setmemsi"
8263 [(parallel [(set (match_operand:BLK 0 "" "")
8264 (match_operand 2 "const_int_operand" ""))
8265 (use (match_operand:SI 1 "" ""))
8266 (use (match_operand:SI 3 "" ""))])]
8270 /* If value to set is not zero, use the library routine. */
8271 if (operands[2] != const0_rtx)
8274 if (expand_block_clear (operands))
8280 ;; String/block move insn.
8281 ;; Argument 0 is the destination
8282 ;; Argument 1 is the source
8283 ;; Argument 2 is the length
8284 ;; Argument 3 is the alignment
8286 (define_expand "movmemsi"
8287 [(parallel [(set (match_operand:BLK 0 "" "")
8288 (match_operand:BLK 1 "" ""))
8289 (use (match_operand:SI 2 "" ""))
8290 (use (match_operand:SI 3 "" ""))])]
8294 if (expand_block_move (operands))
8300 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
8301 ;; register allocator doesn't have a clue about allocating 8 word registers.
8302 ;; rD/rS = r5 is preferred, efficient form.
8303 (define_expand "movmemsi_8reg"
8304 [(parallel [(set (match_operand 0 "" "")
8305 (match_operand 1 "" ""))
8306 (use (match_operand 2 "" ""))
8307 (use (match_operand 3 "" ""))
8308 (clobber (reg:SI 5))
8309 (clobber (reg:SI 6))
8310 (clobber (reg:SI 7))
8311 (clobber (reg:SI 8))
8312 (clobber (reg:SI 9))
8313 (clobber (reg:SI 10))
8314 (clobber (reg:SI 11))
8315 (clobber (reg:SI 12))
8316 (clobber (match_scratch:SI 4 ""))])]
8321 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8322 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8323 (use (match_operand:SI 2 "immediate_operand" "i"))
8324 (use (match_operand:SI 3 "immediate_operand" "i"))
8325 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8326 (clobber (reg:SI 6))
8327 (clobber (reg:SI 7))
8328 (clobber (reg:SI 8))
8329 (clobber (reg:SI 9))
8330 (clobber (reg:SI 10))
8331 (clobber (reg:SI 11))
8332 (clobber (reg:SI 12))
8333 (clobber (match_scratch:SI 5 "=X"))]
8335 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8336 || INTVAL (operands[2]) == 0)
8337 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8338 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8339 && REGNO (operands[4]) == 5"
8340 "lswi %4,%1,%2\;stswi %4,%0,%2"
8341 [(set_attr "type" "store")
8342 (set_attr "update" "yes")
8343 (set_attr "indexed" "yes")
8344 (set_attr "cell_micro" "always")
8345 (set_attr "length" "8")])
8347 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
8348 ;; register allocator doesn't have a clue about allocating 6 word registers.
8349 ;; rD/rS = r5 is preferred, efficient form.
8350 (define_expand "movmemsi_6reg"
8351 [(parallel [(set (match_operand 0 "" "")
8352 (match_operand 1 "" ""))
8353 (use (match_operand 2 "" ""))
8354 (use (match_operand 3 "" ""))
8355 (clobber (reg:SI 5))
8356 (clobber (reg:SI 6))
8357 (clobber (reg:SI 7))
8358 (clobber (reg:SI 8))
8359 (clobber (reg:SI 9))
8360 (clobber (reg:SI 10))
8361 (clobber (match_scratch:SI 4 ""))])]
8366 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8367 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8368 (use (match_operand:SI 2 "immediate_operand" "i"))
8369 (use (match_operand:SI 3 "immediate_operand" "i"))
8370 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8371 (clobber (reg:SI 6))
8372 (clobber (reg:SI 7))
8373 (clobber (reg:SI 8))
8374 (clobber (reg:SI 9))
8375 (clobber (reg:SI 10))
8376 (clobber (match_scratch:SI 5 "=X"))]
8378 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8379 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8380 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8381 && REGNO (operands[4]) == 5"
8382 "lswi %4,%1,%2\;stswi %4,%0,%2"
8383 [(set_attr "type" "store")
8384 (set_attr "update" "yes")
8385 (set_attr "indexed" "yes")
8386 (set_attr "cell_micro" "always")
8387 (set_attr "length" "8")])
8389 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8390 ;; problems with TImode.
8391 ;; rD/rS = r5 is preferred, efficient form.
8392 (define_expand "movmemsi_4reg"
8393 [(parallel [(set (match_operand 0 "" "")
8394 (match_operand 1 "" ""))
8395 (use (match_operand 2 "" ""))
8396 (use (match_operand 3 "" ""))
8397 (clobber (reg:SI 5))
8398 (clobber (reg:SI 6))
8399 (clobber (reg:SI 7))
8400 (clobber (reg:SI 8))
8401 (clobber (match_scratch:SI 4 ""))])]
8406 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8407 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8408 (use (match_operand:SI 2 "immediate_operand" "i"))
8409 (use (match_operand:SI 3 "immediate_operand" "i"))
8410 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8411 (clobber (reg:SI 6))
8412 (clobber (reg:SI 7))
8413 (clobber (reg:SI 8))
8414 (clobber (match_scratch:SI 5 "=X"))]
8416 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8417 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8418 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8419 && REGNO (operands[4]) == 5"
8420 "lswi %4,%1,%2\;stswi %4,%0,%2"
8421 [(set_attr "type" "store")
8422 (set_attr "update" "yes")
8423 (set_attr "indexed" "yes")
8424 (set_attr "cell_micro" "always")
8425 (set_attr "length" "8")])
8427 ;; Move up to 8 bytes at a time.
8428 (define_expand "movmemsi_2reg"
8429 [(parallel [(set (match_operand 0 "" "")
8430 (match_operand 1 "" ""))
8431 (use (match_operand 2 "" ""))
8432 (use (match_operand 3 "" ""))
8433 (clobber (match_scratch:DI 4 ""))
8434 (clobber (match_scratch:SI 5 ""))])]
8435 "TARGET_STRING && ! TARGET_POWERPC64"
8439 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8440 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8441 (use (match_operand:SI 2 "immediate_operand" "i"))
8442 (use (match_operand:SI 3 "immediate_operand" "i"))
8443 (clobber (match_scratch:DI 4 "=&r"))
8444 (clobber (match_scratch:SI 5 "=X"))]
8445 "TARGET_STRING && ! TARGET_POWERPC64
8446 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8447 "lswi %4,%1,%2\;stswi %4,%0,%2"
8448 [(set_attr "type" "store")
8449 (set_attr "update" "yes")
8450 (set_attr "indexed" "yes")
8451 (set_attr "cell_micro" "always")
8452 (set_attr "length" "8")])
8454 ;; Move up to 4 bytes at a time.
8455 (define_expand "movmemsi_1reg"
8456 [(parallel [(set (match_operand 0 "" "")
8457 (match_operand 1 "" ""))
8458 (use (match_operand 2 "" ""))
8459 (use (match_operand 3 "" ""))
8460 (clobber (match_scratch:SI 4 ""))
8461 (clobber (match_scratch:SI 5 ""))])]
8466 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8467 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8468 (use (match_operand:SI 2 "immediate_operand" "i"))
8469 (use (match_operand:SI 3 "immediate_operand" "i"))
8470 (clobber (match_scratch:SI 4 "=&r"))
8471 (clobber (match_scratch:SI 5 "=X"))]
8472 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8473 "lswi %4,%1,%2\;stswi %4,%0,%2"
8474 [(set_attr "type" "store")
8475 (set_attr "update" "yes")
8476 (set_attr "indexed" "yes")
8477 (set_attr "cell_micro" "always")
8478 (set_attr "length" "8")])
8480 ;; Define insns that do load or store with update. Some of these we can
8481 ;; get by using pre-decrement or pre-increment, but the hardware can also
8482 ;; do cases where the increment is not the size of the object.
8484 ;; In all these cases, we use operands 0 and 1 for the register being
8485 ;; incremented because those are the operands that local-alloc will
8486 ;; tie and these are the pair most likely to be tieable (and the ones
8487 ;; that will benefit the most).
8489 (define_insn "*movdi_update1"
8490 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8491 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8492 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8493 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8494 (plus:DI (match_dup 1) (match_dup 2)))]
8495 "TARGET_POWERPC64 && TARGET_UPDATE
8496 && (!avoiding_indexed_address_p (DImode)
8497 || !gpc_reg_operand (operands[2], DImode))"
8501 [(set_attr "type" "load")
8502 (set_attr "update" "yes")
8503 (set_attr "indexed" "yes,no")])
8505 (define_insn "movdi_<mode>_update"
8506 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8507 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8508 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8509 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8510 (plus:P (match_dup 1) (match_dup 2)))]
8511 "TARGET_POWERPC64 && TARGET_UPDATE
8512 && (!avoiding_indexed_address_p (Pmode)
8513 || !gpc_reg_operand (operands[2], Pmode)
8514 || (REG_P (operands[0])
8515 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8519 [(set_attr "type" "store")
8520 (set_attr "update" "yes")
8521 (set_attr "indexed" "yes,no")])
8523 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8524 ;; needed for stack allocation, even if the user passes -mno-update.
8525 (define_insn "movdi_<mode>_update_stack"
8526 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8527 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8528 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8529 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8530 (plus:P (match_dup 1) (match_dup 2)))]
8535 [(set_attr "type" "store")
8536 (set_attr "update" "yes")
8537 (set_attr "indexed" "yes,no")])
8539 (define_insn "*movsi_update1"
8540 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8541 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8542 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8543 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8544 (plus:SI (match_dup 1) (match_dup 2)))]
8546 && (!avoiding_indexed_address_p (SImode)
8547 || !gpc_reg_operand (operands[2], SImode))"
8551 [(set_attr "type" "load")
8552 (set_attr "update" "yes")
8553 (set_attr "indexed" "yes,no")])
8555 (define_insn "*movsi_update2"
8556 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8558 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8559 (match_operand:DI 2 "gpc_reg_operand" "r")))))
8560 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8561 (plus:DI (match_dup 1) (match_dup 2)))]
8562 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8563 && !avoiding_indexed_address_p (DImode)"
8565 [(set_attr "type" "load")
8566 (set_attr "sign_extend" "yes")
8567 (set_attr "update" "yes")
8568 (set_attr "indexed" "yes")])
8570 (define_insn "movsi_update"
8571 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8572 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8573 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8574 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8575 (plus:SI (match_dup 1) (match_dup 2)))]
8577 && (!avoiding_indexed_address_p (SImode)
8578 || !gpc_reg_operand (operands[2], SImode)
8579 || (REG_P (operands[0])
8580 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8584 [(set_attr "type" "store")
8585 (set_attr "update" "yes")
8586 (set_attr "indexed" "yes,no")])
8588 ;; This is an unconditional pattern; needed for stack allocation, even
8589 ;; if the user passes -mno-update.
8590 (define_insn "movsi_update_stack"
8591 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8592 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8593 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8594 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8595 (plus:SI (match_dup 1) (match_dup 2)))]
8600 [(set_attr "type" "store")
8601 (set_attr "update" "yes")
8602 (set_attr "indexed" "yes,no")])
8604 (define_insn "*movhi_update1"
8605 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8606 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8607 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8608 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8609 (plus:SI (match_dup 1) (match_dup 2)))]
8611 && (!avoiding_indexed_address_p (SImode)
8612 || !gpc_reg_operand (operands[2], SImode))"
8616 [(set_attr "type" "load")
8617 (set_attr "update" "yes")
8618 (set_attr "indexed" "yes,no")])
8620 (define_insn "*movhi_update2"
8621 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8623 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8624 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8625 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8626 (plus:SI (match_dup 1) (match_dup 2)))]
8628 && (!avoiding_indexed_address_p (SImode)
8629 || !gpc_reg_operand (operands[2], SImode))"
8633 [(set_attr "type" "load")
8634 (set_attr "update" "yes")
8635 (set_attr "indexed" "yes,no")])
8637 (define_insn "*movhi_update3"
8638 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8640 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8641 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8642 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8643 (plus:SI (match_dup 1) (match_dup 2)))]
8644 "TARGET_UPDATE && rs6000_gen_cell_microcode
8645 && (!avoiding_indexed_address_p (SImode)
8646 || !gpc_reg_operand (operands[2], SImode))"
8650 [(set_attr "type" "load")
8651 (set_attr "sign_extend" "yes")
8652 (set_attr "update" "yes")
8653 (set_attr "indexed" "yes,no")])
8655 (define_insn "*movhi_update4"
8656 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8657 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8658 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8659 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8660 (plus:SI (match_dup 1) (match_dup 2)))]
8662 && (!avoiding_indexed_address_p (SImode)
8663 || !gpc_reg_operand (operands[2], SImode))"
8667 [(set_attr "type" "store")
8668 (set_attr "update" "yes")
8669 (set_attr "indexed" "yes,no")])
8671 (define_insn "*movqi_update1"
8672 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8673 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8674 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8675 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8676 (plus:SI (match_dup 1) (match_dup 2)))]
8678 && (!avoiding_indexed_address_p (SImode)
8679 || !gpc_reg_operand (operands[2], SImode))"
8683 [(set_attr "type" "load")
8684 (set_attr "update" "yes")
8685 (set_attr "indexed" "yes,no")])
8687 (define_insn "*movqi_update2"
8688 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8690 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8691 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8692 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8693 (plus:SI (match_dup 1) (match_dup 2)))]
8695 && (!avoiding_indexed_address_p (SImode)
8696 || !gpc_reg_operand (operands[2], SImode))"
8700 [(set_attr "type" "load")
8701 (set_attr "update" "yes")
8702 (set_attr "indexed" "yes,no")])
8704 (define_insn "*movqi_update3"
8705 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8706 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8707 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
8708 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8709 (plus:SI (match_dup 1) (match_dup 2)))]
8711 && (!avoiding_indexed_address_p (SImode)
8712 || !gpc_reg_operand (operands[2], SImode))"
8716 [(set_attr "type" "store")
8717 (set_attr "update" "yes")
8718 (set_attr "indexed" "yes,no")])
8720 (define_insn "*movsf_update1"
8721 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
8722 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8723 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8724 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8725 (plus:SI (match_dup 1) (match_dup 2)))]
8726 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8727 && (!avoiding_indexed_address_p (SImode)
8728 || !gpc_reg_operand (operands[2], SImode))"
8732 [(set_attr "type" "fpload")
8733 (set_attr "update" "yes")
8734 (set_attr "indexed" "yes,no")])
8736 (define_insn "*movsf_update2"
8737 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8738 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8739 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
8740 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8741 (plus:SI (match_dup 1) (match_dup 2)))]
8742 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8743 && (!avoiding_indexed_address_p (SImode)
8744 || !gpc_reg_operand (operands[2], SImode))"
8748 [(set_attr "type" "fpstore")
8749 (set_attr "update" "yes")
8750 (set_attr "indexed" "yes,no")])
8752 (define_insn "*movsf_update3"
8753 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
8754 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8755 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8756 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8757 (plus:SI (match_dup 1) (match_dup 2)))]
8758 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8759 && (!avoiding_indexed_address_p (SImode)
8760 || !gpc_reg_operand (operands[2], SImode))"
8764 [(set_attr "type" "load")
8765 (set_attr "update" "yes")
8766 (set_attr "indexed" "yes,no")])
8768 (define_insn "*movsf_update4"
8769 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8770 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8771 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
8772 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8773 (plus:SI (match_dup 1) (match_dup 2)))]
8774 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8775 && (!avoiding_indexed_address_p (SImode)
8776 || !gpc_reg_operand (operands[2], SImode))"
8780 [(set_attr "type" "store")
8781 (set_attr "update" "yes")
8782 (set_attr "indexed" "yes,no")])
8784 (define_insn "*movdf_update1"
8785 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
8786 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8787 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8788 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8789 (plus:SI (match_dup 1) (match_dup 2)))]
8790 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8791 && (!avoiding_indexed_address_p (SImode)
8792 || !gpc_reg_operand (operands[2], SImode))"
8796 [(set_attr "type" "fpload")
8797 (set_attr "update" "yes")
8798 (set_attr "indexed" "yes,no")])
8800 (define_insn "*movdf_update2"
8801 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8802 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8803 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
8804 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8805 (plus:SI (match_dup 1) (match_dup 2)))]
8806 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8807 && (!avoiding_indexed_address_p (SImode)
8808 || !gpc_reg_operand (operands[2], SImode))"
8812 [(set_attr "type" "fpstore")
8813 (set_attr "update" "yes")
8814 (set_attr "indexed" "yes,no")])
8817 ;; After inserting conditional returns we can sometimes have
8818 ;; unnecessary register moves. Unfortunately we cannot have a
8819 ;; modeless peephole here, because some single SImode sets have early
8820 ;; clobber outputs. Although those sets expand to multi-ppc-insn
8821 ;; sequences, using get_attr_length here will smash the operands
8822 ;; array. Neither is there an early_cobbler_p predicate.
8823 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
8824 ;; Also this optimization interferes with scalars going into
8825 ;; altivec registers (the code does reloading through the FPRs).
8827 [(set (match_operand:DF 0 "gpc_reg_operand" "")
8828 (match_operand:DF 1 "any_operand" ""))
8829 (set (match_operand:DF 2 "gpc_reg_operand" "")
8831 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
8832 && !TARGET_UPPER_REGS_DF
8833 && peep2_reg_dead_p (2, operands[0])"
8834 [(set (match_dup 2) (match_dup 1))])
8837 [(set (match_operand:SF 0 "gpc_reg_operand" "")
8838 (match_operand:SF 1 "any_operand" ""))
8839 (set (match_operand:SF 2 "gpc_reg_operand" "")
8841 "!TARGET_UPPER_REGS_SF
8842 && peep2_reg_dead_p (2, operands[0])"
8843 [(set (match_dup 2) (match_dup 1))])
8848 ;; Mode attributes for different ABIs.
8849 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
8850 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
8851 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
8852 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
8854 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
8855 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8856 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8857 (match_operand 4 "" "g")))
8858 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8859 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8861 (clobber (reg:SI LR_REGNO))]
8862 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8864 if (TARGET_CMODEL != CMODEL_SMALL)
8865 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
8868 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
8870 "&& TARGET_TLS_MARKERS"
8872 (unspec:TLSmode [(match_dup 1)
8875 (parallel [(set (match_dup 0)
8876 (call (mem:TLSmode (match_dup 3))
8878 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8879 (clobber (reg:SI LR_REGNO))])]
8881 [(set_attr "type" "two")
8882 (set (attr "length")
8883 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8887 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
8888 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8889 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8890 (match_operand 4 "" "g")))
8891 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8892 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8894 (clobber (reg:SI LR_REGNO))]
8895 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
8899 if (TARGET_SECURE_PLT && flag_pic == 2)
8900 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
8902 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
8905 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
8907 "&& TARGET_TLS_MARKERS"
8909 (unspec:TLSmode [(match_dup 1)
8912 (parallel [(set (match_dup 0)
8913 (call (mem:TLSmode (match_dup 3))
8915 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8916 (clobber (reg:SI LR_REGNO))])]
8918 [(set_attr "type" "two")
8919 (set_attr "length" "8")])
8921 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
8922 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8923 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8924 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8926 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
8927 "addi %0,%1,%2@got@tlsgd"
8928 "&& TARGET_CMODEL != CMODEL_SMALL"
8931 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
8933 (lo_sum:TLSmode (match_dup 3)
8934 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
8937 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
8939 [(set (attr "length")
8940 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8944 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
8945 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8947 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8948 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8950 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8951 "addis %0,%1,%2@got@tlsgd@ha"
8952 [(set_attr "length" "4")])
8954 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
8955 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8956 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
8957 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
8958 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8960 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8961 "addi %0,%1,%2@got@tlsgd@l"
8962 [(set_attr "length" "4")])
8964 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
8965 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8966 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8967 (match_operand 2 "" "g")))
8968 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8970 (clobber (reg:SI LR_REGNO))]
8971 "HAVE_AS_TLS && TARGET_TLS_MARKERS
8972 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8973 "bl %z1(%3@tlsgd)\;nop"
8974 [(set_attr "type" "branch")
8975 (set_attr "length" "8")])
8977 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
8978 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8979 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8980 (match_operand 2 "" "g")))
8981 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8983 (clobber (reg:SI LR_REGNO))]
8984 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
8988 if (TARGET_SECURE_PLT && flag_pic == 2)
8989 return "bl %z1+32768(%3@tlsgd)@plt";
8990 return "bl %z1(%3@tlsgd)@plt";
8992 return "bl %z1(%3@tlsgd)";
8994 [(set_attr "type" "branch")
8995 (set_attr "length" "4")])
8997 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
8998 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8999 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9000 (match_operand 3 "" "g")))
9001 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9003 (clobber (reg:SI LR_REGNO))]
9004 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9006 if (TARGET_CMODEL != CMODEL_SMALL)
9007 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9010 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9012 "&& TARGET_TLS_MARKERS"
9014 (unspec:TLSmode [(match_dup 1)]
9016 (parallel [(set (match_dup 0)
9017 (call (mem:TLSmode (match_dup 2))
9019 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9020 (clobber (reg:SI LR_REGNO))])]
9022 [(set_attr "type" "two")
9023 (set (attr "length")
9024 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9028 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9029 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9030 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9031 (match_operand 3 "" "g")))
9032 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9034 (clobber (reg:SI LR_REGNO))]
9035 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9039 if (TARGET_SECURE_PLT && flag_pic == 2)
9040 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9042 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9045 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9047 "&& TARGET_TLS_MARKERS"
9049 (unspec:TLSmode [(match_dup 1)]
9051 (parallel [(set (match_dup 0)
9052 (call (mem:TLSmode (match_dup 2))
9054 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9055 (clobber (reg:SI LR_REGNO))])]
9057 [(set_attr "length" "8")])
9059 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9060 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9061 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9063 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9064 "addi %0,%1,%&@got@tlsld"
9065 "&& TARGET_CMODEL != CMODEL_SMALL"
9068 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9070 (lo_sum:TLSmode (match_dup 2)
9071 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9074 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9076 [(set (attr "length")
9077 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9081 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9082 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9084 (unspec:TLSmode [(const_int 0)
9085 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9087 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9088 "addis %0,%1,%&@got@tlsld@ha"
9089 [(set_attr "length" "4")])
9091 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9092 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9093 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9094 (unspec:TLSmode [(const_int 0)
9095 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9097 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9098 "addi %0,%1,%&@got@tlsld@l"
9099 [(set_attr "length" "4")])
9101 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9102 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9103 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9104 (match_operand 2 "" "g")))
9105 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9106 (clobber (reg:SI LR_REGNO))]
9107 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9108 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9109 "bl %z1(%&@tlsld)\;nop"
9110 [(set_attr "type" "branch")
9111 (set_attr "length" "8")])
9113 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9114 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9115 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9116 (match_operand 2 "" "g")))
9117 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9118 (clobber (reg:SI LR_REGNO))]
9119 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9123 if (TARGET_SECURE_PLT && flag_pic == 2)
9124 return "bl %z1+32768(%&@tlsld)@plt";
9125 return "bl %z1(%&@tlsld)@plt";
9127 return "bl %z1(%&@tlsld)";
9129 [(set_attr "type" "branch")
9130 (set_attr "length" "4")])
9132 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9133 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9134 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9135 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9138 "addi %0,%1,%2@dtprel")
9140 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9141 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9142 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9143 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9144 UNSPEC_TLSDTPRELHA))]
9146 "addis %0,%1,%2@dtprel@ha")
9148 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9149 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9150 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9151 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9152 UNSPEC_TLSDTPRELLO))]
9154 "addi %0,%1,%2@dtprel@l")
9156 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9157 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9158 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9159 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9160 UNSPEC_TLSGOTDTPREL))]
9162 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9163 "&& TARGET_CMODEL != CMODEL_SMALL"
9166 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9168 (lo_sum:TLSmode (match_dup 3)
9169 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9172 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9174 [(set (attr "length")
9175 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9179 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9180 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9182 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9183 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9184 UNSPEC_TLSGOTDTPREL)))]
9185 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9186 "addis %0,%1,%2@got@dtprel@ha"
9187 [(set_attr "length" "4")])
9189 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9190 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9191 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9192 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9193 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9194 UNSPEC_TLSGOTDTPREL)))]
9195 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9196 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9197 [(set_attr "length" "4")])
9199 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9200 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9201 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9202 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9205 "addi %0,%1,%2@tprel")
9207 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9208 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9209 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9210 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9211 UNSPEC_TLSTPRELHA))]
9213 "addis %0,%1,%2@tprel@ha")
9215 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9216 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9217 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9218 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9219 UNSPEC_TLSTPRELLO))]
9221 "addi %0,%1,%2@tprel@l")
9223 ;; "b" output constraint here and on tls_tls input to support linker tls
9224 ;; optimization. The linker may edit the instructions emitted by a
9225 ;; tls_got_tprel/tls_tls pair to addis,addi.
9226 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9227 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9228 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9229 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9230 UNSPEC_TLSGOTTPREL))]
9232 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9233 "&& TARGET_CMODEL != CMODEL_SMALL"
9236 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9238 (lo_sum:TLSmode (match_dup 3)
9239 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9242 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9244 [(set (attr "length")
9245 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9249 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9250 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9252 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9253 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9254 UNSPEC_TLSGOTTPREL)))]
9255 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9256 "addis %0,%1,%2@got@tprel@ha"
9257 [(set_attr "length" "4")])
9259 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9260 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9261 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9262 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9263 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9264 UNSPEC_TLSGOTTPREL)))]
9265 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9266 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9267 [(set_attr "length" "4")])
9269 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9270 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9271 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9272 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9274 "TARGET_ELF && HAVE_AS_TLS"
9277 (define_expand "tls_get_tpointer"
9278 [(set (match_operand:SI 0 "gpc_reg_operand" "")
9279 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9280 "TARGET_XCOFF && HAVE_AS_TLS"
9283 emit_insn (gen_tls_get_tpointer_internal ());
9284 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9288 (define_insn "tls_get_tpointer_internal"
9290 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9291 (clobber (reg:SI LR_REGNO))]
9292 "TARGET_XCOFF && HAVE_AS_TLS"
9293 "bla __get_tpointer")
9295 (define_expand "tls_get_addr<mode>"
9296 [(set (match_operand:P 0 "gpc_reg_operand" "")
9297 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9298 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9299 "TARGET_XCOFF && HAVE_AS_TLS"
9302 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9303 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9304 emit_insn (gen_tls_get_addr_internal<mode> ());
9305 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9309 (define_insn "tls_get_addr_internal<mode>"
9311 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9315 (clobber (reg:P 11))
9316 (clobber (reg:CC CR0_REGNO))
9317 (clobber (reg:P LR_REGNO))]
9318 "TARGET_XCOFF && HAVE_AS_TLS"
9319 "bla __tls_get_addr")
9321 ;; Next come insns related to the calling sequence.
9323 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9324 ;; We move the back-chain and decrement the stack pointer.
9326 (define_expand "allocate_stack"
9327 [(set (match_operand 0 "gpc_reg_operand" "")
9328 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9330 (minus (reg 1) (match_dup 1)))]
9333 { rtx chain = gen_reg_rtx (Pmode);
9334 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9336 rtx insn, par, set, mem;
9338 emit_move_insn (chain, stack_bot);
9340 /* Check stack bounds if necessary. */
9341 if (crtl->limit_stack)
9344 available = expand_binop (Pmode, sub_optab,
9345 stack_pointer_rtx, stack_limit_rtx,
9346 NULL_RTX, 1, OPTAB_WIDEN);
9347 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9350 if (GET_CODE (operands[1]) != CONST_INT
9351 || INTVAL (operands[1]) < -32767
9352 || INTVAL (operands[1]) > 32768)
9354 neg_op0 = gen_reg_rtx (Pmode);
9356 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9358 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9361 neg_op0 = GEN_INT (- INTVAL (operands[1]));
9363 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9364 : gen_movdi_di_update_stack))
9365 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9367 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9368 it now and set the alias set/attributes. The above gen_*_update
9369 calls will generate a PARALLEL with the MEM set being the first
9371 par = PATTERN (insn);
9372 gcc_assert (GET_CODE (par) == PARALLEL);
9373 set = XVECEXP (par, 0, 0);
9374 gcc_assert (GET_CODE (set) == SET);
9375 mem = SET_DEST (set);
9376 gcc_assert (MEM_P (mem));
9377 MEM_NOTRAP_P (mem) = 1;
9378 set_mem_alias_set (mem, get_frame_alias_set ());
9380 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9384 ;; These patterns say how to save and restore the stack pointer. We need not
9385 ;; save the stack pointer at function level since we are careful to
9386 ;; preserve the backchain. At block level, we have to restore the backchain
9387 ;; when we restore the stack pointer.
9389 ;; For nonlocal gotos, we must save both the stack pointer and its
9390 ;; backchain and restore both. Note that in the nonlocal case, the
9391 ;; save area is a memory location.
9393 (define_expand "save_stack_function"
9394 [(match_operand 0 "any_operand" "")
9395 (match_operand 1 "any_operand" "")]
9399 (define_expand "restore_stack_function"
9400 [(match_operand 0 "any_operand" "")
9401 (match_operand 1 "any_operand" "")]
9405 ;; Adjust stack pointer (op0) to a new value (op1).
9406 ;; First copy old stack backchain to new location, and ensure that the
9407 ;; scheduler won't reorder the sp assignment before the backchain write.
9408 (define_expand "restore_stack_block"
9409 [(set (match_dup 2) (match_dup 3))
9410 (set (match_dup 4) (match_dup 2))
9412 (set (match_operand 0 "register_operand" "")
9413 (match_operand 1 "register_operand" ""))]
9419 operands[1] = force_reg (Pmode, operands[1]);
9420 operands[2] = gen_reg_rtx (Pmode);
9421 operands[3] = gen_frame_mem (Pmode, operands[0]);
9422 operands[4] = gen_frame_mem (Pmode, operands[1]);
9423 p = rtvec_alloc (1);
9424 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9426 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9429 (define_expand "save_stack_nonlocal"
9430 [(set (match_dup 3) (match_dup 4))
9431 (set (match_operand 0 "memory_operand" "") (match_dup 3))
9432 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9436 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9438 /* Copy the backchain to the first word, sp to the second. */
9439 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9440 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9441 operands[3] = gen_reg_rtx (Pmode);
9442 operands[4] = gen_frame_mem (Pmode, operands[1]);
9445 (define_expand "restore_stack_nonlocal"
9446 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9447 (set (match_dup 3) (match_dup 4))
9448 (set (match_dup 5) (match_dup 2))
9450 (set (match_operand 0 "register_operand" "") (match_dup 3))]
9454 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9457 /* Restore the backchain from the first word, sp from the second. */
9458 operands[2] = gen_reg_rtx (Pmode);
9459 operands[3] = gen_reg_rtx (Pmode);
9460 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9461 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9462 operands[5] = gen_frame_mem (Pmode, operands[3]);
9463 p = rtvec_alloc (1);
9464 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9466 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9469 ;; TOC register handling.
9471 ;; Code to initialize the TOC register...
9473 (define_insn "load_toc_aix_si"
9474 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9475 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9477 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9481 extern int need_toc_init;
9483 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9484 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9485 operands[2] = gen_rtx_REG (Pmode, 2);
9486 return \"lwz %0,%1(%2)\";
9488 [(set_attr "type" "load")
9489 (set_attr "update" "no")
9490 (set_attr "indexed" "no")])
9492 (define_insn "load_toc_aix_di"
9493 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9494 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9496 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9500 extern int need_toc_init;
9502 #ifdef TARGET_RELOCATABLE
9503 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9504 !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
9506 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9509 strcat (buf, \"@toc\");
9510 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9511 operands[2] = gen_rtx_REG (Pmode, 2);
9512 return \"ld %0,%1(%2)\";
9514 [(set_attr "type" "load")
9515 (set_attr "update" "no")
9516 (set_attr "indexed" "no")])
9518 (define_insn "load_toc_v4_pic_si"
9519 [(set (reg:SI LR_REGNO)
9520 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9521 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9522 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9523 [(set_attr "type" "branch")
9524 (set_attr "length" "4")])
9526 (define_expand "load_toc_v4_PIC_1"
9527 [(parallel [(set (reg:SI LR_REGNO)
9528 (match_operand:SI 0 "immediate_operand" "s"))
9529 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9530 "TARGET_ELF && DEFAULT_ABI == ABI_V4
9531 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9534 (define_insn "load_toc_v4_PIC_1_normal"
9535 [(set (reg:SI LR_REGNO)
9536 (match_operand:SI 0 "immediate_operand" "s"))
9537 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9538 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9539 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9540 "bcl 20,31,%0\\n%0:"
9541 [(set_attr "type" "branch")
9542 (set_attr "length" "4")
9543 (set_attr "cannot_copy" "yes")])
9545 (define_insn "load_toc_v4_PIC_1_476"
9546 [(set (reg:SI LR_REGNO)
9547 (match_operand:SI 0 "immediate_operand" "s"))
9548 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9549 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9550 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9554 static char templ[32];
9556 get_ppc476_thunk_name (name);
9557 sprintf (templ, \"bl %s\\n%%0:\", name);
9560 [(set_attr "type" "branch")
9561 (set_attr "length" "4")
9562 (set_attr "cannot_copy" "yes")])
9564 (define_expand "load_toc_v4_PIC_1b"
9565 [(parallel [(set (reg:SI LR_REGNO)
9566 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9567 (label_ref (match_operand 1 "" ""))]
9570 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9573 (define_insn "load_toc_v4_PIC_1b_normal"
9574 [(set (reg:SI LR_REGNO)
9575 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9576 (label_ref (match_operand 1 "" ""))]
9579 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9580 "bcl 20,31,$+8\;.long %0-$"
9581 [(set_attr "type" "branch")
9582 (set_attr "length" "8")])
9584 (define_insn "load_toc_v4_PIC_1b_476"
9585 [(set (reg:SI LR_REGNO)
9586 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9587 (label_ref (match_operand 1 "" ""))]
9590 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9594 static char templ[32];
9596 get_ppc476_thunk_name (name);
9597 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9600 [(set_attr "type" "branch")
9601 (set_attr "length" "16")])
9603 (define_insn "load_toc_v4_PIC_2"
9604 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9605 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9606 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9607 (match_operand:SI 3 "immediate_operand" "s")))))]
9608 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9610 [(set_attr "type" "load")])
9612 (define_insn "load_toc_v4_PIC_3b"
9613 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9614 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9616 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9617 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9618 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9619 "addis %0,%1,%2-%3@ha")
9621 (define_insn "load_toc_v4_PIC_3c"
9622 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9623 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9624 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9625 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9626 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9627 "addi %0,%1,%2-%3@l")
9629 ;; If the TOC is shared over a translation unit, as happens with all
9630 ;; the kinds of PIC that we support, we need to restore the TOC
9631 ;; pointer only when jumping over units of translation.
9632 ;; On Darwin, we need to reload the picbase.
9634 (define_expand "builtin_setjmp_receiver"
9635 [(use (label_ref (match_operand 0 "" "")))]
9636 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9637 || (TARGET_TOC && TARGET_MINIMAL_TOC)
9638 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9642 if (DEFAULT_ABI == ABI_DARWIN)
9644 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9645 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9649 crtl->uses_pic_offset_table = 1;
9650 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9651 CODE_LABEL_NUMBER (operands[0]));
9652 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9654 emit_insn (gen_load_macho_picbase (tmplabrtx));
9655 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9656 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9660 rs6000_emit_load_toc_table (FALSE);
9665 (define_insn "*largetoc_high"
9666 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9668 (unspec [(match_operand:DI 1 "" "")
9669 (match_operand:DI 2 "gpc_reg_operand" "b")]
9671 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9672 "addis %0,%2,%1@toc@ha")
9674 (define_insn "*largetoc_high_aix<mode>"
9675 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9677 (unspec [(match_operand:P 1 "" "")
9678 (match_operand:P 2 "gpc_reg_operand" "b")]
9680 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9681 "addis %0,%1@u(%2)")
9683 (define_insn "*largetoc_high_plus"
9684 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9687 (unspec [(match_operand:DI 1 "" "")
9688 (match_operand:DI 2 "gpc_reg_operand" "b")]
9690 (match_operand:DI 3 "add_cint_operand" "n"))))]
9691 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9692 "addis %0,%2,%1+%3@toc@ha")
9694 (define_insn "*largetoc_high_plus_aix<mode>"
9695 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9698 (unspec [(match_operand:P 1 "" "")
9699 (match_operand:P 2 "gpc_reg_operand" "b")]
9701 (match_operand:P 3 "add_cint_operand" "n"))))]
9702 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9703 "addis %0,%1+%3@u(%2)")
9705 (define_insn "*largetoc_low"
9706 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9707 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9708 (match_operand:DI 2 "" "")))]
9709 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9712 (define_insn "*largetoc_low_aix<mode>"
9713 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9714 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9715 (match_operand:P 2 "" "")))]
9716 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9719 (define_insn_and_split "*tocref<mode>"
9720 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9721 (match_operand:P 1 "small_toc_ref" "R"))]
9724 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
9725 [(set (match_dup 0) (high:P (match_dup 1)))
9726 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
9728 ;; Elf specific ways of loading addresses for non-PIC code.
9729 ;; The output of this could be r0, but we make a very strong
9730 ;; preference for a base register because it will usually
9732 (define_insn "elf_high"
9733 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
9734 (high:SI (match_operand 1 "" "")))]
9735 "TARGET_ELF && ! TARGET_64BIT"
9738 (define_insn "elf_low"
9739 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9740 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9741 (match_operand 2 "" "")))]
9742 "TARGET_ELF && ! TARGET_64BIT"
9745 ;; Call and call_value insns
9746 (define_expand "call"
9747 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
9748 (match_operand 1 "" ""))
9749 (use (match_operand 2 "" ""))
9750 (clobber (reg:SI LR_REGNO))])]
9755 if (MACHOPIC_INDIRECT)
9756 operands[0] = machopic_indirect_call_target (operands[0]);
9759 gcc_assert (GET_CODE (operands[0]) == MEM);
9760 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
9762 operands[0] = XEXP (operands[0], 0);
9764 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9766 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
9770 if (GET_CODE (operands[0]) != SYMBOL_REF
9771 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
9773 if (INTVAL (operands[2]) & CALL_LONG)
9774 operands[0] = rs6000_longcall_ref (operands[0]);
9776 switch (DEFAULT_ABI)
9780 operands[0] = force_reg (Pmode, operands[0]);
9789 (define_expand "call_value"
9790 [(parallel [(set (match_operand 0 "" "")
9791 (call (mem:SI (match_operand 1 "address_operand" ""))
9792 (match_operand 2 "" "")))
9793 (use (match_operand 3 "" ""))
9794 (clobber (reg:SI LR_REGNO))])]
9799 if (MACHOPIC_INDIRECT)
9800 operands[1] = machopic_indirect_call_target (operands[1]);
9803 gcc_assert (GET_CODE (operands[1]) == MEM);
9804 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
9806 operands[1] = XEXP (operands[1], 0);
9808 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9810 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
9814 if (GET_CODE (operands[1]) != SYMBOL_REF
9815 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
9817 if (INTVAL (operands[3]) & CALL_LONG)
9818 operands[1] = rs6000_longcall_ref (operands[1]);
9820 switch (DEFAULT_ABI)
9824 operands[1] = force_reg (Pmode, operands[1]);
9833 ;; Call to function in current module. No TOC pointer reload needed.
9834 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
9835 ;; either the function was not prototyped, or it was prototyped as a
9836 ;; variable argument function. It is > 0 if FP registers were passed
9837 ;; and < 0 if they were not.
9839 (define_insn "*call_local32"
9840 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
9841 (match_operand 1 "" "g,g"))
9842 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9843 (clobber (reg:SI LR_REGNO))]
9844 "(INTVAL (operands[2]) & CALL_LONG) == 0"
9847 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9848 output_asm_insn (\"crxor 6,6,6\", operands);
9850 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9851 output_asm_insn (\"creqv 6,6,6\", operands);
9853 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9855 [(set_attr "type" "branch")
9856 (set_attr "length" "4,8")])
9858 (define_insn "*call_local64"
9859 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
9860 (match_operand 1 "" "g,g"))
9861 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9862 (clobber (reg:SI LR_REGNO))]
9863 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
9866 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9867 output_asm_insn (\"crxor 6,6,6\", operands);
9869 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9870 output_asm_insn (\"creqv 6,6,6\", operands);
9872 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9874 [(set_attr "type" "branch")
9875 (set_attr "length" "4,8")])
9877 (define_insn "*call_value_local32"
9878 [(set (match_operand 0 "" "")
9879 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
9880 (match_operand 2 "" "g,g")))
9881 (use (match_operand:SI 3 "immediate_operand" "O,n"))
9882 (clobber (reg:SI LR_REGNO))]
9883 "(INTVAL (operands[3]) & CALL_LONG) == 0"
9886 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9887 output_asm_insn (\"crxor 6,6,6\", operands);
9889 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9890 output_asm_insn (\"creqv 6,6,6\", operands);
9892 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9894 [(set_attr "type" "branch")
9895 (set_attr "length" "4,8")])
9898 (define_insn "*call_value_local64"
9899 [(set (match_operand 0 "" "")
9900 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
9901 (match_operand 2 "" "g,g")))
9902 (use (match_operand:SI 3 "immediate_operand" "O,n"))
9903 (clobber (reg:SI LR_REGNO))]
9904 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
9907 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9908 output_asm_insn (\"crxor 6,6,6\", operands);
9910 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9911 output_asm_insn (\"creqv 6,6,6\", operands);
9913 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9915 [(set_attr "type" "branch")
9916 (set_attr "length" "4,8")])
9919 ;; A function pointer under System V is just a normal pointer
9920 ;; operands[0] is the function pointer
9921 ;; operands[1] is the stack size to clean up
9922 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
9923 ;; which indicates how to set cr1
9925 (define_insn "*call_indirect_nonlocal_sysv<mode>"
9926 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
9927 (match_operand 1 "" "g,g,g,g"))
9928 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
9929 (clobber (reg:SI LR_REGNO))]
9930 "DEFAULT_ABI == ABI_V4
9931 || DEFAULT_ABI == ABI_DARWIN"
9933 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9934 output_asm_insn ("crxor 6,6,6", operands);
9936 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9937 output_asm_insn ("creqv 6,6,6", operands);
9941 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
9942 (set_attr "length" "4,4,8,8")])
9944 (define_insn_and_split "*call_nonlocal_sysv<mode>"
9945 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9946 (match_operand 1 "" "g,g"))
9947 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9948 (clobber (reg:SI LR_REGNO))]
9949 "(DEFAULT_ABI == ABI_DARWIN
9950 || (DEFAULT_ABI == ABI_V4
9951 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
9953 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9954 output_asm_insn ("crxor 6,6,6", operands);
9956 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9957 output_asm_insn ("creqv 6,6,6", operands);
9960 return output_call(insn, operands, 0, 2);
9962 if (DEFAULT_ABI == ABI_V4 && flag_pic)
9964 gcc_assert (!TARGET_SECURE_PLT);
9965 return "bl %z0@plt";
9971 "DEFAULT_ABI == ABI_V4
9972 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9973 && (INTVAL (operands[2]) & CALL_LONG) == 0"
9974 [(parallel [(call (mem:SI (match_dup 0))
9978 (clobber (reg:SI LR_REGNO))])]
9980 operands[3] = pic_offset_table_rtx;
9982 [(set_attr "type" "branch,branch")
9983 (set_attr "length" "4,8")])
9985 (define_insn "*call_nonlocal_sysv_secure<mode>"
9986 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9987 (match_operand 1 "" "g,g"))
9988 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9989 (use (match_operand:SI 3 "register_operand" "r,r"))
9990 (clobber (reg:SI LR_REGNO))]
9991 "(DEFAULT_ABI == ABI_V4
9992 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9993 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
9995 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9996 output_asm_insn ("crxor 6,6,6", operands);
9998 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9999 output_asm_insn ("creqv 6,6,6", operands);
10002 /* The magic 32768 offset here and in the other sysv call insns
10003 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10004 See sysv4.h:toc_section. */
10005 return "bl %z0+32768@plt";
10007 return "bl %z0@plt";
10009 [(set_attr "type" "branch,branch")
10010 (set_attr "length" "4,8")])
10012 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10013 [(set (match_operand 0 "" "")
10014 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10015 (match_operand 2 "" "g,g,g,g")))
10016 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10017 (clobber (reg:SI LR_REGNO))]
10018 "DEFAULT_ABI == ABI_V4
10019 || DEFAULT_ABI == ABI_DARWIN"
10021 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10022 output_asm_insn ("crxor 6,6,6", operands);
10024 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10025 output_asm_insn ("creqv 6,6,6", operands);
10029 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10030 (set_attr "length" "4,4,8,8")])
10032 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10033 [(set (match_operand 0 "" "")
10034 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10035 (match_operand 2 "" "g,g")))
10036 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10037 (clobber (reg:SI LR_REGNO))]
10038 "(DEFAULT_ABI == ABI_DARWIN
10039 || (DEFAULT_ABI == ABI_V4
10040 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10042 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10043 output_asm_insn ("crxor 6,6,6", operands);
10045 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10046 output_asm_insn ("creqv 6,6,6", operands);
10049 return output_call(insn, operands, 1, 3);
10051 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10053 gcc_assert (!TARGET_SECURE_PLT);
10054 return "bl %z1@plt";
10060 "DEFAULT_ABI == ABI_V4
10061 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10062 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10063 [(parallel [(set (match_dup 0)
10064 (call (mem:SI (match_dup 1))
10066 (use (match_dup 3))
10067 (use (match_dup 4))
10068 (clobber (reg:SI LR_REGNO))])]
10070 operands[4] = pic_offset_table_rtx;
10072 [(set_attr "type" "branch,branch")
10073 (set_attr "length" "4,8")])
10075 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10076 [(set (match_operand 0 "" "")
10077 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10078 (match_operand 2 "" "g,g")))
10079 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10080 (use (match_operand:SI 4 "register_operand" "r,r"))
10081 (clobber (reg:SI LR_REGNO))]
10082 "(DEFAULT_ABI == ABI_V4
10083 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10084 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10086 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10087 output_asm_insn ("crxor 6,6,6", operands);
10089 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10090 output_asm_insn ("creqv 6,6,6", operands);
10093 return "bl %z1+32768@plt";
10095 return "bl %z1@plt";
10097 [(set_attr "type" "branch,branch")
10098 (set_attr "length" "4,8")])
10101 ;; Call to AIX abi function in the same module.
10103 (define_insn "*call_local_aix<mode>"
10104 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10105 (match_operand 1 "" "g"))
10106 (clobber (reg:P LR_REGNO))]
10107 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10109 [(set_attr "type" "branch")
10110 (set_attr "length" "4")])
10112 (define_insn "*call_value_local_aix<mode>"
10113 [(set (match_operand 0 "" "")
10114 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10115 (match_operand 2 "" "g")))
10116 (clobber (reg:P LR_REGNO))]
10117 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10119 [(set_attr "type" "branch")
10120 (set_attr "length" "4")])
10122 ;; Call to AIX abi function which may be in another module.
10123 ;; Restore the TOC pointer (r2) after the call.
10125 (define_insn "*call_nonlocal_aix<mode>"
10126 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10127 (match_operand 1 "" "g"))
10128 (clobber (reg:P LR_REGNO))]
10129 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10131 [(set_attr "type" "branch")
10132 (set_attr "length" "8")])
10134 (define_insn "*call_value_nonlocal_aix<mode>"
10135 [(set (match_operand 0 "" "")
10136 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10137 (match_operand 2 "" "g")))
10138 (clobber (reg:P LR_REGNO))]
10139 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10141 [(set_attr "type" "branch")
10142 (set_attr "length" "8")])
10144 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10145 ;; Operand0 is the addresss of the function to call
10146 ;; Operand2 is the location in the function descriptor to load r2 from
10147 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10149 (define_insn "*call_indirect_aix<mode>"
10150 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10151 (match_operand 1 "" "g,g"))
10152 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10153 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10154 (clobber (reg:P LR_REGNO))]
10155 "DEFAULT_ABI == ABI_AIX"
10156 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10157 [(set_attr "type" "jmpreg")
10158 (set_attr "length" "12")])
10160 (define_insn "*call_value_indirect_aix<mode>"
10161 [(set (match_operand 0 "" "")
10162 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10163 (match_operand 2 "" "g,g")))
10164 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10165 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10166 (clobber (reg:P LR_REGNO))]
10167 "DEFAULT_ABI == ABI_AIX"
10168 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10169 [(set_attr "type" "jmpreg")
10170 (set_attr "length" "12")])
10172 ;; Call to indirect functions with the ELFv2 ABI.
10173 ;; Operand0 is the addresss of the function to call
10174 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10176 (define_insn "*call_indirect_elfv2<mode>"
10177 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10178 (match_operand 1 "" "g,g"))
10179 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10180 (clobber (reg:P LR_REGNO))]
10181 "DEFAULT_ABI == ABI_ELFv2"
10182 "b%T0l\;<ptrload> 2,%2(1)"
10183 [(set_attr "type" "jmpreg")
10184 (set_attr "length" "8")])
10186 (define_insn "*call_value_indirect_elfv2<mode>"
10187 [(set (match_operand 0 "" "")
10188 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10189 (match_operand 2 "" "g,g")))
10190 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10191 (clobber (reg:P LR_REGNO))]
10192 "DEFAULT_ABI == ABI_ELFv2"
10193 "b%T1l\;<ptrload> 2,%3(1)"
10194 [(set_attr "type" "jmpreg")
10195 (set_attr "length" "8")])
10198 ;; Call subroutine returning any type.
10199 (define_expand "untyped_call"
10200 [(parallel [(call (match_operand 0 "" "")
10202 (match_operand 1 "" "")
10203 (match_operand 2 "" "")])]
10209 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10211 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10213 rtx set = XVECEXP (operands[2], 0, i);
10214 emit_move_insn (SET_DEST (set), SET_SRC (set));
10217 /* The optimizer does not know that the call sets the function value
10218 registers we stored in the result block. We avoid problems by
10219 claiming that all hard registers are used and clobbered at this
10221 emit_insn (gen_blockage ());
10226 ;; sibling call patterns
10227 (define_expand "sibcall"
10228 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10229 (match_operand 1 "" ""))
10230 (use (match_operand 2 "" ""))
10231 (use (reg:SI LR_REGNO))
10237 if (MACHOPIC_INDIRECT)
10238 operands[0] = machopic_indirect_call_target (operands[0]);
10241 gcc_assert (GET_CODE (operands[0]) == MEM);
10242 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10244 operands[0] = XEXP (operands[0], 0);
10246 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10248 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10253 (define_expand "sibcall_value"
10254 [(parallel [(set (match_operand 0 "register_operand" "")
10255 (call (mem:SI (match_operand 1 "address_operand" ""))
10256 (match_operand 2 "" "")))
10257 (use (match_operand 3 "" ""))
10258 (use (reg:SI LR_REGNO))
10264 if (MACHOPIC_INDIRECT)
10265 operands[1] = machopic_indirect_call_target (operands[1]);
10268 gcc_assert (GET_CODE (operands[1]) == MEM);
10269 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10271 operands[1] = XEXP (operands[1], 0);
10273 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10275 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10280 ;; this and similar patterns must be marked as using LR, otherwise
10281 ;; dataflow will try to delete the store into it. This is true
10282 ;; even when the actual reg to jump to is in CTR, when LR was
10283 ;; saved and restored around the PIC-setting BCL.
10284 (define_insn "*sibcall_local32"
10285 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10286 (match_operand 1 "" "g,g"))
10287 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10288 (use (reg:SI LR_REGNO))
10290 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10293 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10294 output_asm_insn (\"crxor 6,6,6\", operands);
10296 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10297 output_asm_insn (\"creqv 6,6,6\", operands);
10299 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10301 [(set_attr "type" "branch")
10302 (set_attr "length" "4,8")])
10304 (define_insn "*sibcall_local64"
10305 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10306 (match_operand 1 "" "g,g"))
10307 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10308 (use (reg:SI LR_REGNO))
10310 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10313 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10314 output_asm_insn (\"crxor 6,6,6\", operands);
10316 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10317 output_asm_insn (\"creqv 6,6,6\", operands);
10319 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10321 [(set_attr "type" "branch")
10322 (set_attr "length" "4,8")])
10324 (define_insn "*sibcall_value_local32"
10325 [(set (match_operand 0 "" "")
10326 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10327 (match_operand 2 "" "g,g")))
10328 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10329 (use (reg:SI LR_REGNO))
10331 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10334 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10335 output_asm_insn (\"crxor 6,6,6\", operands);
10337 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10338 output_asm_insn (\"creqv 6,6,6\", operands);
10340 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10342 [(set_attr "type" "branch")
10343 (set_attr "length" "4,8")])
10345 (define_insn "*sibcall_value_local64"
10346 [(set (match_operand 0 "" "")
10347 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10348 (match_operand 2 "" "g,g")))
10349 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10350 (use (reg:SI LR_REGNO))
10352 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10355 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10356 output_asm_insn (\"crxor 6,6,6\", operands);
10358 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10359 output_asm_insn (\"creqv 6,6,6\", operands);
10361 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10363 [(set_attr "type" "branch")
10364 (set_attr "length" "4,8")])
10366 (define_insn "*sibcall_nonlocal_sysv<mode>"
10367 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10368 (match_operand 1 "" ""))
10369 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10370 (use (reg:SI LR_REGNO))
10372 "(DEFAULT_ABI == ABI_DARWIN
10373 || DEFAULT_ABI == ABI_V4)
10374 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10377 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10378 output_asm_insn (\"crxor 6,6,6\", operands);
10380 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10381 output_asm_insn (\"creqv 6,6,6\", operands);
10383 if (which_alternative >= 2)
10385 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10387 gcc_assert (!TARGET_SECURE_PLT);
10388 return \"b %z0@plt\";
10393 [(set_attr "type" "branch")
10394 (set_attr "length" "4,8,4,8")])
10396 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10397 [(set (match_operand 0 "" "")
10398 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10399 (match_operand 2 "" "")))
10400 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10401 (use (reg:SI LR_REGNO))
10403 "(DEFAULT_ABI == ABI_DARWIN
10404 || DEFAULT_ABI == ABI_V4)
10405 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10408 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10409 output_asm_insn (\"crxor 6,6,6\", operands);
10411 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10412 output_asm_insn (\"creqv 6,6,6\", operands);
10414 if (which_alternative >= 2)
10416 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10418 gcc_assert (!TARGET_SECURE_PLT);
10419 return \"b %z1@plt\";
10424 [(set_attr "type" "branch")
10425 (set_attr "length" "4,8,4,8")])
10427 ;; AIX ABI sibling call patterns.
10429 (define_insn "*sibcall_aix<mode>"
10430 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10431 (match_operand 1 "" "g,g"))
10433 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10437 [(set_attr "type" "branch")
10438 (set_attr "length" "4")])
10440 (define_insn "*sibcall_value_aix<mode>"
10441 [(set (match_operand 0 "" "")
10442 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10443 (match_operand 2 "" "g,g")))
10445 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10449 [(set_attr "type" "branch")
10450 (set_attr "length" "4")])
10452 (define_expand "sibcall_epilogue"
10453 [(use (const_int 0))]
10456 if (!TARGET_SCHED_PROLOG)
10457 emit_insn (gen_blockage ());
10458 rs6000_emit_epilogue (TRUE);
10462 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10463 ;; all of memory. This blocks insns from being moved across this point.
10465 (define_insn "blockage"
10466 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10470 (define_expand "probe_stack_address"
10471 [(use (match_operand 0 "address_operand"))]
10474 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10475 MEM_VOLATILE_P (operands[0]) = 1;
10478 emit_insn (gen_probe_stack_di (operands[0]));
10480 emit_insn (gen_probe_stack_si (operands[0]));
10484 (define_insn "probe_stack_<mode>"
10485 [(set (match_operand:P 0 "memory_operand" "=m")
10486 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10489 operands[1] = gen_rtx_REG (Pmode, 0);
10490 return "st<wd>%U0%X0 %1,%0";
10492 [(set_attr "type" "store")
10493 (set (attr "update")
10494 (if_then_else (match_operand 0 "update_address_mem")
10495 (const_string "yes")
10496 (const_string "no")))
10497 (set (attr "indexed")
10498 (if_then_else (match_operand 0 "indexed_address_mem")
10499 (const_string "yes")
10500 (const_string "no")))
10501 (set_attr "length" "4")])
10503 (define_insn "probe_stack_range<P:mode>"
10504 [(set (match_operand:P 0 "register_operand" "=r")
10505 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10506 (match_operand:P 2 "register_operand" "r")]
10507 UNSPECV_PROBE_STACK_RANGE))]
10509 "* return output_probe_stack_range (operands[0], operands[2]);"
10510 [(set_attr "type" "three")])
10512 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
10513 ;; signed & unsigned, and one type of branch.
10515 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10516 ;; insns, and branches.
10518 (define_expand "cbranch<mode>4"
10519 [(use (match_operator 0 "rs6000_cbranch_operator"
10520 [(match_operand:GPR 1 "gpc_reg_operand" "")
10521 (match_operand:GPR 2 "reg_or_short_operand" "")]))
10522 (use (match_operand 3 ""))]
10526 /* Take care of the possibility that operands[2] might be negative but
10527 this might be a logical operation. That insn doesn't exist. */
10528 if (GET_CODE (operands[2]) == CONST_INT
10529 && INTVAL (operands[2]) < 0)
10531 operands[2] = force_reg (<MODE>mode, operands[2]);
10532 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10533 GET_MODE (operands[0]),
10534 operands[1], operands[2]);
10537 rs6000_emit_cbranch (<MODE>mode, operands);
10541 (define_expand "cbranch<mode>4"
10542 [(use (match_operator 0 "rs6000_cbranch_operator"
10543 [(match_operand:FP 1 "gpc_reg_operand" "")
10544 (match_operand:FP 2 "gpc_reg_operand" "")]))
10545 (use (match_operand 3 ""))]
10549 rs6000_emit_cbranch (<MODE>mode, operands);
10553 (define_expand "cstore<mode>4_signed"
10554 [(use (match_operator 1 "signed_comparison_operator"
10555 [(match_operand:P 2 "gpc_reg_operand")
10556 (match_operand:P 3 "gpc_reg_operand")]))
10557 (clobber (match_operand:P 0 "gpc_reg_operand"))]
10560 enum rtx_code cond_code = GET_CODE (operands[1]);
10562 rtx op0 = operands[0];
10563 rtx op1 = operands[2];
10564 rtx op2 = operands[3];
10566 if (cond_code == GE || cond_code == LT)
10568 cond_code = swap_condition (cond_code);
10569 std::swap (op1, op2);
10572 rtx tmp1 = gen_reg_rtx (<MODE>mode);
10573 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10574 rtx tmp3 = gen_reg_rtx (<MODE>mode);
10576 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10577 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10578 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10580 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10582 if (cond_code == LE)
10583 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
10586 rtx tmp4 = gen_reg_rtx (<MODE>mode);
10587 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
10588 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
10594 (define_expand "cstore<mode>4_unsigned"
10595 [(use (match_operator 1 "unsigned_comparison_operator"
10596 [(match_operand:P 2 "gpc_reg_operand")
10597 (match_operand:P 3 "reg_or_short_operand")]))
10598 (clobber (match_operand:P 0 "gpc_reg_operand"))]
10601 enum rtx_code cond_code = GET_CODE (operands[1]);
10603 rtx op0 = operands[0];
10604 rtx op1 = operands[2];
10605 rtx op2 = operands[3];
10607 if (cond_code == GEU || cond_code == LTU)
10609 cond_code = swap_condition (cond_code);
10610 std::swap (op1, op2);
10613 if (!gpc_reg_operand (op1, <MODE>mode))
10614 op1 = force_reg (<MODE>mode, op1);
10615 if (!reg_or_short_operand (op2, <MODE>mode))
10616 op2 = force_reg (<MODE>mode, op2);
10618 rtx tmp = gen_reg_rtx (<MODE>mode);
10619 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10621 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10622 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10624 if (cond_code == LEU)
10625 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10627 emit_insn (gen_neg<mode>2 (op0, tmp2));
10632 (define_expand "cstore_si_as_di"
10633 [(use (match_operator 1 "unsigned_comparison_operator"
10634 [(match_operand:SI 2 "gpc_reg_operand")
10635 (match_operand:SI 3 "reg_or_short_operand")]))
10636 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10639 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10640 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10642 operands[2] = force_reg (SImode, operands[2]);
10643 operands[3] = force_reg (SImode, operands[3]);
10644 rtx op1 = gen_reg_rtx (DImode);
10645 rtx op2 = gen_reg_rtx (DImode);
10646 convert_move (op1, operands[2], uns_flag);
10647 convert_move (op2, operands[3], uns_flag);
10649 if (cond_code == GT || cond_code == LE)
10651 cond_code = swap_condition (cond_code);
10652 std::swap (op1, op2);
10655 rtx tmp = gen_reg_rtx (DImode);
10656 rtx tmp2 = gen_reg_rtx (DImode);
10657 emit_insn (gen_subdi3 (tmp, op1, op2));
10658 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
10664 gcc_unreachable ();
10669 tmp3 = gen_reg_rtx (DImode);
10670 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
10674 convert_move (operands[0], tmp3, 1);
10679 (define_expand "cstore<mode>4_signed_imm"
10680 [(use (match_operator 1 "signed_comparison_operator"
10681 [(match_operand:GPR 2 "gpc_reg_operand")
10682 (match_operand:GPR 3 "immediate_operand")]))
10683 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10686 bool invert = false;
10688 enum rtx_code cond_code = GET_CODE (operands[1]);
10690 rtx op0 = operands[0];
10691 rtx op1 = operands[2];
10692 HOST_WIDE_INT val = INTVAL (operands[3]);
10694 if (cond_code == GE || cond_code == GT)
10696 cond_code = reverse_condition (cond_code);
10700 if (cond_code == LE)
10703 rtx tmp = gen_reg_rtx (<MODE>mode);
10704 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10705 rtx x = gen_reg_rtx (<MODE>mode);
10707 emit_insn (gen_and<mode>3 (x, op1, tmp));
10709 emit_insn (gen_ior<mode>3 (x, op1, tmp));
10713 rtx tmp = gen_reg_rtx (<MODE>mode);
10714 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10718 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10719 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10724 (define_expand "cstore<mode>4_unsigned_imm"
10725 [(use (match_operator 1 "unsigned_comparison_operator"
10726 [(match_operand:GPR 2 "gpc_reg_operand")
10727 (match_operand:GPR 3 "immediate_operand")]))
10728 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10731 bool invert = false;
10733 enum rtx_code cond_code = GET_CODE (operands[1]);
10735 rtx op0 = operands[0];
10736 rtx op1 = operands[2];
10737 HOST_WIDE_INT val = INTVAL (operands[3]);
10739 if (cond_code == GEU || cond_code == GTU)
10741 cond_code = reverse_condition (cond_code);
10745 if (cond_code == LEU)
10748 rtx tmp = gen_reg_rtx (<MODE>mode);
10749 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10750 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10751 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
10752 rtx x = gen_reg_rtx (<MODE>mode);
10754 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
10756 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
10760 rtx tmp = gen_reg_rtx (<MODE>mode);
10761 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10765 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10766 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10771 (define_expand "cstore<mode>4"
10772 [(use (match_operator 1 "rs6000_cbranch_operator"
10773 [(match_operand:GPR 2 "gpc_reg_operand")
10774 (match_operand:GPR 3 "reg_or_short_operand")]))
10775 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10778 /* Use ISEL if the user asked for it. */
10780 rs6000_emit_sISEL (<MODE>mode, operands);
10782 /* Expanding EQ and NE directly to some machine instructions does not help
10783 but does hurt combine. So don't. */
10784 else if (GET_CODE (operands[1]) == EQ)
10785 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
10786 else if (<MODE>mode == Pmode
10787 && GET_CODE (operands[1]) == NE)
10788 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
10789 else if (GET_CODE (operands[1]) == NE)
10791 rtx tmp = gen_reg_rtx (<MODE>mode);
10792 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
10793 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
10796 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
10797 etc. combinations magically work out just right. */
10798 else if (<MODE>mode == Pmode
10799 && unsigned_comparison_operator (operands[1], VOIDmode))
10800 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
10801 operands[2], operands[3]));
10803 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
10804 else if (<MODE>mode == SImode && Pmode == DImode)
10805 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
10806 operands[2], operands[3]));
10808 /* For signed comparisons against a constant, we can do some simple
10810 else if (signed_comparison_operator (operands[1], VOIDmode)
10811 && CONST_INT_P (operands[3]))
10812 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
10813 operands[2], operands[3]));
10815 /* And similarly for unsigned comparisons. */
10816 else if (unsigned_comparison_operator (operands[1], VOIDmode)
10817 && CONST_INT_P (operands[3]))
10818 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
10819 operands[2], operands[3]));
10821 /* We also do not want to use mfcr for signed comparisons. */
10822 else if (<MODE>mode == Pmode
10823 && signed_comparison_operator (operands[1], VOIDmode))
10824 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
10825 operands[2], operands[3]));
10827 /* Everything else, use the mfcr brute force. */
10829 rs6000_emit_sCOND (<MODE>mode, operands);
10834 (define_expand "cstore<mode>4"
10835 [(use (match_operator 1 "rs6000_cbranch_operator"
10836 [(match_operand:FP 2 "gpc_reg_operand")
10837 (match_operand:FP 3 "gpc_reg_operand")]))
10838 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10841 rs6000_emit_sCOND (<MODE>mode, operands);
10846 (define_expand "stack_protect_set"
10847 [(match_operand 0 "memory_operand" "")
10848 (match_operand 1 "memory_operand" "")]
10851 #ifdef TARGET_THREAD_SSP_OFFSET
10852 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10853 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10854 operands[1] = gen_rtx_MEM (Pmode, addr);
10857 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10859 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10863 (define_insn "stack_protect_setsi"
10864 [(set (match_operand:SI 0 "memory_operand" "=m")
10865 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
10866 (set (match_scratch:SI 2 "=&r") (const_int 0))]
10868 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
10869 [(set_attr "type" "three")
10870 (set_attr "length" "12")])
10872 (define_insn "stack_protect_setdi"
10873 [(set (match_operand:DI 0 "memory_operand" "=Y")
10874 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
10875 (set (match_scratch:DI 2 "=&r") (const_int 0))]
10877 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
10878 [(set_attr "type" "three")
10879 (set_attr "length" "12")])
10881 (define_expand "stack_protect_test"
10882 [(match_operand 0 "memory_operand" "")
10883 (match_operand 1 "memory_operand" "")
10884 (match_operand 2 "" "")]
10887 rtx test, op0, op1;
10888 #ifdef TARGET_THREAD_SSP_OFFSET
10889 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10890 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10891 operands[1] = gen_rtx_MEM (Pmode, addr);
10894 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
10895 test = gen_rtx_EQ (VOIDmode, op0, op1);
10896 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
10900 (define_insn "stack_protect_testsi"
10901 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10902 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
10903 (match_operand:SI 2 "memory_operand" "m,m")]
10905 (set (match_scratch:SI 4 "=r,r") (const_int 0))
10906 (clobber (match_scratch:SI 3 "=&r,&r"))]
10909 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10910 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
10911 [(set_attr "length" "16,20")])
10913 (define_insn "stack_protect_testdi"
10914 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10915 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
10916 (match_operand:DI 2 "memory_operand" "Y,Y")]
10918 (set (match_scratch:DI 4 "=r,r") (const_int 0))
10919 (clobber (match_scratch:DI 3 "=&r,&r"))]
10922 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10923 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
10924 [(set_attr "length" "16,20")])
10927 ;; Here are the actual compare insns.
10928 (define_insn "*cmp<mode>_signed"
10929 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
10930 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
10931 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
10933 "cmp<wd>%I2 %0,%1,%2"
10934 [(set_attr "type" "cmp")])
10936 (define_insn "*cmp<mode>_unsigned"
10937 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
10938 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
10939 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
10941 "cmpl<wd>%I2 %0,%1,%2"
10942 [(set_attr "type" "cmp")])
10944 ;; If we are comparing a register for equality with a large constant,
10945 ;; we can do this with an XOR followed by a compare. But this is profitable
10946 ;; only if the large constant is only used for the comparison (and in this
10947 ;; case we already have a register to reuse as scratch).
10949 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
10950 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
10953 [(set (match_operand:SI 0 "register_operand")
10954 (match_operand:SI 1 "logical_const_operand" ""))
10955 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
10957 (match_operand:SI 2 "logical_const_operand" "")]))
10958 (set (match_operand:CC 4 "cc_reg_operand" "")
10959 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
10962 (if_then_else (match_operator 6 "equality_operator"
10963 [(match_dup 4) (const_int 0)])
10964 (match_operand 7 "" "")
10965 (match_operand 8 "" "")))]
10966 "peep2_reg_dead_p (3, operands[0])
10967 && peep2_reg_dead_p (4, operands[4])
10968 && REGNO (operands[0]) != REGNO (operands[5])"
10969 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
10970 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
10971 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
10974 /* Get the constant we are comparing against, and see what it looks like
10975 when sign-extended from 16 to 32 bits. Then see what constant we could
10976 XOR with SEXTC to get the sign-extended value. */
10977 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
10979 operands[1], operands[2]);
10980 HOST_WIDE_INT c = INTVAL (cnst);
10981 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
10982 HOST_WIDE_INT xorv = c ^ sextc;
10984 operands[9] = GEN_INT (xorv);
10985 operands[10] = GEN_INT (sextc);
10988 ;; The following two insns don't exist as single insns, but if we provide
10989 ;; them, we can swap an add and compare, which will enable us to overlap more
10990 ;; of the required delay between a compare and branch. We generate code for
10991 ;; them by splitting.
10994 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
10995 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
10996 (match_operand:SI 2 "short_cint_operand" "i")))
10997 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
10998 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11001 [(set_attr "length" "8")])
11004 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11005 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11006 (match_operand:SI 2 "u_short_cint_operand" "i")))
11007 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11008 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11011 [(set_attr "length" "8")])
11014 [(set (match_operand:CC 3 "cc_reg_operand" "")
11015 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11016 (match_operand:SI 2 "short_cint_operand" "")))
11017 (set (match_operand:SI 0 "gpc_reg_operand" "")
11018 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11020 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11021 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11024 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11025 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11026 (match_operand:SI 2 "u_short_cint_operand" "")))
11027 (set (match_operand:SI 0 "gpc_reg_operand" "")
11028 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11030 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11031 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11033 ;; Only need to compare second words if first words equal
11034 (define_insn "*cmp<mode>_internal1"
11035 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11036 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11037 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11038 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11039 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11040 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11041 [(set_attr "type" "fpcompare")
11042 (set_attr "length" "12")])
11044 (define_insn_and_split "*cmp<mode>_internal2"
11045 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11046 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11047 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11048 (clobber (match_scratch:DF 3 "=d"))
11049 (clobber (match_scratch:DF 4 "=d"))
11050 (clobber (match_scratch:DF 5 "=d"))
11051 (clobber (match_scratch:DF 6 "=d"))
11052 (clobber (match_scratch:DF 7 "=d"))
11053 (clobber (match_scratch:DF 8 "=d"))
11054 (clobber (match_scratch:DF 9 "=d"))
11055 (clobber (match_scratch:DF 10 "=d"))
11056 (clobber (match_scratch:GPR 11 "=b"))]
11057 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11058 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11060 "&& reload_completed"
11061 [(set (match_dup 3) (match_dup 14))
11062 (set (match_dup 4) (match_dup 15))
11063 (set (match_dup 9) (abs:DF (match_dup 5)))
11064 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11065 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11066 (label_ref (match_dup 12))
11068 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11069 (set (pc) (label_ref (match_dup 13)))
11071 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11072 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11073 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11074 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11077 REAL_VALUE_TYPE rv;
11078 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11079 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11081 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11082 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11083 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11084 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11085 operands[12] = gen_label_rtx ();
11086 operands[13] = gen_label_rtx ();
11088 operands[14] = force_const_mem (DFmode,
11089 const_double_from_real_value (rv, DFmode));
11090 operands[15] = force_const_mem (DFmode,
11091 const_double_from_real_value (dconst0,
11096 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11097 operands[14] = gen_const_mem (DFmode, tocref);
11098 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11099 operands[15] = gen_const_mem (DFmode, tocref);
11100 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11101 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11105 ;; Now we have the scc insns. We can do some combinations because of the
11106 ;; way the machine works.
11108 ;; Note that this is probably faster if we can put an insn between the
11109 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11110 ;; cases the insns below which don't use an intermediate CR field will
11111 ;; be used instead.
11113 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11114 (match_operator:SI 1 "scc_comparison_operator"
11115 [(match_operand 2 "cc_reg_operand" "y")
11118 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11119 [(set (attr "type")
11120 (cond [(match_test "TARGET_MFCRF")
11121 (const_string "mfcrf")
11123 (const_string "mfcr")))
11124 (set_attr "length" "8")])
11126 ;; Same as above, but get the GT bit.
11127 (define_insn "move_from_CR_gt_bit"
11128 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11129 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11130 "TARGET_HARD_FLOAT && !TARGET_FPRS"
11131 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11132 [(set_attr "type" "mfcr")
11133 (set_attr "length" "8")])
11135 ;; Same as above, but get the OV/ORDERED bit.
11136 (define_insn "move_from_CR_ov_bit"
11137 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11138 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11141 "mfcr %0\;rlwinm %0,%0,%t1,1"
11142 [(set_attr "type" "mfcr")
11143 (set_attr "length" "8")])
11146 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11147 (match_operator:DI 1 "scc_comparison_operator"
11148 [(match_operand 2 "cc_reg_operand" "y")
11151 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11152 [(set (attr "type")
11153 (cond [(match_test "TARGET_MFCRF")
11154 (const_string "mfcrf")
11156 (const_string "mfcr")))
11157 (set_attr "length" "8")])
11160 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11161 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11162 [(match_operand 2 "cc_reg_operand" "y,y")
11165 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11166 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11169 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11171 [(set_attr "type" "shift")
11172 (set_attr "dot" "yes")
11173 (set_attr "length" "8,16")])
11176 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11177 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11178 [(match_operand 2 "cc_reg_operand" "")
11181 (set (match_operand:SI 3 "gpc_reg_operand" "")
11182 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11183 "TARGET_32BIT && reload_completed"
11184 [(set (match_dup 3)
11185 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11187 (compare:CC (match_dup 3)
11192 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11193 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11194 [(match_operand 2 "cc_reg_operand" "y")
11196 (match_operand:SI 3 "const_int_operand" "n")))]
11200 int is_bit = ccr_bit (operands[1], 1);
11201 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11204 if (is_bit >= put_bit)
11205 count = is_bit - put_bit;
11207 count = 32 - (put_bit - is_bit);
11209 operands[4] = GEN_INT (count);
11210 operands[5] = GEN_INT (put_bit);
11212 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11214 [(set (attr "type")
11215 (cond [(match_test "TARGET_MFCRF")
11216 (const_string "mfcrf")
11218 (const_string "mfcr")))
11219 (set_attr "length" "8")])
11222 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11224 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11225 [(match_operand 2 "cc_reg_operand" "y,y")
11227 (match_operand:SI 3 "const_int_operand" "n,n"))
11229 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11230 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11235 int is_bit = ccr_bit (operands[1], 1);
11236 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11239 /* Force split for non-cc0 compare. */
11240 if (which_alternative == 1)
11243 if (is_bit >= put_bit)
11244 count = is_bit - put_bit;
11246 count = 32 - (put_bit - is_bit);
11248 operands[5] = GEN_INT (count);
11249 operands[6] = GEN_INT (put_bit);
11251 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11253 [(set_attr "type" "shift")
11254 (set_attr "dot" "yes")
11255 (set_attr "length" "8,16")])
11258 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11260 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11261 [(match_operand 2 "cc_reg_operand" "")
11263 (match_operand:SI 3 "const_int_operand" ""))
11265 (set (match_operand:SI 4 "gpc_reg_operand" "")
11266 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11269 [(set (match_dup 4)
11270 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11273 (compare:CC (match_dup 4)
11277 ;; There is a 3 cycle delay between consecutive mfcr instructions
11278 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
11281 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11282 (match_operator:SI 1 "scc_comparison_operator"
11283 [(match_operand 2 "cc_reg_operand" "y")
11285 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
11286 (match_operator:SI 4 "scc_comparison_operator"
11287 [(match_operand 5 "cc_reg_operand" "y")
11289 "REGNO (operands[2]) != REGNO (operands[5])"
11290 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11291 [(set_attr "type" "mfcr")
11292 (set_attr "length" "12")])
11295 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11296 (match_operator:DI 1 "scc_comparison_operator"
11297 [(match_operand 2 "cc_reg_operand" "y")
11299 (set (match_operand:DI 3 "gpc_reg_operand" "=r")
11300 (match_operator:DI 4 "scc_comparison_operator"
11301 [(match_operand 5 "cc_reg_operand" "y")
11303 "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
11304 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11305 [(set_attr "type" "mfcr")
11306 (set_attr "length" "12")])
11309 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11312 (define_insn_and_split "eq<mode>3"
11313 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11314 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11315 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11316 (clobber (match_scratch:GPR 3 "=r"))
11317 (clobber (match_scratch:GPR 4 "=r"))]
11321 [(set (match_dup 4)
11322 (clz:GPR (match_dup 3)))
11324 (lshiftrt:GPR (match_dup 4)
11327 operands[3] = rs6000_emit_eqne (<MODE>mode,
11328 operands[1], operands[2], operands[3]);
11330 if (GET_CODE (operands[4]) == SCRATCH)
11331 operands[4] = gen_reg_rtx (<MODE>mode);
11333 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11335 [(set (attr "length")
11336 (if_then_else (match_test "operands[2] == const0_rtx")
11338 (const_string "12")))])
11340 (define_insn_and_split "ne<mode>3"
11341 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11342 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11343 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11344 (clobber (match_scratch:P 3 "=r"))
11345 (clobber (match_scratch:P 4 "=r"))
11346 (clobber (reg:P CA_REGNO))]
11350 [(parallel [(set (match_dup 4)
11351 (plus:P (match_dup 3)
11353 (set (reg:P CA_REGNO)
11354 (ne:P (match_dup 3)
11356 (parallel [(set (match_dup 0)
11357 (plus:P (plus:P (not:P (match_dup 4))
11360 (clobber (reg:P CA_REGNO))])]
11362 operands[3] = rs6000_emit_eqne (<MODE>mode,
11363 operands[1], operands[2], operands[3]);
11365 if (GET_CODE (operands[4]) == SCRATCH)
11366 operands[4] = gen_reg_rtx (<MODE>mode);
11368 [(set (attr "length")
11369 (if_then_else (match_test "operands[2] == const0_rtx")
11371 (const_string "12")))])
11373 (define_insn_and_split "*neg_eq_<mode>"
11374 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11375 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11376 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11377 (clobber (match_scratch:P 3 "=r"))
11378 (clobber (match_scratch:P 4 "=r"))
11379 (clobber (reg:P CA_REGNO))]
11383 [(parallel [(set (match_dup 4)
11384 (plus:P (match_dup 3)
11386 (set (reg:P CA_REGNO)
11387 (ne:P (match_dup 3)
11389 (parallel [(set (match_dup 0)
11390 (plus:P (reg:P CA_REGNO)
11392 (clobber (reg:P CA_REGNO))])]
11394 operands[3] = rs6000_emit_eqne (<MODE>mode,
11395 operands[1], operands[2], operands[3]);
11397 if (GET_CODE (operands[4]) == SCRATCH)
11398 operands[4] = gen_reg_rtx (<MODE>mode);
11400 [(set (attr "length")
11401 (if_then_else (match_test "operands[2] == const0_rtx")
11403 (const_string "12")))])
11405 (define_insn_and_split "*neg_ne_<mode>"
11406 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11407 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11408 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11409 (clobber (match_scratch:P 3 "=r"))
11410 (clobber (match_scratch:P 4 "=r"))
11411 (clobber (reg:P CA_REGNO))]
11415 [(parallel [(set (match_dup 4)
11416 (neg:P (match_dup 3)))
11417 (set (reg:P CA_REGNO)
11418 (eq:P (match_dup 3)
11420 (parallel [(set (match_dup 0)
11421 (plus:P (reg:P CA_REGNO)
11423 (clobber (reg:P CA_REGNO))])]
11425 operands[3] = rs6000_emit_eqne (<MODE>mode,
11426 operands[1], operands[2], operands[3]);
11428 if (GET_CODE (operands[4]) == SCRATCH)
11429 operands[4] = gen_reg_rtx (<MODE>mode);
11431 [(set (attr "length")
11432 (if_then_else (match_test "operands[2] == const0_rtx")
11434 (const_string "12")))])
11436 (define_insn_and_split "*plus_eq_<mode>"
11437 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11438 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11439 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11440 (match_operand:P 3 "gpc_reg_operand" "r")))
11441 (clobber (match_scratch:P 4 "=r"))
11442 (clobber (match_scratch:P 5 "=r"))
11443 (clobber (reg:P CA_REGNO))]
11447 [(parallel [(set (match_dup 5)
11448 (neg:P (match_dup 4)))
11449 (set (reg:P CA_REGNO)
11450 (eq:P (match_dup 4)
11452 (parallel [(set (match_dup 0)
11453 (plus:P (match_dup 3)
11455 (clobber (reg:P CA_REGNO))])]
11457 operands[4] = rs6000_emit_eqne (<MODE>mode,
11458 operands[1], operands[2], operands[4]);
11460 if (GET_CODE (operands[5]) == SCRATCH)
11461 operands[5] = gen_reg_rtx (<MODE>mode);
11463 [(set (attr "length")
11464 (if_then_else (match_test "operands[2] == const0_rtx")
11466 (const_string "12")))])
11468 (define_insn_and_split "*plus_ne_<mode>"
11469 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11470 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11471 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11472 (match_operand:P 3 "gpc_reg_operand" "r")))
11473 (clobber (match_scratch:P 4 "=r"))
11474 (clobber (match_scratch:P 5 "=r"))
11475 (clobber (reg:P CA_REGNO))]
11479 [(parallel [(set (match_dup 5)
11480 (plus:P (match_dup 4)
11482 (set (reg:P CA_REGNO)
11483 (ne:P (match_dup 4)
11485 (parallel [(set (match_dup 0)
11486 (plus:P (match_dup 3)
11488 (clobber (reg:P CA_REGNO))])]
11490 operands[4] = rs6000_emit_eqne (<MODE>mode,
11491 operands[1], operands[2], operands[4]);
11493 if (GET_CODE (operands[5]) == SCRATCH)
11494 operands[5] = gen_reg_rtx (<MODE>mode);
11496 [(set (attr "length")
11497 (if_then_else (match_test "operands[2] == const0_rtx")
11499 (const_string "12")))])
11501 (define_insn_and_split "*minus_eq_<mode>"
11502 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11503 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11504 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11505 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11506 (clobber (match_scratch:P 4 "=r"))
11507 (clobber (match_scratch:P 5 "=r"))
11508 (clobber (reg:P CA_REGNO))]
11512 [(parallel [(set (match_dup 5)
11513 (plus:P (match_dup 4)
11515 (set (reg:P CA_REGNO)
11516 (ne:P (match_dup 4)
11518 (parallel [(set (match_dup 0)
11519 (plus:P (plus:P (match_dup 3)
11522 (clobber (reg:P CA_REGNO))])]
11524 operands[4] = rs6000_emit_eqne (<MODE>mode,
11525 operands[1], operands[2], operands[4]);
11527 if (GET_CODE (operands[5]) == SCRATCH)
11528 operands[5] = gen_reg_rtx (<MODE>mode);
11530 [(set (attr "length")
11531 (if_then_else (match_test "operands[2] == const0_rtx")
11533 (const_string "12")))])
11535 (define_insn_and_split "*minus_ne_<mode>"
11536 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11537 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11538 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11539 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11540 (clobber (match_scratch:P 4 "=r"))
11541 (clobber (match_scratch:P 5 "=r"))
11542 (clobber (reg:P CA_REGNO))]
11546 [(parallel [(set (match_dup 5)
11547 (neg:P (match_dup 4)))
11548 (set (reg:P CA_REGNO)
11549 (eq:P (match_dup 4)
11551 (parallel [(set (match_dup 0)
11552 (plus:P (plus:P (match_dup 3)
11555 (clobber (reg:P CA_REGNO))])]
11557 operands[4] = rs6000_emit_eqne (<MODE>mode,
11558 operands[1], operands[2], operands[4]);
11560 if (GET_CODE (operands[5]) == SCRATCH)
11561 operands[5] = gen_reg_rtx (<MODE>mode);
11563 [(set (attr "length")
11564 (if_then_else (match_test "operands[2] == const0_rtx")
11566 (const_string "12")))])
11568 (define_insn_and_split "*eqsi3_ext<mode>"
11569 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11570 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11571 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11572 (clobber (match_scratch:SI 3 "=r"))
11573 (clobber (match_scratch:SI 4 "=r"))]
11577 [(set (match_dup 4)
11578 (clz:SI (match_dup 3)))
11581 (lshiftrt:SI (match_dup 4)
11584 operands[3] = rs6000_emit_eqne (SImode,
11585 operands[1], operands[2], operands[3]);
11587 if (GET_CODE (operands[4]) == SCRATCH)
11588 operands[4] = gen_reg_rtx (SImode);
11590 [(set (attr "length")
11591 (if_then_else (match_test "operands[2] == const0_rtx")
11593 (const_string "12")))])
11595 (define_insn_and_split "*nesi3_ext<mode>"
11596 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11597 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11598 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11599 (clobber (match_scratch:SI 3 "=r"))
11600 (clobber (match_scratch:SI 4 "=r"))
11601 (clobber (match_scratch:EXTSI 5 "=r"))]
11605 [(set (match_dup 4)
11606 (clz:SI (match_dup 3)))
11609 (lshiftrt:SI (match_dup 4)
11612 (xor:EXTSI (match_dup 5)
11615 operands[3] = rs6000_emit_eqne (SImode,
11616 operands[1], operands[2], operands[3]);
11618 if (GET_CODE (operands[4]) == SCRATCH)
11619 operands[4] = gen_reg_rtx (SImode);
11620 if (GET_CODE (operands[5]) == SCRATCH)
11621 operands[5] = gen_reg_rtx (<MODE>mode);
11623 [(set (attr "length")
11624 (if_then_else (match_test "operands[2] == const0_rtx")
11625 (const_string "12")
11626 (const_string "16")))])
11628 ;; Define both directions of branch and return. If we need a reload
11629 ;; register, we'd rather use CR0 since it is much easier to copy a
11630 ;; register CC value to there.
11634 (if_then_else (match_operator 1 "branch_comparison_operator"
11636 "cc_reg_operand" "y")
11638 (label_ref (match_operand 0 "" ""))
11643 return output_cbranch (operands[1], \"%l0\", 0, insn);
11645 [(set_attr "type" "branch")])
11649 (if_then_else (match_operator 0 "branch_comparison_operator"
11651 "cc_reg_operand" "y")
11658 return output_cbranch (operands[0], NULL, 0, insn);
11660 [(set_attr "type" "jmpreg")
11661 (set_attr "length" "4")])
11665 (if_then_else (match_operator 1 "branch_comparison_operator"
11667 "cc_reg_operand" "y")
11670 (label_ref (match_operand 0 "" ""))))]
11674 return output_cbranch (operands[1], \"%l0\", 1, insn);
11676 [(set_attr "type" "branch")])
11680 (if_then_else (match_operator 0 "branch_comparison_operator"
11682 "cc_reg_operand" "y")
11689 return output_cbranch (operands[0], NULL, 1, insn);
11691 [(set_attr "type" "jmpreg")
11692 (set_attr "length" "4")])
11694 ;; Logic on condition register values.
11696 ; This pattern matches things like
11697 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11698 ; (eq:SI (reg:CCFP 68) (const_int 0)))
11700 ; which are generated by the branch logic.
11701 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11703 (define_insn "*cceq_ior_compare"
11704 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11705 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11706 [(match_operator:SI 2
11707 "branch_positive_comparison_operator"
11709 "cc_reg_operand" "y,y")
11711 (match_operator:SI 4
11712 "branch_positive_comparison_operator"
11714 "cc_reg_operand" "0,y")
11718 "cr%q1 %E0,%j2,%j4"
11719 [(set_attr "type" "cr_logical,delayed_cr")])
11721 ; Why is the constant -1 here, but 1 in the previous pattern?
11722 ; Because ~1 has all but the low bit set.
11724 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11725 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11726 [(not:SI (match_operator:SI 2
11727 "branch_positive_comparison_operator"
11729 "cc_reg_operand" "y,y")
11731 (match_operator:SI 4
11732 "branch_positive_comparison_operator"
11734 "cc_reg_operand" "0,y")
11738 "cr%q1 %E0,%j2,%j4"
11739 [(set_attr "type" "cr_logical,delayed_cr")])
11741 (define_insn "*cceq_rev_compare"
11742 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11743 (compare:CCEQ (match_operator:SI 1
11744 "branch_positive_comparison_operator"
11746 "cc_reg_operand" "0,y")
11751 [(set_attr "type" "cr_logical,delayed_cr")])
11753 ;; If we are comparing the result of two comparisons, this can be done
11754 ;; using creqv or crxor.
11756 (define_insn_and_split ""
11757 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
11758 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
11759 [(match_operand 2 "cc_reg_operand" "y")
11761 (match_operator 3 "branch_comparison_operator"
11762 [(match_operand 4 "cc_reg_operand" "y")
11767 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
11771 int positive_1, positive_2;
11773 positive_1 = branch_positive_comparison_operator (operands[1],
11774 GET_MODE (operands[1]));
11775 positive_2 = branch_positive_comparison_operator (operands[3],
11776 GET_MODE (operands[3]));
11779 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
11780 GET_CODE (operands[1])),
11782 operands[2], const0_rtx);
11783 else if (GET_MODE (operands[1]) != SImode)
11784 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
11785 operands[2], const0_rtx);
11788 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
11789 GET_CODE (operands[3])),
11791 operands[4], const0_rtx);
11792 else if (GET_MODE (operands[3]) != SImode)
11793 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
11794 operands[4], const0_rtx);
11796 if (positive_1 == positive_2)
11798 operands[1] = gen_rtx_NOT (SImode, operands[1]);
11799 operands[5] = constm1_rtx;
11803 operands[5] = const1_rtx;
11807 ;; Unconditional branch and return.
11809 (define_insn "jump"
11811 (label_ref (match_operand 0 "" "")))]
11814 [(set_attr "type" "branch")])
11816 (define_insn "<return_str>return"
11820 [(set_attr "type" "jmpreg")])
11822 (define_expand "indirect_jump"
11823 [(set (pc) (match_operand 0 "register_operand" ""))])
11825 (define_insn "*indirect_jump<mode>"
11826 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
11831 [(set_attr "type" "jmpreg")])
11833 ;; Table jump for switch statements:
11834 (define_expand "tablejump"
11835 [(use (match_operand 0 "" ""))
11836 (use (label_ref (match_operand 1 "" "")))]
11841 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
11843 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
11847 (define_expand "tablejumpsi"
11848 [(set (match_dup 3)
11849 (plus:SI (match_operand:SI 0 "" "")
11851 (parallel [(set (pc) (match_dup 3))
11852 (use (label_ref (match_operand 1 "" "")))])]
11855 { operands[0] = force_reg (SImode, operands[0]);
11856 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
11857 operands[3] = gen_reg_rtx (SImode);
11860 (define_expand "tablejumpdi"
11861 [(set (match_dup 4)
11862 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
11864 (plus:DI (match_dup 4)
11866 (parallel [(set (pc) (match_dup 3))
11867 (use (label_ref (match_operand 1 "" "")))])]
11870 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
11871 operands[3] = gen_reg_rtx (DImode);
11872 operands[4] = gen_reg_rtx (DImode);
11875 (define_insn "*tablejump<mode>_internal1"
11877 (match_operand:P 0 "register_operand" "c,*l"))
11878 (use (label_ref (match_operand 1 "" "")))]
11883 [(set_attr "type" "jmpreg")])
11886 [(unspec [(const_int 0)] UNSPEC_NOP)]
11890 (define_insn "group_ending_nop"
11891 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
11895 if (rs6000_cpu_attr == CPU_POWER6)
11896 return \"ori 1,1,0\";
11897 return \"ori 2,2,0\";
11900 ;; Define the subtract-one-and-jump insns, starting with the template
11901 ;; so loop.c knows what to generate.
11903 (define_expand "doloop_end"
11904 [(use (match_operand 0 "" "")) ; loop pseudo
11905 (use (match_operand 1 "" ""))] ; label
11911 if (GET_MODE (operands[0]) != DImode)
11913 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
11917 if (GET_MODE (operands[0]) != SImode)
11919 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
11924 (define_expand "ctr<mode>"
11925 [(parallel [(set (pc)
11926 (if_then_else (ne (match_operand:P 0 "register_operand" "")
11928 (label_ref (match_operand 1 "" ""))
11931 (plus:P (match_dup 0)
11933 (clobber (match_scratch:CC 2 ""))
11934 (clobber (match_scratch:P 3 ""))])]
11938 ;; We need to be able to do this for any operand, including MEM, or we
11939 ;; will cause reload to blow up since we don't allow output reloads on
11941 ;; For the length attribute to be calculated correctly, the
11942 ;; label MUST be operand 0.
11944 (define_insn "*ctr<mode>_internal1"
11946 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11948 (label_ref (match_operand 0 "" ""))
11950 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
11951 (plus:P (match_dup 1)
11953 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11954 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11958 if (which_alternative != 0)
11960 else if (get_attr_length (insn) == 4)
11961 return \"bdnz %l0\";
11963 return \"bdz $+8\;b %l0\";
11965 [(set_attr "type" "branch")
11966 (set_attr "length" "*,16,20,20")])
11968 (define_insn "*ctr<mode>_internal2"
11970 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11973 (label_ref (match_operand 0 "" ""))))
11974 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
11975 (plus:P (match_dup 1)
11977 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11978 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11982 if (which_alternative != 0)
11984 else if (get_attr_length (insn) == 4)
11985 return \"bdz %l0\";
11987 return \"bdnz $+8\;b %l0\";
11989 [(set_attr "type" "branch")
11990 (set_attr "length" "*,16,20,20")])
11992 ;; Similar but use EQ
11994 (define_insn "*ctr<mode>_internal5"
11996 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11998 (label_ref (match_operand 0 "" ""))
12000 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
12001 (plus:P (match_dup 1)
12003 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12004 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12008 if (which_alternative != 0)
12010 else if (get_attr_length (insn) == 4)
12011 return \"bdz %l0\";
12013 return \"bdnz $+8\;b %l0\";
12015 [(set_attr "type" "branch")
12016 (set_attr "length" "*,16,20,20")])
12018 (define_insn "*ctr<mode>_internal6"
12020 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12023 (label_ref (match_operand 0 "" ""))))
12024 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
12025 (plus:P (match_dup 1)
12027 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12028 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12032 if (which_alternative != 0)
12034 else if (get_attr_length (insn) == 4)
12035 return \"bdnz %l0\";
12037 return \"bdz $+8\;b %l0\";
12039 [(set_attr "type" "branch")
12040 (set_attr "length" "*,16,20,20")])
12042 ;; Now the splitters if we could not allocate the CTR register
12046 (if_then_else (match_operator 2 "comparison_operator"
12047 [(match_operand:P 1 "gpc_reg_operand" "")
12049 (match_operand 5 "" "")
12050 (match_operand 6 "" "")))
12051 (set (match_operand:P 0 "int_reg_operand" "")
12052 (plus:P (match_dup 1) (const_int -1)))
12053 (clobber (match_scratch:CC 3 ""))
12054 (clobber (match_scratch:P 4 ""))]
12056 [(set (match_dup 3)
12057 (compare:CC (match_dup 1)
12060 (plus:P (match_dup 1)
12062 (set (pc) (if_then_else (match_dup 7)
12066 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12067 operands[3], const0_rtx); }")
12071 (if_then_else (match_operator 2 "comparison_operator"
12072 [(match_operand:P 1 "gpc_reg_operand" "")
12074 (match_operand 5 "" "")
12075 (match_operand 6 "" "")))
12076 (set (match_operand:P 0 "nonimmediate_operand" "")
12077 (plus:P (match_dup 1) (const_int -1)))
12078 (clobber (match_scratch:CC 3 ""))
12079 (clobber (match_scratch:P 4 ""))]
12080 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12081 [(set (match_dup 3)
12082 (compare:CC (match_dup 1)
12085 (plus:P (match_dup 1)
12089 (set (pc) (if_then_else (match_dup 7)
12093 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12094 operands[3], const0_rtx); }")
12096 (define_insn "trap"
12097 [(trap_if (const_int 1) (const_int 0))]
12100 [(set_attr "type" "trap")])
12102 (define_expand "ctrap<mode>4"
12103 [(trap_if (match_operator 0 "ordered_comparison_operator"
12104 [(match_operand:GPR 1 "register_operand")
12105 (match_operand:GPR 2 "reg_or_short_operand")])
12106 (match_operand 3 "zero_constant" ""))]
12111 [(trap_if (match_operator 0 "ordered_comparison_operator"
12112 [(match_operand:GPR 1 "register_operand" "r")
12113 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12116 "t<wd>%V0%I2 %1,%2"
12117 [(set_attr "type" "trap")])
12119 ;; Insns related to generating the function prologue and epilogue.
12121 (define_expand "prologue"
12122 [(use (const_int 0))]
12125 rs6000_emit_prologue ();
12126 if (!TARGET_SCHED_PROLOG)
12127 emit_insn (gen_blockage ());
12131 (define_insn "*movesi_from_cr_one"
12132 [(match_parallel 0 "mfcr_operation"
12133 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12134 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12135 (match_operand 3 "immediate_operand" "n")]
12136 UNSPEC_MOVESI_FROM_CR))])]
12142 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12144 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12145 operands[4] = GEN_INT (mask);
12146 output_asm_insn (\"mfcr %1,%4\", operands);
12150 [(set_attr "type" "mfcrf")])
12152 (define_insn "movesi_from_cr"
12153 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12154 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12155 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12156 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12157 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12158 UNSPEC_MOVESI_FROM_CR))]
12161 [(set_attr "type" "mfcr")])
12163 (define_insn "*crsave"
12164 [(match_parallel 0 "crsave_operation"
12165 [(set (match_operand:SI 1 "memory_operand" "=m")
12166 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12169 [(set_attr "type" "store")])
12171 (define_insn "*stmw"
12172 [(match_parallel 0 "stmw_operation"
12173 [(set (match_operand:SI 1 "memory_operand" "=m")
12174 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12177 [(set_attr "type" "store")
12178 (set_attr "update" "yes")
12179 (set_attr "indexed" "yes")])
12181 ; The following comment applies to:
12185 ; return_and_restore_gpregs*
12186 ; return_and_restore_fpregs*
12187 ; return_and_restore_fpregs_aix*
12189 ; The out-of-line save / restore functions expects one input argument.
12190 ; Since those are not standard call_insn's, we must avoid using
12191 ; MATCH_OPERAND for that argument. That way the register rename
12192 ; optimization will not try to rename this register.
12193 ; Each pattern is repeated for each possible register number used in
12194 ; various ABIs (r11, r1, and for some functions r12)
12196 (define_insn "*save_gpregs_<mode>_r11"
12197 [(match_parallel 0 "any_parallel_operand"
12198 [(clobber (reg:P 65))
12199 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12201 (set (match_operand:P 2 "memory_operand" "=m")
12202 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12205 [(set_attr "type" "branch")
12206 (set_attr "length" "4")])
12208 (define_insn "*save_gpregs_<mode>_r12"
12209 [(match_parallel 0 "any_parallel_operand"
12210 [(clobber (reg:P 65))
12211 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12213 (set (match_operand:P 2 "memory_operand" "=m")
12214 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12217 [(set_attr "type" "branch")
12218 (set_attr "length" "4")])
12220 (define_insn "*save_gpregs_<mode>_r1"
12221 [(match_parallel 0 "any_parallel_operand"
12222 [(clobber (reg:P 65))
12223 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12225 (set (match_operand:P 2 "memory_operand" "=m")
12226 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12229 [(set_attr "type" "branch")
12230 (set_attr "length" "4")])
12232 (define_insn "*save_fpregs_<mode>_r11"
12233 [(match_parallel 0 "any_parallel_operand"
12234 [(clobber (reg:P 65))
12235 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12237 (set (match_operand:DF 2 "memory_operand" "=m")
12238 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12241 [(set_attr "type" "branch")
12242 (set_attr "length" "4")])
12244 (define_insn "*save_fpregs_<mode>_r12"
12245 [(match_parallel 0 "any_parallel_operand"
12246 [(clobber (reg:P 65))
12247 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12249 (set (match_operand:DF 2 "memory_operand" "=m")
12250 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12253 [(set_attr "type" "branch")
12254 (set_attr "length" "4")])
12256 (define_insn "*save_fpregs_<mode>_r1"
12257 [(match_parallel 0 "any_parallel_operand"
12258 [(clobber (reg:P 65))
12259 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12261 (set (match_operand:DF 2 "memory_operand" "=m")
12262 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12265 [(set_attr "type" "branch")
12266 (set_attr "length" "4")])
12268 ; This is to explain that changes to the stack pointer should
12269 ; not be moved over loads from or stores to stack memory.
12270 (define_insn "stack_tie"
12271 [(match_parallel 0 "tie_operand"
12272 [(set (mem:BLK (reg 1)) (const_int 0))])]
12275 [(set_attr "length" "0")])
12277 (define_expand "epilogue"
12278 [(use (const_int 0))]
12281 if (!TARGET_SCHED_PROLOG)
12282 emit_insn (gen_blockage ());
12283 rs6000_emit_epilogue (FALSE);
12287 ; On some processors, doing the mtcrf one CC register at a time is
12288 ; faster (like on the 604e). On others, doing them all at once is
12289 ; faster; for instance, on the 601 and 750.
12291 (define_expand "movsi_to_cr_one"
12292 [(set (match_operand:CC 0 "cc_reg_operand" "")
12293 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12294 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12296 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12298 (define_insn "*movsi_to_cr"
12299 [(match_parallel 0 "mtcrf_operation"
12300 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12301 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12302 (match_operand 3 "immediate_operand" "n")]
12303 UNSPEC_MOVESI_TO_CR))])]
12309 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12310 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12311 operands[4] = GEN_INT (mask);
12312 return \"mtcrf %4,%2\";
12314 [(set_attr "type" "mtcr")])
12316 (define_insn "*mtcrfsi"
12317 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12318 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12319 (match_operand 2 "immediate_operand" "n")]
12320 UNSPEC_MOVESI_TO_CR))]
12321 "GET_CODE (operands[0]) == REG
12322 && CR_REGNO_P (REGNO (operands[0]))
12323 && GET_CODE (operands[2]) == CONST_INT
12324 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12326 [(set_attr "type" "mtcr")])
12328 ; The load-multiple instructions have similar properties.
12329 ; Note that "load_multiple" is a name known to the machine-independent
12330 ; code that actually corresponds to the PowerPC load-string.
12332 (define_insn "*lmw"
12333 [(match_parallel 0 "lmw_operation"
12334 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12335 (match_operand:SI 2 "memory_operand" "m"))])]
12338 [(set_attr "type" "load")
12339 (set_attr "update" "yes")
12340 (set_attr "indexed" "yes")
12341 (set_attr "cell_micro" "always")])
12343 (define_insn "*return_internal_<mode>"
12345 (use (match_operand:P 0 "register_operand" "lc"))]
12348 [(set_attr "type" "jmpreg")])
12350 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12351 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
12353 ; The following comment applies to:
12357 ; return_and_restore_gpregs*
12358 ; return_and_restore_fpregs*
12359 ; return_and_restore_fpregs_aix*
12361 ; The out-of-line save / restore functions expects one input argument.
12362 ; Since those are not standard call_insn's, we must avoid using
12363 ; MATCH_OPERAND for that argument. That way the register rename
12364 ; optimization will not try to rename this register.
12365 ; Each pattern is repeated for each possible register number used in
12366 ; various ABIs (r11, r1, and for some functions r12)
12368 (define_insn "*restore_gpregs_<mode>_r11"
12369 [(match_parallel 0 "any_parallel_operand"
12370 [(clobber (match_operand:P 1 "register_operand" "=l"))
12371 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12373 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12374 (match_operand:P 4 "memory_operand" "m"))])]
12377 [(set_attr "type" "branch")
12378 (set_attr "length" "4")])
12380 (define_insn "*restore_gpregs_<mode>_r12"
12381 [(match_parallel 0 "any_parallel_operand"
12382 [(clobber (match_operand:P 1 "register_operand" "=l"))
12383 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12385 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12386 (match_operand:P 4 "memory_operand" "m"))])]
12389 [(set_attr "type" "branch")
12390 (set_attr "length" "4")])
12392 (define_insn "*restore_gpregs_<mode>_r1"
12393 [(match_parallel 0 "any_parallel_operand"
12394 [(clobber (match_operand:P 1 "register_operand" "=l"))
12395 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12397 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12398 (match_operand:P 4 "memory_operand" "m"))])]
12401 [(set_attr "type" "branch")
12402 (set_attr "length" "4")])
12404 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12405 [(match_parallel 0 "any_parallel_operand"
12407 (clobber (match_operand:P 1 "register_operand" "=l"))
12408 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12410 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12411 (match_operand:P 4 "memory_operand" "m"))])]
12414 [(set_attr "type" "branch")
12415 (set_attr "length" "4")])
12417 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12418 [(match_parallel 0 "any_parallel_operand"
12420 (clobber (match_operand:P 1 "register_operand" "=l"))
12421 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12423 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12424 (match_operand:P 4 "memory_operand" "m"))])]
12427 [(set_attr "type" "branch")
12428 (set_attr "length" "4")])
12430 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12431 [(match_parallel 0 "any_parallel_operand"
12433 (clobber (match_operand:P 1 "register_operand" "=l"))
12434 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12436 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12437 (match_operand:P 4 "memory_operand" "m"))])]
12440 [(set_attr "type" "branch")
12441 (set_attr "length" "4")])
12443 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12444 [(match_parallel 0 "any_parallel_operand"
12446 (clobber (match_operand:P 1 "register_operand" "=l"))
12447 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12449 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12450 (match_operand:DF 4 "memory_operand" "m"))])]
12453 [(set_attr "type" "branch")
12454 (set_attr "length" "4")])
12456 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12457 [(match_parallel 0 "any_parallel_operand"
12459 (clobber (match_operand:P 1 "register_operand" "=l"))
12460 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12462 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12463 (match_operand:DF 4 "memory_operand" "m"))])]
12466 [(set_attr "type" "branch")
12467 (set_attr "length" "4")])
12469 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12470 [(match_parallel 0 "any_parallel_operand"
12472 (clobber (match_operand:P 1 "register_operand" "=l"))
12473 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12475 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12476 (match_operand:DF 4 "memory_operand" "m"))])]
12479 [(set_attr "type" "branch")
12480 (set_attr "length" "4")])
12482 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12483 [(match_parallel 0 "any_parallel_operand"
12485 (use (match_operand:P 1 "register_operand" "l"))
12486 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12488 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12489 (match_operand:DF 4 "memory_operand" "m"))])]
12492 [(set_attr "type" "branch")
12493 (set_attr "length" "4")])
12495 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12496 [(match_parallel 0 "any_parallel_operand"
12498 (use (match_operand:P 1 "register_operand" "l"))
12499 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12501 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12502 (match_operand:DF 4 "memory_operand" "m"))])]
12505 [(set_attr "type" "branch")
12506 (set_attr "length" "4")])
12508 ; This is used in compiling the unwind routines.
12509 (define_expand "eh_return"
12510 [(use (match_operand 0 "general_operand" ""))]
12515 emit_insn (gen_eh_set_lr_si (operands[0]));
12517 emit_insn (gen_eh_set_lr_di (operands[0]));
12521 ; We can't expand this before we know where the link register is stored.
12522 (define_insn "eh_set_lr_<mode>"
12523 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12525 (clobber (match_scratch:P 1 "=&b"))]
12530 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12531 (clobber (match_scratch 1 ""))]
12536 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12540 (define_insn "prefetch"
12541 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12542 (match_operand:SI 1 "const_int_operand" "n")
12543 (match_operand:SI 2 "const_int_operand" "n"))]
12547 if (GET_CODE (operands[0]) == REG)
12548 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12549 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12551 [(set_attr "type" "load")])
12553 ;; Handle -fsplit-stack.
12555 (define_expand "split_stack_prologue"
12559 rs6000_expand_split_stack_prologue ();
12563 (define_expand "load_split_stack_limit"
12564 [(set (match_operand 0)
12565 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12568 emit_insn (gen_rtx_SET (operands[0],
12569 gen_rtx_UNSPEC (Pmode,
12570 gen_rtvec (1, const0_rtx),
12571 UNSPEC_STACK_CHECK)));
12575 (define_insn "load_split_stack_limit_di"
12576 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12577 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12579 "ld %0,-0x7040(13)"
12580 [(set_attr "type" "load")
12581 (set_attr "update" "no")
12582 (set_attr "indexed" "no")])
12584 (define_insn "load_split_stack_limit_si"
12585 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12586 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12588 "lwz %0,-0x7020(2)"
12589 [(set_attr "type" "load")
12590 (set_attr "update" "no")
12591 (set_attr "indexed" "no")])
12593 ;; A return instruction which the middle-end doesn't see.
12594 (define_insn "split_stack_return"
12595 [(unspec_volatile [(const_int 0)] UNSPECV_SPLIT_STACK_RETURN)]
12598 [(set_attr "type" "jmpreg")])
12600 ;; If there are operand 0 bytes available on the stack, jump to
12602 (define_expand "split_stack_space_check"
12603 [(set (match_dup 2)
12604 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12606 (minus (reg STACK_POINTER_REGNUM)
12607 (match_operand 0)))
12608 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12609 (set (pc) (if_then_else
12610 (geu (match_dup 4) (const_int 0))
12611 (label_ref (match_operand 1))
12615 rs6000_split_stack_space_check (operands[0], operands[1]);
12619 (define_insn "bpermd_<mode>"
12620 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12621 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12622 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12625 [(set_attr "type" "popcnt")])
12628 ;; Builtin fma support. Handle
12629 ;; Note that the conditions for expansion are in the FMA_F iterator.
12631 (define_expand "fma<mode>4"
12632 [(set (match_operand:FMA_F 0 "register_operand" "")
12634 (match_operand:FMA_F 1 "register_operand" "")
12635 (match_operand:FMA_F 2 "register_operand" "")
12636 (match_operand:FMA_F 3 "register_operand" "")))]
12640 (define_insn "*fma<mode>4_fpr"
12641 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12643 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12644 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12645 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12646 "TARGET_<MODE>_FPR"
12648 fmadd<Ftrad> %0,%1,%2,%3
12649 xsmadda<Fvsx> %x0,%x1,%x2
12650 xsmaddm<Fvsx> %x0,%x1,%x3"
12651 [(set_attr "type" "fp")
12652 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12654 ; Altivec only has fma and nfms.
12655 (define_expand "fms<mode>4"
12656 [(set (match_operand:FMA_F 0 "register_operand" "")
12658 (match_operand:FMA_F 1 "register_operand" "")
12659 (match_operand:FMA_F 2 "register_operand" "")
12660 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12661 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12664 (define_insn "*fms<mode>4_fpr"
12665 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12667 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12668 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12669 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12670 "TARGET_<MODE>_FPR"
12672 fmsub<Ftrad> %0,%1,%2,%3
12673 xsmsuba<Fvsx> %x0,%x1,%x2
12674 xsmsubm<Fvsx> %x0,%x1,%x3"
12675 [(set_attr "type" "fp")
12676 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12678 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12679 (define_expand "fnma<mode>4"
12680 [(set (match_operand:FMA_F 0 "register_operand" "")
12683 (match_operand:FMA_F 1 "register_operand" "")
12684 (match_operand:FMA_F 2 "register_operand" "")
12685 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12686 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12689 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12690 (define_expand "fnms<mode>4"
12691 [(set (match_operand:FMA_F 0 "register_operand" "")
12694 (match_operand:FMA_F 1 "register_operand" "")
12695 (match_operand:FMA_F 2 "register_operand" "")
12696 (match_operand:FMA_F 3 "register_operand" ""))))]
12697 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12700 ; Not an official optab name, but used from builtins.
12701 (define_expand "nfma<mode>4"
12702 [(set (match_operand:FMA_F 0 "register_operand" "")
12705 (match_operand:FMA_F 1 "register_operand" "")
12706 (match_operand:FMA_F 2 "register_operand" "")
12707 (match_operand:FMA_F 3 "register_operand" ""))))]
12708 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12711 (define_insn "*nfma<mode>4_fpr"
12712 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12715 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12716 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12717 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12718 "TARGET_<MODE>_FPR"
12720 fnmadd<Ftrad> %0,%1,%2,%3
12721 xsnmadda<Fvsx> %x0,%x1,%x2
12722 xsnmaddm<Fvsx> %x0,%x1,%x3"
12723 [(set_attr "type" "fp")
12724 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12726 ; Not an official optab name, but used from builtins.
12727 (define_expand "nfms<mode>4"
12728 [(set (match_operand:FMA_F 0 "register_operand" "")
12731 (match_operand:FMA_F 1 "register_operand" "")
12732 (match_operand:FMA_F 2 "register_operand" "")
12733 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12737 (define_insn "*nfmssf4_fpr"
12738 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12741 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12742 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12744 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
12745 "TARGET_<MODE>_FPR"
12747 fnmsub<Ftrad> %0,%1,%2,%3
12748 xsnmsuba<Fvsx> %x0,%x1,%x2
12749 xsnmsubm<Fvsx> %x0,%x1,%x3"
12750 [(set_attr "type" "fp")
12751 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12754 (define_expand "rs6000_get_timebase"
12755 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
12758 if (TARGET_POWERPC64)
12759 emit_insn (gen_rs6000_mftb_di (operands[0]));
12761 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
12765 (define_insn "rs6000_get_timebase_ppc32"
12766 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12767 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
12768 (clobber (match_scratch:SI 1 "=r"))
12769 (clobber (match_scratch:CC 2 "=y"))]
12770 "!TARGET_POWERPC64"
12772 if (WORDS_BIG_ENDIAN)
12775 return "mfspr %0,269\;"
12783 return "mftbu %0\;"
12792 return "mfspr %L0,269\;"
12800 return "mftbu %L0\;"
12807 [(set_attr "length" "20")])
12809 (define_insn "rs6000_mftb_<mode>"
12810 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12811 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
12815 return "mfspr %0,268";
12821 (define_insn "rs6000_mffs"
12822 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
12823 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
12824 "TARGET_HARD_FLOAT && TARGET_FPRS"
12827 (define_insn "rs6000_mtfsf"
12828 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
12829 (match_operand:DF 1 "gpc_reg_operand" "d")]
12831 "TARGET_HARD_FLOAT && TARGET_FPRS"
12835 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
12836 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
12837 ;; register that is being loaded. The fused ops must be physically adjacent.
12839 ;; There are two parts to addis fusion. The support for fused TOCs occur
12840 ;; before register allocation, and is meant to reduce the lifetime for the
12841 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
12842 ;; to use the register that is being load. The peephole2 then gathers any
12843 ;; other fused possibilities that it can find after register allocation. If
12844 ;; power9 fusion is selected, we also fuse floating point loads/stores.
12846 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
12847 ;; before register allocation, so that we can avoid allocating a temporary base
12848 ;; register that won't be used, and that we try to load into base registers,
12849 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
12850 ;; (addis followed by load) even on power8.
12853 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
12854 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
12855 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
12856 [(parallel [(set (match_dup 0) (match_dup 2))
12857 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12858 (use (match_dup 3))
12859 (clobber (scratch:DI))])]
12861 operands[2] = fusion_wrap_memory_address (operands[1]);
12862 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
12865 (define_insn "*toc_fusionload_<mode>"
12866 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
12867 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
12868 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12869 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
12870 (clobber (match_scratch:DI 3 "=X,&b"))]
12871 "TARGET_TOC_FUSION_INT"
12873 if (base_reg_operand (operands[0], <MODE>mode))
12874 return emit_fusion_gpr_load (operands[0], operands[1]);
12876 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
12878 [(set_attr "type" "load")
12879 (set_attr "length" "8")])
12881 (define_insn "*toc_fusionload_di"
12882 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
12883 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
12884 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12885 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
12886 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
12887 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
12888 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
12890 if (base_reg_operand (operands[0], DImode))
12891 return emit_fusion_gpr_load (operands[0], operands[1]);
12893 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
12895 [(set_attr "type" "load")
12896 (set_attr "length" "8")])
12899 ;; Find cases where the addis that feeds into a load instruction is either used
12900 ;; once or is the same as the target register, and replace it with the fusion
12904 [(set (match_operand:P 0 "base_reg_operand" "")
12905 (match_operand:P 1 "fusion_gpr_addis" ""))
12906 (set (match_operand:INT1 2 "base_reg_operand" "")
12907 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
12909 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
12913 expand_fusion_gpr_load (operands);
12917 ;; Fusion insn, created by the define_peephole2 above (and eventually by
12920 (define_insn "fusion_gpr_load_<mode>"
12921 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
12922 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
12923 UNSPEC_FUSION_GPR))]
12926 return emit_fusion_gpr_load (operands[0], operands[1]);
12928 [(set_attr "type" "load")
12929 (set_attr "length" "8")])
12932 ;; ISA 3.0 (power9) fusion support
12933 ;; Merge addis with floating load/store to FPRs (or GPRs).
12935 [(set (match_operand:P 0 "base_reg_operand" "")
12936 (match_operand:P 1 "fusion_gpr_addis" ""))
12937 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
12938 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
12939 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
12940 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
12943 expand_fusion_p9_load (operands);
12948 [(set (match_operand:P 0 "base_reg_operand" "")
12949 (match_operand:P 1 "fusion_gpr_addis" ""))
12950 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
12951 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
12952 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
12953 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
12956 expand_fusion_p9_store (operands);
12961 [(set (match_operand:SDI 0 "int_reg_operand" "")
12962 (match_operand:SDI 1 "upper16_cint_operand" ""))
12964 (ior:SDI (match_dup 0)
12965 (match_operand:SDI 2 "u_short_cint_operand" "")))]
12967 [(set (match_dup 0)
12968 (unspec:SDI [(match_dup 1)
12969 (match_dup 2)] UNSPEC_FUSION_P9))])
12972 [(set (match_operand:SDI 0 "int_reg_operand" "")
12973 (match_operand:SDI 1 "upper16_cint_operand" ""))
12974 (set (match_operand:SDI 2 "int_reg_operand" "")
12975 (ior:SDI (match_dup 0)
12976 (match_operand:SDI 3 "u_short_cint_operand" "")))]
12978 && !rtx_equal_p (operands[0], operands[2])
12979 && peep2_reg_dead_p (2, operands[0])"
12980 [(set (match_dup 2)
12981 (unspec:SDI [(match_dup 1)
12982 (match_dup 3)] UNSPEC_FUSION_P9))])
12984 ;; Fusion insns, created by the define_peephole2 above (and eventually by
12985 ;; reload). Because we want to eventually have secondary_reload generate
12986 ;; these, they have to have a single alternative that gives the register
12987 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
12988 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
12989 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
12991 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
12993 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
12996 /* This insn is a secondary reload insn, which cannot have alternatives.
12997 If we are not loading up register 0, use the power8 fusion instead. */
12998 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
12999 return emit_fusion_gpr_load (operands[0], operands[1]);
13001 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13003 [(set_attr "type" "load")
13004 (set_attr "length" "8")])
13006 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13007 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13009 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13011 (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
13014 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13016 [(set_attr "type" "store")
13017 (set_attr "length" "8")])
13019 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
13020 [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
13022 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13024 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13027 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13029 [(set_attr "type" "fpload")
13030 (set_attr "length" "8")])
13032 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
13033 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13035 [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
13037 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13040 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13042 [(set_attr "type" "fpstore")
13043 (set_attr "length" "8")])
13045 (define_insn "*fusion_p9_<mode>_constant"
13046 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13047 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13048 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13049 UNSPEC_FUSION_P9))]
13052 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13053 return "ori %0,%0,%2";
13055 [(set_attr "type" "two")
13056 (set_attr "length" "8")])
13059 ;; Miscellaneous ISA 2.06 (power7) instructions
13060 (define_insn "addg6s"
13061 [(set (match_operand:SI 0 "register_operand" "=r")
13062 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13063 (match_operand:SI 2 "register_operand" "r")]
13067 [(set_attr "type" "integer")
13068 (set_attr "length" "4")])
13070 (define_insn "cdtbcd"
13071 [(set (match_operand:SI 0 "register_operand" "=r")
13072 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13076 [(set_attr "type" "integer")
13077 (set_attr "length" "4")])
13079 (define_insn "cbcdtd"
13080 [(set (match_operand:SI 0 "register_operand" "=r")
13081 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13085 [(set_attr "type" "integer")
13086 (set_attr "length" "4")])
13088 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13093 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13094 (UNSPEC_DIVEO "eo")
13095 (UNSPEC_DIVEU "eu")
13096 (UNSPEC_DIVEUO "euo")])
13098 (define_insn "div<div_extend>_<mode>"
13099 [(set (match_operand:GPR 0 "register_operand" "=r")
13100 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13101 (match_operand:GPR 2 "register_operand" "r")]
13102 UNSPEC_DIV_EXTEND))]
13104 "div<wd><div_extend> %0,%1,%2"
13105 [(set_attr "type" "div")
13106 (set_attr "size" "<bits>")])
13109 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13111 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13112 (define_mode_attr FP128_64 [(TF "DF")
13117 (define_expand "unpack<mode>"
13118 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13120 [(match_operand:FMOVE128 1 "register_operand" "")
13121 (match_operand:QI 2 "const_0_to_1_operand" "")]
13122 UNSPEC_UNPACK_128BIT))]
13123 "FLOAT128_2REG_P (<MODE>mode)"
13126 (define_insn_and_split "unpack<mode>_dm"
13127 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13129 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13130 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13131 UNSPEC_UNPACK_128BIT))]
13132 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13134 "&& reload_completed"
13135 [(set (match_dup 0) (match_dup 3))]
13137 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13139 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13141 emit_note (NOTE_INSN_DELETED);
13145 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13147 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13148 (set_attr "length" "4")])
13150 (define_insn_and_split "unpack<mode>_nodm"
13151 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13153 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13154 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13155 UNSPEC_UNPACK_128BIT))]
13156 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13158 "&& reload_completed"
13159 [(set (match_dup 0) (match_dup 3))]
13161 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13163 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13165 emit_note (NOTE_INSN_DELETED);
13169 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13171 [(set_attr "type" "fp,fpstore")
13172 (set_attr "length" "4")])
13174 (define_insn_and_split "pack<mode>"
13175 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13177 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13178 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13179 UNSPEC_PACK_128BIT))]
13180 "FLOAT128_2REG_P (<MODE>mode)"
13184 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13185 [(set (match_dup 3) (match_dup 1))
13186 (set (match_dup 4) (match_dup 2))]
13188 unsigned dest_hi = REGNO (operands[0]);
13189 unsigned dest_lo = dest_hi + 1;
13191 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13192 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13194 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13195 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13197 [(set_attr "type" "fp,fp")
13198 (set_attr "length" "4,8")])
13200 (define_insn "unpack<mode>"
13201 [(set (match_operand:DI 0 "register_operand" "=d,d")
13202 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13203 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13204 UNSPEC_UNPACK_128BIT))]
13205 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13207 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13208 return ASM_COMMENT_START " xxpermdi to same register";
13210 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13211 return "xxpermdi %x0,%x1,%x1,%3";
13213 [(set_attr "type" "vecperm")])
13215 (define_insn "pack<mode>"
13216 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13217 (unspec:FMOVE128_VSX
13218 [(match_operand:DI 1 "register_operand" "d")
13219 (match_operand:DI 2 "register_operand" "d")]
13220 UNSPEC_PACK_128BIT))]
13222 "xxpermdi %x0,%x1,%x2,0"
13223 [(set_attr "type" "vecperm")])
13227 ;; ISA 2.08 IEEE 128-bit floating point support.
13229 (define_insn "add<mode>3"
13230 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13232 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13233 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13234 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13236 [(set_attr "type" "vecfloat")])
13238 (define_insn "sub<mode>3"
13239 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13241 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13242 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13243 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13245 [(set_attr "type" "vecfloat")])
13247 (define_insn "mul<mode>3"
13248 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13250 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13251 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13252 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13254 [(set_attr "type" "vecfloat")])
13256 (define_insn "div<mode>3"
13257 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13259 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13260 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13261 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13263 [(set_attr "type" "vecdiv")])
13265 (define_insn "sqrt<mode>2"
13266 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13268 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13269 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13271 [(set_attr "type" "vecdiv")])
13273 (define_insn "copysign<mode>3"
13274 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13276 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13277 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13279 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13280 "xscpsgnqp %0,%2,%1"
13281 [(set_attr "type" "vecsimple")])
13283 (define_insn "neg<mode>2_hw"
13284 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13286 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13287 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13289 [(set_attr "type" "vecfloat")])
13292 (define_insn "abs<mode>2_hw"
13293 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13295 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13296 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13298 [(set_attr "type" "vecfloat")])
13301 (define_insn "*nabs<mode>2_hw"
13302 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13305 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13306 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13308 [(set_attr "type" "vecfloat")])
13310 ;; Initially don't worry about doing fusion
13311 (define_insn "*fma<mode>4_hw"
13312 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13314 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13315 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13316 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13317 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13318 "xsmaddqp %0,%1,%2"
13319 [(set_attr "type" "vecfloat")])
13321 (define_insn "*fms<mode>4_hw"
13322 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13324 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13325 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13327 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13328 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13329 "xsmsubqp %0,%1,%2"
13330 [(set_attr "type" "vecfloat")])
13332 (define_insn "*nfma<mode>4_hw"
13333 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13336 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13337 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13338 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13339 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13340 "xsnmaddqp %0,%1,%2"
13341 [(set_attr "type" "vecfloat")])
13343 (define_insn "*nfms<mode>4_hw"
13344 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13347 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13348 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13350 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13351 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13352 "xsnmsubqp %0,%1,%2"
13353 [(set_attr "type" "vecfloat")])
13355 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13356 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13357 (float_extend:IEEE128
13358 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13359 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13361 [(set_attr "type" "vecfloat")])
13363 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13364 ;; point is a simple copy.
13365 (define_insn_and_split "extendkftf2"
13366 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13367 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13368 "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13372 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13375 emit_note (NOTE_INSN_DELETED);
13378 [(set_attr "type" "*,vecsimple")
13379 (set_attr "length" "0,4")])
13381 (define_insn_and_split "trunctfkf2"
13382 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13383 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13384 "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13388 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13391 emit_note (NOTE_INSN_DELETED);
13394 [(set_attr "type" "*,vecsimple")
13395 (set_attr "length" "0,4")])
13397 (define_insn "trunc<mode>df2_hw"
13398 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13400 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13401 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13403 [(set_attr "type" "vecfloat")])
13405 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13406 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13408 (define_insn_and_split "trunc<mode>sf2_hw"
13409 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13411 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13412 (clobber (match_scratch:DF 2 "=v"))]
13413 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13416 [(set (match_dup 2)
13417 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13419 (float_truncate:SF (match_dup 2)))]
13421 if (GET_CODE (operands[2]) == SCRATCH)
13422 operands[2] = gen_reg_rtx (DFmode);
13424 [(set_attr "type" "vecfloat")
13425 (set_attr "length" "8")])
13427 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13428 ;; allowed in the traditional floating point registers. Use V2DImode so that
13429 ;; we can get a value in an Altivec register.
13431 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13432 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13433 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13434 (clobber (match_scratch:V2DI 2 "=v,v"))]
13435 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13440 convert_float128_to_int (operands, <CODE>);
13443 [(set_attr "length" "8")
13444 (set_attr "type" "mftgpr,fpstore")])
13446 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13447 [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13448 (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13449 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13450 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13455 convert_float128_to_int (operands, <CODE>);
13458 [(set_attr "length" "8")
13459 (set_attr "type" "mftgpr,vecsimple,fpstore")])
13461 (define_insn_and_split "float<uns>_<mode>si2_hw"
13462 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13463 (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13464 (clobber (match_scratch:V2DI 2 "=v,v"))]
13465 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13470 convert_int_to_float128 (operands, <CODE>);
13473 [(set_attr "length" "8")
13474 (set_attr "type" "vecfloat")])
13476 (define_insn_and_split "float<uns>_<mode>di2_hw"
13477 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13478 (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13479 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13480 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13485 convert_int_to_float128 (operands, <CODE>);
13488 [(set_attr "length" "8")
13489 (set_attr "type" "vecfloat")])
13491 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13492 (define_insn "*xscvqp<su>wz_<mode>"
13493 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13496 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13497 UNSPEC_IEEE128_CONVERT))]
13498 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13499 "xscvqp<su>wz %0,%1"
13500 [(set_attr "type" "vecfloat")])
13502 (define_insn "*xscvqp<su>dz_<mode>"
13503 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13506 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13507 UNSPEC_IEEE128_CONVERT))]
13508 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13509 "xscvqp<su>dz %0,%1"
13510 [(set_attr "type" "vecfloat")])
13512 (define_insn "*xscv<su>dqp_<mode>"
13513 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13515 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13516 UNSPEC_IEEE128_CONVERT)))]
13517 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13518 "xscv<su>dqp %0,%1"
13519 [(set_attr "type" "vecfloat")])
13521 (define_insn "*ieee128_mfvsrd_64bit"
13522 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13523 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13524 UNSPEC_IEEE128_MOVE))]
13525 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13530 [(set_attr "type" "mftgpr,fpstore,vecsimple")])
13533 (define_insn "*ieee128_mfvsrd_32bit"
13534 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13535 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13536 UNSPEC_IEEE128_MOVE))]
13537 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13541 [(set_attr "type" "fpstore,vecsimple")])
13543 (define_insn "*ieee128_mfvsrwz"
13544 [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13545 (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13546 UNSPEC_IEEE128_MOVE))]
13547 "TARGET_FLOAT128_HW"
13551 [(set_attr "type" "mftgpr,fpstore")])
13553 ;; 0 says do sign-extension, 1 says zero-extension
13554 (define_insn "*ieee128_mtvsrw"
13555 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13556 (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13557 (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13558 UNSPEC_IEEE128_MOVE))]
13559 "TARGET_FLOAT128_HW"
13565 [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13568 (define_insn "*ieee128_mtvsrd_64bit"
13569 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13570 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13571 UNSPEC_IEEE128_MOVE))]
13572 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13577 [(set_attr "type" "mffgpr,fpload,vecsimple")])
13579 (define_insn "*ieee128_mtvsrd_32bit"
13580 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
13581 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
13582 UNSPEC_IEEE128_MOVE))]
13583 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13587 [(set_attr "type" "fpload,vecsimple")])
13589 ;; IEEE 128-bit instructions with round to odd semantics
13590 (define_insn "*trunc<mode>df2_odd"
13591 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13592 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13593 UNSPEC_ROUND_TO_ODD))]
13594 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13596 [(set_attr "type" "vecfloat")])
13598 ;; IEEE 128-bit comparisons
13599 (define_insn "*cmp<mode>_hw"
13600 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13601 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13602 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13603 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13604 "xscmpuqp %0,%1,%2"
13605 [(set_attr "type" "fpcompare")])
13609 (include "sync.md")
13610 (include "vector.md")
13612 (include "altivec.md")
13615 (include "paired.md")
13616 (include "crypto.md")