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
154 ;; UNSPEC_VOLATILE usage
157 (define_c_enum "unspecv"
159 UNSPECV_LL ; load-locked
160 UNSPECV_SC ; store-conditional
161 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
162 UNSPECV_EH_RR ; eh_reg_restore
163 UNSPECV_ISYNC ; isync instruction
164 UNSPECV_MFTB ; move from time base
165 UNSPECV_NLGR ; non-local goto receiver
166 UNSPECV_MFFS ; Move from FPSCR
167 UNSPECV_MTFSF ; Move to FPSCR Fields
168 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
172 ;; Define an insn type attribute. This is used in function unit delay
176 add,logical,shift,insert,
178 exts,cntlz,popcnt,isel,
179 load,store,fpload,fpstore,vecload,vecstore,
181 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
182 cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
183 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
185 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
186 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
187 veclogical,veccmpfx,vecexts,vecmove,
189 (const_string "integer"))
191 ;; What data size does this instruction work on?
192 ;; This is used for insert, mul and others as necessary.
193 (define_attr "size" "8,16,32,64,128" (const_string "32"))
195 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
196 ;; This is used for add, logical, shift, exts, mul.
197 (define_attr "dot" "no,yes" (const_string "no"))
199 ;; Does this instruction sign-extend its result?
200 ;; This is used for load insns.
201 (define_attr "sign_extend" "no,yes" (const_string "no"))
203 ;; Does this instruction use indexed (that is, reg+reg) addressing?
204 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
205 ;; it is automatically set based on that. If a load or store instruction
206 ;; has fewer than two operands it needs to set this attribute manually
207 ;; or the compiler will crash.
208 (define_attr "indexed" "no,yes"
209 (if_then_else (ior (match_operand 0 "indexed_address_mem")
210 (match_operand 1 "indexed_address_mem"))
212 (const_string "no")))
214 ;; Does this instruction use update addressing?
215 ;; This is used for load and store insns. See the comments for "indexed".
216 (define_attr "update" "no,yes"
217 (if_then_else (ior (match_operand 0 "update_address_mem")
218 (match_operand 1 "update_address_mem"))
220 (const_string "no")))
222 ;; Is this instruction using operands[2] as shift amount, and can that be a
224 ;; This is used for shift insns.
225 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
227 ;; Is this instruction using a shift amount from a register?
228 ;; This is used for shift insns.
229 (define_attr "var_shift" "no,yes"
230 (if_then_else (and (eq_attr "type" "shift")
231 (eq_attr "maybe_var_shift" "yes"))
232 (if_then_else (match_operand 2 "gpc_reg_operand")
235 (const_string "no")))
237 ;; Is copying of this instruction disallowed?
238 (define_attr "cannot_copy" "no,yes" (const_string "no"))
240 ;; Define floating point instruction sub-types for use with Xfpu.md
241 (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"))
243 ;; Length (in bytes).
244 ; '(pc)' in the following doesn't include the instruction itself; it is
245 ; calculated as if the instruction had zero size.
246 (define_attr "length" ""
247 (if_then_else (eq_attr "type" "branch")
248 (if_then_else (and (ge (minus (match_dup 0) (pc))
250 (lt (minus (match_dup 0) (pc))
256 ;; Processor type -- this attribute must exactly match the processor_type
257 ;; enumeration in rs6000-opts.h.
259 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
260 ppc750,ppc7400,ppc7450,
261 ppc403,ppc405,ppc440,ppc476,
262 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
263 power4,power5,power6,power7,power8,power9,
264 rs64a,mpccore,cell,ppca2,titan"
265 (const (symbol_ref "rs6000_cpu_attr")))
268 ;; If this instruction is microcoded on the CELL processor
269 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
270 (define_attr "cell_micro" "not,conditional,always"
271 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
272 (eq_attr "dot" "yes"))
273 (and (eq_attr "type" "load")
274 (eq_attr "sign_extend" "yes"))
275 (and (eq_attr "type" "shift")
276 (eq_attr "var_shift" "yes")))
277 (const_string "always")
278 (const_string "not")))
280 (automata_option "ndfa")
293 (include "e300c2c3.md")
294 (include "e500mc.md")
295 (include "e500mc64.md")
298 (include "power4.md")
299 (include "power5.md")
300 (include "power6.md")
301 (include "power7.md")
302 (include "power8.md")
303 (include "power9.md")
309 (include "predicates.md")
310 (include "constraints.md")
312 (include "darwin.md")
317 ; This mode iterator allows :GPR to be used to indicate the allowable size
318 ; of whole values in GPRs.
319 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
321 ; Any supported integer mode.
322 (define_mode_iterator INT [QI HI SI DI TI PTI])
324 ; Any supported integer mode that fits in one register.
325 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
327 ; Everything we can extend QImode to.
328 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
330 ; Everything we can extend HImode to.
331 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
333 ; Everything we can extend SImode to.
334 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
336 ; QImode or HImode for small atomic ops
337 (define_mode_iterator QHI [QI HI])
339 ; QImode, HImode, SImode for fused ops only for GPR loads
340 (define_mode_iterator QHSI [QI HI SI])
342 ; HImode or SImode for sign extended fusion ops
343 (define_mode_iterator HSI [HI SI])
345 ; SImode or DImode, even if DImode doesn't fit in GPRs.
346 (define_mode_iterator SDI [SI DI])
348 ; Types that can be fused with an ADDIS instruction to load or store a GPR
349 ; register that has reg+offset addressing.
350 (define_mode_iterator GPR_FUSION [QI
353 (DI "TARGET_POWERPC64")
355 (DF "TARGET_POWERPC64")])
357 ; Types that can be fused with an ADDIS instruction to load or store a FPR
358 ; register that has reg+offset addressing.
359 (define_mode_iterator FPR_FUSION [DI SF DF])
361 ; The size of a pointer. Also, the size of the value that a record-condition
362 ; (one with a '.') will compare; and the size used for arithmetic carries.
363 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
365 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
366 ; PTImode is GPR only)
367 (define_mode_iterator TI2 [TI PTI])
369 ; Any hardware-supported floating-point mode
370 (define_mode_iterator FP [
371 (SF "TARGET_HARD_FLOAT
372 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
373 (DF "TARGET_HARD_FLOAT
374 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
375 (TF "TARGET_HARD_FLOAT
376 && (TARGET_FPRS || TARGET_E500_DOUBLE)
377 && TARGET_LONG_DOUBLE_128")
378 (IF "TARGET_FLOAT128")
379 (KF "TARGET_FLOAT128")
383 ; Any fma capable floating-point mode.
384 (define_mode_iterator FMA_F [
385 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
386 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
387 || VECTOR_UNIT_VSX_P (DFmode)")
388 (V2SF "TARGET_PAIRED_FLOAT")
389 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
390 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
391 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
392 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
395 ; Floating point move iterators to combine binary and decimal moves
396 (define_mode_iterator FMOVE32 [SF SD])
397 (define_mode_iterator FMOVE64 [DF DD])
398 (define_mode_iterator FMOVE64X [DI DF DD])
399 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
400 (IF "TARGET_LONG_DOUBLE_128")
401 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
403 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
404 (IF "FLOAT128_2REG_P (IFmode)")
405 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
407 ; Iterators for 128 bit types for direct move
408 (define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE")
416 (KF "FLOAT128_VECTOR_P (KFmode)")
417 (TF "FLOAT128_VECTOR_P (TFmode)")])
419 ; Iterator for 128-bit VSX types for pack/unpack
420 (define_mode_iterator FMOVE128_VSX [V1TI KF])
422 ; Whether a floating point move is ok, don't allow SD without hardware FP
423 (define_mode_attr fmove_ok [(SF "")
425 (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
428 ; Convert REAL_VALUE to the appropriate bits
429 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
430 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
431 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
432 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
434 ; Whether 0.0 has an all-zero bit pattern
435 (define_mode_attr zero_fp [(SF "j")
444 ; Definitions for load to 32-bit fpr register
445 (define_mode_attr f32_lr [(SF "f") (SD "wz")])
446 (define_mode_attr f32_lr2 [(SF "wb") (SD "wn")])
447 (define_mode_attr f32_lm [(SF "m") (SD "Z")])
448 (define_mode_attr f32_lm2 [(SF "o") (SD "wn")])
449 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
450 (define_mode_attr f32_li2 [(SF "lxssp %0,%1") (SD "lfiwzx %0,%y1")])
451 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
453 ; Definitions for store from 32-bit fpr register
454 (define_mode_attr f32_sr [(SF "f") (SD "wx")])
455 (define_mode_attr f32_sr2 [(SF "wb") (SD "wn")])
456 (define_mode_attr f32_sm [(SF "m") (SD "Z")])
457 (define_mode_attr f32_sm2 [(SF "o") (SD "wn")])
458 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
459 (define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")])
460 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")])
462 ; Definitions for 32-bit fpr direct move
463 ; At present, the decimal modes are not allowed in the traditional altivec
464 ; registers, so restrict the constraints to just the traditional FPRs.
465 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
467 ; Definitions for 32-bit VSX
468 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
470 ; Definitions for 32-bit use of altivec registers
471 (define_mode_attr f32_av [(SF "wu") (SD "wn")])
473 ; Definitions for 64-bit VSX
474 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
476 ; Definitions for 64-bit direct move
477 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
479 ; Definitions for 64-bit use of altivec registers
480 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
482 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
483 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
485 ; These modes do not fit in integer registers in 32-bit mode.
486 ; but on e500v2, the gpr are 64 bit registers
487 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
489 ; Iterator for reciprocal estimate instructions
490 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
492 ; Iterator for just SF/DF
493 (define_mode_iterator SFDF [SF DF])
495 ; Like SFDF, but a different name to match conditional move where the
496 ; comparison operands may be a different mode than the input operands.
497 (define_mode_iterator SFDF2 [SF DF])
499 ; Iterator for 128-bit floating point that uses the IBM double-double format
500 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
501 (TF "FLOAT128_IBM_P (TFmode)")])
503 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
504 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
505 (TF "FLOAT128_IEEE_P (TFmode)")])
507 ; Iterator for 128-bit floating point
508 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128")
509 (IF "TARGET_FLOAT128")
510 (TF "TARGET_LONG_DOUBLE_128")])
512 ; Iterator for signbit on 64-bit machines with direct move
513 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
514 (TF "FLOAT128_VECTOR_P (TFmode)")])
516 (define_mode_attr Fsignbit [(KF "wa")
519 ; Iterator for ISA 3.0 supported floating point types
520 (define_mode_iterator FP_ISA3 [SF
522 (KF "FLOAT128_IEEE_P (KFmode)")
523 (TF "FLOAT128_IEEE_P (TFmode)")])
525 ; SF/DF suffix for traditional floating instructions
526 (define_mode_attr Ftrad [(SF "s") (DF "")])
528 ; SF/DF suffix for VSX instructions
529 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
531 ; SF/DF constraint for arithmetic on traditional floating point registers
532 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
534 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
535 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
536 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
538 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
540 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
541 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
542 ; instructions added in ISA 2.07 (power8)
543 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
545 ; SF/DF constraint for arithmetic on altivec registers
546 (define_mode_attr Fa [(SF "wu") (DF "wv")])
548 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
549 (define_mode_attr Fs [(SF "s") (DF "d")])
552 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
553 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
555 ; Conditional returns.
556 (define_code_iterator any_return [return simple_return])
557 (define_code_attr return_pred [(return "direct_return ()")
558 (simple_return "1")])
559 (define_code_attr return_str [(return "") (simple_return "simple_")])
562 (define_code_iterator iorxor [ior xor])
564 ; Signed/unsigned variants of ops.
565 (define_code_iterator any_extend [sign_extend zero_extend])
566 (define_code_iterator any_fix [fix unsigned_fix])
567 (define_code_iterator any_float [float unsigned_float])
569 (define_code_attr u [(sign_extend "")
572 (define_code_attr su [(sign_extend "s")
577 (unsigned_float "u")])
579 (define_code_attr az [(sign_extend "a")
584 (unsigned_float "z")])
586 (define_code_attr uns [(fix "")
589 (unsigned_float "uns")])
591 ; Various instructions that come in SI and DI forms.
592 ; A generic w/d attribute, for things like cmpw/cmpd.
593 (define_mode_attr wd [(QI "b")
604 ;; How many bits in this mode?
605 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
608 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
610 ;; ISEL/ISEL64 target selection
611 (define_mode_attr sel [(SI "") (DI "64")])
613 ;; Bitmask for shift instructions
614 (define_mode_attr hH [(SI "h") (DI "H")])
616 ;; A mode twice the size of the given mode
617 (define_mode_attr dmode [(SI "di") (DI "ti")])
618 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
620 ;; Suffix for reload patterns
621 (define_mode_attr ptrsize [(SI "32bit")
624 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
625 (DI "TARGET_64BIT")])
627 (define_mode_attr mptrsize [(SI "si")
630 (define_mode_attr ptrload [(SI "lwz")
633 (define_mode_attr ptrm [(SI "m")
636 (define_mode_attr rreg [(SF "f")
643 (define_mode_attr rreg2 [(SF "f")
646 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
647 (DF "TARGET_FCFID")])
649 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
650 (DF "TARGET_E500_DOUBLE")])
652 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
653 (DF "TARGET_DOUBLE_FLOAT")])
655 ;; Mode iterator for logical operations on 128-bit types
656 (define_mode_iterator BOOL_128 [TI
658 (V16QI "TARGET_ALTIVEC")
659 (V8HI "TARGET_ALTIVEC")
660 (V4SI "TARGET_ALTIVEC")
661 (V4SF "TARGET_ALTIVEC")
662 (V2DI "TARGET_ALTIVEC")
663 (V2DF "TARGET_ALTIVEC")
664 (V1TI "TARGET_ALTIVEC")])
666 ;; For the GPRs we use 3 constraints for register outputs, two that are the
667 ;; same as the output register, and a third where the output register is an
668 ;; early clobber, so we don't have to deal with register overlaps. For the
669 ;; vector types, we prefer to use the vector registers. For TI mode, allow
672 ;; Mode attribute for boolean operation register constraints for output
673 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
675 (V16QI "wa,v,&?r,?r,?r")
676 (V8HI "wa,v,&?r,?r,?r")
677 (V4SI "wa,v,&?r,?r,?r")
678 (V4SF "wa,v,&?r,?r,?r")
679 (V2DI "wa,v,&?r,?r,?r")
680 (V2DF "wa,v,&?r,?r,?r")
681 (V1TI "wa,v,&?r,?r,?r")])
683 ;; Mode attribute for boolean operation register constraints for operand1
684 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
692 (V1TI "wa,v,r,0,r")])
694 ;; Mode attribute for boolean operation register constraints for operand2
695 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
703 (V1TI "wa,v,r,r,0")])
705 ;; Mode attribute for boolean operation register constraints for operand1
706 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
707 ;; is used for operand1 or operand2
708 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
716 (V1TI "wa,v,r,0,0")])
718 ;; Reload iterator for creating the function to allocate a base register to
719 ;; supplement addressing modes.
720 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
721 SF SD SI DF DD DI TI PTI KF IF TF])
723 ;; Iterate over smin, smax
724 (define_code_iterator fp_minmax [smin smax])
726 (define_code_attr minmax [(smin "min")
729 (define_code_attr SMINMAX [(smin "SMIN")
733 ;; Start with fixed-point load and store insns. Here we put only the more
734 ;; complex forms. Basic data transfer is done later.
736 (define_insn "zero_extendqi<mode>2"
737 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
738 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
743 [(set_attr "type" "load,shift")])
745 (define_insn_and_split "*zero_extendqi<mode>2_dot"
746 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
747 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
749 (clobber (match_scratch:EXTQI 0 "=r,r"))]
750 "rs6000_gen_cell_microcode"
754 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
756 (zero_extend:EXTQI (match_dup 1)))
758 (compare:CC (match_dup 0)
761 [(set_attr "type" "logical")
762 (set_attr "dot" "yes")
763 (set_attr "length" "4,8")])
765 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
766 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
767 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
769 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
770 (zero_extend:EXTQI (match_dup 1)))]
771 "rs6000_gen_cell_microcode"
775 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
777 (zero_extend:EXTQI (match_dup 1)))
779 (compare:CC (match_dup 0)
782 [(set_attr "type" "logical")
783 (set_attr "dot" "yes")
784 (set_attr "length" "4,8")])
787 (define_insn "zero_extendhi<mode>2"
788 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
789 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
793 rlwinm %0,%1,0,0xffff"
794 [(set_attr "type" "load,shift")])
796 (define_insn_and_split "*zero_extendhi<mode>2_dot"
797 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
798 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
800 (clobber (match_scratch:EXTHI 0 "=r,r"))]
801 "rs6000_gen_cell_microcode"
805 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
807 (zero_extend:EXTHI (match_dup 1)))
809 (compare:CC (match_dup 0)
812 [(set_attr "type" "logical")
813 (set_attr "dot" "yes")
814 (set_attr "length" "4,8")])
816 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
817 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
818 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
820 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
821 (zero_extend:EXTHI (match_dup 1)))]
822 "rs6000_gen_cell_microcode"
826 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
828 (zero_extend:EXTHI (match_dup 1)))
830 (compare:CC (match_dup 0)
833 [(set_attr "type" "logical")
834 (set_attr "dot" "yes")
835 (set_attr "length" "4,8")])
838 (define_insn "zero_extendsi<mode>2"
839 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
840 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
848 [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
850 (define_insn_and_split "*zero_extendsi<mode>2_dot"
851 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
852 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
854 (clobber (match_scratch:EXTSI 0 "=r,r"))]
855 "rs6000_gen_cell_microcode"
859 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
861 (zero_extend:DI (match_dup 1)))
863 (compare:CC (match_dup 0)
866 [(set_attr "type" "shift")
867 (set_attr "dot" "yes")
868 (set_attr "length" "4,8")])
870 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
871 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
872 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
874 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
875 (zero_extend:EXTSI (match_dup 1)))]
876 "rs6000_gen_cell_microcode"
880 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
882 (zero_extend:EXTSI (match_dup 1)))
884 (compare:CC (match_dup 0)
887 [(set_attr "type" "shift")
888 (set_attr "dot" "yes")
889 (set_attr "length" "4,8")])
892 (define_insn "extendqi<mode>2"
893 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
894 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
897 [(set_attr "type" "exts")])
899 (define_insn_and_split "*extendqi<mode>2_dot"
900 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
901 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
903 (clobber (match_scratch:EXTQI 0 "=r,r"))]
904 "rs6000_gen_cell_microcode"
908 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
910 (sign_extend:EXTQI (match_dup 1)))
912 (compare:CC (match_dup 0)
915 [(set_attr "type" "exts")
916 (set_attr "dot" "yes")
917 (set_attr "length" "4,8")])
919 (define_insn_and_split "*extendqi<mode>2_dot2"
920 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
921 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
923 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
924 (sign_extend:EXTQI (match_dup 1)))]
925 "rs6000_gen_cell_microcode"
929 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
931 (sign_extend:EXTQI (match_dup 1)))
933 (compare:CC (match_dup 0)
936 [(set_attr "type" "exts")
937 (set_attr "dot" "yes")
938 (set_attr "length" "4,8")])
941 (define_expand "extendhi<mode>2"
942 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
943 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
947 (define_insn "*extendhi<mode>2"
948 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
949 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
950 "rs6000_gen_cell_microcode"
954 [(set_attr "type" "load,exts")
955 (set_attr "sign_extend" "yes")])
957 (define_insn "*extendhi<mode>2_noload"
958 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
959 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
960 "!rs6000_gen_cell_microcode"
962 [(set_attr "type" "exts")])
964 (define_insn_and_split "*extendhi<mode>2_dot"
965 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
966 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
968 (clobber (match_scratch:EXTHI 0 "=r,r"))]
969 "rs6000_gen_cell_microcode"
973 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
975 (sign_extend:EXTHI (match_dup 1)))
977 (compare:CC (match_dup 0)
980 [(set_attr "type" "exts")
981 (set_attr "dot" "yes")
982 (set_attr "length" "4,8")])
984 (define_insn_and_split "*extendhi<mode>2_dot2"
985 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
986 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
988 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
989 (sign_extend:EXTHI (match_dup 1)))]
990 "rs6000_gen_cell_microcode"
994 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
996 (sign_extend:EXTHI (match_dup 1)))
998 (compare:CC (match_dup 0)
1001 [(set_attr "type" "exts")
1002 (set_attr "dot" "yes")
1003 (set_attr "length" "4,8")])
1006 (define_insn "extendsi<mode>2"
1007 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
1008 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
1016 [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
1017 (set_attr "sign_extend" "yes")])
1019 (define_insn_and_split "*extendsi<mode>2_dot"
1020 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1021 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1023 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1024 "rs6000_gen_cell_microcode"
1028 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1030 (sign_extend:EXTSI (match_dup 1)))
1032 (compare:CC (match_dup 0)
1035 [(set_attr "type" "exts")
1036 (set_attr "dot" "yes")
1037 (set_attr "length" "4,8")])
1039 (define_insn_and_split "*extendsi<mode>2_dot2"
1040 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1041 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1043 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1044 (sign_extend:EXTSI (match_dup 1)))]
1045 "rs6000_gen_cell_microcode"
1049 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1051 (sign_extend:EXTSI (match_dup 1)))
1053 (compare:CC (match_dup 0)
1056 [(set_attr "type" "exts")
1057 (set_attr "dot" "yes")
1058 (set_attr "length" "4,8")])
1060 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1062 (define_insn "*macchwc"
1063 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1064 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1065 (match_operand:SI 2 "gpc_reg_operand" "r")
1068 (match_operand:HI 1 "gpc_reg_operand" "r")))
1069 (match_operand:SI 4 "gpc_reg_operand" "0"))
1071 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1072 (plus:SI (mult:SI (ashiftrt:SI
1080 [(set_attr "type" "halfmul")])
1082 (define_insn "*macchw"
1083 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1084 (plus:SI (mult:SI (ashiftrt:SI
1085 (match_operand:SI 2 "gpc_reg_operand" "r")
1088 (match_operand:HI 1 "gpc_reg_operand" "r")))
1089 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1092 [(set_attr "type" "halfmul")])
1094 (define_insn "*macchwuc"
1095 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1096 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1097 (match_operand:SI 2 "gpc_reg_operand" "r")
1100 (match_operand:HI 1 "gpc_reg_operand" "r")))
1101 (match_operand:SI 4 "gpc_reg_operand" "0"))
1103 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1104 (plus:SI (mult:SI (lshiftrt:SI
1112 [(set_attr "type" "halfmul")])
1114 (define_insn "*macchwu"
1115 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1116 (plus:SI (mult:SI (lshiftrt:SI
1117 (match_operand:SI 2 "gpc_reg_operand" "r")
1120 (match_operand:HI 1 "gpc_reg_operand" "r")))
1121 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1124 [(set_attr "type" "halfmul")])
1126 (define_insn "*machhwc"
1127 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1128 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1129 (match_operand:SI 1 "gpc_reg_operand" "%r")
1132 (match_operand:SI 2 "gpc_reg_operand" "r")
1134 (match_operand:SI 4 "gpc_reg_operand" "0"))
1136 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1137 (plus:SI (mult:SI (ashiftrt:SI
1146 [(set_attr "type" "halfmul")])
1148 (define_insn "*machhw"
1149 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1150 (plus:SI (mult:SI (ashiftrt:SI
1151 (match_operand:SI 1 "gpc_reg_operand" "%r")
1154 (match_operand:SI 2 "gpc_reg_operand" "r")
1156 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1159 [(set_attr "type" "halfmul")])
1161 (define_insn "*machhwuc"
1162 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1163 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1164 (match_operand:SI 1 "gpc_reg_operand" "%r")
1167 (match_operand:SI 2 "gpc_reg_operand" "r")
1169 (match_operand:SI 4 "gpc_reg_operand" "0"))
1171 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1172 (plus:SI (mult:SI (lshiftrt:SI
1181 [(set_attr "type" "halfmul")])
1183 (define_insn "*machhwu"
1184 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1185 (plus:SI (mult:SI (lshiftrt:SI
1186 (match_operand:SI 1 "gpc_reg_operand" "%r")
1189 (match_operand:SI 2 "gpc_reg_operand" "r")
1191 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1194 [(set_attr "type" "halfmul")])
1196 (define_insn "*maclhwc"
1197 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1198 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1199 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1201 (match_operand:HI 2 "gpc_reg_operand" "r")))
1202 (match_operand:SI 4 "gpc_reg_operand" "0"))
1204 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1205 (plus:SI (mult:SI (sign_extend:SI
1212 [(set_attr "type" "halfmul")])
1214 (define_insn "*maclhw"
1215 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1216 (plus:SI (mult:SI (sign_extend:SI
1217 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1219 (match_operand:HI 2 "gpc_reg_operand" "r")))
1220 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1223 [(set_attr "type" "halfmul")])
1225 (define_insn "*maclhwuc"
1226 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1227 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1228 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1230 (match_operand:HI 2 "gpc_reg_operand" "r")))
1231 (match_operand:SI 4 "gpc_reg_operand" "0"))
1233 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1234 (plus:SI (mult:SI (zero_extend:SI
1241 [(set_attr "type" "halfmul")])
1243 (define_insn "*maclhwu"
1244 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1245 (plus:SI (mult:SI (zero_extend:SI
1246 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1248 (match_operand:HI 2 "gpc_reg_operand" "r")))
1249 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1252 [(set_attr "type" "halfmul")])
1254 (define_insn "*nmacchwc"
1255 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1256 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1257 (mult:SI (ashiftrt:SI
1258 (match_operand:SI 2 "gpc_reg_operand" "r")
1261 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1263 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1264 (minus:SI (match_dup 4)
1265 (mult:SI (ashiftrt:SI
1272 [(set_attr "type" "halfmul")])
1274 (define_insn "*nmacchw"
1275 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1276 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1277 (mult:SI (ashiftrt:SI
1278 (match_operand:SI 2 "gpc_reg_operand" "r")
1281 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1284 [(set_attr "type" "halfmul")])
1286 (define_insn "*nmachhwc"
1287 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1288 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1289 (mult:SI (ashiftrt:SI
1290 (match_operand:SI 1 "gpc_reg_operand" "%r")
1293 (match_operand:SI 2 "gpc_reg_operand" "r")
1296 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1297 (minus:SI (match_dup 4)
1298 (mult:SI (ashiftrt:SI
1306 [(set_attr "type" "halfmul")])
1308 (define_insn "*nmachhw"
1309 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1310 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1311 (mult:SI (ashiftrt:SI
1312 (match_operand:SI 1 "gpc_reg_operand" "%r")
1315 (match_operand:SI 2 "gpc_reg_operand" "r")
1319 [(set_attr "type" "halfmul")])
1321 (define_insn "*nmaclhwc"
1322 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1323 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1324 (mult:SI (sign_extend:SI
1325 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1327 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1329 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1330 (minus:SI (match_dup 4)
1331 (mult:SI (sign_extend:SI
1337 [(set_attr "type" "halfmul")])
1339 (define_insn "*nmaclhw"
1340 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1342 (mult:SI (sign_extend:SI
1343 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1345 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1348 [(set_attr "type" "halfmul")])
1350 (define_insn "*mulchwc"
1351 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1352 (compare:CC (mult:SI (ashiftrt:SI
1353 (match_operand:SI 2 "gpc_reg_operand" "r")
1356 (match_operand:HI 1 "gpc_reg_operand" "r")))
1358 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1359 (mult:SI (ashiftrt:SI
1366 [(set_attr "type" "halfmul")])
1368 (define_insn "*mulchw"
1369 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1370 (mult:SI (ashiftrt:SI
1371 (match_operand:SI 2 "gpc_reg_operand" "r")
1374 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1377 [(set_attr "type" "halfmul")])
1379 (define_insn "*mulchwuc"
1380 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1381 (compare:CC (mult:SI (lshiftrt:SI
1382 (match_operand:SI 2 "gpc_reg_operand" "r")
1385 (match_operand:HI 1 "gpc_reg_operand" "r")))
1387 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1388 (mult:SI (lshiftrt:SI
1395 [(set_attr "type" "halfmul")])
1397 (define_insn "*mulchwu"
1398 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1399 (mult:SI (lshiftrt:SI
1400 (match_operand:SI 2 "gpc_reg_operand" "r")
1403 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1406 [(set_attr "type" "halfmul")])
1408 (define_insn "*mulhhwc"
1409 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1410 (compare:CC (mult:SI (ashiftrt:SI
1411 (match_operand:SI 1 "gpc_reg_operand" "%r")
1414 (match_operand:SI 2 "gpc_reg_operand" "r")
1417 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1418 (mult:SI (ashiftrt:SI
1426 [(set_attr "type" "halfmul")])
1428 (define_insn "*mulhhw"
1429 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1430 (mult:SI (ashiftrt:SI
1431 (match_operand:SI 1 "gpc_reg_operand" "%r")
1434 (match_operand:SI 2 "gpc_reg_operand" "r")
1438 [(set_attr "type" "halfmul")])
1440 (define_insn "*mulhhwuc"
1441 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1442 (compare:CC (mult:SI (lshiftrt:SI
1443 (match_operand:SI 1 "gpc_reg_operand" "%r")
1446 (match_operand:SI 2 "gpc_reg_operand" "r")
1449 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1450 (mult:SI (lshiftrt:SI
1458 [(set_attr "type" "halfmul")])
1460 (define_insn "*mulhhwu"
1461 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1462 (mult:SI (lshiftrt:SI
1463 (match_operand:SI 1 "gpc_reg_operand" "%r")
1466 (match_operand:SI 2 "gpc_reg_operand" "r")
1470 [(set_attr "type" "halfmul")])
1472 (define_insn "*mullhwc"
1473 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1474 (compare:CC (mult:SI (sign_extend:SI
1475 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1477 (match_operand:HI 2 "gpc_reg_operand" "r")))
1479 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1480 (mult:SI (sign_extend:SI
1486 [(set_attr "type" "halfmul")])
1488 (define_insn "*mullhw"
1489 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1490 (mult:SI (sign_extend:SI
1491 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1493 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1496 [(set_attr "type" "halfmul")])
1498 (define_insn "*mullhwuc"
1499 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1500 (compare:CC (mult:SI (zero_extend:SI
1501 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1503 (match_operand:HI 2 "gpc_reg_operand" "r")))
1505 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1506 (mult:SI (zero_extend:SI
1512 [(set_attr "type" "halfmul")])
1514 (define_insn "*mullhwu"
1515 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1516 (mult:SI (zero_extend:SI
1517 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1519 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1522 [(set_attr "type" "halfmul")])
1524 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1525 (define_insn "dlmzb"
1526 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1527 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1528 (match_operand:SI 2 "gpc_reg_operand" "r")]
1530 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1531 (unspec:SI [(match_dup 1)
1537 (define_expand "strlensi"
1538 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1539 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1540 (match_operand:QI 2 "const_int_operand" "")
1541 (match_operand 3 "const_int_operand" "")]
1542 UNSPEC_DLMZB_STRLEN))
1543 (clobber (match_scratch:CC 4 "=x"))]
1544 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1546 rtx result = operands[0];
1547 rtx src = operands[1];
1548 rtx search_char = operands[2];
1549 rtx align = operands[3];
1550 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1551 rtx loop_label, end_label, mem, cr0, cond;
1552 if (search_char != const0_rtx
1553 || GET_CODE (align) != CONST_INT
1554 || INTVAL (align) < 8)
1556 word1 = gen_reg_rtx (SImode);
1557 word2 = gen_reg_rtx (SImode);
1558 scratch_dlmzb = gen_reg_rtx (SImode);
1559 scratch_string = gen_reg_rtx (Pmode);
1560 loop_label = gen_label_rtx ();
1561 end_label = gen_label_rtx ();
1562 addr = force_reg (Pmode, XEXP (src, 0));
1563 emit_move_insn (scratch_string, addr);
1564 emit_label (loop_label);
1565 mem = change_address (src, SImode, scratch_string);
1566 emit_move_insn (word1, mem);
1567 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1568 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1569 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1570 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1571 emit_jump_insn (gen_rtx_SET (pc_rtx,
1572 gen_rtx_IF_THEN_ELSE (VOIDmode,
1578 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1579 emit_jump_insn (gen_rtx_SET (pc_rtx,
1580 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1582 emit_label (end_label);
1583 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1584 emit_insn (gen_subsi3 (result, scratch_string, addr));
1585 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1589 ;; Fixed-point arithmetic insns.
1591 (define_expand "add<mode>3"
1592 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1593 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1594 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1597 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1599 rtx lo0 = gen_lowpart (SImode, operands[0]);
1600 rtx lo1 = gen_lowpart (SImode, operands[1]);
1601 rtx lo2 = gen_lowpart (SImode, operands[2]);
1602 rtx hi0 = gen_highpart (SImode, operands[0]);
1603 rtx hi1 = gen_highpart (SImode, operands[1]);
1604 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1606 if (!reg_or_short_operand (lo2, SImode))
1607 lo2 = force_reg (SImode, lo2);
1608 if (!adde_operand (hi2, SImode))
1609 hi2 = force_reg (SImode, hi2);
1611 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1612 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1616 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1618 rtx tmp = ((!can_create_pseudo_p ()
1619 || rtx_equal_p (operands[0], operands[1]))
1620 ? operands[0] : gen_reg_rtx (<MODE>mode));
1622 HOST_WIDE_INT val = INTVAL (operands[2]);
1623 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1624 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1626 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1629 /* The ordering here is important for the prolog expander.
1630 When space is allocated from the stack, adding 'low' first may
1631 produce a temporary deallocation (which would be bad). */
1632 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1633 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1638 (define_insn "*add<mode>3"
1639 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1640 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1641 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1647 [(set_attr "type" "add")])
1649 (define_insn "addsi3_high"
1650 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1651 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1652 (high:SI (match_operand 2 "" ""))))]
1653 "TARGET_MACHO && !TARGET_64BIT"
1654 "addis %0,%1,ha16(%2)"
1655 [(set_attr "type" "add")])
1657 (define_insn_and_split "*add<mode>3_dot"
1658 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1659 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1660 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1662 (clobber (match_scratch:GPR 0 "=r,r"))]
1663 "<MODE>mode == Pmode"
1667 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1669 (plus:GPR (match_dup 1)
1672 (compare:CC (match_dup 0)
1675 [(set_attr "type" "add")
1676 (set_attr "dot" "yes")
1677 (set_attr "length" "4,8")])
1679 (define_insn_and_split "*add<mode>3_dot2"
1680 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1681 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1682 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1684 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1685 (plus:GPR (match_dup 1)
1687 "<MODE>mode == Pmode"
1691 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1693 (plus:GPR (match_dup 1)
1696 (compare:CC (match_dup 0)
1699 [(set_attr "type" "add")
1700 (set_attr "dot" "yes")
1701 (set_attr "length" "4,8")])
1703 (define_insn_and_split "*add<mode>3_imm_dot"
1704 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1705 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1706 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1708 (clobber (match_scratch:GPR 0 "=r,r"))
1709 (clobber (reg:GPR CA_REGNO))]
1710 "<MODE>mode == Pmode"
1714 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1716 (plus:GPR (match_dup 1)
1719 (compare:CC (match_dup 0)
1722 [(set_attr "type" "add")
1723 (set_attr "dot" "yes")
1724 (set_attr "length" "4,8")])
1726 (define_insn_and_split "*add<mode>3_imm_dot2"
1727 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1728 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1729 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1731 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1732 (plus:GPR (match_dup 1)
1734 (clobber (reg:GPR CA_REGNO))]
1735 "<MODE>mode == Pmode"
1739 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1741 (plus:GPR (match_dup 1)
1744 (compare:CC (match_dup 0)
1747 [(set_attr "type" "add")
1748 (set_attr "dot" "yes")
1749 (set_attr "length" "4,8")])
1751 ;; Split an add that we can't do in one insn into two insns, each of which
1752 ;; does one 16-bit part. This is used by combine. Note that the low-order
1753 ;; add should be last in case the result gets used in an address.
1756 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1757 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1758 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1760 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1761 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1763 HOST_WIDE_INT val = INTVAL (operands[2]);
1764 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1765 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1767 operands[4] = GEN_INT (low);
1768 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1769 operands[3] = GEN_INT (rest);
1770 else if (can_create_pseudo_p ())
1772 operands[3] = gen_reg_rtx (DImode);
1773 emit_move_insn (operands[3], operands[2]);
1774 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1782 (define_insn "add<mode>3_carry"
1783 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1784 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1785 (match_operand:P 2 "reg_or_short_operand" "rI")))
1786 (set (reg:P CA_REGNO)
1787 (ltu:P (plus:P (match_dup 1)
1792 [(set_attr "type" "add")])
1794 (define_insn "*add<mode>3_imm_carry_pos"
1795 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1796 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1797 (match_operand:P 2 "short_cint_operand" "n")))
1798 (set (reg:P CA_REGNO)
1799 (geu:P (match_dup 1)
1800 (match_operand:P 3 "const_int_operand" "n")))]
1801 "INTVAL (operands[2]) > 0
1802 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1804 [(set_attr "type" "add")])
1806 (define_insn "*add<mode>3_imm_carry_0"
1807 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1808 (match_operand:P 1 "gpc_reg_operand" "r"))
1809 (set (reg:P CA_REGNO)
1813 [(set_attr "type" "add")])
1815 (define_insn "*add<mode>3_imm_carry_m1"
1816 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1817 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1819 (set (reg:P CA_REGNO)
1824 [(set_attr "type" "add")])
1826 (define_insn "*add<mode>3_imm_carry_neg"
1827 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1828 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1829 (match_operand:P 2 "short_cint_operand" "n")))
1830 (set (reg:P CA_REGNO)
1831 (gtu:P (match_dup 1)
1832 (match_operand:P 3 "const_int_operand" "n")))]
1833 "INTVAL (operands[2]) < 0
1834 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1836 [(set_attr "type" "add")])
1839 (define_expand "add<mode>3_carry_in"
1841 (set (match_operand:GPR 0 "gpc_reg_operand")
1842 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1843 (match_operand:GPR 2 "adde_operand"))
1844 (reg:GPR CA_REGNO)))
1845 (clobber (reg:GPR CA_REGNO))])]
1848 if (operands[2] == const0_rtx)
1850 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1853 if (operands[2] == constm1_rtx)
1855 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1860 (define_insn "*add<mode>3_carry_in_internal"
1861 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1862 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1863 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1864 (reg:GPR CA_REGNO)))
1865 (clobber (reg:GPR CA_REGNO))]
1868 [(set_attr "type" "add")])
1870 (define_insn "add<mode>3_carry_in_0"
1871 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1872 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1873 (reg:GPR CA_REGNO)))
1874 (clobber (reg:GPR CA_REGNO))]
1877 [(set_attr "type" "add")])
1879 (define_insn "add<mode>3_carry_in_m1"
1880 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1881 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1884 (clobber (reg:GPR CA_REGNO))]
1887 [(set_attr "type" "add")])
1890 (define_expand "one_cmpl<mode>2"
1891 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1892 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1895 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1897 rs6000_split_logical (operands, NOT, false, false, false);
1902 (define_insn "*one_cmpl<mode>2"
1903 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1904 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1908 (define_insn_and_split "*one_cmpl<mode>2_dot"
1909 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1910 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1912 (clobber (match_scratch:GPR 0 "=r,r"))]
1913 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1917 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1919 (not:GPR (match_dup 1)))
1921 (compare:CC (match_dup 0)
1924 [(set_attr "type" "logical")
1925 (set_attr "dot" "yes")
1926 (set_attr "length" "4,8")])
1928 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1929 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1930 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1932 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1933 (not:GPR (match_dup 1)))]
1934 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1938 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1940 (not:GPR (match_dup 1)))
1942 (compare:CC (match_dup 0)
1945 [(set_attr "type" "logical")
1946 (set_attr "dot" "yes")
1947 (set_attr "length" "4,8")])
1950 (define_expand "sub<mode>3"
1951 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1952 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1953 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1956 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1958 rtx lo0 = gen_lowpart (SImode, operands[0]);
1959 rtx lo1 = gen_lowpart (SImode, operands[1]);
1960 rtx lo2 = gen_lowpart (SImode, operands[2]);
1961 rtx hi0 = gen_highpart (SImode, operands[0]);
1962 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1963 rtx hi2 = gen_highpart (SImode, operands[2]);
1965 if (!reg_or_short_operand (lo1, SImode))
1966 lo1 = force_reg (SImode, lo1);
1967 if (!adde_operand (hi1, SImode))
1968 hi1 = force_reg (SImode, hi1);
1970 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1971 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1975 if (short_cint_operand (operands[1], <MODE>mode))
1977 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1982 (define_insn "*subf<mode>3"
1983 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1984 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1985 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1988 [(set_attr "type" "add")])
1990 (define_insn_and_split "*subf<mode>3_dot"
1991 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1992 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1993 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1995 (clobber (match_scratch:GPR 0 "=r,r"))]
1996 "<MODE>mode == Pmode"
2000 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2002 (minus:GPR (match_dup 2)
2005 (compare:CC (match_dup 0)
2008 [(set_attr "type" "add")
2009 (set_attr "dot" "yes")
2010 (set_attr "length" "4,8")])
2012 (define_insn_and_split "*subf<mode>3_dot2"
2013 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2014 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2015 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2017 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2018 (minus:GPR (match_dup 2)
2020 "<MODE>mode == Pmode"
2024 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2026 (minus:GPR (match_dup 2)
2029 (compare:CC (match_dup 0)
2032 [(set_attr "type" "add")
2033 (set_attr "dot" "yes")
2034 (set_attr "length" "4,8")])
2036 (define_insn "subf<mode>3_imm"
2037 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2038 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2039 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2040 (clobber (reg:GPR CA_REGNO))]
2043 [(set_attr "type" "add")])
2046 (define_insn "subf<mode>3_carry"
2047 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2048 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2049 (match_operand:P 1 "gpc_reg_operand" "r")))
2050 (set (reg:P CA_REGNO)
2051 (leu:P (match_dup 1)
2055 [(set_attr "type" "add")])
2057 (define_insn "*subf<mode>3_imm_carry_0"
2058 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2059 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2060 (set (reg:P CA_REGNO)
2065 [(set_attr "type" "add")])
2067 (define_insn "*subf<mode>3_imm_carry_m1"
2068 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2069 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2070 (set (reg:P CA_REGNO)
2074 [(set_attr "type" "add")])
2077 (define_expand "subf<mode>3_carry_in"
2079 (set (match_operand:GPR 0 "gpc_reg_operand")
2080 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2082 (match_operand:GPR 2 "adde_operand")))
2083 (clobber (reg:GPR CA_REGNO))])]
2086 if (operands[2] == const0_rtx)
2088 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2091 if (operands[2] == constm1_rtx)
2093 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2098 (define_insn "*subf<mode>3_carry_in_internal"
2099 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2100 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2102 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2103 (clobber (reg:GPR CA_REGNO))]
2106 [(set_attr "type" "add")])
2108 (define_insn "subf<mode>3_carry_in_0"
2109 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2110 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2111 (reg:GPR CA_REGNO)))
2112 (clobber (reg:GPR CA_REGNO))]
2115 [(set_attr "type" "add")])
2117 (define_insn "subf<mode>3_carry_in_m1"
2118 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2119 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2120 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2122 (clobber (reg:GPR CA_REGNO))]
2125 [(set_attr "type" "add")])
2127 (define_insn "subf<mode>3_carry_in_xx"
2128 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2129 (plus:GPR (reg:GPR CA_REGNO)
2131 (clobber (reg:GPR CA_REGNO))]
2134 [(set_attr "type" "add")])
2137 (define_insn "neg<mode>2"
2138 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2139 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2142 [(set_attr "type" "add")])
2144 (define_insn_and_split "*neg<mode>2_dot"
2145 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2146 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2148 (clobber (match_scratch:GPR 0 "=r,r"))]
2149 "<MODE>mode == Pmode"
2153 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2155 (neg:GPR (match_dup 1)))
2157 (compare:CC (match_dup 0)
2160 [(set_attr "type" "add")
2161 (set_attr "dot" "yes")
2162 (set_attr "length" "4,8")])
2164 (define_insn_and_split "*neg<mode>2_dot2"
2165 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2166 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2168 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2169 (neg:GPR (match_dup 1)))]
2170 "<MODE>mode == Pmode"
2174 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2176 (neg:GPR (match_dup 1)))
2178 (compare:CC (match_dup 0)
2181 [(set_attr "type" "add")
2182 (set_attr "dot" "yes")
2183 (set_attr "length" "4,8")])
2186 (define_insn "clz<mode>2"
2187 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2188 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2191 [(set_attr "type" "cntlz")])
2193 (define_expand "ctz<mode>2"
2195 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2197 (and:GPR (match_dup 1)
2200 (clz:GPR (match_dup 3)))
2201 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2202 (minus:GPR (match_dup 5)
2204 (clobber (reg:GPR CA_REGNO))])]
2209 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2213 operands[2] = gen_reg_rtx (<MODE>mode);
2214 operands[3] = gen_reg_rtx (<MODE>mode);
2215 operands[4] = gen_reg_rtx (<MODE>mode);
2216 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2219 (define_insn "ctz<mode>2_hw"
2220 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2221 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2224 [(set_attr "type" "cntlz")])
2226 (define_expand "ffs<mode>2"
2228 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2230 (and:GPR (match_dup 1)
2233 (clz:GPR (match_dup 3)))
2234 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2235 (minus:GPR (match_dup 5)
2237 (clobber (reg:GPR CA_REGNO))])]
2240 operands[2] = gen_reg_rtx (<MODE>mode);
2241 operands[3] = gen_reg_rtx (<MODE>mode);
2242 operands[4] = gen_reg_rtx (<MODE>mode);
2243 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2247 (define_expand "popcount<mode>2"
2248 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2249 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2250 "TARGET_POPCNTB || TARGET_POPCNTD"
2252 rs6000_emit_popcount (operands[0], operands[1]);
2256 (define_insn "popcntb<mode>2"
2257 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2258 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2262 [(set_attr "type" "popcnt")])
2264 (define_insn "popcntd<mode>2"
2265 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2266 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2269 [(set_attr "type" "popcnt")])
2272 (define_expand "parity<mode>2"
2273 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2274 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2277 rs6000_emit_parity (operands[0], operands[1]);
2281 (define_insn "parity<mode>2_cmpb"
2282 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2283 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2284 "TARGET_CMPB && TARGET_POPCNTB"
2286 [(set_attr "type" "popcnt")])
2289 ;; Since the hardware zeros the upper part of the register, save generating the
2290 ;; AND immediate if we are converting to unsigned
2291 (define_insn "*bswaphi2_extenddi"
2292 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2294 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2297 [(set_attr "length" "4")
2298 (set_attr "type" "load")])
2300 (define_insn "*bswaphi2_extendsi"
2301 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2303 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2306 [(set_attr "length" "4")
2307 (set_attr "type" "load")])
2309 (define_expand "bswaphi2"
2310 [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2312 (match_operand:HI 1 "reg_or_mem_operand" "")))
2313 (clobber (match_scratch:SI 2 ""))])]
2316 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2317 operands[1] = force_reg (HImode, operands[1]);
2320 (define_insn "bswaphi2_internal"
2321 [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2323 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2324 (clobber (match_scratch:SI 2 "=X,X,&r"))]
2330 [(set_attr "length" "4,4,12")
2331 (set_attr "type" "load,store,*")])
2334 [(set (match_operand:HI 0 "gpc_reg_operand" "")
2335 (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2336 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2339 (and:SI (lshiftrt:SI (match_dup 4)
2343 (and:SI (ashift:SI (match_dup 4)
2345 (const_int 65280))) ;; 0xff00
2347 (ior:SI (match_dup 3)
2351 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2352 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2355 (define_insn "*bswapsi2_extenddi"
2356 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2358 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2361 [(set_attr "length" "4")
2362 (set_attr "type" "load")])
2364 (define_expand "bswapsi2"
2365 [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2367 (match_operand:SI 1 "reg_or_mem_operand" "")))]
2370 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2371 operands[1] = force_reg (SImode, operands[1]);
2374 (define_insn "*bswapsi2_internal"
2375 [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2377 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2383 [(set_attr "length" "4,4,12")
2384 (set_attr "type" "load,store,*")])
2386 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2387 ;; zero_extract insns do not change for -mlittle.
2389 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2390 (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2392 [(set (match_dup 0) ; DABC
2393 (rotate:SI (match_dup 1)
2395 (set (match_dup 0) ; DCBC
2396 (ior:SI (and:SI (ashift:SI (match_dup 1)
2398 (const_int 16711680))
2399 (and:SI (match_dup 0)
2400 (const_int -16711681))))
2401 (set (match_dup 0) ; DCBA
2402 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2405 (and:SI (match_dup 0)
2411 (define_expand "bswapdi2"
2412 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2414 (match_operand:DI 1 "reg_or_mem_operand" "")))
2415 (clobber (match_scratch:DI 2 ""))
2416 (clobber (match_scratch:DI 3 ""))])]
2419 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2420 operands[1] = force_reg (DImode, operands[1]);
2422 if (!TARGET_POWERPC64)
2424 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2425 that uses 64-bit registers needs the same scratch registers as 64-bit
2427 emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2432 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2433 (define_insn "*bswapdi2_ldbrx"
2434 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2435 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2436 (clobber (match_scratch:DI 2 "=X,X,&r"))
2437 (clobber (match_scratch:DI 3 "=X,X,&r"))]
2438 "TARGET_POWERPC64 && TARGET_LDBRX
2439 && (REG_P (operands[0]) || REG_P (operands[1]))"
2444 [(set_attr "length" "4,4,36")
2445 (set_attr "type" "load,store,*")])
2447 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2448 (define_insn "*bswapdi2_64bit"
2449 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2450 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2451 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2452 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2453 "TARGET_POWERPC64 && !TARGET_LDBRX
2454 && (REG_P (operands[0]) || REG_P (operands[1]))
2455 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2456 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2458 [(set_attr "length" "16,12,36")])
2461 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2462 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2463 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2464 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2465 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2469 rtx dest = operands[0];
2470 rtx src = operands[1];
2471 rtx op2 = operands[2];
2472 rtx op3 = operands[3];
2473 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2474 BYTES_BIG_ENDIAN ? 4 : 0);
2475 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2476 BYTES_BIG_ENDIAN ? 4 : 0);
2482 addr1 = XEXP (src, 0);
2483 if (GET_CODE (addr1) == PLUS)
2485 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2486 if (TARGET_AVOID_XFORM)
2488 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2492 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2494 else if (TARGET_AVOID_XFORM)
2496 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2501 emit_move_insn (op2, GEN_INT (4));
2502 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2505 word1 = change_address (src, SImode, addr1);
2506 word2 = change_address (src, SImode, addr2);
2508 if (BYTES_BIG_ENDIAN)
2510 emit_insn (gen_bswapsi2 (op3_32, word2));
2511 emit_insn (gen_bswapsi2 (dest_32, word1));
2515 emit_insn (gen_bswapsi2 (op3_32, word1));
2516 emit_insn (gen_bswapsi2 (dest_32, word2));
2519 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2520 emit_insn (gen_iordi3 (dest, dest, op3));
2525 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2526 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2527 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2528 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2529 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2533 rtx dest = operands[0];
2534 rtx src = operands[1];
2535 rtx op2 = operands[2];
2536 rtx op3 = operands[3];
2537 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2538 BYTES_BIG_ENDIAN ? 4 : 0);
2539 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2540 BYTES_BIG_ENDIAN ? 4 : 0);
2546 addr1 = XEXP (dest, 0);
2547 if (GET_CODE (addr1) == PLUS)
2549 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2550 if (TARGET_AVOID_XFORM)
2552 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2556 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2558 else if (TARGET_AVOID_XFORM)
2560 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2565 emit_move_insn (op2, GEN_INT (4));
2566 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2569 word1 = change_address (dest, SImode, addr1);
2570 word2 = change_address (dest, SImode, addr2);
2572 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2574 if (BYTES_BIG_ENDIAN)
2576 emit_insn (gen_bswapsi2 (word1, src_si));
2577 emit_insn (gen_bswapsi2 (word2, op3_si));
2581 emit_insn (gen_bswapsi2 (word2, src_si));
2582 emit_insn (gen_bswapsi2 (word1, op3_si));
2588 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2589 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2590 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2591 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2592 "TARGET_POWERPC64 && reload_completed"
2596 rtx dest = operands[0];
2597 rtx src = operands[1];
2598 rtx op2 = operands[2];
2599 rtx op3 = operands[3];
2600 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2601 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2602 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2603 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2604 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2606 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2607 emit_insn (gen_bswapsi2 (dest_si, src_si));
2608 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2609 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2610 emit_insn (gen_iordi3 (dest, dest, op3));
2614 (define_insn "bswapdi2_32bit"
2615 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2616 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2617 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2618 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2620 [(set_attr "length" "16,12,36")])
2623 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2624 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2625 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2626 "!TARGET_POWERPC64 && reload_completed"
2630 rtx dest = operands[0];
2631 rtx src = operands[1];
2632 rtx op2 = operands[2];
2633 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2634 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2640 addr1 = XEXP (src, 0);
2641 if (GET_CODE (addr1) == PLUS)
2643 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2644 if (TARGET_AVOID_XFORM
2645 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2647 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2651 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2653 else if (TARGET_AVOID_XFORM
2654 || REGNO (addr1) == REGNO (dest2))
2656 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2661 emit_move_insn (op2, GEN_INT (4));
2662 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2665 word1 = change_address (src, SImode, addr1);
2666 word2 = change_address (src, SImode, addr2);
2668 emit_insn (gen_bswapsi2 (dest2, word1));
2669 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2670 thus allowing us to omit an early clobber on the output. */
2671 emit_insn (gen_bswapsi2 (dest1, word2));
2676 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2677 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2678 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2679 "!TARGET_POWERPC64 && reload_completed"
2683 rtx dest = operands[0];
2684 rtx src = operands[1];
2685 rtx op2 = operands[2];
2686 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2687 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2693 addr1 = XEXP (dest, 0);
2694 if (GET_CODE (addr1) == PLUS)
2696 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2697 if (TARGET_AVOID_XFORM)
2699 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2703 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2705 else if (TARGET_AVOID_XFORM)
2707 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2712 emit_move_insn (op2, GEN_INT (4));
2713 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2716 word1 = change_address (dest, SImode, addr1);
2717 word2 = change_address (dest, SImode, addr2);
2719 emit_insn (gen_bswapsi2 (word2, src1));
2720 emit_insn (gen_bswapsi2 (word1, src2));
2725 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2726 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2727 (clobber (match_operand:SI 2 "" ""))]
2728 "!TARGET_POWERPC64 && reload_completed"
2732 rtx dest = operands[0];
2733 rtx src = operands[1];
2734 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2735 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2736 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2737 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2739 emit_insn (gen_bswapsi2 (dest1, src2));
2740 emit_insn (gen_bswapsi2 (dest2, src1));
2745 (define_insn "mul<mode>3"
2746 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2747 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2748 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2753 [(set_attr "type" "mul")
2755 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2757 (match_operand:GPR 2 "short_cint_operand" "")
2758 (const_string "16")]
2759 (const_string "<bits>")))])
2761 (define_insn_and_split "*mul<mode>3_dot"
2762 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2763 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2764 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2766 (clobber (match_scratch:GPR 0 "=r,r"))]
2767 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2771 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2773 (mult:GPR (match_dup 1)
2776 (compare:CC (match_dup 0)
2779 [(set_attr "type" "mul")
2780 (set_attr "size" "<bits>")
2781 (set_attr "dot" "yes")
2782 (set_attr "length" "4,8")])
2784 (define_insn_and_split "*mul<mode>3_dot2"
2785 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2786 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2787 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2789 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2790 (mult:GPR (match_dup 1)
2792 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2796 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2798 (mult:GPR (match_dup 1)
2801 (compare:CC (match_dup 0)
2804 [(set_attr "type" "mul")
2805 (set_attr "size" "<bits>")
2806 (set_attr "dot" "yes")
2807 (set_attr "length" "4,8")])
2810 (define_expand "<su>mul<mode>3_highpart"
2811 [(set (match_operand:GPR 0 "gpc_reg_operand")
2813 (mult:<DMODE> (any_extend:<DMODE>
2814 (match_operand:GPR 1 "gpc_reg_operand"))
2816 (match_operand:GPR 2 "gpc_reg_operand")))
2820 if (<MODE>mode == SImode && TARGET_POWERPC64)
2822 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2827 if (!WORDS_BIG_ENDIAN)
2829 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2835 (define_insn "*<su>mul<mode>3_highpart"
2836 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2838 (mult:<DMODE> (any_extend:<DMODE>
2839 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2841 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2843 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2844 "mulh<wd><u> %0,%1,%2"
2845 [(set_attr "type" "mul")
2846 (set_attr "size" "<bits>")])
2848 (define_insn "<su>mulsi3_highpart_le"
2849 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2851 (mult:DI (any_extend:DI
2852 (match_operand:SI 1 "gpc_reg_operand" "r"))
2854 (match_operand:SI 2 "gpc_reg_operand" "r")))
2856 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2858 [(set_attr "type" "mul")])
2860 (define_insn "<su>muldi3_highpart_le"
2861 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2863 (mult:TI (any_extend:TI
2864 (match_operand:DI 1 "gpc_reg_operand" "r"))
2866 (match_operand:DI 2 "gpc_reg_operand" "r")))
2868 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2870 [(set_attr "type" "mul")
2871 (set_attr "size" "64")])
2873 (define_insn "<su>mulsi3_highpart_64"
2874 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2877 (mult:DI (any_extend:DI
2878 (match_operand:SI 1 "gpc_reg_operand" "r"))
2880 (match_operand:SI 2 "gpc_reg_operand" "r")))
2884 [(set_attr "type" "mul")])
2886 (define_expand "<u>mul<mode><dmode>3"
2887 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2888 (mult:<DMODE> (any_extend:<DMODE>
2889 (match_operand:GPR 1 "gpc_reg_operand"))
2891 (match_operand:GPR 2 "gpc_reg_operand"))))]
2892 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2894 rtx l = gen_reg_rtx (<MODE>mode);
2895 rtx h = gen_reg_rtx (<MODE>mode);
2896 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2897 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2898 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2899 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2903 (define_insn "*maddld4"
2904 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2905 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2906 (match_operand:DI 2 "gpc_reg_operand" "r"))
2907 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2909 "maddld %0,%1,%2,%3"
2910 [(set_attr "type" "mul")])
2912 (define_insn "udiv<mode>3"
2913 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2914 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2915 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2918 [(set_attr "type" "div")
2919 (set_attr "size" "<bits>")])
2922 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2923 ;; modulus. If it isn't a power of two, force operands into register and do
2925 (define_expand "div<mode>3"
2926 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2927 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2928 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2931 if (CONST_INT_P (operands[2])
2932 && INTVAL (operands[2]) > 0
2933 && exact_log2 (INTVAL (operands[2])) >= 0)
2935 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2939 operands[2] = force_reg (<MODE>mode, operands[2]);
2942 (define_insn "*div<mode>3"
2943 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2944 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2945 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2948 [(set_attr "type" "div")
2949 (set_attr "size" "<bits>")])
2951 (define_insn "div<mode>3_sra"
2952 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2953 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2954 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2955 (clobber (reg:GPR CA_REGNO))]
2957 "sra<wd>i %0,%1,%p2\;addze %0,%0"
2958 [(set_attr "type" "two")
2959 (set_attr "length" "8")])
2961 (define_insn_and_split "*div<mode>3_sra_dot"
2962 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2963 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2964 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2966 (clobber (match_scratch:GPR 0 "=r,r"))
2967 (clobber (reg:GPR CA_REGNO))]
2968 "<MODE>mode == Pmode"
2970 sra<wd>i %0,%1,%p2\;addze. %0,%0
2972 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2973 [(parallel [(set (match_dup 0)
2974 (div:GPR (match_dup 1)
2976 (clobber (reg:GPR CA_REGNO))])
2978 (compare:CC (match_dup 0)
2981 [(set_attr "type" "two")
2982 (set_attr "length" "8,12")
2983 (set_attr "cell_micro" "not")])
2985 (define_insn_and_split "*div<mode>3_sra_dot2"
2986 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2987 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2988 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2990 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2991 (div:GPR (match_dup 1)
2993 (clobber (reg:GPR CA_REGNO))]
2994 "<MODE>mode == Pmode"
2996 sra<wd>i %0,%1,%p2\;addze. %0,%0
2998 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2999 [(parallel [(set (match_dup 0)
3000 (div:GPR (match_dup 1)
3002 (clobber (reg:GPR CA_REGNO))])
3004 (compare:CC (match_dup 0)
3007 [(set_attr "type" "two")
3008 (set_attr "length" "8,12")
3009 (set_attr "cell_micro" "not")])
3011 (define_expand "mod<mode>3"
3012 [(set (match_operand:GPR 0 "gpc_reg_operand")
3013 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3014 (match_operand:GPR 2 "reg_or_cint_operand")))]
3021 if (GET_CODE (operands[2]) != CONST_INT
3022 || INTVAL (operands[2]) <= 0
3023 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3028 operands[2] = force_reg (<MODE>mode, operands[2]);
3032 temp1 = gen_reg_rtx (<MODE>mode);
3033 temp2 = gen_reg_rtx (<MODE>mode);
3035 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3036 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3037 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3042 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3043 ;; mod, prefer putting the result of mod into a different register
3044 (define_insn "*mod<mode>3"
3045 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3046 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3047 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3050 [(set_attr "type" "div")
3051 (set_attr "size" "<bits>")])
3054 (define_insn "umod<mode>3"
3055 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3056 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3057 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3060 [(set_attr "type" "div")
3061 (set_attr "size" "<bits>")])
3063 ;; On machines with modulo support, do a combined div/mod the old fashioned
3064 ;; method, since the multiply/subtract is faster than doing the mod instruction
3068 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3069 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3070 (match_operand:GPR 2 "gpc_reg_operand" "")))
3071 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3072 (mod:GPR (match_dup 1)
3075 && ! reg_mentioned_p (operands[0], operands[1])
3076 && ! reg_mentioned_p (operands[0], operands[2])
3077 && ! reg_mentioned_p (operands[3], operands[1])
3078 && ! reg_mentioned_p (operands[3], operands[2])"
3080 (div:GPR (match_dup 1)
3083 (mult:GPR (match_dup 0)
3086 (minus:GPR (match_dup 1)
3090 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3091 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3092 (match_operand:GPR 2 "gpc_reg_operand" "")))
3093 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3094 (umod:GPR (match_dup 1)
3097 && ! reg_mentioned_p (operands[0], operands[1])
3098 && ! reg_mentioned_p (operands[0], operands[2])
3099 && ! reg_mentioned_p (operands[3], operands[1])
3100 && ! reg_mentioned_p (operands[3], operands[2])"
3102 (div:GPR (match_dup 1)
3105 (mult:GPR (match_dup 0)
3108 (minus:GPR (match_dup 1)
3112 ;; Logical instructions
3113 ;; The logical instructions are mostly combined by using match_operator,
3114 ;; but the plain AND insns are somewhat different because there is no
3115 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3116 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3118 (define_expand "and<mode>3"
3119 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3120 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3121 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3124 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3126 rs6000_split_logical (operands, AND, false, false, false);
3130 if (CONST_INT_P (operands[2]))
3132 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3134 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3138 if (logical_const_operand (operands[2], <MODE>mode)
3139 && rs6000_gen_cell_microcode)
3141 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3145 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3147 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3151 operands[2] = force_reg (<MODE>mode, operands[2]);
3156 (define_insn "and<mode>3_imm"
3157 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3158 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3159 (match_operand:GPR 2 "logical_const_operand" "n")))
3160 (clobber (match_scratch:CC 3 "=x"))]
3161 "rs6000_gen_cell_microcode
3162 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3163 "andi%e2. %0,%1,%u2"
3164 [(set_attr "type" "logical")
3165 (set_attr "dot" "yes")])
3167 (define_insn_and_split "*and<mode>3_imm_dot"
3168 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3169 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3170 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3172 (clobber (match_scratch:GPR 0 "=r,r"))
3173 (clobber (match_scratch:CC 4 "=X,x"))]
3174 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3175 && rs6000_gen_cell_microcode
3176 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3180 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3181 [(parallel [(set (match_dup 0)
3182 (and:GPR (match_dup 1)
3184 (clobber (match_dup 4))])
3186 (compare:CC (match_dup 0)
3189 [(set_attr "type" "logical")
3190 (set_attr "dot" "yes")
3191 (set_attr "length" "4,8")])
3193 (define_insn_and_split "*and<mode>3_imm_dot2"
3194 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3195 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3196 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3198 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3199 (and:GPR (match_dup 1)
3201 (clobber (match_scratch:CC 4 "=X,x"))]
3202 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3203 && rs6000_gen_cell_microcode
3204 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3208 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3209 [(parallel [(set (match_dup 0)
3210 (and:GPR (match_dup 1)
3212 (clobber (match_dup 4))])
3214 (compare:CC (match_dup 0)
3217 [(set_attr "type" "logical")
3218 (set_attr "dot" "yes")
3219 (set_attr "length" "4,8")])
3221 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3222 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3223 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3224 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3226 (clobber (match_scratch:GPR 0 "=r,r"))]
3227 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3228 && rs6000_gen_cell_microcode"
3232 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3234 (and:GPR (match_dup 1)
3237 (compare:CC (match_dup 0)
3240 [(set_attr "type" "logical")
3241 (set_attr "dot" "yes")
3242 (set_attr "length" "4,8")])
3244 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3245 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3246 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3247 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3249 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3250 (and:GPR (match_dup 1)
3252 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3253 && rs6000_gen_cell_microcode"
3257 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3259 (and:GPR (match_dup 1)
3262 (compare:CC (match_dup 0)
3265 [(set_attr "type" "logical")
3266 (set_attr "dot" "yes")
3267 (set_attr "length" "4,8")])
3269 (define_insn "*and<mode>3_imm_dot_shifted"
3270 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3273 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3274 (match_operand:SI 4 "const_int_operand" "n"))
3275 (match_operand:GPR 2 "const_int_operand" "n"))
3277 (clobber (match_scratch:GPR 0 "=r"))]
3278 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3279 << INTVAL (operands[4])),
3281 && (<MODE>mode == Pmode
3282 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3283 && rs6000_gen_cell_microcode"
3285 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3286 return "andi%e2. %0,%1,%u2";
3288 [(set_attr "type" "logical")
3289 (set_attr "dot" "yes")])
3292 (define_insn "and<mode>3_mask"
3293 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3294 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3295 (match_operand:GPR 2 "const_int_operand" "n")))]
3296 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3298 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3300 [(set_attr "type" "shift")])
3302 (define_insn_and_split "*and<mode>3_mask_dot"
3303 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3304 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3305 (match_operand:GPR 2 "const_int_operand" "n,n"))
3307 (clobber (match_scratch:GPR 0 "=r,r"))]
3308 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3309 && rs6000_gen_cell_microcode
3310 && !logical_const_operand (operands[2], <MODE>mode)
3311 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3313 if (which_alternative == 0)
3314 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3318 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3320 (and:GPR (match_dup 1)
3323 (compare:CC (match_dup 0)
3326 [(set_attr "type" "shift")
3327 (set_attr "dot" "yes")
3328 (set_attr "length" "4,8")])
3330 (define_insn_and_split "*and<mode>3_mask_dot2"
3331 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3332 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3333 (match_operand:GPR 2 "const_int_operand" "n,n"))
3335 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3336 (and:GPR (match_dup 1)
3338 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3339 && rs6000_gen_cell_microcode
3340 && !logical_const_operand (operands[2], <MODE>mode)
3341 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3343 if (which_alternative == 0)
3344 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3348 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3350 (and:GPR (match_dup 1)
3353 (compare:CC (match_dup 0)
3356 [(set_attr "type" "shift")
3357 (set_attr "dot" "yes")
3358 (set_attr "length" "4,8")])
3361 (define_insn_and_split "*and<mode>3_2insn"
3362 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3363 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3364 (match_operand:GPR 2 "const_int_operand" "n")))]
3365 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3366 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3367 || (logical_const_operand (operands[2], <MODE>mode)
3368 && rs6000_gen_cell_microcode))"
3373 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3376 [(set_attr "type" "shift")
3377 (set_attr "length" "8")])
3379 (define_insn_and_split "*and<mode>3_2insn_dot"
3380 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3381 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3382 (match_operand:GPR 2 "const_int_operand" "n,n"))
3384 (clobber (match_scratch:GPR 0 "=r,r"))]
3385 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3386 && rs6000_gen_cell_microcode
3387 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3388 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3389 || (logical_const_operand (operands[2], <MODE>mode)
3390 && rs6000_gen_cell_microcode))"
3392 "&& reload_completed"
3395 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3398 [(set_attr "type" "shift")
3399 (set_attr "dot" "yes")
3400 (set_attr "length" "8,12")])
3402 (define_insn_and_split "*and<mode>3_2insn_dot2"
3403 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3404 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3405 (match_operand:GPR 2 "const_int_operand" "n,n"))
3407 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3408 (and:GPR (match_dup 1)
3410 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3411 && rs6000_gen_cell_microcode
3412 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3413 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3414 || (logical_const_operand (operands[2], <MODE>mode)
3415 && rs6000_gen_cell_microcode))"
3417 "&& reload_completed"
3420 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3423 [(set_attr "type" "shift")
3424 (set_attr "dot" "yes")
3425 (set_attr "length" "8,12")])
3428 (define_expand "<code><mode>3"
3429 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3430 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3431 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3434 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3436 rs6000_split_logical (operands, <CODE>, false, false, false);
3440 if (non_logical_cint_operand (operands[2], <MODE>mode))
3442 rtx tmp = ((!can_create_pseudo_p ()
3443 || rtx_equal_p (operands[0], operands[1]))
3444 ? operands[0] : gen_reg_rtx (<MODE>mode));
3446 HOST_WIDE_INT value = INTVAL (operands[2]);
3447 HOST_WIDE_INT lo = value & 0xffff;
3448 HOST_WIDE_INT hi = value - lo;
3450 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3451 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3455 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3456 operands[2] = force_reg (<MODE>mode, operands[2]);
3460 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3461 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3462 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3465 (iorxor:GPR (match_dup 1)
3468 (iorxor:GPR (match_dup 3)
3471 operands[3] = ((!can_create_pseudo_p ()
3472 || rtx_equal_p (operands[0], operands[1]))
3473 ? operands[0] : gen_reg_rtx (<MODE>mode));
3475 HOST_WIDE_INT value = INTVAL (operands[2]);
3476 HOST_WIDE_INT lo = value & 0xffff;
3477 HOST_WIDE_INT hi = value - lo;
3479 operands[4] = GEN_INT (hi);
3480 operands[5] = GEN_INT (lo);
3483 (define_insn "*bool<mode>3_imm"
3484 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3485 (match_operator:GPR 3 "boolean_or_operator"
3486 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3487 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3490 [(set_attr "type" "logical")])
3492 (define_insn "*bool<mode>3"
3493 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3494 (match_operator:GPR 3 "boolean_operator"
3495 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3496 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3499 [(set_attr "type" "logical")])
3501 (define_insn_and_split "*bool<mode>3_dot"
3502 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3503 (compare:CC (match_operator:GPR 3 "boolean_operator"
3504 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3505 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3507 (clobber (match_scratch:GPR 0 "=r,r"))]
3508 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3512 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3516 (compare:CC (match_dup 0)
3519 [(set_attr "type" "logical")
3520 (set_attr "dot" "yes")
3521 (set_attr "length" "4,8")])
3523 (define_insn_and_split "*bool<mode>3_dot2"
3524 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3525 (compare:CC (match_operator:GPR 3 "boolean_operator"
3526 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3527 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3529 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3531 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3535 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3539 (compare:CC (match_dup 0)
3542 [(set_attr "type" "logical")
3543 (set_attr "dot" "yes")
3544 (set_attr "length" "4,8")])
3547 (define_insn "*boolc<mode>3"
3548 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3549 (match_operator:GPR 3 "boolean_operator"
3550 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3551 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3554 [(set_attr "type" "logical")])
3556 (define_insn_and_split "*boolc<mode>3_dot"
3557 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3558 (compare:CC (match_operator:GPR 3 "boolean_operator"
3559 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3560 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3562 (clobber (match_scratch:GPR 0 "=r,r"))]
3563 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3567 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3571 (compare:CC (match_dup 0)
3574 [(set_attr "type" "logical")
3575 (set_attr "dot" "yes")
3576 (set_attr "length" "4,8")])
3578 (define_insn_and_split "*boolc<mode>3_dot2"
3579 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3580 (compare:CC (match_operator:GPR 3 "boolean_operator"
3581 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3582 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3584 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3586 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3590 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3594 (compare:CC (match_dup 0)
3597 [(set_attr "type" "logical")
3598 (set_attr "dot" "yes")
3599 (set_attr "length" "4,8")])
3602 (define_insn "*boolcc<mode>3"
3603 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3604 (match_operator:GPR 3 "boolean_operator"
3605 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3606 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3609 [(set_attr "type" "logical")])
3611 (define_insn_and_split "*boolcc<mode>3_dot"
3612 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3613 (compare:CC (match_operator:GPR 3 "boolean_operator"
3614 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3615 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3617 (clobber (match_scratch:GPR 0 "=r,r"))]
3618 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3622 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3626 (compare:CC (match_dup 0)
3629 [(set_attr "type" "logical")
3630 (set_attr "dot" "yes")
3631 (set_attr "length" "4,8")])
3633 (define_insn_and_split "*boolcc<mode>3_dot2"
3634 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3635 (compare:CC (match_operator:GPR 3 "boolean_operator"
3636 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3637 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3639 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3641 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3645 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3649 (compare:CC (match_dup 0)
3652 [(set_attr "type" "logical")
3653 (set_attr "dot" "yes")
3654 (set_attr "length" "4,8")])
3657 ;; TODO: Should have dots of this as well.
3658 (define_insn "*eqv<mode>3"
3659 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3660 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3661 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3664 [(set_attr "type" "logical")])
3666 ;; Rotate-and-mask and insert.
3668 (define_insn "*rotl<mode>3_mask"
3669 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3670 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3671 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3672 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3673 (match_operand:GPR 3 "const_int_operand" "n")))]
3674 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3676 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3678 [(set_attr "type" "shift")
3679 (set_attr "maybe_var_shift" "yes")])
3681 (define_insn_and_split "*rotl<mode>3_mask_dot"
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 (clobber (match_scratch:GPR 0 "=r,r"))]
3690 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3691 && rs6000_gen_cell_microcode
3692 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3694 if (which_alternative == 0)
3695 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3699 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3701 (and:GPR (match_dup 4)
3704 (compare:CC (match_dup 0)
3707 [(set_attr "type" "shift")
3708 (set_attr "maybe_var_shift" "yes")
3709 (set_attr "dot" "yes")
3710 (set_attr "length" "4,8")])
3712 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3713 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3715 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3716 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3717 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3718 (match_operand:GPR 3 "const_int_operand" "n,n"))
3720 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3721 (and:GPR (match_dup 4)
3723 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3724 && rs6000_gen_cell_microcode
3725 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3727 if (which_alternative == 0)
3728 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3732 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3734 (and:GPR (match_dup 4)
3737 (compare:CC (match_dup 0)
3740 [(set_attr "type" "shift")
3741 (set_attr "maybe_var_shift" "yes")
3742 (set_attr "dot" "yes")
3743 (set_attr "length" "4,8")])
3745 ; Special case for less-than-0. We can do it with just one machine
3746 ; instruction, but the generic optimizers do not realise it is cheap.
3747 (define_insn "*lt0_disi"
3748 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3749 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3752 "rlwinm %0,%1,1,31,31"
3753 [(set_attr "type" "shift")])
3757 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3758 ; both are an AND so are the same precedence).
3759 (define_insn "*rotl<mode>3_insert"
3760 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3761 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3762 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3763 (match_operand:SI 2 "const_int_operand" "n")])
3764 (match_operand:GPR 3 "const_int_operand" "n"))
3765 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3766 (match_operand:GPR 6 "const_int_operand" "n"))))]
3767 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3768 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3770 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3772 [(set_attr "type" "insert")])
3773 ; FIXME: this needs an attr "size", so that the scheduler can see the
3774 ; difference between rlwimi and rldimi. We also might want dot forms,
3775 ; but not for rlwimi on POWER4 and similar processors.
3777 (define_insn "*rotl<mode>3_insert_2"
3778 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3779 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3780 (match_operand:GPR 6 "const_int_operand" "n"))
3781 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3782 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3783 (match_operand:SI 2 "const_int_operand" "n")])
3784 (match_operand:GPR 3 "const_int_operand" "n"))))]
3785 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3786 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3788 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3790 [(set_attr "type" "insert")])
3792 ; There are also some forms without one of the ANDs.
3793 (define_insn "*rotl<mode>3_insert_3"
3794 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3795 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3796 (match_operand:GPR 4 "const_int_operand" "n"))
3797 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3798 (match_operand:SI 2 "const_int_operand" "n"))))]
3799 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3801 if (<MODE>mode == SImode)
3802 return "rlwimi %0,%1,%h2,0,31-%h2";
3804 return "rldimi %0,%1,%H2,0";
3806 [(set_attr "type" "insert")])
3808 (define_insn "*rotl<mode>3_insert_4"
3809 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3810 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3811 (match_operand:GPR 4 "const_int_operand" "n"))
3812 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3813 (match_operand:SI 2 "const_int_operand" "n"))))]
3814 "<MODE>mode == SImode &&
3815 GET_MODE_PRECISION (<MODE>mode)
3816 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3818 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3819 - INTVAL (operands[2]));
3820 if (<MODE>mode == SImode)
3821 return "rlwimi %0,%1,%h2,32-%h2,31";
3823 return "rldimi %0,%1,%H2,64-%H2";
3825 [(set_attr "type" "insert")])
3828 ; This handles the important case of multiple-precision shifts. There is
3829 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3831 [(set (match_operand:GPR 0 "gpc_reg_operand")
3832 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3833 (match_operand:SI 3 "const_int_operand"))
3834 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3835 (match_operand:SI 4 "const_int_operand"))))]
3836 "can_create_pseudo_p ()
3837 && INTVAL (operands[3]) + INTVAL (operands[4])
3838 >= GET_MODE_PRECISION (<MODE>mode)"
3840 (lshiftrt:GPR (match_dup 2)
3843 (ior:GPR (and:GPR (match_dup 5)
3845 (ashift:GPR (match_dup 1)
3848 unsigned HOST_WIDE_INT mask = 1;
3849 mask = (mask << INTVAL (operands[3])) - 1;
3850 operands[5] = gen_reg_rtx (<MODE>mode);
3851 operands[6] = GEN_INT (mask);
3855 [(set (match_operand:GPR 0 "gpc_reg_operand")
3856 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3857 (match_operand:SI 4 "const_int_operand"))
3858 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3859 (match_operand:SI 3 "const_int_operand"))))]
3860 "can_create_pseudo_p ()
3861 && INTVAL (operands[3]) + INTVAL (operands[4])
3862 >= GET_MODE_PRECISION (<MODE>mode)"
3864 (lshiftrt:GPR (match_dup 2)
3867 (ior:GPR (and:GPR (match_dup 5)
3869 (ashift:GPR (match_dup 1)
3872 unsigned HOST_WIDE_INT mask = 1;
3873 mask = (mask << INTVAL (operands[3])) - 1;
3874 operands[5] = gen_reg_rtx (<MODE>mode);
3875 operands[6] = GEN_INT (mask);
3879 ; Another important case is setting some bits to 1; we can do that with
3880 ; an insert instruction, in many cases.
3881 (define_insn_and_split "*ior<mode>_mask"
3882 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3883 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3884 (match_operand:GPR 2 "const_int_operand" "n")))
3885 (clobber (match_scratch:GPR 3 "=r"))]
3886 "!logical_const_operand (operands[2], <MODE>mode)
3887 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3893 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3896 (and:GPR (match_dup 1)
3900 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3901 if (GET_CODE (operands[3]) == SCRATCH)
3902 operands[3] = gen_reg_rtx (<MODE>mode);
3903 operands[4] = GEN_INT (ne);
3904 operands[5] = GEN_INT (~UINTVAL (operands[2]));
3906 [(set_attr "type" "two")
3907 (set_attr "length" "8")])
3910 ;; Now the simple shifts.
3912 (define_insn "rotl<mode>3"
3913 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3914 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3915 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3917 "rotl<wd>%I2 %0,%1,%<hH>2"
3918 [(set_attr "type" "shift")
3919 (set_attr "maybe_var_shift" "yes")])
3921 (define_insn "*rotlsi3_64"
3922 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3924 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3925 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3927 "rotlw%I2 %0,%1,%h2"
3928 [(set_attr "type" "shift")
3929 (set_attr "maybe_var_shift" "yes")])
3931 (define_insn_and_split "*rotl<mode>3_dot"
3932 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3933 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3934 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3936 (clobber (match_scratch:GPR 0 "=r,r"))]
3937 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3939 rotl<wd>%I2. %0,%1,%<hH>2
3941 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3943 (rotate:GPR (match_dup 1)
3946 (compare:CC (match_dup 0)
3949 [(set_attr "type" "shift")
3950 (set_attr "maybe_var_shift" "yes")
3951 (set_attr "dot" "yes")
3952 (set_attr "length" "4,8")])
3954 (define_insn_and_split "*rotl<mode>3_dot2"
3955 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3956 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3957 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3959 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3960 (rotate:GPR (match_dup 1)
3962 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3964 rotl<wd>%I2. %0,%1,%<hH>2
3966 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3968 (rotate:GPR (match_dup 1)
3971 (compare:CC (match_dup 0)
3974 [(set_attr "type" "shift")
3975 (set_attr "maybe_var_shift" "yes")
3976 (set_attr "dot" "yes")
3977 (set_attr "length" "4,8")])
3980 (define_insn "ashl<mode>3"
3981 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3982 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3983 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3985 "sl<wd>%I2 %0,%1,%<hH>2"
3986 [(set_attr "type" "shift")
3987 (set_attr "maybe_var_shift" "yes")])
3989 (define_insn "*ashlsi3_64"
3990 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3992 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3993 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3996 [(set_attr "type" "shift")
3997 (set_attr "maybe_var_shift" "yes")])
3999 (define_insn_and_split "*ashl<mode>3_dot"
4000 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4001 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4002 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4004 (clobber (match_scratch:GPR 0 "=r,r"))]
4005 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4007 sl<wd>%I2. %0,%1,%<hH>2
4009 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4011 (ashift:GPR (match_dup 1)
4014 (compare:CC (match_dup 0)
4017 [(set_attr "type" "shift")
4018 (set_attr "maybe_var_shift" "yes")
4019 (set_attr "dot" "yes")
4020 (set_attr "length" "4,8")])
4022 (define_insn_and_split "*ashl<mode>3_dot2"
4023 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4024 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4025 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4027 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4028 (ashift:GPR (match_dup 1)
4030 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4032 sl<wd>%I2. %0,%1,%<hH>2
4034 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4036 (ashift:GPR (match_dup 1)
4039 (compare:CC (match_dup 0)
4042 [(set_attr "type" "shift")
4043 (set_attr "maybe_var_shift" "yes")
4044 (set_attr "dot" "yes")
4045 (set_attr "length" "4,8")])
4047 ;; Pretend we have a memory form of extswsli until register allocation is done
4048 ;; so that we use LWZ to load the value from memory, instead of LWA.
4049 (define_insn_and_split "ashdi3_extswsli"
4050 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4052 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4053 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4058 "&& reload_completed && MEM_P (operands[1])"
4062 (ashift:DI (sign_extend:DI (match_dup 3))
4065 operands[3] = gen_lowpart (SImode, operands[0]);
4067 [(set_attr "type" "shift")
4068 (set_attr "maybe_var_shift" "no")])
4071 (define_insn_and_split "ashdi3_extswsli_dot"
4072 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4075 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4076 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4078 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4085 "&& reload_completed
4086 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4087 || memory_operand (operands[1], SImode))"
4090 rtx dest = operands[0];
4091 rtx src = operands[1];
4092 rtx shift = operands[2];
4093 rtx cr = operands[3];
4100 src2 = gen_lowpart (SImode, dest);
4101 emit_move_insn (src2, src);
4104 if (REGNO (cr) == CR0_REGNO)
4106 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4110 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4111 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4114 [(set_attr "type" "shift")
4115 (set_attr "maybe_var_shift" "no")
4116 (set_attr "dot" "yes")
4117 (set_attr "length" "4,8,8,12")])
4119 (define_insn_and_split "ashdi3_extswsli_dot2"
4120 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4123 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4124 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4126 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4127 (ashift:DI (sign_extend:DI (match_dup 1))
4135 "&& reload_completed
4136 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4137 || memory_operand (operands[1], SImode))"
4140 rtx dest = operands[0];
4141 rtx src = operands[1];
4142 rtx shift = operands[2];
4143 rtx cr = operands[3];
4150 src2 = gen_lowpart (SImode, dest);
4151 emit_move_insn (src2, src);
4154 if (REGNO (cr) == CR0_REGNO)
4156 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4160 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4161 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4164 [(set_attr "type" "shift")
4165 (set_attr "maybe_var_shift" "no")
4166 (set_attr "dot" "yes")
4167 (set_attr "length" "4,8,8,12")])
4169 (define_insn "lshr<mode>3"
4170 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4171 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4172 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4174 "sr<wd>%I2 %0,%1,%<hH>2"
4175 [(set_attr "type" "shift")
4176 (set_attr "maybe_var_shift" "yes")])
4178 (define_insn "*lshrsi3_64"
4179 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4181 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4182 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4185 [(set_attr "type" "shift")
4186 (set_attr "maybe_var_shift" "yes")])
4188 (define_insn_and_split "*lshr<mode>3_dot"
4189 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4190 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4191 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4193 (clobber (match_scratch:GPR 0 "=r,r"))]
4194 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4196 sr<wd>%I2. %0,%1,%<hH>2
4198 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4200 (lshiftrt:GPR (match_dup 1)
4203 (compare:CC (match_dup 0)
4206 [(set_attr "type" "shift")
4207 (set_attr "maybe_var_shift" "yes")
4208 (set_attr "dot" "yes")
4209 (set_attr "length" "4,8")])
4211 (define_insn_and_split "*lshr<mode>3_dot2"
4212 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4213 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4214 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4216 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4217 (lshiftrt:GPR (match_dup 1)
4219 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4221 sr<wd>%I2. %0,%1,%<hH>2
4223 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4225 (lshiftrt:GPR (match_dup 1)
4228 (compare:CC (match_dup 0)
4231 [(set_attr "type" "shift")
4232 (set_attr "maybe_var_shift" "yes")
4233 (set_attr "dot" "yes")
4234 (set_attr "length" "4,8")])
4237 (define_insn "ashr<mode>3"
4238 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4239 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4240 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4241 (clobber (reg:GPR CA_REGNO))]
4243 "sra<wd>%I2 %0,%1,%<hH>2"
4244 [(set_attr "type" "shift")
4245 (set_attr "maybe_var_shift" "yes")])
4247 (define_insn "*ashrsi3_64"
4248 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4250 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4251 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4252 (clobber (reg:SI CA_REGNO))]
4255 [(set_attr "type" "shift")
4256 (set_attr "maybe_var_shift" "yes")])
4258 (define_insn_and_split "*ashr<mode>3_dot"
4259 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4260 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4261 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4263 (clobber (match_scratch:GPR 0 "=r,r"))
4264 (clobber (reg:GPR CA_REGNO))]
4265 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4267 sra<wd>%I2. %0,%1,%<hH>2
4269 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4270 [(parallel [(set (match_dup 0)
4271 (ashiftrt:GPR (match_dup 1)
4273 (clobber (reg:GPR CA_REGNO))])
4275 (compare:CC (match_dup 0)
4278 [(set_attr "type" "shift")
4279 (set_attr "maybe_var_shift" "yes")
4280 (set_attr "dot" "yes")
4281 (set_attr "length" "4,8")])
4283 (define_insn_and_split "*ashr<mode>3_dot2"
4284 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4285 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4286 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4288 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4289 (ashiftrt:GPR (match_dup 1)
4291 (clobber (reg:GPR CA_REGNO))]
4292 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4294 sra<wd>%I2. %0,%1,%<hH>2
4296 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4297 [(parallel [(set (match_dup 0)
4298 (ashiftrt:GPR (match_dup 1)
4300 (clobber (reg:GPR CA_REGNO))])
4302 (compare:CC (match_dup 0)
4305 [(set_attr "type" "shift")
4306 (set_attr "maybe_var_shift" "yes")
4307 (set_attr "dot" "yes")
4308 (set_attr "length" "4,8")])
4310 ;; Builtins to replace a division to generate FRE reciprocal estimate
4311 ;; instructions and the necessary fixup instructions
4312 (define_expand "recip<mode>3"
4313 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4314 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4315 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4316 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4318 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4322 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4323 ;; hardware division. This is only done before register allocation and with
4324 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4326 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4327 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4328 (match_operand 2 "gpc_reg_operand" "")))]
4329 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4330 && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4331 && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4334 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4338 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4339 ;; appropriate fixup.
4340 (define_expand "rsqrt<mode>2"
4341 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4342 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4343 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4345 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4349 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4350 ;; modes here, and also add in conditional vsx/power8-vector support to access
4351 ;; values in the traditional Altivec registers if the appropriate
4352 ;; -mupper-regs-{df,sf} option is enabled.
4354 (define_expand "abs<mode>2"
4355 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4356 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4357 "TARGET_<MODE>_INSN"
4360 (define_insn "*abs<mode>2_fpr"
4361 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4362 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4367 [(set_attr "type" "fpsimple")
4368 (set_attr "fp_type" "fp_addsub_<Fs>")])
4370 (define_insn "*nabs<mode>2_fpr"
4371 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4374 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4379 [(set_attr "type" "fpsimple")
4380 (set_attr "fp_type" "fp_addsub_<Fs>")])
4382 (define_expand "neg<mode>2"
4383 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4384 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4385 "TARGET_<MODE>_INSN"
4388 (define_insn "*neg<mode>2_fpr"
4389 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4390 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4395 [(set_attr "type" "fpsimple")
4396 (set_attr "fp_type" "fp_addsub_<Fs>")])
4398 (define_expand "add<mode>3"
4399 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4400 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4401 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4402 "TARGET_<MODE>_INSN"
4405 (define_insn "*add<mode>3_fpr"
4406 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4407 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4408 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4411 fadd<Ftrad> %0,%1,%2
4412 xsadd<Fvsx> %x0,%x1,%x2"
4413 [(set_attr "type" "fp")
4414 (set_attr "fp_type" "fp_addsub_<Fs>")])
4416 (define_expand "sub<mode>3"
4417 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4418 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4419 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4420 "TARGET_<MODE>_INSN"
4423 (define_insn "*sub<mode>3_fpr"
4424 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4425 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4426 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4429 fsub<Ftrad> %0,%1,%2
4430 xssub<Fvsx> %x0,%x1,%x2"
4431 [(set_attr "type" "fp")
4432 (set_attr "fp_type" "fp_addsub_<Fs>")])
4434 (define_expand "mul<mode>3"
4435 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4436 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4437 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4438 "TARGET_<MODE>_INSN"
4441 (define_insn "*mul<mode>3_fpr"
4442 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4443 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4444 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4447 fmul<Ftrad> %0,%1,%2
4448 xsmul<Fvsx> %x0,%x1,%x2"
4449 [(set_attr "type" "dmul")
4450 (set_attr "fp_type" "fp_mul_<Fs>")])
4452 (define_expand "div<mode>3"
4453 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4454 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4455 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4456 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4459 (define_insn "*div<mode>3_fpr"
4460 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4461 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4462 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4463 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4465 fdiv<Ftrad> %0,%1,%2
4466 xsdiv<Fvsx> %x0,%x1,%x2"
4467 [(set_attr "type" "<Fs>div")
4468 (set_attr "fp_type" "fp_div_<Fs>")])
4470 (define_insn "*sqrt<mode>2_internal"
4471 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4472 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4473 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4474 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4477 xssqrt<Fvsx> %x0,%x1"
4478 [(set_attr "type" "<Fs>sqrt")
4479 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4481 (define_expand "sqrt<mode>2"
4482 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4483 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4484 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4485 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4487 if (<MODE>mode == SFmode
4488 && TARGET_RECIP_PRECISION
4489 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4490 && !optimize_function_for_size_p (cfun)
4491 && flag_finite_math_only && !flag_trapping_math
4492 && flag_unsafe_math_optimizations)
4494 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4499 ;; Floating point reciprocal approximation
4500 (define_insn "fre<Fs>"
4501 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4502 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4508 [(set_attr "type" "fp")])
4510 (define_insn "*rsqrt<mode>2"
4511 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4512 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4514 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4516 frsqrte<Ftrad> %0,%1
4517 xsrsqrte<Fvsx> %x0,%x1"
4518 [(set_attr "type" "fp")])
4520 ;; Floating point comparisons
4521 (define_insn "*cmp<mode>_fpr"
4522 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4523 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4524 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4528 xscmpudp %0,%x1,%x2"
4529 [(set_attr "type" "fpcompare")])
4531 ;; Floating point conversions
4532 (define_expand "extendsfdf2"
4533 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4534 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4535 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4538 (define_insn_and_split "*extendsfdf2_fpr"
4539 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4540 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))]
4541 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4547 xscpsgndp %x0,%x1,%x1
4550 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4553 emit_note (NOTE_INSN_DELETED);
4556 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4558 (define_expand "truncdfsf2"
4559 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4560 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4561 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4564 (define_insn "*truncdfsf2_fpr"
4565 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4566 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4567 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4571 [(set_attr "type" "fp")])
4573 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4574 ;; builtins.c and optabs.c that are not correct for IBM long double
4575 ;; when little-endian.
4576 (define_expand "signbit<mode>2"
4578 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4580 (subreg:DI (match_dup 2) 0))
4583 (set (match_operand:SI 0 "gpc_reg_operand" "")
4586 && (TARGET_FPRS || TARGET_E500_DOUBLE)
4587 && (!FLOAT128_IEEE_P (<MODE>mode)
4588 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4590 if (FLOAT128_IEEE_P (<MODE>mode))
4592 if (<MODE>mode == KFmode)
4593 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4594 else if (<MODE>mode == TFmode)
4595 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4600 operands[2] = gen_reg_rtx (DFmode);
4601 operands[3] = gen_reg_rtx (DImode);
4602 if (TARGET_POWERPC64)
4604 operands[4] = gen_reg_rtx (DImode);
4605 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4606 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4607 WORDS_BIG_ENDIAN ? 4 : 0);
4611 operands[4] = gen_reg_rtx (SImode);
4612 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4613 WORDS_BIG_ENDIAN ? 0 : 4);
4614 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4618 (define_expand "copysign<mode>3"
4620 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4622 (neg:SFDF (abs:SFDF (match_dup 1))))
4623 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4624 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4628 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4629 && ((TARGET_PPC_GFXOPT
4630 && !HONOR_NANS (<MODE>mode)
4631 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4633 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4635 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4637 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4642 operands[3] = gen_reg_rtx (<MODE>mode);
4643 operands[4] = gen_reg_rtx (<MODE>mode);
4644 operands[5] = CONST0_RTX (<MODE>mode);
4647 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4649 (define_insn_and_split "signbit<mode>2_dm"
4650 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4652 [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,m,r")]
4654 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4656 "&& reload_completed"
4659 rs6000_split_signbit (operands[0], operands[1]);
4662 [(set_attr "length" "8,8,12")
4663 (set_attr "type" "mftgpr,load,integer")])
4665 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4666 ;; point types, which makes normal SUBREG's problematical. Instead use a
4667 ;; special pattern to avoid using a normal movdi.
4668 (define_insn "signbit<mode>2_dm2"
4669 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4670 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
4673 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4675 [(set_attr "type" "mftgpr")])
4678 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4679 ;; compiler from optimizing -0.0
4680 (define_insn "copysign<mode>3_fcpsgn"
4681 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4682 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4683 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4685 "TARGET_<MODE>_FPR && TARGET_CMPB"
4688 xscpsgndp %x0,%x2,%x1"
4689 [(set_attr "type" "fpsimple")])
4691 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4692 ;; fsel instruction and some auxiliary computations. Then we just have a
4693 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4695 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4696 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4697 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4698 ;; define_splits to make them if made by combine. On VSX machines we have the
4699 ;; min/max instructions.
4701 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4702 ;; to allow either DF/SF to use only traditional registers.
4704 (define_expand "s<minmax><mode>3"
4705 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4706 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4707 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4708 "TARGET_MINMAX_<MODE>"
4710 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4714 (define_insn "*s<minmax><mode>3_vsx"
4715 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4716 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4717 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4718 "TARGET_VSX && TARGET_<MODE>_FPR"
4720 return (TARGET_P9_MINMAX
4721 ? "xs<minmax>cdp %x0,%x1,%x2"
4722 : "xs<minmax>dp %x0,%x1,%x2");
4724 [(set_attr "type" "fp")])
4726 ;; The conditional move instructions allow us to perform max and min operations
4727 ;; even when we don't have the appropriate max/min instruction using the FSEL
4730 (define_insn_and_split "*s<minmax><mode>3_fpr"
4731 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4732 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4733 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4734 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4739 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4743 (define_expand "mov<mode>cc"
4744 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4745 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4746 (match_operand:GPR 2 "gpc_reg_operand" "")
4747 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4751 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4757 ;; We use the BASE_REGS for the isel input operands because, if rA is
4758 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4759 ;; because we may switch the operands and rB may end up being rA.
4761 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4762 ;; leave out the mode in operand 4 and use one pattern, but reload can
4763 ;; change the mode underneath our feet and then gets confused trying
4764 ;; to reload the value.
4765 (define_insn "isel_signed_<mode>"
4766 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4768 (match_operator 1 "scc_comparison_operator"
4769 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4771 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4772 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4775 { return output_isel (operands); }"
4776 [(set_attr "type" "isel")
4777 (set_attr "length" "4")])
4779 (define_insn "isel_unsigned_<mode>"
4780 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4782 (match_operator 1 "scc_comparison_operator"
4783 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4785 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4786 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4789 { return output_isel (operands); }"
4790 [(set_attr "type" "isel")
4791 (set_attr "length" "4")])
4793 ;; These patterns can be useful for combine; they let combine know that
4794 ;; isel can handle reversed comparisons so long as the operands are
4797 (define_insn "*isel_reversed_signed_<mode>"
4798 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4800 (match_operator 1 "scc_rev_comparison_operator"
4801 [(match_operand:CC 4 "cc_reg_operand" "y")
4803 (match_operand:GPR 2 "gpc_reg_operand" "b")
4804 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4807 { return output_isel (operands); }"
4808 [(set_attr "type" "isel")
4809 (set_attr "length" "4")])
4811 (define_insn "*isel_reversed_unsigned_<mode>"
4812 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4814 (match_operator 1 "scc_rev_comparison_operator"
4815 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4817 (match_operand:GPR 2 "gpc_reg_operand" "b")
4818 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4821 { return output_isel (operands); }"
4822 [(set_attr "type" "isel")
4823 (set_attr "length" "4")])
4825 ;; Floating point conditional move
4826 (define_expand "mov<mode>cc"
4827 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4828 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4829 (match_operand:SFDF 2 "gpc_reg_operand" "")
4830 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4831 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4834 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4840 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4841 [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4843 (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4844 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4845 (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4846 (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4847 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4849 [(set_attr "type" "fp")])
4851 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4852 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4854 (match_operator:CCFP 1 "fpmask_comparison_operator"
4855 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4856 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4857 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4858 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4859 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4864 (if_then_else:V2DI (match_dup 1)
4868 (if_then_else:SFDF (ne (match_dup 6)
4873 if (GET_CODE (operands[6]) == SCRATCH)
4874 operands[6] = gen_reg_rtx (V2DImode);
4876 operands[7] = CONSTM1_RTX (V2DImode);
4877 operands[8] = CONST0_RTX (V2DImode);
4879 [(set_attr "length" "8")
4880 (set_attr "type" "vecperm")])
4882 (define_insn "*fpmask<mode>"
4883 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
4885 (match_operator:CCFP 1 "fpmask_comparison_operator"
4886 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
4887 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
4888 (match_operand:V2DI 4 "all_ones_constant" "")
4889 (match_operand:V2DI 5 "zero_constant" "")))]
4891 "xscmp%V1dp %x0,%x2,%x3"
4892 [(set_attr "type" "fpcompare")])
4894 (define_insn "*xxsel<mode>"
4895 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4896 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
4897 (match_operand:V2DI 2 "zero_constant" ""))
4898 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
4899 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
4901 "xxsel %x0,%x1,%x3,%x4"
4902 [(set_attr "type" "vecmove")])
4905 ;; Conversions to and from floating-point.
4907 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4908 ; don't want to support putting SImode in FPR registers.
4909 (define_insn "lfiwax"
4910 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4911 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4913 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4918 [(set_attr "type" "fpload,fpload,mffgpr")])
4920 ; This split must be run before register allocation because it allocates the
4921 ; memory slot that is needed to move values to/from the FPR. We don't allocate
4922 ; it earlier to allow for the combiner to merge insns together where it might
4923 ; not be needed and also in case the insns are deleted as dead code.
4925 (define_insn_and_split "floatsi<mode>2_lfiwax"
4926 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4927 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4928 (clobber (match_scratch:DI 2 "=wi"))]
4929 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4930 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4936 rtx dest = operands[0];
4937 rtx src = operands[1];
4940 if (!MEM_P (src) && TARGET_POWERPC64
4941 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4942 tmp = convert_to_mode (DImode, src, false);
4946 if (GET_CODE (tmp) == SCRATCH)
4947 tmp = gen_reg_rtx (DImode);
4950 src = rs6000_address_for_fpconvert (src);
4951 emit_insn (gen_lfiwax (tmp, src));
4955 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4956 emit_move_insn (stack, src);
4957 emit_insn (gen_lfiwax (tmp, stack));
4960 emit_insn (gen_floatdi<mode>2 (dest, tmp));
4963 [(set_attr "length" "12")
4964 (set_attr "type" "fpload")])
4966 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
4967 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4970 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
4971 (clobber (match_scratch:DI 2 "=wi"))]
4972 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4979 operands[1] = rs6000_address_for_fpconvert (operands[1]);
4980 if (GET_CODE (operands[2]) == SCRATCH)
4981 operands[2] = gen_reg_rtx (DImode);
4982 emit_insn (gen_lfiwax (operands[2], operands[1]));
4983 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4986 [(set_attr "length" "8")
4987 (set_attr "type" "fpload")])
4989 (define_insn "lfiwzx"
4990 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4991 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4993 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
4998 [(set_attr "type" "fpload,fpload,mftgpr")])
5000 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5001 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5002 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5003 (clobber (match_scratch:DI 2 "=wi"))]
5004 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5011 rtx dest = operands[0];
5012 rtx src = operands[1];
5015 if (!MEM_P (src) && TARGET_POWERPC64
5016 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5017 tmp = convert_to_mode (DImode, src, true);
5021 if (GET_CODE (tmp) == SCRATCH)
5022 tmp = gen_reg_rtx (DImode);
5025 src = rs6000_address_for_fpconvert (src);
5026 emit_insn (gen_lfiwzx (tmp, src));
5030 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5031 emit_move_insn (stack, src);
5032 emit_insn (gen_lfiwzx (tmp, stack));
5035 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5038 [(set_attr "length" "12")
5039 (set_attr "type" "fpload")])
5041 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5042 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5043 (unsigned_float:SFDF
5045 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5046 (clobber (match_scratch:DI 2 "=wi"))]
5047 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5054 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5055 if (GET_CODE (operands[2]) == SCRATCH)
5056 operands[2] = gen_reg_rtx (DImode);
5057 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5058 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5061 [(set_attr "length" "8")
5062 (set_attr "type" "fpload")])
5064 ; For each of these conversions, there is a define_expand, a define_insn
5065 ; with a '#' template, and a define_split (with C code). The idea is
5066 ; to allow constant folding with the template of the define_insn,
5067 ; then to have the insns split later (between sched1 and final).
5069 (define_expand "floatsidf2"
5070 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5071 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5074 (clobber (match_dup 4))
5075 (clobber (match_dup 5))
5076 (clobber (match_dup 6))])]
5078 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5081 if (TARGET_E500_DOUBLE)
5083 if (!REG_P (operands[1]))
5084 operands[1] = force_reg (SImode, operands[1]);
5085 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5088 else if (TARGET_LFIWAX && TARGET_FCFID)
5090 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5093 else if (TARGET_FCFID)
5095 rtx dreg = operands[1];
5097 dreg = force_reg (SImode, dreg);
5098 dreg = convert_to_mode (DImode, dreg, false);
5099 emit_insn (gen_floatdidf2 (operands[0], dreg));
5103 if (!REG_P (operands[1]))
5104 operands[1] = force_reg (SImode, operands[1]);
5105 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5106 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5107 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5108 operands[5] = gen_reg_rtx (DFmode);
5109 operands[6] = gen_reg_rtx (SImode);
5112 (define_insn_and_split "*floatsidf2_internal"
5113 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5114 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5115 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5116 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5117 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5118 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5119 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5120 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5126 rtx lowword, highword;
5127 gcc_assert (MEM_P (operands[4]));
5128 highword = adjust_address (operands[4], SImode, 0);
5129 lowword = adjust_address (operands[4], SImode, 4);
5130 if (! WORDS_BIG_ENDIAN)
5131 std::swap (lowword, highword);
5133 emit_insn (gen_xorsi3 (operands[6], operands[1],
5134 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5135 emit_move_insn (lowword, operands[6]);
5136 emit_move_insn (highword, operands[2]);
5137 emit_move_insn (operands[5], operands[4]);
5138 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5141 [(set_attr "length" "24")
5142 (set_attr "type" "fp")])
5144 ;; If we don't have a direct conversion to single precision, don't enable this
5145 ;; conversion for 32-bit without fast math, because we don't have the insn to
5146 ;; generate the fixup swizzle to avoid double rounding problems.
5147 (define_expand "floatunssisf2"
5148 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5149 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5150 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5153 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5154 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5155 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5160 if (!REG_P (operands[1]))
5161 operands[1] = force_reg (SImode, operands[1]);
5163 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5165 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5170 rtx dreg = operands[1];
5172 dreg = force_reg (SImode, dreg);
5173 dreg = convert_to_mode (DImode, dreg, true);
5174 emit_insn (gen_floatdisf2 (operands[0], dreg));
5179 (define_expand "floatunssidf2"
5180 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5181 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5184 (clobber (match_dup 4))
5185 (clobber (match_dup 5))])]
5187 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5190 if (TARGET_E500_DOUBLE)
5192 if (!REG_P (operands[1]))
5193 operands[1] = force_reg (SImode, operands[1]);
5194 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5197 else if (TARGET_LFIWZX && TARGET_FCFID)
5199 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5202 else if (TARGET_FCFID)
5204 rtx dreg = operands[1];
5206 dreg = force_reg (SImode, dreg);
5207 dreg = convert_to_mode (DImode, dreg, true);
5208 emit_insn (gen_floatdidf2 (operands[0], dreg));
5212 if (!REG_P (operands[1]))
5213 operands[1] = force_reg (SImode, operands[1]);
5214 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5215 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5216 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5217 operands[5] = gen_reg_rtx (DFmode);
5220 (define_insn_and_split "*floatunssidf2_internal"
5221 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5222 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5223 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5224 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5225 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5226 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5227 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5228 && !(TARGET_FCFID && TARGET_POWERPC64)"
5234 rtx lowword, highword;
5235 gcc_assert (MEM_P (operands[4]));
5236 highword = adjust_address (operands[4], SImode, 0);
5237 lowword = adjust_address (operands[4], SImode, 4);
5238 if (! WORDS_BIG_ENDIAN)
5239 std::swap (lowword, highword);
5241 emit_move_insn (lowword, operands[1]);
5242 emit_move_insn (highword, operands[2]);
5243 emit_move_insn (operands[5], operands[4]);
5244 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5247 [(set_attr "length" "20")
5248 (set_attr "type" "fp")])
5250 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5251 ;; vector registers. At the moment, QI/HImode are not allowed in floating
5252 ;; point or vector registers, so we use UNSPEC's to use the load byte and
5253 ;; half-word instructions.
5255 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5256 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5258 (match_operand:QHI 1 "input_operand")))
5259 (clobber (match_scratch:DI 2))
5260 (clobber (match_scratch:DI 3))])]
5261 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5263 if (MEM_P (operands[1]))
5264 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5267 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5268 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5270 (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5271 (clobber (match_scratch:DI 2 "=wi,v"))
5272 (clobber (match_scratch:DI 3 "=r,X"))]
5273 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5274 && TARGET_UPPER_REGS_DI"
5276 "&& reload_completed"
5279 rtx result = operands[0];
5280 rtx input = operands[1];
5281 rtx di = operands[2];
5285 rtx tmp = operands[3];
5286 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5287 emit_move_insn (di, tmp);
5294 emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5296 if (<MODE>mode == QImode)
5298 else if (<MODE>mode == HImode)
5303 di_vector = gen_rtx_REG (vmode, REGNO (di));
5304 emit_insn (gen_vsx_sign_extend_<QHI:mode>_di (di, di_vector));
5307 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5311 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5312 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "")
5313 (unsigned_float:FP_ISA3
5314 (match_operand:QHI 1 "input_operand" "")))
5315 (clobber (match_scratch:DI 2 ""))
5316 (clobber (match_scratch:DI 3 ""))])]
5317 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5319 if (MEM_P (operands[1]))
5320 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5323 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5324 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>")
5325 (unsigned_float:FP_ISA3
5326 (match_operand:QHI 1 "reg_or_indexed_operand" "r,Z")))
5327 (clobber (match_scratch:DI 2 "=wi,wi"))
5328 (clobber (match_scratch:DI 3 "=r,X"))]
5329 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5331 "&& reload_completed"
5334 rtx result = operands[0];
5335 rtx input = operands[1];
5336 rtx di = operands[2];
5337 rtx tmp = operands[3];
5341 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5342 emit_move_insn (di, tmp);
5345 emit_insn (gen_p9_lxsi<QHI:wd>zx (di, input));
5347 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5351 (define_expand "fix_trunc<mode>si2"
5352 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5353 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5354 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5357 if (!<E500_CONVERT>)
5362 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5365 tmp = gen_reg_rtx (DImode);
5366 stack = rs6000_allocate_stack_temp (DImode, true, false);
5367 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5374 ; Like the convert to float patterns, this insn must be split before
5375 ; register allocation so that it can allocate the memory slot if it
5377 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5378 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5379 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5380 (clobber (match_scratch:DI 2 "=d"))]
5381 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5382 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5383 && TARGET_STFIWX && can_create_pseudo_p ()"
5388 rtx dest = operands[0];
5389 rtx src = operands[1];
5390 rtx tmp = operands[2];
5392 if (GET_CODE (tmp) == SCRATCH)
5393 tmp = gen_reg_rtx (DImode);
5395 emit_insn (gen_fctiwz_<mode> (tmp, src));
5398 dest = rs6000_address_for_fpconvert (dest);
5399 emit_insn (gen_stfiwx (dest, tmp));
5402 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5404 dest = gen_lowpart (DImode, dest);
5405 emit_move_insn (dest, tmp);
5410 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5411 emit_insn (gen_stfiwx (stack, tmp));
5412 emit_move_insn (dest, stack);
5416 [(set_attr "length" "12")
5417 (set_attr "type" "fp")])
5419 (define_insn_and_split "fix_trunc<mode>si2_internal"
5420 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5421 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5422 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5423 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5424 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5431 gcc_assert (MEM_P (operands[3]));
5432 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5434 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5435 emit_move_insn (operands[3], operands[2]);
5436 emit_move_insn (operands[0], lowword);
5439 [(set_attr "length" "16")
5440 (set_attr "type" "fp")])
5442 (define_expand "fix_trunc<mode>di2"
5443 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5444 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5445 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5449 (define_insn "*fix_trunc<mode>di2_fctidz"
5450 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5451 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5452 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5457 [(set_attr "type" "fp")])
5459 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5460 [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5461 (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5462 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5464 rtx op0 = operands[0];
5465 rtx op1 = operands[1];
5466 rtx di_tmp = gen_reg_rtx (DImode);
5469 op0 = rs6000_address_for_fpconvert (op0);
5471 emit_insn (gen_fctiwz_<SFDF:mode> (di_tmp, op1));
5472 emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5476 (define_expand "fixuns_trunc<mode>si2"
5477 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5478 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5480 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5484 if (!<E500_CONVERT>)
5486 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5491 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5492 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5493 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5494 (clobber (match_scratch:DI 2 "=d"))]
5495 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5496 && TARGET_STFIWX && can_create_pseudo_p ()"
5501 rtx dest = operands[0];
5502 rtx src = operands[1];
5503 rtx tmp = operands[2];
5505 if (GET_CODE (tmp) == SCRATCH)
5506 tmp = gen_reg_rtx (DImode);
5508 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5511 dest = rs6000_address_for_fpconvert (dest);
5512 emit_insn (gen_stfiwx (dest, tmp));
5515 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5517 dest = gen_lowpart (DImode, dest);
5518 emit_move_insn (dest, tmp);
5523 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5524 emit_insn (gen_stfiwx (stack, tmp));
5525 emit_move_insn (dest, stack);
5529 [(set_attr "length" "12")
5530 (set_attr "type" "fp")])
5532 (define_expand "fixuns_trunc<mode>di2"
5533 [(set (match_operand:DI 0 "register_operand" "")
5534 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5535 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5538 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5539 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5540 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5541 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5546 [(set_attr "type" "fp")])
5548 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5549 [(use (match_operand:QHI 0 "rs6000_nonimmediate_operand" ""))
5550 (use (match_operand:SFDF 1 "vsx_register_operand" ""))]
5551 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5553 rtx op0 = operands[0];
5554 rtx op1 = operands[1];
5555 rtx di_tmp = gen_reg_rtx (DImode);
5558 op0 = rs6000_address_for_fpconvert (op0);
5560 emit_insn (gen_fctiwuz_<SFDF:mode> (di_tmp, op1));
5561 emit_insn (gen_p9_stxsi<QHI:wd>x (op0, di_tmp));
5565 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5566 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5567 ; because the first makes it clear that operand 0 is not live
5568 ; before the instruction.
5569 (define_insn "fctiwz_<mode>"
5570 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5571 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5573 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5577 [(set_attr "type" "fp")])
5579 (define_insn "fctiwuz_<mode>"
5580 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5581 (unspec:DI [(unsigned_fix:SI
5582 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5584 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5588 [(set_attr "type" "fp")])
5590 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5591 ;; since the friz instruction does not truncate the value if the floating
5592 ;; point value is < LONG_MIN or > LONG_MAX.
5593 (define_insn "*friz"
5594 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5595 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5596 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5597 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5601 [(set_attr "type" "fp")])
5603 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5604 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5605 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5606 ;; extend it, store it back on the stack from the GPR, load it back into the
5607 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5608 ;; disable using store and load to sign/zero extend the value.
5609 (define_insn_and_split "*round32<mode>2_fprs"
5610 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5612 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5613 (clobber (match_scratch:DI 2 "=d"))
5614 (clobber (match_scratch:DI 3 "=d"))]
5615 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5616 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5617 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5622 rtx dest = operands[0];
5623 rtx src = operands[1];
5624 rtx tmp1 = operands[2];
5625 rtx tmp2 = operands[3];
5626 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5628 if (GET_CODE (tmp1) == SCRATCH)
5629 tmp1 = gen_reg_rtx (DImode);
5630 if (GET_CODE (tmp2) == SCRATCH)
5631 tmp2 = gen_reg_rtx (DImode);
5633 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5634 emit_insn (gen_stfiwx (stack, tmp1));
5635 emit_insn (gen_lfiwax (tmp2, stack));
5636 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5639 [(set_attr "type" "fpload")
5640 (set_attr "length" "16")])
5642 (define_insn_and_split "*roundu32<mode>2_fprs"
5643 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5644 (unsigned_float:SFDF
5645 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5646 (clobber (match_scratch:DI 2 "=d"))
5647 (clobber (match_scratch:DI 3 "=d"))]
5648 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5649 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5650 && can_create_pseudo_p ()"
5655 rtx dest = operands[0];
5656 rtx src = operands[1];
5657 rtx tmp1 = operands[2];
5658 rtx tmp2 = operands[3];
5659 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5661 if (GET_CODE (tmp1) == SCRATCH)
5662 tmp1 = gen_reg_rtx (DImode);
5663 if (GET_CODE (tmp2) == SCRATCH)
5664 tmp2 = gen_reg_rtx (DImode);
5666 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5667 emit_insn (gen_stfiwx (stack, tmp1));
5668 emit_insn (gen_lfiwzx (tmp2, stack));
5669 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5672 [(set_attr "type" "fpload")
5673 (set_attr "length" "16")])
5675 ;; No VSX equivalent to fctid
5676 (define_insn "lrint<mode>di2"
5677 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5678 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5680 "TARGET_<MODE>_FPR && TARGET_FPRND"
5682 [(set_attr "type" "fp")])
5684 (define_insn "btrunc<mode>2"
5685 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5686 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5688 "TARGET_<MODE>_FPR && TARGET_FPRND"
5692 [(set_attr "type" "fp")
5693 (set_attr "fp_type" "fp_addsub_<Fs>")])
5695 (define_insn "ceil<mode>2"
5696 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5697 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5699 "TARGET_<MODE>_FPR && TARGET_FPRND"
5703 [(set_attr "type" "fp")
5704 (set_attr "fp_type" "fp_addsub_<Fs>")])
5706 (define_insn "floor<mode>2"
5707 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5708 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5710 "TARGET_<MODE>_FPR && TARGET_FPRND"
5714 [(set_attr "type" "fp")
5715 (set_attr "fp_type" "fp_addsub_<Fs>")])
5717 ;; No VSX equivalent to frin
5718 (define_insn "round<mode>2"
5719 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5720 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5722 "TARGET_<MODE>_FPR && TARGET_FPRND"
5724 [(set_attr "type" "fp")
5725 (set_attr "fp_type" "fp_addsub_<Fs>")])
5727 (define_insn "*xsrdpi<mode>2"
5728 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5729 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5731 "TARGET_<MODE>_FPR && TARGET_VSX"
5733 [(set_attr "type" "fp")
5734 (set_attr "fp_type" "fp_addsub_<Fs>")])
5736 (define_expand "lround<mode>di2"
5738 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5740 (set (match_operand:DI 0 "gpc_reg_operand" "")
5741 (unspec:DI [(match_dup 2)]
5743 "TARGET_<MODE>_FPR && TARGET_VSX"
5745 operands[2] = gen_reg_rtx (<MODE>mode);
5748 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5749 (define_insn "stfiwx"
5750 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5751 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wv")]
5757 [(set_attr "type" "fpstore")])
5759 ;; If we don't have a direct conversion to single precision, don't enable this
5760 ;; conversion for 32-bit without fast math, because we don't have the insn to
5761 ;; generate the fixup swizzle to avoid double rounding problems.
5762 (define_expand "floatsisf2"
5763 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5764 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5765 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5768 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5769 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5770 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5775 if (!REG_P (operands[1]))
5776 operands[1] = force_reg (SImode, operands[1]);
5778 else if (TARGET_FCFIDS && TARGET_LFIWAX)
5780 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5783 else if (TARGET_FCFID && TARGET_LFIWAX)
5785 rtx dfreg = gen_reg_rtx (DFmode);
5786 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5787 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5792 rtx dreg = operands[1];
5794 dreg = force_reg (SImode, dreg);
5795 dreg = convert_to_mode (DImode, dreg, false);
5796 emit_insn (gen_floatdisf2 (operands[0], dreg));
5801 (define_expand "floatdidf2"
5802 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5803 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5804 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5807 (define_insn "*floatdidf2_fpr"
5808 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5809 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5810 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5814 [(set_attr "type" "fp")])
5816 ; Allow the combiner to merge source memory operands to the conversion so that
5817 ; the optimizer/register allocator doesn't try to load the value too early in a
5818 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5819 ; hit. We will split after reload to avoid the trip through the GPRs
5821 (define_insn_and_split "*floatdidf2_mem"
5822 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5823 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5824 (clobber (match_scratch:DI 2 "=d,wi"))]
5825 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5827 "&& reload_completed"
5828 [(set (match_dup 2) (match_dup 1))
5829 (set (match_dup 0) (float:DF (match_dup 2)))]
5831 [(set_attr "length" "8")
5832 (set_attr "type" "fpload")])
5834 (define_expand "floatunsdidf2"
5835 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5837 (match_operand:DI 1 "gpc_reg_operand" "")))]
5838 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5841 (define_insn "*floatunsdidf2_fcfidu"
5842 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5843 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5844 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5848 [(set_attr "type" "fp")
5849 (set_attr "length" "4")])
5851 (define_insn_and_split "*floatunsdidf2_mem"
5852 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5853 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5854 (clobber (match_scratch:DI 2 "=d,wi"))]
5855 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5857 "&& reload_completed"
5858 [(set (match_dup 2) (match_dup 1))
5859 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5861 [(set_attr "length" "8")
5862 (set_attr "type" "fpload")])
5864 (define_expand "floatdisf2"
5865 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5866 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5867 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5868 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5873 rtx val = operands[1];
5874 if (!flag_unsafe_math_optimizations)
5876 rtx label = gen_label_rtx ();
5877 val = gen_reg_rtx (DImode);
5878 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5881 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5886 (define_insn "floatdisf2_fcfids"
5887 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5888 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5889 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5890 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5894 [(set_attr "type" "fp")])
5896 (define_insn_and_split "*floatdisf2_mem"
5897 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5898 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5899 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5900 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5901 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5903 "&& reload_completed"
5907 emit_move_insn (operands[2], operands[1]);
5908 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5911 [(set_attr "length" "8")])
5913 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5914 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5915 ;; from double rounding.
5916 ;; Instead of creating a new cpu type for two FP operations, just use fp
5917 (define_insn_and_split "floatdisf2_internal1"
5918 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5919 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5920 (clobber (match_scratch:DF 2 "=d"))]
5921 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5924 "&& reload_completed"
5926 (float:DF (match_dup 1)))
5928 (float_truncate:SF (match_dup 2)))]
5930 [(set_attr "length" "8")
5931 (set_attr "type" "fp")])
5933 ;; Twiddles bits to avoid double rounding.
5934 ;; Bits that might be truncated when converting to DFmode are replaced
5935 ;; by a bit that won't be lost at that stage, but is below the SFmode
5936 ;; rounding position.
5937 (define_expand "floatdisf2_internal2"
5938 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5940 (clobber (reg:DI CA_REGNO))])
5941 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5943 (set (match_dup 3) (plus:DI (match_dup 3)
5945 (set (match_dup 0) (plus:DI (match_dup 0)
5947 (set (match_dup 4) (compare:CCUNS (match_dup 3)
5949 (set (match_dup 0) (ior:DI (match_dup 0)
5951 (set (match_dup 0) (and:DI (match_dup 0)
5953 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5954 (label_ref (match_operand:DI 2 "" ""))
5956 (set (match_dup 0) (match_dup 1))]
5957 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5961 operands[3] = gen_reg_rtx (DImode);
5962 operands[4] = gen_reg_rtx (CCUNSmode);
5965 (define_expand "floatunsdisf2"
5966 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5967 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5968 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5969 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5972 (define_insn "floatunsdisf2_fcfidus"
5973 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5974 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5975 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5976 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5980 [(set_attr "type" "fp")])
5982 (define_insn_and_split "*floatunsdisf2_mem"
5983 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5984 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5985 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5986 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5987 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5989 "&& reload_completed"
5993 emit_move_insn (operands[2], operands[1]);
5994 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
5997 [(set_attr "length" "8")
5998 (set_attr "type" "fpload")])
6000 ;; Define the TImode operations that can be done in a small number
6001 ;; of instructions. The & constraints are to prevent the register
6002 ;; allocator from allocating registers that overlap with the inputs
6003 ;; (for example, having an input in 7,8 and an output in 6,7). We
6004 ;; also allow for the output being the same as one of the inputs.
6006 (define_expand "addti3"
6007 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6008 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6009 (match_operand:TI 2 "reg_or_short_operand" "")))]
6012 rtx lo0 = gen_lowpart (DImode, operands[0]);
6013 rtx lo1 = gen_lowpart (DImode, operands[1]);
6014 rtx lo2 = gen_lowpart (DImode, operands[2]);
6015 rtx hi0 = gen_highpart (DImode, operands[0]);
6016 rtx hi1 = gen_highpart (DImode, operands[1]);
6017 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6019 if (!reg_or_short_operand (lo2, DImode))
6020 lo2 = force_reg (DImode, lo2);
6021 if (!adde_operand (hi2, DImode))
6022 hi2 = force_reg (DImode, hi2);
6024 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6025 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6029 (define_expand "subti3"
6030 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6031 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6032 (match_operand:TI 2 "gpc_reg_operand" "")))]
6035 rtx lo0 = gen_lowpart (DImode, operands[0]);
6036 rtx lo1 = gen_lowpart (DImode, operands[1]);
6037 rtx lo2 = gen_lowpart (DImode, operands[2]);
6038 rtx hi0 = gen_highpart (DImode, operands[0]);
6039 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6040 rtx hi2 = gen_highpart (DImode, operands[2]);
6042 if (!reg_or_short_operand (lo1, DImode))
6043 lo1 = force_reg (DImode, lo1);
6044 if (!adde_operand (hi1, DImode))
6045 hi1 = force_reg (DImode, hi1);
6047 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6048 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6052 ;; 128-bit logical operations expanders
6054 (define_expand "and<mode>3"
6055 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6056 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6057 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6061 (define_expand "ior<mode>3"
6062 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6063 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6064 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6068 (define_expand "xor<mode>3"
6069 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6070 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6071 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6075 (define_expand "one_cmpl<mode>2"
6076 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6077 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6081 (define_expand "nor<mode>3"
6082 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6084 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6085 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6089 (define_expand "andc<mode>3"
6090 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6092 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6093 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6097 ;; Power8 vector logical instructions.
6098 (define_expand "eqv<mode>3"
6099 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6101 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6102 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6103 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6106 ;; Rewrite nand into canonical form
6107 (define_expand "nand<mode>3"
6108 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6110 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6111 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6112 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6115 ;; The canonical form is to have the negated element first, so we need to
6116 ;; reverse arguments.
6117 (define_expand "orc<mode>3"
6118 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6120 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6121 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6122 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6125 ;; 128-bit logical operations insns and split operations
6126 (define_insn_and_split "*and<mode>3_internal"
6127 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6129 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6130 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6133 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6134 return "xxland %x0,%x1,%x2";
6136 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6137 return "vand %0,%1,%2";
6141 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6144 rs6000_split_logical (operands, AND, false, false, false);
6149 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6150 (const_string "veclogical")
6151 (const_string "integer")))
6152 (set (attr "length")
6154 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6157 (match_test "TARGET_POWERPC64")
6159 (const_string "16"))))])
6162 (define_insn_and_split "*bool<mode>3_internal"
6163 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6164 (match_operator:BOOL_128 3 "boolean_or_operator"
6165 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6166 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6169 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6170 return "xxl%q3 %x0,%x1,%x2";
6172 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6173 return "v%q3 %0,%1,%2";
6177 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6180 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6185 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6186 (const_string "veclogical")
6187 (const_string "integer")))
6188 (set (attr "length")
6190 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6193 (match_test "TARGET_POWERPC64")
6195 (const_string "16"))))])
6198 (define_insn_and_split "*boolc<mode>3_internal1"
6199 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6200 (match_operator:BOOL_128 3 "boolean_operator"
6202 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6203 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6204 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6206 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6207 return "xxl%q3 %x0,%x1,%x2";
6209 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6210 return "v%q3 %0,%1,%2";
6214 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6215 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6218 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6223 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6224 (const_string "veclogical")
6225 (const_string "integer")))
6226 (set (attr "length")
6228 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6231 (match_test "TARGET_POWERPC64")
6233 (const_string "16"))))])
6235 (define_insn_and_split "*boolc<mode>3_internal2"
6236 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6237 (match_operator:TI2 3 "boolean_operator"
6239 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6240 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6241 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6243 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6246 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6249 [(set_attr "type" "integer")
6250 (set (attr "length")
6252 (match_test "TARGET_POWERPC64")
6254 (const_string "16")))])
6257 (define_insn_and_split "*boolcc<mode>3_internal1"
6258 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6259 (match_operator:BOOL_128 3 "boolean_operator"
6261 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6263 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6264 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6266 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6267 return "xxl%q3 %x0,%x1,%x2";
6269 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6270 return "v%q3 %0,%1,%2";
6274 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6275 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6278 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6283 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6284 (const_string "veclogical")
6285 (const_string "integer")))
6286 (set (attr "length")
6288 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6291 (match_test "TARGET_POWERPC64")
6293 (const_string "16"))))])
6295 (define_insn_and_split "*boolcc<mode>3_internal2"
6296 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6297 (match_operator:TI2 3 "boolean_operator"
6299 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6301 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6302 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6304 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6307 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6310 [(set_attr "type" "integer")
6311 (set (attr "length")
6313 (match_test "TARGET_POWERPC64")
6315 (const_string "16")))])
6319 (define_insn_and_split "*eqv<mode>3_internal1"
6320 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6323 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6324 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6327 if (vsx_register_operand (operands[0], <MODE>mode))
6328 return "xxleqv %x0,%x1,%x2";
6332 "TARGET_P8_VECTOR && reload_completed
6333 && int_reg_operand (operands[0], <MODE>mode)"
6336 rs6000_split_logical (operands, XOR, true, false, false);
6341 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6342 (const_string "veclogical")
6343 (const_string "integer")))
6344 (set (attr "length")
6346 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6349 (match_test "TARGET_POWERPC64")
6351 (const_string "16"))))])
6353 (define_insn_and_split "*eqv<mode>3_internal2"
6354 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6357 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6358 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6361 "reload_completed && !TARGET_P8_VECTOR"
6364 rs6000_split_logical (operands, XOR, true, false, false);
6367 [(set_attr "type" "integer")
6368 (set (attr "length")
6370 (match_test "TARGET_POWERPC64")
6372 (const_string "16")))])
6374 ;; 128-bit one's complement
6375 (define_insn_and_split "*one_cmpl<mode>3_internal"
6376 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6378 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6381 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6382 return "xxlnor %x0,%x1,%x1";
6384 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6385 return "vnor %0,%1,%1";
6389 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6392 rs6000_split_logical (operands, NOT, false, false, false);
6397 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6398 (const_string "veclogical")
6399 (const_string "integer")))
6400 (set (attr "length")
6402 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6405 (match_test "TARGET_POWERPC64")
6407 (const_string "16"))))])
6410 ;; Now define ways of moving data around.
6412 ;; Set up a register with a value from the GOT table
6414 (define_expand "movsi_got"
6415 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6416 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6417 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6418 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6421 if (GET_CODE (operands[1]) == CONST)
6423 rtx offset = const0_rtx;
6424 HOST_WIDE_INT value;
6426 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6427 value = INTVAL (offset);
6430 rtx tmp = (!can_create_pseudo_p ()
6432 : gen_reg_rtx (Pmode));
6433 emit_insn (gen_movsi_got (tmp, operands[1]));
6434 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6439 operands[2] = rs6000_got_register (operands[1]);
6442 (define_insn "*movsi_got_internal"
6443 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6444 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6445 (match_operand:SI 2 "gpc_reg_operand" "b")]
6447 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6448 "lwz %0,%a1@got(%2)"
6449 [(set_attr "type" "load")])
6451 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6452 ;; didn't get allocated to a hard register.
6454 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6455 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6456 (match_operand:SI 2 "memory_operand" "")]
6458 "DEFAULT_ABI == ABI_V4
6460 && (reload_in_progress || reload_completed)"
6461 [(set (match_dup 0) (match_dup 2))
6462 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6466 ;; For SI, we special-case integers that can't be loaded in one insn. We
6467 ;; do the load 16-bits at a time. We could do this by loading from memory,
6468 ;; and this is even supposed to be faster, but it is simpler not to get
6469 ;; integers in the TOC.
6470 (define_insn "movsi_low"
6471 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6472 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6473 (match_operand 2 "" ""))))]
6474 "TARGET_MACHO && ! TARGET_64BIT"
6475 "lwz %0,lo16(%2)(%1)"
6476 [(set_attr "type" "load")
6477 (set_attr "length" "4")])
6479 (define_insn "*movsi_internal1"
6480 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6481 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6482 "!TARGET_SINGLE_FPU &&
6483 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6496 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6497 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6499 (define_insn "*movsi_internal1_single"
6500 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6501 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6502 "TARGET_SINGLE_FPU &&
6503 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6518 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6519 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6521 ;; Split a load of a large constant into the appropriate two-insn
6525 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6526 (match_operand:SI 1 "const_int_operand" ""))]
6527 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6528 && (INTVAL (operands[1]) & 0xffff) != 0"
6532 (ior:SI (match_dup 0)
6536 if (rs6000_emit_set_const (operands[0], operands[1]))
6542 (define_insn "*mov<mode>_internal2"
6543 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6544 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6546 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6552 [(set_attr "type" "cmp,logical,cmp")
6553 (set_attr "dot" "yes")
6554 (set_attr "length" "4,4,8")])
6557 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6558 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6560 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6562 [(set (match_dup 0) (match_dup 1))
6564 (compare:CC (match_dup 0)
6568 (define_insn "*movhi_internal"
6569 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6570 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6571 "gpc_reg_operand (operands[0], HImode)
6572 || gpc_reg_operand (operands[1], HImode)"
6581 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6583 (define_expand "mov<mode>"
6584 [(set (match_operand:INT 0 "general_operand" "")
6585 (match_operand:INT 1 "any_operand" ""))]
6587 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6589 (define_insn "*movqi_internal"
6590 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6591 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6592 "gpc_reg_operand (operands[0], QImode)
6593 || gpc_reg_operand (operands[1], QImode)"
6602 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6604 ;; Here is how to move condition codes around. When we store CC data in
6605 ;; an integer register or memory, we store just the high-order 4 bits.
6606 ;; This lets us not shift in the most common case of CR0.
6607 (define_expand "movcc"
6608 [(set (match_operand:CC 0 "nonimmediate_operand" "")
6609 (match_operand:CC 1 "nonimmediate_operand" ""))]
6613 (define_insn "*movcc_internal1"
6614 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6615 (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6616 "register_operand (operands[0], CCmode)
6617 || register_operand (operands[1], CCmode)"
6621 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6624 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6632 (cond [(eq_attr "alternative" "0,3")
6633 (const_string "cr_logical")
6634 (eq_attr "alternative" "1,2")
6635 (const_string "mtcr")
6636 (eq_attr "alternative" "6,7")
6637 (const_string "integer")
6638 (eq_attr "alternative" "8")
6639 (const_string "mfjmpr")
6640 (eq_attr "alternative" "9")
6641 (const_string "mtjmpr")
6642 (eq_attr "alternative" "10")
6643 (const_string "load")
6644 (eq_attr "alternative" "11")
6645 (const_string "store")
6646 (match_test "TARGET_MFCRF")
6647 (const_string "mfcrf")
6649 (const_string "mfcr")))
6650 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6652 ;; For floating-point, we normally deal with the floating-point registers
6653 ;; unless -msoft-float is used. The sole exception is that parameter passing
6654 ;; can produce floating-point values in fixed-point registers. Unless the
6655 ;; value is a simple constant or already in memory, we deal with this by
6656 ;; allocating memory and copying the value explicitly via that memory location.
6658 ;; Move 32-bit binary/decimal floating point
6659 (define_expand "mov<mode>"
6660 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6661 (match_operand:FMOVE32 1 "any_operand" ""))]
6663 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6666 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6667 (match_operand:FMOVE32 1 "const_double_operand" ""))]
6669 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6670 || (GET_CODE (operands[0]) == SUBREG
6671 && GET_CODE (SUBREG_REG (operands[0])) == REG
6672 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6673 [(set (match_dup 2) (match_dup 3))]
6678 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6680 if (! TARGET_POWERPC64)
6681 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6683 operands[2] = gen_lowpart (SImode, operands[0]);
6685 operands[3] = gen_int_mode (l, SImode);
6688 (define_insn "mov<mode>_hardfloat"
6689 [(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")
6690 (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"))]
6691 "(gpc_reg_operand (operands[0], <MODE>mode)
6692 || gpc_reg_operand (operands[1], <MODE>mode))
6693 && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6699 xscpsgndp %x0,%x1,%x1
6713 [(set_attr "type" "*,load,store,fpsimple,fpsimple,veclogical,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mffgpr,mftgpr,mtjmpr,mfjmpr,*")
6714 (set_attr "length" "4")])
6716 (define_insn "*mov<mode>_softfloat"
6717 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6718 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6719 "(gpc_reg_operand (operands[0], <MODE>mode)
6720 || gpc_reg_operand (operands[1], <MODE>mode))
6721 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6733 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6734 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6737 ;; Move 64-bit binary/decimal floating point
6738 (define_expand "mov<mode>"
6739 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6740 (match_operand:FMOVE64 1 "any_operand" ""))]
6742 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6745 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6746 (match_operand:FMOVE64 1 "const_int_operand" ""))]
6747 "! TARGET_POWERPC64 && reload_completed
6748 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6749 || (GET_CODE (operands[0]) == SUBREG
6750 && GET_CODE (SUBREG_REG (operands[0])) == REG
6751 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6752 [(set (match_dup 2) (match_dup 4))
6753 (set (match_dup 3) (match_dup 1))]
6756 int endian = (WORDS_BIG_ENDIAN == 0);
6757 HOST_WIDE_INT value = INTVAL (operands[1]);
6759 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6760 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6761 operands[4] = GEN_INT (value >> 32);
6762 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6766 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6767 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6768 "! TARGET_POWERPC64 && reload_completed
6769 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6770 || (GET_CODE (operands[0]) == SUBREG
6771 && GET_CODE (SUBREG_REG (operands[0])) == REG
6772 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6773 [(set (match_dup 2) (match_dup 4))
6774 (set (match_dup 3) (match_dup 5))]
6777 int endian = (WORDS_BIG_ENDIAN == 0);
6780 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6782 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6783 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6784 operands[4] = gen_int_mode (l[endian], SImode);
6785 operands[5] = gen_int_mode (l[1 - endian], SImode);
6789 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6790 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6791 "TARGET_POWERPC64 && reload_completed
6792 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6793 || (GET_CODE (operands[0]) == SUBREG
6794 && GET_CODE (SUBREG_REG (operands[0])) == REG
6795 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6796 [(set (match_dup 2) (match_dup 3))]
6799 int endian = (WORDS_BIG_ENDIAN == 0);
6803 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6805 operands[2] = gen_lowpart (DImode, operands[0]);
6806 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
6807 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6808 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6810 operands[3] = gen_int_mode (val, DImode);
6813 ;; Don't have reload use general registers to load a constant. It is
6814 ;; less efficient than loading the constant into an FP register, since
6815 ;; it will probably be used there.
6817 ;; The move constraints are ordered to prefer floating point registers before
6818 ;; general purpose registers to avoid doing a store and a load to get the value
6819 ;; into a floating point register when it is needed for a floating point
6820 ;; operation. Prefer traditional floating point registers over VSX registers,
6821 ;; since the D-form version of the memory instructions does not need a GPR for
6822 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6825 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6826 ;; except for 0.0 which can be created on VSX with an xor instruction.
6828 (define_insn "*mov<mode>_hardfloat32"
6829 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6830 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
6831 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6832 && (gpc_reg_operand (operands[0], <MODE>mode)
6833 || gpc_reg_operand (operands[1], <MODE>mode))"
6848 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
6849 (set_attr "size" "64")
6850 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6852 (define_insn "*mov<mode>_softfloat32"
6853 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6854 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6856 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
6857 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6858 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6859 && (gpc_reg_operand (operands[0], <MODE>mode)
6860 || gpc_reg_operand (operands[1], <MODE>mode))"
6862 [(set_attr "type" "store,load,two,*,*,*")
6863 (set_attr "length" "8,8,8,8,12,16")])
6865 ; ld/std require word-aligned displacements -> 'Y' constraint.
6866 ; List Y->r and r->Y before r->r for reload.
6867 (define_insn "*mov<mode>_hardfloat64"
6868 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
6869 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
6870 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6871 && (gpc_reg_operand (operands[0], <MODE>mode)
6872 || gpc_reg_operand (operands[1], <MODE>mode))"
6894 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6895 (set_attr "size" "64")
6896 (set_attr "length" "4")])
6898 (define_insn "*mov<mode>_softfloat64"
6899 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6900 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6901 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6902 && (gpc_reg_operand (operands[0], <MODE>mode)
6903 || gpc_reg_operand (operands[1], <MODE>mode))"
6914 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6915 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6917 (define_expand "mov<mode>"
6918 [(set (match_operand:FMOVE128 0 "general_operand" "")
6919 (match_operand:FMOVE128 1 "any_operand" ""))]
6921 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6923 ;; It's important to list Y->r and r->Y before r->r because otherwise
6924 ;; reload, given m->r, will try to pick r->r and reload it, which
6925 ;; doesn't make progress.
6927 ;; We can't split little endian direct moves of TDmode, because the words are
6928 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
6929 ;; problematical. Don't allow direct move for this case.
6931 (define_insn_and_split "*mov<mode>_64bit_dm"
6932 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
6933 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
6934 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6935 && FLOAT128_2REG_P (<MODE>mode)
6936 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6937 && (gpc_reg_operand (operands[0], <MODE>mode)
6938 || gpc_reg_operand (operands[1], <MODE>mode))"
6940 "&& reload_completed"
6942 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6943 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6945 (define_insn_and_split "*movtd_64bit_nodm"
6946 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
6947 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
6948 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6949 && (gpc_reg_operand (operands[0], TDmode)
6950 || gpc_reg_operand (operands[1], TDmode))"
6952 "&& reload_completed"
6954 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6955 [(set_attr "length" "8,8,8,12,12,8")])
6957 (define_insn_and_split "*mov<mode>_32bit"
6958 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
6959 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
6960 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
6961 && (FLOAT128_2REG_P (<MODE>mode)
6962 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
6963 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
6964 && (gpc_reg_operand (operands[0], <MODE>mode)
6965 || gpc_reg_operand (operands[1], <MODE>mode))"
6967 "&& reload_completed"
6969 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6970 [(set_attr "length" "8,8,8,8,20,20,16")])
6972 (define_insn_and_split "*mov<mode>_softfloat"
6973 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
6974 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
6975 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
6976 && (gpc_reg_operand (operands[0], <MODE>mode)
6977 || gpc_reg_operand (operands[1], <MODE>mode))"
6979 "&& reload_completed"
6981 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6982 [(set_attr "length" "20,20,16")])
6984 (define_expand "extenddf<mode>2"
6985 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6986 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
6987 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
6988 && TARGET_LONG_DOUBLE_128"
6990 if (FLOAT128_IEEE_P (<MODE>mode))
6991 rs6000_expand_float128_convert (operands[0], operands[1], false);
6992 else if (TARGET_E500_DOUBLE)
6994 gcc_assert (<MODE>mode == TFmode);
6995 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
6997 else if (TARGET_VSX)
6999 if (<MODE>mode == TFmode)
7000 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7001 else if (<MODE>mode == IFmode)
7002 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7008 rtx zero = gen_reg_rtx (DFmode);
7009 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7011 if (<MODE>mode == TFmode)
7012 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7013 else if (<MODE>mode == IFmode)
7014 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7021 ;; Allow memory operands for the source to be created by the combiner.
7022 (define_insn_and_split "extenddf<mode>2_fprs"
7023 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7024 (float_extend:IBM128
7025 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7026 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7027 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7028 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7030 "&& reload_completed"
7031 [(set (match_dup 3) (match_dup 1))
7032 (set (match_dup 4) (match_dup 2))]
7034 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7035 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7037 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7038 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7041 (define_insn_and_split "extenddf<mode>2_vsx"
7042 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7043 (float_extend:IBM128
7044 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7045 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7047 "&& reload_completed"
7048 [(set (match_dup 2) (match_dup 1))
7049 (set (match_dup 3) (match_dup 4))]
7051 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7052 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7054 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7055 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7056 operands[4] = CONST0_RTX (DFmode);
7059 (define_expand "extendsf<mode>2"
7060 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7061 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7063 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7064 && TARGET_LONG_DOUBLE_128"
7066 if (FLOAT128_IEEE_P (<MODE>mode))
7067 rs6000_expand_float128_convert (operands[0], operands[1], false);
7070 rtx tmp = gen_reg_rtx (DFmode);
7071 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7072 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7077 (define_expand "trunc<mode>df2"
7078 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7079 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7081 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7082 && TARGET_LONG_DOUBLE_128"
7084 if (FLOAT128_IEEE_P (<MODE>mode))
7086 rs6000_expand_float128_convert (operands[0], operands[1], false);
7091 (define_insn_and_split "trunc<mode>df2_internal1"
7092 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7094 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7095 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7096 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7100 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7103 emit_note (NOTE_INSN_DELETED);
7106 [(set_attr "type" "fpsimple")])
7108 (define_insn "trunc<mode>df2_internal2"
7109 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7110 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7111 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7112 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7114 [(set_attr "type" "fp")
7115 (set_attr "fp_type" "fp_addsub_d")])
7117 (define_expand "trunc<mode>sf2"
7118 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7119 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7121 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7122 && TARGET_LONG_DOUBLE_128"
7124 if (FLOAT128_IEEE_P (<MODE>mode))
7125 rs6000_expand_float128_convert (operands[0], operands[1], false);
7126 else if (TARGET_E500_DOUBLE)
7128 gcc_assert (<MODE>mode == TFmode);
7129 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7131 else if (<MODE>mode == TFmode)
7132 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7133 else if (<MODE>mode == IFmode)
7134 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7140 (define_insn_and_split "trunc<mode>sf2_fprs"
7141 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7142 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7143 (clobber (match_scratch:DF 2 "=d"))]
7144 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7145 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7147 "&& reload_completed"
7149 (float_truncate:DF (match_dup 1)))
7151 (float_truncate:SF (match_dup 2)))]
7154 (define_expand "floatsi<mode>2"
7155 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7156 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7158 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7159 && TARGET_LONG_DOUBLE_128"
7161 if (FLOAT128_IEEE_P (<MODE>mode))
7162 rs6000_expand_float128_convert (operands[0], operands[1], false);
7165 rtx tmp = gen_reg_rtx (DFmode);
7166 expand_float (tmp, operands[1], false);
7167 if (<MODE>mode == TFmode)
7168 emit_insn (gen_extenddftf2 (operands[0], tmp));
7169 else if (<MODE>mode == IFmode)
7170 emit_insn (gen_extenddfif2 (operands[0], tmp));
7177 ; fadd, but rounding towards zero.
7178 ; This is probably not the optimal code sequence.
7179 (define_insn "fix_trunc_helper<mode>"
7180 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7181 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7182 UNSPEC_FIX_TRUNC_TF))
7183 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7184 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7185 && FLOAT128_IBM_P (<MODE>mode)"
7186 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7187 [(set_attr "type" "fp")
7188 (set_attr "length" "20")])
7190 (define_expand "fix_trunc<mode>si2"
7191 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7192 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7194 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7196 if (FLOAT128_IEEE_P (<MODE>mode))
7197 rs6000_expand_float128_convert (operands[0], operands[1], false);
7198 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7199 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7200 else if (<MODE>mode == TFmode)
7201 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7202 else if (<MODE>mode == IFmode)
7203 emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7209 (define_expand "fix_trunc<mode>si2_fprs"
7210 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7211 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7212 (clobber (match_dup 2))
7213 (clobber (match_dup 3))
7214 (clobber (match_dup 4))
7215 (clobber (match_dup 5))])]
7216 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7218 operands[2] = gen_reg_rtx (DFmode);
7219 operands[3] = gen_reg_rtx (DFmode);
7220 operands[4] = gen_reg_rtx (DImode);
7221 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7224 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7225 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7226 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7227 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7228 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7229 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7230 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7231 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7237 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7240 gcc_assert (MEM_P (operands[5]));
7241 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7243 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7244 emit_move_insn (operands[5], operands[4]);
7245 emit_move_insn (operands[0], lowword);
7249 (define_expand "fix_trunc<mode>di2"
7250 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7251 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7254 rs6000_expand_float128_convert (operands[0], operands[1], false);
7258 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7259 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7260 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7263 rs6000_expand_float128_convert (operands[0], operands[1], true);
7267 (define_expand "floatdi<mode>2"
7268 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7269 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7272 rs6000_expand_float128_convert (operands[0], operands[1], false);
7276 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7277 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7278 (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7281 rs6000_expand_float128_convert (operands[0], operands[1], true);
7285 (define_expand "neg<mode>2"
7286 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7287 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7288 "FLOAT128_IEEE_P (<MODE>mode)
7289 || (FLOAT128_IBM_P (<MODE>mode)
7290 && TARGET_HARD_FLOAT
7291 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7294 if (FLOAT128_IEEE_P (<MODE>mode))
7296 if (TARGET_FLOAT128_HW)
7298 if (<MODE>mode == TFmode)
7299 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7300 else if (<MODE>mode == KFmode)
7301 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7305 else if (TARGET_FLOAT128)
7307 if (<MODE>mode == TFmode)
7308 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7309 else if (<MODE>mode == KFmode)
7310 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7316 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7317 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7319 operands[1], <MODE>mode);
7321 if (target && !rtx_equal_p (target, operands[0]))
7322 emit_move_insn (operands[0], target);
7328 (define_insn "neg<mode>2_internal"
7329 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7330 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7331 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7334 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7335 return \"fneg %L0,%L1\;fneg %0,%1\";
7337 return \"fneg %0,%1\;fneg %L0,%L1\";
7339 [(set_attr "type" "fpsimple")
7340 (set_attr "length" "8")])
7342 (define_expand "abs<mode>2"
7343 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7344 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7345 "FLOAT128_IEEE_P (<MODE>mode)
7346 || (FLOAT128_IBM_P (<MODE>mode)
7347 && TARGET_HARD_FLOAT
7348 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7353 if (FLOAT128_IEEE_P (<MODE>mode))
7355 if (TARGET_FLOAT128_HW)
7357 if (<MODE>mode == TFmode)
7358 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7359 else if (<MODE>mode == KFmode)
7360 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7365 else if (TARGET_FLOAT128)
7367 if (<MODE>mode == TFmode)
7368 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7369 else if (<MODE>mode == KFmode)
7370 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7379 label = gen_label_rtx ();
7380 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7382 if (flag_finite_math_only && !flag_trapping_math)
7383 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7385 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7387 else if (<MODE>mode == TFmode)
7388 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7389 else if (<MODE>mode == TFmode)
7390 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7397 (define_expand "abs<mode>2_internal"
7398 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7399 (match_operand:IBM128 1 "gpc_reg_operand" ""))
7400 (set (match_dup 3) (match_dup 5))
7401 (set (match_dup 5) (abs:DF (match_dup 5)))
7402 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7403 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7404 (label_ref (match_operand 2 "" ""))
7406 (set (match_dup 6) (neg:DF (match_dup 6)))]
7407 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7408 && TARGET_LONG_DOUBLE_128"
7411 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7412 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7413 operands[3] = gen_reg_rtx (DFmode);
7414 operands[4] = gen_reg_rtx (CCFPmode);
7415 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7416 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7420 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7423 (define_expand "ieee_128bit_negative_zero"
7424 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7427 rtvec v = rtvec_alloc (16);
7430 for (i = 0; i < 16; i++)
7431 RTVEC_ELT (v, i) = const0_rtx;
7433 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7434 RTVEC_ELT (v, high) = GEN_INT (0x80);
7436 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7440 ;; IEEE 128-bit negate
7442 ;; We have 2 insns here for negate and absolute value. The first uses
7443 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7444 ;; insns, and second insn after the first split pass loads up the bit to
7445 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
7446 ;; neg/abs to create the constant just once.
7448 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7449 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7450 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7451 (clobber (match_scratch:V16QI 2 "=v"))]
7452 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7455 [(parallel [(set (match_dup 0)
7456 (neg:IEEE128 (match_dup 1)))
7457 (use (match_dup 2))])]
7459 if (GET_CODE (operands[2]) == SCRATCH)
7460 operands[2] = gen_reg_rtx (V16QImode);
7462 operands[3] = gen_reg_rtx (V16QImode);
7463 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7465 [(set_attr "length" "8")
7466 (set_attr "type" "vecsimple")])
7468 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7469 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7470 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7471 (use (match_operand:V16QI 2 "register_operand" "v"))]
7472 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7473 "xxlxor %x0,%x1,%x2"
7474 [(set_attr "type" "veclogical")])
7476 ;; IEEE 128-bit absolute value
7477 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7478 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7479 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7480 (clobber (match_scratch:V16QI 2 "=v"))]
7481 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7484 [(parallel [(set (match_dup 0)
7485 (abs:IEEE128 (match_dup 1)))
7486 (use (match_dup 2))])]
7488 if (GET_CODE (operands[2]) == SCRATCH)
7489 operands[2] = gen_reg_rtx (V16QImode);
7491 operands[3] = gen_reg_rtx (V16QImode);
7492 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7494 [(set_attr "length" "8")
7495 (set_attr "type" "vecsimple")])
7497 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7498 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7499 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7500 (use (match_operand:V16QI 2 "register_operand" "v"))]
7501 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7502 "xxlandc %x0,%x1,%x2"
7503 [(set_attr "type" "veclogical")])
7505 ;; IEEE 128-bit negative absolute value
7506 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7507 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7510 (match_operand:IEEE128 1 "register_operand" "wa"))))
7511 (clobber (match_scratch:V16QI 2 "=v"))]
7512 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7515 [(parallel [(set (match_dup 0)
7516 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7517 (use (match_dup 2))])]
7519 if (GET_CODE (operands[2]) == SCRATCH)
7520 operands[2] = gen_reg_rtx (V16QImode);
7522 operands[3] = gen_reg_rtx (V16QImode);
7523 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7525 [(set_attr "length" "8")
7526 (set_attr "type" "vecsimple")])
7528 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7529 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7532 (match_operand:IEEE128 1 "register_operand" "wa"))))
7533 (use (match_operand:V16QI 2 "register_operand" "v"))]
7534 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7536 [(set_attr "type" "veclogical")])
7538 ;; Float128 conversion functions. These expand to library function calls.
7539 ;; We use expand to convert from IBM double double to IEEE 128-bit
7540 ;; and trunc for the opposite.
7541 (define_expand "extendiftf2"
7542 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7543 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7546 rs6000_expand_float128_convert (operands[0], operands[1], false);
7550 (define_expand "extendifkf2"
7551 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7552 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7555 rs6000_expand_float128_convert (operands[0], operands[1], false);
7559 (define_expand "extendtfkf2"
7560 [(set (match_operand:KF 0 "gpc_reg_operand" "")
7561 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7564 rs6000_expand_float128_convert (operands[0], operands[1], false);
7568 (define_expand "trunciftf2"
7569 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7570 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7573 rs6000_expand_float128_convert (operands[0], operands[1], false);
7577 (define_expand "truncifkf2"
7578 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7579 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7582 rs6000_expand_float128_convert (operands[0], operands[1], false);
7586 (define_expand "trunckftf2"
7587 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7588 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7591 rs6000_expand_float128_convert (operands[0], operands[1], false);
7595 (define_expand "trunctfif2"
7596 [(set (match_operand:IF 0 "gpc_reg_operand" "")
7597 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7600 rs6000_expand_float128_convert (operands[0], operands[1], false);
7605 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
7606 ;; must have 3 arguments, and scratch register constraint must be a single
7609 ;; Reload patterns to support gpr load/store with misaligned mem.
7610 ;; and multiple gpr load/store at offset >= 0xfffc
7611 (define_expand "reload_<mode>_store"
7612 [(parallel [(match_operand 0 "memory_operand" "=m")
7613 (match_operand 1 "gpc_reg_operand" "r")
7614 (match_operand:GPR 2 "register_operand" "=&b")])]
7617 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7621 (define_expand "reload_<mode>_load"
7622 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7623 (match_operand 1 "memory_operand" "m")
7624 (match_operand:GPR 2 "register_operand" "=b")])]
7627 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7632 ;; Reload patterns for various types using the vector registers. We may need
7633 ;; an additional base register to convert the reg+offset addressing to reg+reg
7634 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7635 ;; index register for gpr registers.
7636 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7637 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7638 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7639 (match_operand:P 2 "register_operand" "=b")])]
7642 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7646 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7647 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7648 (match_operand:RELOAD 1 "memory_operand" "m")
7649 (match_operand:P 2 "register_operand" "=b")])]
7652 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7657 ;; Reload sometimes tries to move the address to a GPR, and can generate
7658 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
7659 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7661 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7662 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7663 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7664 (match_operand:P 2 "reg_or_cint_operand" "rI"))
7666 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7668 "&& reload_completed"
7670 (plus:P (match_dup 1)
7673 (and:P (match_dup 0)
7676 ;; Power8 merge instructions to allow direct move to/from floating point
7677 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
7678 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
7679 ;; value, since it is allocated in reload and not all of the flow information
7680 ;; is setup for it. We have two patterns to do the two moves between gprs and
7681 ;; fprs. There isn't a dependancy between the two, but we could potentially
7682 ;; schedule other instructions between the two instructions.
7684 (define_insn "p8_fmrgow_<mode>"
7685 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7687 (match_operand:DF 1 "register_operand" "d")
7688 (match_operand:DF 2 "register_operand" "d")]
7689 UNSPEC_P8V_FMRGOW))]
7690 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7692 [(set_attr "type" "fpsimple")])
7694 (define_insn "p8_mtvsrwz"
7695 [(set (match_operand:DF 0 "register_operand" "=d")
7696 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7697 UNSPEC_P8V_MTVSRWZ))]
7698 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7700 [(set_attr "type" "mftgpr")])
7702 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7703 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7704 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7705 UNSPEC_P8V_RELOAD_FROM_GPR))
7706 (clobber (match_operand:IF 2 "register_operand" "=d"))]
7707 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7709 "&& reload_completed"
7712 rtx dest = operands[0];
7713 rtx src = operands[1];
7714 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7715 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7716 rtx gpr_hi_reg = gen_highpart (SImode, src);
7717 rtx gpr_lo_reg = gen_lowpart (SImode, src);
7719 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7720 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7721 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7724 [(set_attr "length" "12")
7725 (set_attr "type" "three")])
7727 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7728 (define_insn "p8_mtvsrd_df"
7729 [(set (match_operand:DF 0 "register_operand" "=wa")
7730 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7731 UNSPEC_P8V_MTVSRD))]
7732 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7734 [(set_attr "type" "mftgpr")])
7736 (define_insn "p8_xxpermdi_<mode>"
7737 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7738 (unspec:FMOVE128_GPR [
7739 (match_operand:DF 1 "register_operand" "wa")
7740 (match_operand:DF 2 "register_operand" "wa")]
7741 UNSPEC_P8V_XXPERMDI))]
7742 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7743 "xxpermdi %x0,%x1,%x2,0"
7744 [(set_attr "type" "vecperm")])
7746 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7747 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7748 (unspec:FMOVE128_GPR
7749 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7750 UNSPEC_P8V_RELOAD_FROM_GPR))
7751 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
7752 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7754 "&& reload_completed"
7757 rtx dest = operands[0];
7758 rtx src = operands[1];
7759 /* You might think that we could use op0 as one temp and a DF clobber
7760 as op2, but you'd be wrong. Secondary reload move patterns don't
7761 check for overlap of the clobber and the destination. */
7762 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7763 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7764 rtx gpr_hi_reg = gen_highpart (DImode, src);
7765 rtx gpr_lo_reg = gen_lowpart (DImode, src);
7767 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
7768 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
7769 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
7772 [(set_attr "length" "12")
7773 (set_attr "type" "three")])
7776 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7777 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7779 && (int_reg_operand (operands[0], <MODE>mode)
7780 || int_reg_operand (operands[1], <MODE>mode))
7781 && (!TARGET_DIRECT_MOVE_128
7782 || (!vsx_register_operand (operands[0], <MODE>mode)
7783 && !vsx_register_operand (operands[1], <MODE>mode)))"
7785 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7787 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
7788 ;; type is stored internally as double precision in the VSX registers, we have
7789 ;; to convert it from the vector format.
7790 (define_insn "p8_mtvsrd_sf"
7791 [(set (match_operand:SF 0 "register_operand" "=wa")
7792 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
7793 UNSPEC_P8V_MTVSRD))]
7794 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7796 [(set_attr "type" "mftgpr")])
7798 (define_insn_and_split "reload_vsx_from_gprsf"
7799 [(set (match_operand:SF 0 "register_operand" "=wa")
7800 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7801 UNSPEC_P8V_RELOAD_FROM_GPR))
7802 (clobber (match_operand:DI 2 "register_operand" "=r"))]
7803 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7805 "&& reload_completed"
7808 rtx op0 = operands[0];
7809 rtx op1 = operands[1];
7810 rtx op2 = operands[2];
7811 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7813 /* Move SF value to upper 32-bits for xscvspdpn. */
7814 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7815 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7816 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7819 [(set_attr "length" "8")
7820 (set_attr "type" "two")])
7822 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7823 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7824 ;; and then doing a move of that.
7825 (define_insn "p8_mfvsrd_3_<mode>"
7826 [(set (match_operand:DF 0 "register_operand" "=r")
7827 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7828 UNSPEC_P8V_RELOAD_FROM_VSX))]
7829 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7831 [(set_attr "type" "mftgpr")])
7833 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7834 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7835 (unspec:FMOVE128_GPR
7836 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7837 UNSPEC_P8V_RELOAD_FROM_VSX))
7838 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7839 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7841 "&& reload_completed"
7844 rtx dest = operands[0];
7845 rtx src = operands[1];
7846 rtx tmp = operands[2];
7847 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7848 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7850 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7851 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7852 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7855 [(set_attr "length" "12")
7856 (set_attr "type" "three")])
7858 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
7859 ;; type is stored internally as double precision, we have to convert it to the
7862 (define_insn_and_split "reload_gpr_from_vsxsf"
7863 [(set (match_operand:SF 0 "register_operand" "=r")
7864 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7865 UNSPEC_P8V_RELOAD_FROM_VSX))
7866 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7867 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7869 "&& reload_completed"
7872 rtx op0 = operands[0];
7873 rtx op1 = operands[1];
7874 rtx op2 = operands[2];
7875 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7877 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7878 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7879 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7882 [(set_attr "length" "12")
7883 (set_attr "type" "three")])
7885 (define_insn "p8_mfvsrd_4_disf"
7886 [(set (match_operand:DI 0 "register_operand" "=r")
7887 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7888 UNSPEC_P8V_RELOAD_FROM_VSX))]
7889 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7891 [(set_attr "type" "mftgpr")])
7894 ;; Next come the multi-word integer load and store and the load and store
7897 ;; List r->r after r->Y, otherwise reload will try to reload a
7898 ;; non-offsettable address by using r->r which won't make progress.
7899 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7900 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7902 ;; GPR store GPR load GPR move FPR store FPR load FPR move
7903 ;; GPR const AVX store AVX store AVX load AVX load VSX move
7904 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
7907 (define_insn "*movdi_internal32"
7908 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
7909 "=Y, r, r, ?m, ?*d, ?*d,
7910 r, ?wY, ?Z, ?*wb, ?*wv, ?wi,
7911 ?wo, ?wo, ?wv, ?wi, ?wi, ?wv,
7914 (match_operand:DI 1 "input_operand"
7916 IJKnGHF, wb, wv, wY, Z, wi,
7917 Oj, wM, OjwM, Oj, wM, wS,
7921 && (gpc_reg_operand (operands[0], DImode)
7922 || gpc_reg_operand (operands[1], DImode))"
7944 "store, load, *, fpstore, fpload, fpsimple,
7945 *, fpstore, fpstore, fpload, fpload, veclogical,
7946 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
7948 (set_attr "size" "64")])
7951 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7952 (match_operand:DI 1 "const_int_operand" ""))]
7953 "! TARGET_POWERPC64 && reload_completed
7954 && gpr_or_gpr_p (operands[0], operands[1])
7955 && !direct_move_p (operands[0], operands[1])"
7956 [(set (match_dup 2) (match_dup 4))
7957 (set (match_dup 3) (match_dup 1))]
7960 HOST_WIDE_INT value = INTVAL (operands[1]);
7961 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7963 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7965 operands[4] = GEN_INT (value >> 32);
7966 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7970 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7971 (match_operand:DIFD 1 "input_operand" ""))]
7972 "reload_completed && !TARGET_POWERPC64
7973 && gpr_or_gpr_p (operands[0], operands[1])
7974 && !direct_move_p (operands[0], operands[1])"
7976 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7978 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
7979 ;; FPR store FPR load FPR move AVX store AVX store AVX load
7980 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
7981 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
7982 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
7983 (define_insn "*movdi_internal64"
7984 [(set (match_operand:DI 0 "nonimmediate_operand"
7986 ?m, ?*d, ?*d, ?wY, ?Z, ?*wb,
7987 ?*wv, ?wi, ?wo, ?wo, ?wv, ?wi,
7988 ?wi, ?wv, ?wv, r, *h, *h,
7989 ?*r, ?*wg, ?*r, ?*wj")
7991 (match_operand:DI 1 "input_operand"
7993 d, m, d, wb, wv, wY,
7994 Z, wi, Oj, wM, OjwM, Oj,
7995 wM, wS, wB, *h, r, 0,
7999 && (gpc_reg_operand (operands[0], DImode)
8000 || gpc_reg_operand (operands[1], DImode))"
8031 "store, load, *, *, *, *,
8032 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8033 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8034 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8035 mftgpr, mffgpr, mftgpr, mffgpr")
8037 (set_attr "size" "64")
8045 ; Some DImode loads are best done as a load of -1 followed by a mask
8048 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8049 (match_operand:DI 1 "const_int_operand"))]
8051 && num_insns_constant (operands[1], DImode) > 1
8052 && rs6000_is_valid_and_mask (operands[1], DImode)"
8056 (and:DI (match_dup 0)
8060 ;; Split a load of a large constant into the appropriate five-instruction
8061 ;; sequence. Handle anything in a constant number of insns.
8062 ;; When non-easy constants can go in the TOC, this should use
8063 ;; easy_fp_constant predicate.
8065 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8066 (match_operand:DI 1 "const_int_operand" ""))]
8067 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8068 [(set (match_dup 0) (match_dup 2))
8069 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8072 if (rs6000_emit_set_const (operands[0], operands[1]))
8079 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8080 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8081 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8082 [(set (match_dup 0) (match_dup 2))
8083 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8086 if (rs6000_emit_set_const (operands[0], operands[1]))
8093 [(set (match_operand:DI 0 "altivec_register_operand" "")
8094 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8095 "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8098 rtx op0 = operands[0];
8099 rtx op1 = operands[1];
8100 int r = REGNO (op0);
8101 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8103 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8104 if (op1 != const0_rtx && op1 != constm1_rtx)
8106 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8107 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8113 [(set (match_operand:DI 0 "altivec_register_operand" "")
8114 (match_operand:DI 1 "xxspltib_constant_split" ""))]
8115 "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8118 rtx op0 = operands[0];
8119 rtx op1 = operands[1];
8120 int r = REGNO (op0);
8121 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8123 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8124 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8129 ;; TImode/PTImode is similar, except that we usually want to compute the
8130 ;; address into a register and use lsi/stsi (the exception is during reload).
8132 (define_insn "*mov<mode>_string"
8133 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8134 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8136 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8137 && (gpc_reg_operand (operands[0], <MODE>mode)
8138 || gpc_reg_operand (operands[1], <MODE>mode))"
8141 switch (which_alternative)
8147 return \"stswi %1,%P0,16\";
8151 /* If the address is not used in the output, we can use lsi. Otherwise,
8152 fall through to generating four loads. */
8154 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8155 return \"lswi %0,%P1,16\";
8156 /* ... fall through ... */
8163 [(set_attr "type" "store,store,load,load,*,*")
8164 (set_attr "update" "yes")
8165 (set_attr "indexed" "yes")
8166 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8167 (const_string "always")
8168 (const_string "conditional")))])
8170 (define_insn "*mov<mode>_ppc64"
8171 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8172 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8173 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8174 && (gpc_reg_operand (operands[0], <MODE>mode)
8175 || gpc_reg_operand (operands[1], <MODE>mode)))"
8177 return rs6000_output_move_128bit (operands);
8179 [(set_attr "type" "store,store,load,load,*,*")
8180 (set_attr "length" "8")])
8183 [(set (match_operand:TI2 0 "int_reg_operand" "")
8184 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8186 && (VECTOR_MEM_NONE_P (<MODE>mode)
8187 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8188 [(set (match_dup 2) (match_dup 4))
8189 (set (match_dup 3) (match_dup 5))]
8192 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8194 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8196 if (CONST_WIDE_INT_P (operands[1]))
8198 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8199 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8201 else if (CONST_INT_P (operands[1]))
8203 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8204 operands[5] = operands[1];
8211 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8212 (match_operand:TI2 1 "input_operand" ""))]
8214 && gpr_or_gpr_p (operands[0], operands[1])
8215 && !direct_move_p (operands[0], operands[1])
8216 && !quad_load_store_p (operands[0], operands[1])"
8218 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8220 (define_expand "load_multiple"
8221 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8222 (match_operand:SI 1 "" ""))
8223 (use (match_operand:SI 2 "" ""))])]
8224 "TARGET_STRING && !TARGET_POWERPC64"
8232 /* Support only loading a constant number of fixed-point registers from
8233 memory and only bother with this if more than two; the machine
8234 doesn't support more than eight. */
8235 if (GET_CODE (operands[2]) != CONST_INT
8236 || INTVAL (operands[2]) <= 2
8237 || INTVAL (operands[2]) > 8
8238 || GET_CODE (operands[1]) != MEM
8239 || GET_CODE (operands[0]) != REG
8240 || REGNO (operands[0]) >= 32)
8243 count = INTVAL (operands[2]);
8244 regno = REGNO (operands[0]);
8246 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8247 op1 = replace_equiv_address (operands[1],
8248 force_reg (SImode, XEXP (operands[1], 0)));
8250 for (i = 0; i < count; i++)
8251 XVECEXP (operands[3], 0, i)
8252 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8253 adjust_address_nv (op1, SImode, i * 4));
8256 (define_insn "*ldmsi8"
8257 [(match_parallel 0 "load_multiple_operation"
8258 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8259 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8260 (set (match_operand:SI 3 "gpc_reg_operand" "")
8261 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8262 (set (match_operand:SI 4 "gpc_reg_operand" "")
8263 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8264 (set (match_operand:SI 5 "gpc_reg_operand" "")
8265 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8266 (set (match_operand:SI 6 "gpc_reg_operand" "")
8267 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8268 (set (match_operand:SI 7 "gpc_reg_operand" "")
8269 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8270 (set (match_operand:SI 8 "gpc_reg_operand" "")
8271 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8272 (set (match_operand:SI 9 "gpc_reg_operand" "")
8273 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8274 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8276 { return rs6000_output_load_multiple (operands); }"
8277 [(set_attr "type" "load")
8278 (set_attr "update" "yes")
8279 (set_attr "indexed" "yes")
8280 (set_attr "length" "32")])
8282 (define_insn "*ldmsi7"
8283 [(match_parallel 0 "load_multiple_operation"
8284 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8285 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8286 (set (match_operand:SI 3 "gpc_reg_operand" "")
8287 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8288 (set (match_operand:SI 4 "gpc_reg_operand" "")
8289 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8290 (set (match_operand:SI 5 "gpc_reg_operand" "")
8291 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8292 (set (match_operand:SI 6 "gpc_reg_operand" "")
8293 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8294 (set (match_operand:SI 7 "gpc_reg_operand" "")
8295 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8296 (set (match_operand:SI 8 "gpc_reg_operand" "")
8297 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8298 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8300 { return rs6000_output_load_multiple (operands); }"
8301 [(set_attr "type" "load")
8302 (set_attr "update" "yes")
8303 (set_attr "indexed" "yes")
8304 (set_attr "length" "32")])
8306 (define_insn "*ldmsi6"
8307 [(match_parallel 0 "load_multiple_operation"
8308 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8309 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8310 (set (match_operand:SI 3 "gpc_reg_operand" "")
8311 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8312 (set (match_operand:SI 4 "gpc_reg_operand" "")
8313 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8314 (set (match_operand:SI 5 "gpc_reg_operand" "")
8315 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8316 (set (match_operand:SI 6 "gpc_reg_operand" "")
8317 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8318 (set (match_operand:SI 7 "gpc_reg_operand" "")
8319 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8320 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8322 { return rs6000_output_load_multiple (operands); }"
8323 [(set_attr "type" "load")
8324 (set_attr "update" "yes")
8325 (set_attr "indexed" "yes")
8326 (set_attr "length" "32")])
8328 (define_insn "*ldmsi5"
8329 [(match_parallel 0 "load_multiple_operation"
8330 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8331 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8332 (set (match_operand:SI 3 "gpc_reg_operand" "")
8333 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8334 (set (match_operand:SI 4 "gpc_reg_operand" "")
8335 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8336 (set (match_operand:SI 5 "gpc_reg_operand" "")
8337 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8338 (set (match_operand:SI 6 "gpc_reg_operand" "")
8339 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8340 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8342 { return rs6000_output_load_multiple (operands); }"
8343 [(set_attr "type" "load")
8344 (set_attr "update" "yes")
8345 (set_attr "indexed" "yes")
8346 (set_attr "length" "32")])
8348 (define_insn "*ldmsi4"
8349 [(match_parallel 0 "load_multiple_operation"
8350 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8351 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8352 (set (match_operand:SI 3 "gpc_reg_operand" "")
8353 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8354 (set (match_operand:SI 4 "gpc_reg_operand" "")
8355 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8356 (set (match_operand:SI 5 "gpc_reg_operand" "")
8357 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8358 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8360 { return rs6000_output_load_multiple (operands); }"
8361 [(set_attr "type" "load")
8362 (set_attr "update" "yes")
8363 (set_attr "indexed" "yes")
8364 (set_attr "length" "32")])
8366 (define_insn "*ldmsi3"
8367 [(match_parallel 0 "load_multiple_operation"
8368 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8369 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8370 (set (match_operand:SI 3 "gpc_reg_operand" "")
8371 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8372 (set (match_operand:SI 4 "gpc_reg_operand" "")
8373 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8374 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8376 { return rs6000_output_load_multiple (operands); }"
8377 [(set_attr "type" "load")
8378 (set_attr "update" "yes")
8379 (set_attr "indexed" "yes")
8380 (set_attr "length" "32")])
8382 (define_expand "store_multiple"
8383 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8384 (match_operand:SI 1 "" ""))
8385 (clobber (scratch:SI))
8386 (use (match_operand:SI 2 "" ""))])]
8387 "TARGET_STRING && !TARGET_POWERPC64"
8396 /* Support only storing a constant number of fixed-point registers to
8397 memory and only bother with this if more than two; the machine
8398 doesn't support more than eight. */
8399 if (GET_CODE (operands[2]) != CONST_INT
8400 || INTVAL (operands[2]) <= 2
8401 || INTVAL (operands[2]) > 8
8402 || GET_CODE (operands[0]) != MEM
8403 || GET_CODE (operands[1]) != REG
8404 || REGNO (operands[1]) >= 32)
8407 count = INTVAL (operands[2]);
8408 regno = REGNO (operands[1]);
8410 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8411 to = force_reg (SImode, XEXP (operands[0], 0));
8412 op0 = replace_equiv_address (operands[0], to);
8414 XVECEXP (operands[3], 0, 0)
8415 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8416 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8417 gen_rtx_SCRATCH (SImode));
8419 for (i = 1; i < count; i++)
8420 XVECEXP (operands[3], 0, i + 1)
8421 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8422 gen_rtx_REG (SImode, regno + i));
8425 (define_insn "*stmsi8"
8426 [(match_parallel 0 "store_multiple_operation"
8427 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8428 (match_operand:SI 2 "gpc_reg_operand" "r"))
8429 (clobber (match_scratch:SI 3 "=X"))
8430 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8431 (match_operand:SI 4 "gpc_reg_operand" "r"))
8432 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8433 (match_operand:SI 5 "gpc_reg_operand" "r"))
8434 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8435 (match_operand:SI 6 "gpc_reg_operand" "r"))
8436 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8437 (match_operand:SI 7 "gpc_reg_operand" "r"))
8438 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8439 (match_operand:SI 8 "gpc_reg_operand" "r"))
8440 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8441 (match_operand:SI 9 "gpc_reg_operand" "r"))
8442 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8443 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8444 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8446 [(set_attr "type" "store")
8447 (set_attr "update" "yes")
8448 (set_attr "indexed" "yes")
8449 (set_attr "cell_micro" "always")])
8451 (define_insn "*stmsi7"
8452 [(match_parallel 0 "store_multiple_operation"
8453 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8454 (match_operand:SI 2 "gpc_reg_operand" "r"))
8455 (clobber (match_scratch:SI 3 "=X"))
8456 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8457 (match_operand:SI 4 "gpc_reg_operand" "r"))
8458 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8459 (match_operand:SI 5 "gpc_reg_operand" "r"))
8460 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8461 (match_operand:SI 6 "gpc_reg_operand" "r"))
8462 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8463 (match_operand:SI 7 "gpc_reg_operand" "r"))
8464 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8465 (match_operand:SI 8 "gpc_reg_operand" "r"))
8466 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8467 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8468 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8470 [(set_attr "type" "store")
8471 (set_attr "update" "yes")
8472 (set_attr "indexed" "yes")
8473 (set_attr "cell_micro" "always")])
8475 (define_insn "*stmsi6"
8476 [(match_parallel 0 "store_multiple_operation"
8477 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8478 (match_operand:SI 2 "gpc_reg_operand" "r"))
8479 (clobber (match_scratch:SI 3 "=X"))
8480 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8481 (match_operand:SI 4 "gpc_reg_operand" "r"))
8482 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8483 (match_operand:SI 5 "gpc_reg_operand" "r"))
8484 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8485 (match_operand:SI 6 "gpc_reg_operand" "r"))
8486 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8487 (match_operand:SI 7 "gpc_reg_operand" "r"))
8488 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8489 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8490 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8492 [(set_attr "type" "store")
8493 (set_attr "update" "yes")
8494 (set_attr "indexed" "yes")
8495 (set_attr "cell_micro" "always")])
8497 (define_insn "*stmsi5"
8498 [(match_parallel 0 "store_multiple_operation"
8499 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8500 (match_operand:SI 2 "gpc_reg_operand" "r"))
8501 (clobber (match_scratch:SI 3 "=X"))
8502 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8503 (match_operand:SI 4 "gpc_reg_operand" "r"))
8504 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8505 (match_operand:SI 5 "gpc_reg_operand" "r"))
8506 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8507 (match_operand:SI 6 "gpc_reg_operand" "r"))
8508 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8509 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8510 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8512 [(set_attr "type" "store")
8513 (set_attr "update" "yes")
8514 (set_attr "indexed" "yes")
8515 (set_attr "cell_micro" "always")])
8517 (define_insn "*stmsi4"
8518 [(match_parallel 0 "store_multiple_operation"
8519 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8520 (match_operand:SI 2 "gpc_reg_operand" "r"))
8521 (clobber (match_scratch:SI 3 "=X"))
8522 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8523 (match_operand:SI 4 "gpc_reg_operand" "r"))
8524 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8525 (match_operand:SI 5 "gpc_reg_operand" "r"))
8526 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8527 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8528 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8530 [(set_attr "type" "store")
8531 (set_attr "update" "yes")
8532 (set_attr "indexed" "yes")
8533 (set_attr "cell_micro" "always")])
8535 (define_insn "*stmsi3"
8536 [(match_parallel 0 "store_multiple_operation"
8537 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8538 (match_operand:SI 2 "gpc_reg_operand" "r"))
8539 (clobber (match_scratch:SI 3 "=X"))
8540 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8541 (match_operand:SI 4 "gpc_reg_operand" "r"))
8542 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8543 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8544 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8546 [(set_attr "type" "store")
8547 (set_attr "update" "yes")
8548 (set_attr "indexed" "yes")
8549 (set_attr "cell_micro" "always")])
8551 (define_expand "setmemsi"
8552 [(parallel [(set (match_operand:BLK 0 "" "")
8553 (match_operand 2 "const_int_operand" ""))
8554 (use (match_operand:SI 1 "" ""))
8555 (use (match_operand:SI 3 "" ""))])]
8559 /* If value to set is not zero, use the library routine. */
8560 if (operands[2] != const0_rtx)
8563 if (expand_block_clear (operands))
8569 ;; String/block move insn.
8570 ;; Argument 0 is the destination
8571 ;; Argument 1 is the source
8572 ;; Argument 2 is the length
8573 ;; Argument 3 is the alignment
8575 (define_expand "movmemsi"
8576 [(parallel [(set (match_operand:BLK 0 "" "")
8577 (match_operand:BLK 1 "" ""))
8578 (use (match_operand:SI 2 "" ""))
8579 (use (match_operand:SI 3 "" ""))])]
8583 if (expand_block_move (operands))
8589 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
8590 ;; register allocator doesn't have a clue about allocating 8 word registers.
8591 ;; rD/rS = r5 is preferred, efficient form.
8592 (define_expand "movmemsi_8reg"
8593 [(parallel [(set (match_operand 0 "" "")
8594 (match_operand 1 "" ""))
8595 (use (match_operand 2 "" ""))
8596 (use (match_operand 3 "" ""))
8597 (clobber (reg:SI 5))
8598 (clobber (reg:SI 6))
8599 (clobber (reg:SI 7))
8600 (clobber (reg:SI 8))
8601 (clobber (reg:SI 9))
8602 (clobber (reg:SI 10))
8603 (clobber (reg:SI 11))
8604 (clobber (reg:SI 12))
8605 (clobber (match_scratch:SI 4 ""))])]
8610 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8611 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8612 (use (match_operand:SI 2 "immediate_operand" "i"))
8613 (use (match_operand:SI 3 "immediate_operand" "i"))
8614 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8615 (clobber (reg:SI 6))
8616 (clobber (reg:SI 7))
8617 (clobber (reg:SI 8))
8618 (clobber (reg:SI 9))
8619 (clobber (reg:SI 10))
8620 (clobber (reg:SI 11))
8621 (clobber (reg:SI 12))
8622 (clobber (match_scratch:SI 5 "=X"))]
8624 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8625 || INTVAL (operands[2]) == 0)
8626 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8627 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8628 && REGNO (operands[4]) == 5"
8629 "lswi %4,%1,%2\;stswi %4,%0,%2"
8630 [(set_attr "type" "store")
8631 (set_attr "update" "yes")
8632 (set_attr "indexed" "yes")
8633 (set_attr "cell_micro" "always")
8634 (set_attr "length" "8")])
8636 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
8637 ;; register allocator doesn't have a clue about allocating 6 word registers.
8638 ;; rD/rS = r5 is preferred, efficient form.
8639 (define_expand "movmemsi_6reg"
8640 [(parallel [(set (match_operand 0 "" "")
8641 (match_operand 1 "" ""))
8642 (use (match_operand 2 "" ""))
8643 (use (match_operand 3 "" ""))
8644 (clobber (reg:SI 5))
8645 (clobber (reg:SI 6))
8646 (clobber (reg:SI 7))
8647 (clobber (reg:SI 8))
8648 (clobber (reg:SI 9))
8649 (clobber (reg:SI 10))
8650 (clobber (match_scratch:SI 4 ""))])]
8655 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8656 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8657 (use (match_operand:SI 2 "immediate_operand" "i"))
8658 (use (match_operand:SI 3 "immediate_operand" "i"))
8659 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8660 (clobber (reg:SI 6))
8661 (clobber (reg:SI 7))
8662 (clobber (reg:SI 8))
8663 (clobber (reg:SI 9))
8664 (clobber (reg:SI 10))
8665 (clobber (match_scratch:SI 5 "=X"))]
8667 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8668 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8669 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8670 && REGNO (operands[4]) == 5"
8671 "lswi %4,%1,%2\;stswi %4,%0,%2"
8672 [(set_attr "type" "store")
8673 (set_attr "update" "yes")
8674 (set_attr "indexed" "yes")
8675 (set_attr "cell_micro" "always")
8676 (set_attr "length" "8")])
8678 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8679 ;; problems with TImode.
8680 ;; rD/rS = r5 is preferred, efficient form.
8681 (define_expand "movmemsi_4reg"
8682 [(parallel [(set (match_operand 0 "" "")
8683 (match_operand 1 "" ""))
8684 (use (match_operand 2 "" ""))
8685 (use (match_operand 3 "" ""))
8686 (clobber (reg:SI 5))
8687 (clobber (reg:SI 6))
8688 (clobber (reg:SI 7))
8689 (clobber (reg:SI 8))
8690 (clobber (match_scratch:SI 4 ""))])]
8695 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8696 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8697 (use (match_operand:SI 2 "immediate_operand" "i"))
8698 (use (match_operand:SI 3 "immediate_operand" "i"))
8699 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8700 (clobber (reg:SI 6))
8701 (clobber (reg:SI 7))
8702 (clobber (reg:SI 8))
8703 (clobber (match_scratch:SI 5 "=X"))]
8705 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8706 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8707 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8708 && REGNO (operands[4]) == 5"
8709 "lswi %4,%1,%2\;stswi %4,%0,%2"
8710 [(set_attr "type" "store")
8711 (set_attr "update" "yes")
8712 (set_attr "indexed" "yes")
8713 (set_attr "cell_micro" "always")
8714 (set_attr "length" "8")])
8716 ;; Move up to 8 bytes at a time.
8717 (define_expand "movmemsi_2reg"
8718 [(parallel [(set (match_operand 0 "" "")
8719 (match_operand 1 "" ""))
8720 (use (match_operand 2 "" ""))
8721 (use (match_operand 3 "" ""))
8722 (clobber (match_scratch:DI 4 ""))
8723 (clobber (match_scratch:SI 5 ""))])]
8724 "TARGET_STRING && ! TARGET_POWERPC64"
8728 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8729 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8730 (use (match_operand:SI 2 "immediate_operand" "i"))
8731 (use (match_operand:SI 3 "immediate_operand" "i"))
8732 (clobber (match_scratch:DI 4 "=&r"))
8733 (clobber (match_scratch:SI 5 "=X"))]
8734 "TARGET_STRING && ! TARGET_POWERPC64
8735 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8736 "lswi %4,%1,%2\;stswi %4,%0,%2"
8737 [(set_attr "type" "store")
8738 (set_attr "update" "yes")
8739 (set_attr "indexed" "yes")
8740 (set_attr "cell_micro" "always")
8741 (set_attr "length" "8")])
8743 ;; Move up to 4 bytes at a time.
8744 (define_expand "movmemsi_1reg"
8745 [(parallel [(set (match_operand 0 "" "")
8746 (match_operand 1 "" ""))
8747 (use (match_operand 2 "" ""))
8748 (use (match_operand 3 "" ""))
8749 (clobber (match_scratch:SI 4 ""))
8750 (clobber (match_scratch:SI 5 ""))])]
8755 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8756 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8757 (use (match_operand:SI 2 "immediate_operand" "i"))
8758 (use (match_operand:SI 3 "immediate_operand" "i"))
8759 (clobber (match_scratch:SI 4 "=&r"))
8760 (clobber (match_scratch:SI 5 "=X"))]
8761 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8762 "lswi %4,%1,%2\;stswi %4,%0,%2"
8763 [(set_attr "type" "store")
8764 (set_attr "update" "yes")
8765 (set_attr "indexed" "yes")
8766 (set_attr "cell_micro" "always")
8767 (set_attr "length" "8")])
8769 ;; Define insns that do load or store with update. Some of these we can
8770 ;; get by using pre-decrement or pre-increment, but the hardware can also
8771 ;; do cases where the increment is not the size of the object.
8773 ;; In all these cases, we use operands 0 and 1 for the register being
8774 ;; incremented because those are the operands that local-alloc will
8775 ;; tie and these are the pair most likely to be tieable (and the ones
8776 ;; that will benefit the most).
8778 (define_insn "*movdi_update1"
8779 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8780 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8781 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8782 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8783 (plus:DI (match_dup 1) (match_dup 2)))]
8784 "TARGET_POWERPC64 && TARGET_UPDATE
8785 && (!avoiding_indexed_address_p (DImode)
8786 || !gpc_reg_operand (operands[2], DImode))"
8790 [(set_attr "type" "load")
8791 (set_attr "update" "yes")
8792 (set_attr "indexed" "yes,no")])
8794 (define_insn "movdi_<mode>_update"
8795 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8796 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8797 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8798 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8799 (plus:P (match_dup 1) (match_dup 2)))]
8800 "TARGET_POWERPC64 && TARGET_UPDATE
8801 && (!avoiding_indexed_address_p (Pmode)
8802 || !gpc_reg_operand (operands[2], Pmode)
8803 || (REG_P (operands[0])
8804 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8808 [(set_attr "type" "store")
8809 (set_attr "update" "yes")
8810 (set_attr "indexed" "yes,no")])
8812 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8813 ;; needed for stack allocation, even if the user passes -mno-update.
8814 (define_insn "movdi_<mode>_update_stack"
8815 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8816 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8817 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8818 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8819 (plus:P (match_dup 1) (match_dup 2)))]
8824 [(set_attr "type" "store")
8825 (set_attr "update" "yes")
8826 (set_attr "indexed" "yes,no")])
8828 (define_insn "*movsi_update1"
8829 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8830 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8831 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8832 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8833 (plus:SI (match_dup 1) (match_dup 2)))]
8835 && (!avoiding_indexed_address_p (SImode)
8836 || !gpc_reg_operand (operands[2], SImode))"
8840 [(set_attr "type" "load")
8841 (set_attr "update" "yes")
8842 (set_attr "indexed" "yes,no")])
8844 (define_insn "*movsi_update2"
8845 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8847 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8848 (match_operand:DI 2 "gpc_reg_operand" "r")))))
8849 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8850 (plus:DI (match_dup 1) (match_dup 2)))]
8851 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8852 && !avoiding_indexed_address_p (DImode)"
8854 [(set_attr "type" "load")
8855 (set_attr "sign_extend" "yes")
8856 (set_attr "update" "yes")
8857 (set_attr "indexed" "yes")])
8859 (define_insn "movsi_update"
8860 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8861 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8862 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8863 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8864 (plus:SI (match_dup 1) (match_dup 2)))]
8866 && (!avoiding_indexed_address_p (SImode)
8867 || !gpc_reg_operand (operands[2], SImode)
8868 || (REG_P (operands[0])
8869 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8873 [(set_attr "type" "store")
8874 (set_attr "update" "yes")
8875 (set_attr "indexed" "yes,no")])
8877 ;; This is an unconditional pattern; needed for stack allocation, even
8878 ;; if the user passes -mno-update.
8879 (define_insn "movsi_update_stack"
8880 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8881 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8882 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8883 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8884 (plus:SI (match_dup 1) (match_dup 2)))]
8889 [(set_attr "type" "store")
8890 (set_attr "update" "yes")
8891 (set_attr "indexed" "yes,no")])
8893 (define_insn "*movhi_update1"
8894 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8895 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8896 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8897 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8898 (plus:SI (match_dup 1) (match_dup 2)))]
8900 && (!avoiding_indexed_address_p (SImode)
8901 || !gpc_reg_operand (operands[2], SImode))"
8905 [(set_attr "type" "load")
8906 (set_attr "update" "yes")
8907 (set_attr "indexed" "yes,no")])
8909 (define_insn "*movhi_update2"
8910 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8912 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8913 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8914 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8915 (plus:SI (match_dup 1) (match_dup 2)))]
8917 && (!avoiding_indexed_address_p (SImode)
8918 || !gpc_reg_operand (operands[2], SImode))"
8922 [(set_attr "type" "load")
8923 (set_attr "update" "yes")
8924 (set_attr "indexed" "yes,no")])
8926 (define_insn "*movhi_update3"
8927 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8929 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8930 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8931 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8932 (plus:SI (match_dup 1) (match_dup 2)))]
8933 "TARGET_UPDATE && rs6000_gen_cell_microcode
8934 && (!avoiding_indexed_address_p (SImode)
8935 || !gpc_reg_operand (operands[2], SImode))"
8939 [(set_attr "type" "load")
8940 (set_attr "sign_extend" "yes")
8941 (set_attr "update" "yes")
8942 (set_attr "indexed" "yes,no")])
8944 (define_insn "*movhi_update4"
8945 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8946 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8947 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8948 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8949 (plus:SI (match_dup 1) (match_dup 2)))]
8951 && (!avoiding_indexed_address_p (SImode)
8952 || !gpc_reg_operand (operands[2], SImode))"
8956 [(set_attr "type" "store")
8957 (set_attr "update" "yes")
8958 (set_attr "indexed" "yes,no")])
8960 (define_insn "*movqi_update1"
8961 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8962 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8963 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8964 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8965 (plus:SI (match_dup 1) (match_dup 2)))]
8967 && (!avoiding_indexed_address_p (SImode)
8968 || !gpc_reg_operand (operands[2], SImode))"
8972 [(set_attr "type" "load")
8973 (set_attr "update" "yes")
8974 (set_attr "indexed" "yes,no")])
8976 (define_insn "*movqi_update2"
8977 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8979 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8980 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8981 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8982 (plus:SI (match_dup 1) (match_dup 2)))]
8984 && (!avoiding_indexed_address_p (SImode)
8985 || !gpc_reg_operand (operands[2], SImode))"
8989 [(set_attr "type" "load")
8990 (set_attr "update" "yes")
8991 (set_attr "indexed" "yes,no")])
8993 (define_insn "*movqi_update3"
8994 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8995 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8996 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
8997 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8998 (plus:SI (match_dup 1) (match_dup 2)))]
9000 && (!avoiding_indexed_address_p (SImode)
9001 || !gpc_reg_operand (operands[2], SImode))"
9005 [(set_attr "type" "store")
9006 (set_attr "update" "yes")
9007 (set_attr "indexed" "yes,no")])
9009 (define_insn "*movsf_update1"
9010 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9011 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9012 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9013 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9014 (plus:SI (match_dup 1) (match_dup 2)))]
9015 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9016 && (!avoiding_indexed_address_p (SImode)
9017 || !gpc_reg_operand (operands[2], SImode))"
9021 [(set_attr "type" "fpload")
9022 (set_attr "update" "yes")
9023 (set_attr "indexed" "yes,no")])
9025 (define_insn "*movsf_update2"
9026 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9027 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9028 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9029 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9030 (plus:SI (match_dup 1) (match_dup 2)))]
9031 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9032 && (!avoiding_indexed_address_p (SImode)
9033 || !gpc_reg_operand (operands[2], SImode))"
9037 [(set_attr "type" "fpstore")
9038 (set_attr "update" "yes")
9039 (set_attr "indexed" "yes,no")])
9041 (define_insn "*movsf_update3"
9042 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9043 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9044 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9045 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9046 (plus:SI (match_dup 1) (match_dup 2)))]
9047 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9048 && (!avoiding_indexed_address_p (SImode)
9049 || !gpc_reg_operand (operands[2], SImode))"
9053 [(set_attr "type" "load")
9054 (set_attr "update" "yes")
9055 (set_attr "indexed" "yes,no")])
9057 (define_insn "*movsf_update4"
9058 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9059 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9060 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9061 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9062 (plus:SI (match_dup 1) (match_dup 2)))]
9063 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9064 && (!avoiding_indexed_address_p (SImode)
9065 || !gpc_reg_operand (operands[2], SImode))"
9069 [(set_attr "type" "store")
9070 (set_attr "update" "yes")
9071 (set_attr "indexed" "yes,no")])
9073 (define_insn "*movdf_update1"
9074 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9075 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9076 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9077 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9078 (plus:SI (match_dup 1) (match_dup 2)))]
9079 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9080 && (!avoiding_indexed_address_p (SImode)
9081 || !gpc_reg_operand (operands[2], SImode))"
9085 [(set_attr "type" "fpload")
9086 (set_attr "update" "yes")
9087 (set_attr "indexed" "yes,no")
9088 (set_attr "size" "64")])
9090 (define_insn "*movdf_update2"
9091 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9092 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9093 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9094 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9095 (plus:SI (match_dup 1) (match_dup 2)))]
9096 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9097 && (!avoiding_indexed_address_p (SImode)
9098 || !gpc_reg_operand (operands[2], SImode))"
9102 [(set_attr "type" "fpstore")
9103 (set_attr "update" "yes")
9104 (set_attr "indexed" "yes,no")])
9107 ;; After inserting conditional returns we can sometimes have
9108 ;; unnecessary register moves. Unfortunately we cannot have a
9109 ;; modeless peephole here, because some single SImode sets have early
9110 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9111 ;; sequences, using get_attr_length here will smash the operands
9112 ;; array. Neither is there an early_cobbler_p predicate.
9113 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9114 ;; Also this optimization interferes with scalars going into
9115 ;; altivec registers (the code does reloading through the FPRs).
9117 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9118 (match_operand:DF 1 "any_operand" ""))
9119 (set (match_operand:DF 2 "gpc_reg_operand" "")
9121 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9122 && !TARGET_UPPER_REGS_DF
9123 && peep2_reg_dead_p (2, operands[0])"
9124 [(set (match_dup 2) (match_dup 1))])
9127 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9128 (match_operand:SF 1 "any_operand" ""))
9129 (set (match_operand:SF 2 "gpc_reg_operand" "")
9131 "!TARGET_UPPER_REGS_SF
9132 && peep2_reg_dead_p (2, operands[0])"
9133 [(set (match_dup 2) (match_dup 1))])
9138 ;; Mode attributes for different ABIs.
9139 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9140 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9141 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9142 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9144 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9145 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9146 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9147 (match_operand 4 "" "g")))
9148 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9149 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9151 (clobber (reg:SI LR_REGNO))]
9152 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9154 if (TARGET_CMODEL != CMODEL_SMALL)
9155 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9158 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9160 "&& TARGET_TLS_MARKERS"
9162 (unspec:TLSmode [(match_dup 1)
9165 (parallel [(set (match_dup 0)
9166 (call (mem:TLSmode (match_dup 3))
9168 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9169 (clobber (reg:SI LR_REGNO))])]
9171 [(set_attr "type" "two")
9172 (set (attr "length")
9173 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9177 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9178 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9179 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9180 (match_operand 4 "" "g")))
9181 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9182 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9184 (clobber (reg:SI LR_REGNO))]
9185 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9189 if (TARGET_SECURE_PLT && flag_pic == 2)
9190 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9192 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9195 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9197 "&& TARGET_TLS_MARKERS"
9199 (unspec:TLSmode [(match_dup 1)
9202 (parallel [(set (match_dup 0)
9203 (call (mem:TLSmode (match_dup 3))
9205 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9206 (clobber (reg:SI LR_REGNO))])]
9208 [(set_attr "type" "two")
9209 (set_attr "length" "8")])
9211 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9212 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9213 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9214 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9216 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9217 "addi %0,%1,%2@got@tlsgd"
9218 "&& TARGET_CMODEL != CMODEL_SMALL"
9221 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9223 (lo_sum:TLSmode (match_dup 3)
9224 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9227 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9229 [(set (attr "length")
9230 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9234 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9235 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9237 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9238 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9240 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9241 "addis %0,%1,%2@got@tlsgd@ha"
9242 [(set_attr "length" "4")])
9244 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9245 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9246 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9247 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9248 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9250 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9251 "addi %0,%1,%2@got@tlsgd@l"
9252 [(set_attr "length" "4")])
9254 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9255 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9256 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9257 (match_operand 2 "" "g")))
9258 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9260 (clobber (reg:SI LR_REGNO))]
9261 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9262 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9263 "bl %z1(%3@tlsgd)\;nop"
9264 [(set_attr "type" "branch")
9265 (set_attr "length" "8")])
9267 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9268 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9269 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9270 (match_operand 2 "" "g")))
9271 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9273 (clobber (reg:SI LR_REGNO))]
9274 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9278 if (TARGET_SECURE_PLT && flag_pic == 2)
9279 return "bl %z1+32768(%3@tlsgd)@plt";
9280 return "bl %z1(%3@tlsgd)@plt";
9282 return "bl %z1(%3@tlsgd)";
9284 [(set_attr "type" "branch")
9285 (set_attr "length" "4")])
9287 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9288 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9289 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9290 (match_operand 3 "" "g")))
9291 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9293 (clobber (reg:SI LR_REGNO))]
9294 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9296 if (TARGET_CMODEL != CMODEL_SMALL)
9297 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9300 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9302 "&& TARGET_TLS_MARKERS"
9304 (unspec:TLSmode [(match_dup 1)]
9306 (parallel [(set (match_dup 0)
9307 (call (mem:TLSmode (match_dup 2))
9309 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9310 (clobber (reg:SI LR_REGNO))])]
9312 [(set_attr "type" "two")
9313 (set (attr "length")
9314 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9318 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9319 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9320 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9321 (match_operand 3 "" "g")))
9322 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9324 (clobber (reg:SI LR_REGNO))]
9325 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9329 if (TARGET_SECURE_PLT && flag_pic == 2)
9330 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9332 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9335 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9337 "&& TARGET_TLS_MARKERS"
9339 (unspec:TLSmode [(match_dup 1)]
9341 (parallel [(set (match_dup 0)
9342 (call (mem:TLSmode (match_dup 2))
9344 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9345 (clobber (reg:SI LR_REGNO))])]
9347 [(set_attr "length" "8")])
9349 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9350 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9351 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9353 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9354 "addi %0,%1,%&@got@tlsld"
9355 "&& TARGET_CMODEL != CMODEL_SMALL"
9358 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9360 (lo_sum:TLSmode (match_dup 2)
9361 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9364 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9366 [(set (attr "length")
9367 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9371 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9372 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9374 (unspec:TLSmode [(const_int 0)
9375 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9377 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9378 "addis %0,%1,%&@got@tlsld@ha"
9379 [(set_attr "length" "4")])
9381 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9382 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9383 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9384 (unspec:TLSmode [(const_int 0)
9385 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9387 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9388 "addi %0,%1,%&@got@tlsld@l"
9389 [(set_attr "length" "4")])
9391 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9392 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9393 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9394 (match_operand 2 "" "g")))
9395 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9396 (clobber (reg:SI LR_REGNO))]
9397 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9398 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9399 "bl %z1(%&@tlsld)\;nop"
9400 [(set_attr "type" "branch")
9401 (set_attr "length" "8")])
9403 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9404 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9405 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9406 (match_operand 2 "" "g")))
9407 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9408 (clobber (reg:SI LR_REGNO))]
9409 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9413 if (TARGET_SECURE_PLT && flag_pic == 2)
9414 return "bl %z1+32768(%&@tlsld)@plt";
9415 return "bl %z1(%&@tlsld)@plt";
9417 return "bl %z1(%&@tlsld)";
9419 [(set_attr "type" "branch")
9420 (set_attr "length" "4")])
9422 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9423 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9424 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9425 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9428 "addi %0,%1,%2@dtprel")
9430 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9431 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9432 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9433 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9434 UNSPEC_TLSDTPRELHA))]
9436 "addis %0,%1,%2@dtprel@ha")
9438 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9439 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9440 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9441 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9442 UNSPEC_TLSDTPRELLO))]
9444 "addi %0,%1,%2@dtprel@l")
9446 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9447 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9448 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9449 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9450 UNSPEC_TLSGOTDTPREL))]
9452 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9453 "&& TARGET_CMODEL != CMODEL_SMALL"
9456 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9458 (lo_sum:TLSmode (match_dup 3)
9459 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9462 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9464 [(set (attr "length")
9465 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9469 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9470 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9472 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9473 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9474 UNSPEC_TLSGOTDTPREL)))]
9475 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9476 "addis %0,%1,%2@got@dtprel@ha"
9477 [(set_attr "length" "4")])
9479 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9480 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9481 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9482 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9483 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9484 UNSPEC_TLSGOTDTPREL)))]
9485 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9486 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9487 [(set_attr "length" "4")])
9489 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9490 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9491 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9492 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9495 "addi %0,%1,%2@tprel")
9497 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9498 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9499 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9500 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9501 UNSPEC_TLSTPRELHA))]
9503 "addis %0,%1,%2@tprel@ha")
9505 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9506 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9507 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9508 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9509 UNSPEC_TLSTPRELLO))]
9511 "addi %0,%1,%2@tprel@l")
9513 ;; "b" output constraint here and on tls_tls input to support linker tls
9514 ;; optimization. The linker may edit the instructions emitted by a
9515 ;; tls_got_tprel/tls_tls pair to addis,addi.
9516 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9517 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9518 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9519 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9520 UNSPEC_TLSGOTTPREL))]
9522 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9523 "&& TARGET_CMODEL != CMODEL_SMALL"
9526 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9528 (lo_sum:TLSmode (match_dup 3)
9529 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9532 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9534 [(set (attr "length")
9535 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9539 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9540 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9542 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9543 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9544 UNSPEC_TLSGOTTPREL)))]
9545 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9546 "addis %0,%1,%2@got@tprel@ha"
9547 [(set_attr "length" "4")])
9549 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9550 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9551 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9552 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9553 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9554 UNSPEC_TLSGOTTPREL)))]
9555 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9556 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9557 [(set_attr "length" "4")])
9559 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9560 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9561 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9562 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9564 "TARGET_ELF && HAVE_AS_TLS"
9567 (define_expand "tls_get_tpointer"
9568 [(set (match_operand:SI 0 "gpc_reg_operand" "")
9569 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9570 "TARGET_XCOFF && HAVE_AS_TLS"
9573 emit_insn (gen_tls_get_tpointer_internal ());
9574 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9578 (define_insn "tls_get_tpointer_internal"
9580 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9581 (clobber (reg:SI LR_REGNO))]
9582 "TARGET_XCOFF && HAVE_AS_TLS"
9583 "bla __get_tpointer")
9585 (define_expand "tls_get_addr<mode>"
9586 [(set (match_operand:P 0 "gpc_reg_operand" "")
9587 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9588 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9589 "TARGET_XCOFF && HAVE_AS_TLS"
9592 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9593 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9594 emit_insn (gen_tls_get_addr_internal<mode> ());
9595 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9599 (define_insn "tls_get_addr_internal<mode>"
9601 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9605 (clobber (reg:P 11))
9606 (clobber (reg:CC CR0_REGNO))
9607 (clobber (reg:P LR_REGNO))]
9608 "TARGET_XCOFF && HAVE_AS_TLS"
9609 "bla __tls_get_addr")
9611 ;; Next come insns related to the calling sequence.
9613 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9614 ;; We move the back-chain and decrement the stack pointer.
9616 (define_expand "allocate_stack"
9617 [(set (match_operand 0 "gpc_reg_operand" "")
9618 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9620 (minus (reg 1) (match_dup 1)))]
9623 { rtx chain = gen_reg_rtx (Pmode);
9624 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9626 rtx insn, par, set, mem;
9628 emit_move_insn (chain, stack_bot);
9630 /* Check stack bounds if necessary. */
9631 if (crtl->limit_stack)
9634 available = expand_binop (Pmode, sub_optab,
9635 stack_pointer_rtx, stack_limit_rtx,
9636 NULL_RTX, 1, OPTAB_WIDEN);
9637 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9640 if (GET_CODE (operands[1]) != CONST_INT
9641 || INTVAL (operands[1]) < -32767
9642 || INTVAL (operands[1]) > 32768)
9644 neg_op0 = gen_reg_rtx (Pmode);
9646 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9648 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9651 neg_op0 = GEN_INT (- INTVAL (operands[1]));
9653 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9654 : gen_movdi_di_update_stack))
9655 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9657 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9658 it now and set the alias set/attributes. The above gen_*_update
9659 calls will generate a PARALLEL with the MEM set being the first
9661 par = PATTERN (insn);
9662 gcc_assert (GET_CODE (par) == PARALLEL);
9663 set = XVECEXP (par, 0, 0);
9664 gcc_assert (GET_CODE (set) == SET);
9665 mem = SET_DEST (set);
9666 gcc_assert (MEM_P (mem));
9667 MEM_NOTRAP_P (mem) = 1;
9668 set_mem_alias_set (mem, get_frame_alias_set ());
9670 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9674 ;; These patterns say how to save and restore the stack pointer. We need not
9675 ;; save the stack pointer at function level since we are careful to
9676 ;; preserve the backchain. At block level, we have to restore the backchain
9677 ;; when we restore the stack pointer.
9679 ;; For nonlocal gotos, we must save both the stack pointer and its
9680 ;; backchain and restore both. Note that in the nonlocal case, the
9681 ;; save area is a memory location.
9683 (define_expand "save_stack_function"
9684 [(match_operand 0 "any_operand" "")
9685 (match_operand 1 "any_operand" "")]
9689 (define_expand "restore_stack_function"
9690 [(match_operand 0 "any_operand" "")
9691 (match_operand 1 "any_operand" "")]
9695 ;; Adjust stack pointer (op0) to a new value (op1).
9696 ;; First copy old stack backchain to new location, and ensure that the
9697 ;; scheduler won't reorder the sp assignment before the backchain write.
9698 (define_expand "restore_stack_block"
9699 [(set (match_dup 2) (match_dup 3))
9700 (set (match_dup 4) (match_dup 2))
9702 (set (match_operand 0 "register_operand" "")
9703 (match_operand 1 "register_operand" ""))]
9709 operands[1] = force_reg (Pmode, operands[1]);
9710 operands[2] = gen_reg_rtx (Pmode);
9711 operands[3] = gen_frame_mem (Pmode, operands[0]);
9712 operands[4] = gen_frame_mem (Pmode, operands[1]);
9713 p = rtvec_alloc (1);
9714 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9716 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9719 (define_expand "save_stack_nonlocal"
9720 [(set (match_dup 3) (match_dup 4))
9721 (set (match_operand 0 "memory_operand" "") (match_dup 3))
9722 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9726 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9728 /* Copy the backchain to the first word, sp to the second. */
9729 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9730 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9731 operands[3] = gen_reg_rtx (Pmode);
9732 operands[4] = gen_frame_mem (Pmode, operands[1]);
9735 (define_expand "restore_stack_nonlocal"
9736 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9737 (set (match_dup 3) (match_dup 4))
9738 (set (match_dup 5) (match_dup 2))
9740 (set (match_operand 0 "register_operand" "") (match_dup 3))]
9744 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9747 /* Restore the backchain from the first word, sp from the second. */
9748 operands[2] = gen_reg_rtx (Pmode);
9749 operands[3] = gen_reg_rtx (Pmode);
9750 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9751 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9752 operands[5] = gen_frame_mem (Pmode, operands[3]);
9753 p = rtvec_alloc (1);
9754 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9756 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9759 ;; TOC register handling.
9761 ;; Code to initialize the TOC register...
9763 (define_insn "load_toc_aix_si"
9764 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9765 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9767 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9771 extern int need_toc_init;
9773 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9774 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9775 operands[2] = gen_rtx_REG (Pmode, 2);
9776 return \"lwz %0,%1(%2)\";
9778 [(set_attr "type" "load")
9779 (set_attr "update" "no")
9780 (set_attr "indexed" "no")])
9782 (define_insn "load_toc_aix_di"
9783 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9784 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9786 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9790 extern int need_toc_init;
9792 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9793 !TARGET_ELF || !TARGET_MINIMAL_TOC);
9795 strcat (buf, \"@toc\");
9796 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9797 operands[2] = gen_rtx_REG (Pmode, 2);
9798 return \"ld %0,%1(%2)\";
9800 [(set_attr "type" "load")
9801 (set_attr "update" "no")
9802 (set_attr "indexed" "no")])
9804 (define_insn "load_toc_v4_pic_si"
9805 [(set (reg:SI LR_REGNO)
9806 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9807 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9808 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9809 [(set_attr "type" "branch")
9810 (set_attr "length" "4")])
9812 (define_expand "load_toc_v4_PIC_1"
9813 [(parallel [(set (reg:SI LR_REGNO)
9814 (match_operand:SI 0 "immediate_operand" "s"))
9815 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9816 "TARGET_ELF && DEFAULT_ABI == ABI_V4
9817 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9820 (define_insn "load_toc_v4_PIC_1_normal"
9821 [(set (reg:SI LR_REGNO)
9822 (match_operand:SI 0 "immediate_operand" "s"))
9823 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9824 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9825 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9826 "bcl 20,31,%0\\n%0:"
9827 [(set_attr "type" "branch")
9828 (set_attr "length" "4")
9829 (set_attr "cannot_copy" "yes")])
9831 (define_insn "load_toc_v4_PIC_1_476"
9832 [(set (reg:SI LR_REGNO)
9833 (match_operand:SI 0 "immediate_operand" "s"))
9834 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9835 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9836 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9840 static char templ[32];
9842 get_ppc476_thunk_name (name);
9843 sprintf (templ, \"bl %s\\n%%0:\", name);
9846 [(set_attr "type" "branch")
9847 (set_attr "length" "4")
9848 (set_attr "cannot_copy" "yes")])
9850 (define_expand "load_toc_v4_PIC_1b"
9851 [(parallel [(set (reg:SI LR_REGNO)
9852 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9853 (label_ref (match_operand 1 "" ""))]
9856 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9859 (define_insn "load_toc_v4_PIC_1b_normal"
9860 [(set (reg:SI LR_REGNO)
9861 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9862 (label_ref (match_operand 1 "" ""))]
9865 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9866 "bcl 20,31,$+8\;.long %0-$"
9867 [(set_attr "type" "branch")
9868 (set_attr "length" "8")])
9870 (define_insn "load_toc_v4_PIC_1b_476"
9871 [(set (reg:SI LR_REGNO)
9872 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9873 (label_ref (match_operand 1 "" ""))]
9876 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9880 static char templ[32];
9882 get_ppc476_thunk_name (name);
9883 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9886 [(set_attr "type" "branch")
9887 (set_attr "length" "16")])
9889 (define_insn "load_toc_v4_PIC_2"
9890 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9891 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9892 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9893 (match_operand:SI 3 "immediate_operand" "s")))))]
9894 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9896 [(set_attr "type" "load")])
9898 (define_insn "load_toc_v4_PIC_3b"
9899 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9900 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9902 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9903 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9904 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9905 "addis %0,%1,%2-%3@ha")
9907 (define_insn "load_toc_v4_PIC_3c"
9908 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9909 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9910 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9911 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9912 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9913 "addi %0,%1,%2-%3@l")
9915 ;; If the TOC is shared over a translation unit, as happens with all
9916 ;; the kinds of PIC that we support, we need to restore the TOC
9917 ;; pointer only when jumping over units of translation.
9918 ;; On Darwin, we need to reload the picbase.
9920 (define_expand "builtin_setjmp_receiver"
9921 [(use (label_ref (match_operand 0 "" "")))]
9922 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9923 || (TARGET_TOC && TARGET_MINIMAL_TOC)
9924 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9928 if (DEFAULT_ABI == ABI_DARWIN)
9930 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9931 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9935 crtl->uses_pic_offset_table = 1;
9936 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9937 CODE_LABEL_NUMBER (operands[0]));
9938 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9940 emit_insn (gen_load_macho_picbase (tmplabrtx));
9941 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9942 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9946 rs6000_emit_load_toc_table (FALSE);
9951 (define_insn "*largetoc_high"
9952 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9954 (unspec [(match_operand:DI 1 "" "")
9955 (match_operand:DI 2 "gpc_reg_operand" "b")]
9957 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9958 "addis %0,%2,%1@toc@ha")
9960 (define_insn "*largetoc_high_aix<mode>"
9961 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9963 (unspec [(match_operand:P 1 "" "")
9964 (match_operand:P 2 "gpc_reg_operand" "b")]
9966 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9967 "addis %0,%1@u(%2)")
9969 (define_insn "*largetoc_high_plus"
9970 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9973 (unspec [(match_operand:DI 1 "" "")
9974 (match_operand:DI 2 "gpc_reg_operand" "b")]
9976 (match_operand:DI 3 "add_cint_operand" "n"))))]
9977 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9978 "addis %0,%2,%1+%3@toc@ha")
9980 (define_insn "*largetoc_high_plus_aix<mode>"
9981 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9984 (unspec [(match_operand:P 1 "" "")
9985 (match_operand:P 2 "gpc_reg_operand" "b")]
9987 (match_operand:P 3 "add_cint_operand" "n"))))]
9988 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9989 "addis %0,%1+%3@u(%2)")
9991 (define_insn "*largetoc_low"
9992 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9993 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9994 (match_operand:DI 2 "" "")))]
9995 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9998 (define_insn "*largetoc_low_aix<mode>"
9999 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10000 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10001 (match_operand:P 2 "" "")))]
10002 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10005 (define_insn_and_split "*tocref<mode>"
10006 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10007 (match_operand:P 1 "small_toc_ref" "R"))]
10010 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10011 [(set (match_dup 0) (high:P (match_dup 1)))
10012 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10014 ;; Elf specific ways of loading addresses for non-PIC code.
10015 ;; The output of this could be r0, but we make a very strong
10016 ;; preference for a base register because it will usually
10017 ;; be needed there.
10018 (define_insn "elf_high"
10019 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10020 (high:SI (match_operand 1 "" "")))]
10021 "TARGET_ELF && ! TARGET_64BIT"
10024 (define_insn "elf_low"
10025 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10026 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10027 (match_operand 2 "" "")))]
10028 "TARGET_ELF && ! TARGET_64BIT"
10031 ;; Call and call_value insns
10032 (define_expand "call"
10033 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10034 (match_operand 1 "" ""))
10035 (use (match_operand 2 "" ""))
10036 (clobber (reg:SI LR_REGNO))])]
10041 if (MACHOPIC_INDIRECT)
10042 operands[0] = machopic_indirect_call_target (operands[0]);
10045 gcc_assert (GET_CODE (operands[0]) == MEM);
10046 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10048 operands[0] = XEXP (operands[0], 0);
10050 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10052 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10056 if (GET_CODE (operands[0]) != SYMBOL_REF
10057 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10059 if (INTVAL (operands[2]) & CALL_LONG)
10060 operands[0] = rs6000_longcall_ref (operands[0]);
10062 switch (DEFAULT_ABI)
10066 operands[0] = force_reg (Pmode, operands[0]);
10070 gcc_unreachable ();
10075 (define_expand "call_value"
10076 [(parallel [(set (match_operand 0 "" "")
10077 (call (mem:SI (match_operand 1 "address_operand" ""))
10078 (match_operand 2 "" "")))
10079 (use (match_operand 3 "" ""))
10080 (clobber (reg:SI LR_REGNO))])]
10085 if (MACHOPIC_INDIRECT)
10086 operands[1] = machopic_indirect_call_target (operands[1]);
10089 gcc_assert (GET_CODE (operands[1]) == MEM);
10090 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10092 operands[1] = XEXP (operands[1], 0);
10094 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10096 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10100 if (GET_CODE (operands[1]) != SYMBOL_REF
10101 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10103 if (INTVAL (operands[3]) & CALL_LONG)
10104 operands[1] = rs6000_longcall_ref (operands[1]);
10106 switch (DEFAULT_ABI)
10110 operands[1] = force_reg (Pmode, operands[1]);
10114 gcc_unreachable ();
10119 ;; Call to function in current module. No TOC pointer reload needed.
10120 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10121 ;; either the function was not prototyped, or it was prototyped as a
10122 ;; variable argument function. It is > 0 if FP registers were passed
10123 ;; and < 0 if they were not.
10125 (define_insn "*call_local32"
10126 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10127 (match_operand 1 "" "g,g"))
10128 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10129 (clobber (reg:SI LR_REGNO))]
10130 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10133 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10134 output_asm_insn (\"crxor 6,6,6\", operands);
10136 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10137 output_asm_insn (\"creqv 6,6,6\", operands);
10139 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10141 [(set_attr "type" "branch")
10142 (set_attr "length" "4,8")])
10144 (define_insn "*call_local64"
10145 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10146 (match_operand 1 "" "g,g"))
10147 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10148 (clobber (reg:SI LR_REGNO))]
10149 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10152 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10153 output_asm_insn (\"crxor 6,6,6\", operands);
10155 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10156 output_asm_insn (\"creqv 6,6,6\", operands);
10158 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10160 [(set_attr "type" "branch")
10161 (set_attr "length" "4,8")])
10163 (define_insn "*call_value_local32"
10164 [(set (match_operand 0 "" "")
10165 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10166 (match_operand 2 "" "g,g")))
10167 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10168 (clobber (reg:SI LR_REGNO))]
10169 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10172 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10173 output_asm_insn (\"crxor 6,6,6\", operands);
10175 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10176 output_asm_insn (\"creqv 6,6,6\", operands);
10178 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10180 [(set_attr "type" "branch")
10181 (set_attr "length" "4,8")])
10184 (define_insn "*call_value_local64"
10185 [(set (match_operand 0 "" "")
10186 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10187 (match_operand 2 "" "g,g")))
10188 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10189 (clobber (reg:SI LR_REGNO))]
10190 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10193 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10194 output_asm_insn (\"crxor 6,6,6\", operands);
10196 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10197 output_asm_insn (\"creqv 6,6,6\", operands);
10199 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10201 [(set_attr "type" "branch")
10202 (set_attr "length" "4,8")])
10205 ;; A function pointer under System V is just a normal pointer
10206 ;; operands[0] is the function pointer
10207 ;; operands[1] is the stack size to clean up
10208 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10209 ;; which indicates how to set cr1
10211 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10212 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10213 (match_operand 1 "" "g,g,g,g"))
10214 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10215 (clobber (reg:SI LR_REGNO))]
10216 "DEFAULT_ABI == ABI_V4
10217 || DEFAULT_ABI == ABI_DARWIN"
10219 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10220 output_asm_insn ("crxor 6,6,6", operands);
10222 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10223 output_asm_insn ("creqv 6,6,6", operands);
10227 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10228 (set_attr "length" "4,4,8,8")])
10230 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10231 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10232 (match_operand 1 "" "g,g"))
10233 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10234 (clobber (reg:SI LR_REGNO))]
10235 "(DEFAULT_ABI == ABI_DARWIN
10236 || (DEFAULT_ABI == ABI_V4
10237 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10239 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10240 output_asm_insn ("crxor 6,6,6", operands);
10242 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10243 output_asm_insn ("creqv 6,6,6", operands);
10246 return output_call(insn, operands, 0, 2);
10248 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10250 gcc_assert (!TARGET_SECURE_PLT);
10251 return "bl %z0@plt";
10257 "DEFAULT_ABI == ABI_V4
10258 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10259 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10260 [(parallel [(call (mem:SI (match_dup 0))
10262 (use (match_dup 2))
10263 (use (match_dup 3))
10264 (clobber (reg:SI LR_REGNO))])]
10266 operands[3] = pic_offset_table_rtx;
10268 [(set_attr "type" "branch,branch")
10269 (set_attr "length" "4,8")])
10271 (define_insn "*call_nonlocal_sysv_secure<mode>"
10272 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10273 (match_operand 1 "" "g,g"))
10274 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10275 (use (match_operand:SI 3 "register_operand" "r,r"))
10276 (clobber (reg:SI LR_REGNO))]
10277 "(DEFAULT_ABI == ABI_V4
10278 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10279 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10281 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10282 output_asm_insn ("crxor 6,6,6", operands);
10284 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10285 output_asm_insn ("creqv 6,6,6", operands);
10288 /* The magic 32768 offset here and in the other sysv call insns
10289 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10290 See sysv4.h:toc_section. */
10291 return "bl %z0+32768@plt";
10293 return "bl %z0@plt";
10295 [(set_attr "type" "branch,branch")
10296 (set_attr "length" "4,8")])
10298 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10299 [(set (match_operand 0 "" "")
10300 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10301 (match_operand 2 "" "g,g,g,g")))
10302 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10303 (clobber (reg:SI LR_REGNO))]
10304 "DEFAULT_ABI == ABI_V4
10305 || DEFAULT_ABI == ABI_DARWIN"
10307 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10308 output_asm_insn ("crxor 6,6,6", operands);
10310 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10311 output_asm_insn ("creqv 6,6,6", operands);
10315 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10316 (set_attr "length" "4,4,8,8")])
10318 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10319 [(set (match_operand 0 "" "")
10320 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10321 (match_operand 2 "" "g,g")))
10322 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10323 (clobber (reg:SI LR_REGNO))]
10324 "(DEFAULT_ABI == ABI_DARWIN
10325 || (DEFAULT_ABI == ABI_V4
10326 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10328 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10329 output_asm_insn ("crxor 6,6,6", operands);
10331 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10332 output_asm_insn ("creqv 6,6,6", operands);
10335 return output_call(insn, operands, 1, 3);
10337 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10339 gcc_assert (!TARGET_SECURE_PLT);
10340 return "bl %z1@plt";
10346 "DEFAULT_ABI == ABI_V4
10347 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10348 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10349 [(parallel [(set (match_dup 0)
10350 (call (mem:SI (match_dup 1))
10352 (use (match_dup 3))
10353 (use (match_dup 4))
10354 (clobber (reg:SI LR_REGNO))])]
10356 operands[4] = pic_offset_table_rtx;
10358 [(set_attr "type" "branch,branch")
10359 (set_attr "length" "4,8")])
10361 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10362 [(set (match_operand 0 "" "")
10363 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10364 (match_operand 2 "" "g,g")))
10365 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10366 (use (match_operand:SI 4 "register_operand" "r,r"))
10367 (clobber (reg:SI LR_REGNO))]
10368 "(DEFAULT_ABI == ABI_V4
10369 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10370 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10372 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10373 output_asm_insn ("crxor 6,6,6", operands);
10375 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10376 output_asm_insn ("creqv 6,6,6", operands);
10379 return "bl %z1+32768@plt";
10381 return "bl %z1@plt";
10383 [(set_attr "type" "branch,branch")
10384 (set_attr "length" "4,8")])
10387 ;; Call to AIX abi function in the same module.
10389 (define_insn "*call_local_aix<mode>"
10390 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10391 (match_operand 1 "" "g"))
10392 (clobber (reg:P LR_REGNO))]
10393 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10395 [(set_attr "type" "branch")
10396 (set_attr "length" "4")])
10398 (define_insn "*call_value_local_aix<mode>"
10399 [(set (match_operand 0 "" "")
10400 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10401 (match_operand 2 "" "g")))
10402 (clobber (reg:P LR_REGNO))]
10403 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10405 [(set_attr "type" "branch")
10406 (set_attr "length" "4")])
10408 ;; Call to AIX abi function which may be in another module.
10409 ;; Restore the TOC pointer (r2) after the call.
10411 (define_insn "*call_nonlocal_aix<mode>"
10412 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10413 (match_operand 1 "" "g"))
10414 (clobber (reg:P LR_REGNO))]
10415 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10417 [(set_attr "type" "branch")
10418 (set_attr "length" "8")])
10420 (define_insn "*call_value_nonlocal_aix<mode>"
10421 [(set (match_operand 0 "" "")
10422 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10423 (match_operand 2 "" "g")))
10424 (clobber (reg:P LR_REGNO))]
10425 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10427 [(set_attr "type" "branch")
10428 (set_attr "length" "8")])
10430 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10431 ;; Operand0 is the addresss of the function to call
10432 ;; Operand2 is the location in the function descriptor to load r2 from
10433 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10435 (define_insn "*call_indirect_aix<mode>"
10436 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10437 (match_operand 1 "" "g,g"))
10438 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10439 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10440 (clobber (reg:P LR_REGNO))]
10441 "DEFAULT_ABI == ABI_AIX"
10442 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10443 [(set_attr "type" "jmpreg")
10444 (set_attr "length" "12")])
10446 (define_insn "*call_value_indirect_aix<mode>"
10447 [(set (match_operand 0 "" "")
10448 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10449 (match_operand 2 "" "g,g")))
10450 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10451 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10452 (clobber (reg:P LR_REGNO))]
10453 "DEFAULT_ABI == ABI_AIX"
10454 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10455 [(set_attr "type" "jmpreg")
10456 (set_attr "length" "12")])
10458 ;; Call to indirect functions with the ELFv2 ABI.
10459 ;; Operand0 is the addresss of the function to call
10460 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10462 (define_insn "*call_indirect_elfv2<mode>"
10463 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10464 (match_operand 1 "" "g,g"))
10465 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10466 (clobber (reg:P LR_REGNO))]
10467 "DEFAULT_ABI == ABI_ELFv2"
10468 "b%T0l\;<ptrload> 2,%2(1)"
10469 [(set_attr "type" "jmpreg")
10470 (set_attr "length" "8")])
10472 (define_insn "*call_value_indirect_elfv2<mode>"
10473 [(set (match_operand 0 "" "")
10474 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10475 (match_operand 2 "" "g,g")))
10476 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10477 (clobber (reg:P LR_REGNO))]
10478 "DEFAULT_ABI == ABI_ELFv2"
10479 "b%T1l\;<ptrload> 2,%3(1)"
10480 [(set_attr "type" "jmpreg")
10481 (set_attr "length" "8")])
10484 ;; Call subroutine returning any type.
10485 (define_expand "untyped_call"
10486 [(parallel [(call (match_operand 0 "" "")
10488 (match_operand 1 "" "")
10489 (match_operand 2 "" "")])]
10495 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10497 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10499 rtx set = XVECEXP (operands[2], 0, i);
10500 emit_move_insn (SET_DEST (set), SET_SRC (set));
10503 /* The optimizer does not know that the call sets the function value
10504 registers we stored in the result block. We avoid problems by
10505 claiming that all hard registers are used and clobbered at this
10507 emit_insn (gen_blockage ());
10512 ;; sibling call patterns
10513 (define_expand "sibcall"
10514 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10515 (match_operand 1 "" ""))
10516 (use (match_operand 2 "" ""))
10517 (use (reg:SI LR_REGNO))
10523 if (MACHOPIC_INDIRECT)
10524 operands[0] = machopic_indirect_call_target (operands[0]);
10527 gcc_assert (GET_CODE (operands[0]) == MEM);
10528 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10530 operands[0] = XEXP (operands[0], 0);
10532 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10534 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10539 (define_expand "sibcall_value"
10540 [(parallel [(set (match_operand 0 "register_operand" "")
10541 (call (mem:SI (match_operand 1 "address_operand" ""))
10542 (match_operand 2 "" "")))
10543 (use (match_operand 3 "" ""))
10544 (use (reg:SI LR_REGNO))
10550 if (MACHOPIC_INDIRECT)
10551 operands[1] = machopic_indirect_call_target (operands[1]);
10554 gcc_assert (GET_CODE (operands[1]) == MEM);
10555 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10557 operands[1] = XEXP (operands[1], 0);
10559 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10561 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10566 ;; this and similar patterns must be marked as using LR, otherwise
10567 ;; dataflow will try to delete the store into it. This is true
10568 ;; even when the actual reg to jump to is in CTR, when LR was
10569 ;; saved and restored around the PIC-setting BCL.
10570 (define_insn "*sibcall_local32"
10571 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10572 (match_operand 1 "" "g,g"))
10573 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10574 (use (reg:SI LR_REGNO))
10576 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10579 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10580 output_asm_insn (\"crxor 6,6,6\", operands);
10582 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10583 output_asm_insn (\"creqv 6,6,6\", operands);
10585 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10587 [(set_attr "type" "branch")
10588 (set_attr "length" "4,8")])
10590 (define_insn "*sibcall_local64"
10591 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10592 (match_operand 1 "" "g,g"))
10593 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10594 (use (reg:SI LR_REGNO))
10596 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10599 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10600 output_asm_insn (\"crxor 6,6,6\", operands);
10602 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10603 output_asm_insn (\"creqv 6,6,6\", operands);
10605 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10607 [(set_attr "type" "branch")
10608 (set_attr "length" "4,8")])
10610 (define_insn "*sibcall_value_local32"
10611 [(set (match_operand 0 "" "")
10612 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10613 (match_operand 2 "" "g,g")))
10614 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10615 (use (reg:SI LR_REGNO))
10617 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10620 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10621 output_asm_insn (\"crxor 6,6,6\", operands);
10623 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10624 output_asm_insn (\"creqv 6,6,6\", operands);
10626 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10628 [(set_attr "type" "branch")
10629 (set_attr "length" "4,8")])
10631 (define_insn "*sibcall_value_local64"
10632 [(set (match_operand 0 "" "")
10633 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10634 (match_operand 2 "" "g,g")))
10635 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10636 (use (reg:SI LR_REGNO))
10638 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10641 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10642 output_asm_insn (\"crxor 6,6,6\", operands);
10644 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10645 output_asm_insn (\"creqv 6,6,6\", operands);
10647 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10649 [(set_attr "type" "branch")
10650 (set_attr "length" "4,8")])
10652 (define_insn "*sibcall_nonlocal_sysv<mode>"
10653 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10654 (match_operand 1 "" ""))
10655 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10656 (use (reg:SI LR_REGNO))
10658 "(DEFAULT_ABI == ABI_DARWIN
10659 || DEFAULT_ABI == ABI_V4)
10660 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10663 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10664 output_asm_insn (\"crxor 6,6,6\", operands);
10666 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10667 output_asm_insn (\"creqv 6,6,6\", operands);
10669 if (which_alternative >= 2)
10671 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10673 gcc_assert (!TARGET_SECURE_PLT);
10674 return \"b %z0@plt\";
10679 [(set_attr "type" "branch")
10680 (set_attr "length" "4,8,4,8")])
10682 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10683 [(set (match_operand 0 "" "")
10684 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10685 (match_operand 2 "" "")))
10686 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10687 (use (reg:SI LR_REGNO))
10689 "(DEFAULT_ABI == ABI_DARWIN
10690 || DEFAULT_ABI == ABI_V4)
10691 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10694 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10695 output_asm_insn (\"crxor 6,6,6\", operands);
10697 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10698 output_asm_insn (\"creqv 6,6,6\", operands);
10700 if (which_alternative >= 2)
10702 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10704 gcc_assert (!TARGET_SECURE_PLT);
10705 return \"b %z1@plt\";
10710 [(set_attr "type" "branch")
10711 (set_attr "length" "4,8,4,8")])
10713 ;; AIX ABI sibling call patterns.
10715 (define_insn "*sibcall_aix<mode>"
10716 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10717 (match_operand 1 "" "g,g"))
10719 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10723 [(set_attr "type" "branch")
10724 (set_attr "length" "4")])
10726 (define_insn "*sibcall_value_aix<mode>"
10727 [(set (match_operand 0 "" "")
10728 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10729 (match_operand 2 "" "g,g")))
10731 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10735 [(set_attr "type" "branch")
10736 (set_attr "length" "4")])
10738 (define_expand "sibcall_epilogue"
10739 [(use (const_int 0))]
10742 if (!TARGET_SCHED_PROLOG)
10743 emit_insn (gen_blockage ());
10744 rs6000_emit_epilogue (TRUE);
10748 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10749 ;; all of memory. This blocks insns from being moved across this point.
10751 (define_insn "blockage"
10752 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10756 (define_expand "probe_stack_address"
10757 [(use (match_operand 0 "address_operand"))]
10760 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10761 MEM_VOLATILE_P (operands[0]) = 1;
10764 emit_insn (gen_probe_stack_di (operands[0]));
10766 emit_insn (gen_probe_stack_si (operands[0]));
10770 (define_insn "probe_stack_<mode>"
10771 [(set (match_operand:P 0 "memory_operand" "=m")
10772 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10775 operands[1] = gen_rtx_REG (Pmode, 0);
10776 return "st<wd>%U0%X0 %1,%0";
10778 [(set_attr "type" "store")
10779 (set (attr "update")
10780 (if_then_else (match_operand 0 "update_address_mem")
10781 (const_string "yes")
10782 (const_string "no")))
10783 (set (attr "indexed")
10784 (if_then_else (match_operand 0 "indexed_address_mem")
10785 (const_string "yes")
10786 (const_string "no")))
10787 (set_attr "length" "4")])
10789 (define_insn "probe_stack_range<P:mode>"
10790 [(set (match_operand:P 0 "register_operand" "=r")
10791 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10792 (match_operand:P 2 "register_operand" "r")]
10793 UNSPECV_PROBE_STACK_RANGE))]
10795 "* return output_probe_stack_range (operands[0], operands[2]);"
10796 [(set_attr "type" "three")])
10798 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
10799 ;; signed & unsigned, and one type of branch.
10801 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10802 ;; insns, and branches.
10804 (define_expand "cbranch<mode>4"
10805 [(use (match_operator 0 "rs6000_cbranch_operator"
10806 [(match_operand:GPR 1 "gpc_reg_operand" "")
10807 (match_operand:GPR 2 "reg_or_short_operand" "")]))
10808 (use (match_operand 3 ""))]
10812 /* Take care of the possibility that operands[2] might be negative but
10813 this might be a logical operation. That insn doesn't exist. */
10814 if (GET_CODE (operands[2]) == CONST_INT
10815 && INTVAL (operands[2]) < 0)
10817 operands[2] = force_reg (<MODE>mode, operands[2]);
10818 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10819 GET_MODE (operands[0]),
10820 operands[1], operands[2]);
10823 rs6000_emit_cbranch (<MODE>mode, operands);
10827 (define_expand "cbranch<mode>4"
10828 [(use (match_operator 0 "rs6000_cbranch_operator"
10829 [(match_operand:FP 1 "gpc_reg_operand" "")
10830 (match_operand:FP 2 "gpc_reg_operand" "")]))
10831 (use (match_operand 3 ""))]
10835 rs6000_emit_cbranch (<MODE>mode, operands);
10839 (define_expand "cstore<mode>4_signed"
10840 [(use (match_operator 1 "signed_comparison_operator"
10841 [(match_operand:P 2 "gpc_reg_operand")
10842 (match_operand:P 3 "gpc_reg_operand")]))
10843 (clobber (match_operand:P 0 "gpc_reg_operand"))]
10846 enum rtx_code cond_code = GET_CODE (operands[1]);
10848 rtx op0 = operands[0];
10849 rtx op1 = operands[2];
10850 rtx op2 = operands[3];
10852 if (cond_code == GE || cond_code == LT)
10854 cond_code = swap_condition (cond_code);
10855 std::swap (op1, op2);
10858 rtx tmp1 = gen_reg_rtx (<MODE>mode);
10859 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10860 rtx tmp3 = gen_reg_rtx (<MODE>mode);
10862 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10863 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10864 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10866 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10868 if (cond_code == LE)
10869 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
10872 rtx tmp4 = gen_reg_rtx (<MODE>mode);
10873 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
10874 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
10880 (define_expand "cstore<mode>4_unsigned"
10881 [(use (match_operator 1 "unsigned_comparison_operator"
10882 [(match_operand:P 2 "gpc_reg_operand")
10883 (match_operand:P 3 "reg_or_short_operand")]))
10884 (clobber (match_operand:P 0 "gpc_reg_operand"))]
10887 enum rtx_code cond_code = GET_CODE (operands[1]);
10889 rtx op0 = operands[0];
10890 rtx op1 = operands[2];
10891 rtx op2 = operands[3];
10893 if (cond_code == GEU || cond_code == LTU)
10895 cond_code = swap_condition (cond_code);
10896 std::swap (op1, op2);
10899 if (!gpc_reg_operand (op1, <MODE>mode))
10900 op1 = force_reg (<MODE>mode, op1);
10901 if (!reg_or_short_operand (op2, <MODE>mode))
10902 op2 = force_reg (<MODE>mode, op2);
10904 rtx tmp = gen_reg_rtx (<MODE>mode);
10905 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10907 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10908 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10910 if (cond_code == LEU)
10911 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10913 emit_insn (gen_neg<mode>2 (op0, tmp2));
10918 (define_expand "cstore_si_as_di"
10919 [(use (match_operator 1 "unsigned_comparison_operator"
10920 [(match_operand:SI 2 "gpc_reg_operand")
10921 (match_operand:SI 3 "reg_or_short_operand")]))
10922 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10925 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10926 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10928 operands[2] = force_reg (SImode, operands[2]);
10929 operands[3] = force_reg (SImode, operands[3]);
10930 rtx op1 = gen_reg_rtx (DImode);
10931 rtx op2 = gen_reg_rtx (DImode);
10932 convert_move (op1, operands[2], uns_flag);
10933 convert_move (op2, operands[3], uns_flag);
10935 if (cond_code == GT || cond_code == LE)
10937 cond_code = swap_condition (cond_code);
10938 std::swap (op1, op2);
10941 rtx tmp = gen_reg_rtx (DImode);
10942 rtx tmp2 = gen_reg_rtx (DImode);
10943 emit_insn (gen_subdi3 (tmp, op1, op2));
10944 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
10950 gcc_unreachable ();
10955 tmp3 = gen_reg_rtx (DImode);
10956 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
10960 convert_move (operands[0], tmp3, 1);
10965 (define_expand "cstore<mode>4_signed_imm"
10966 [(use (match_operator 1 "signed_comparison_operator"
10967 [(match_operand:GPR 2 "gpc_reg_operand")
10968 (match_operand:GPR 3 "immediate_operand")]))
10969 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10972 bool invert = false;
10974 enum rtx_code cond_code = GET_CODE (operands[1]);
10976 rtx op0 = operands[0];
10977 rtx op1 = operands[2];
10978 HOST_WIDE_INT val = INTVAL (operands[3]);
10980 if (cond_code == GE || cond_code == GT)
10982 cond_code = reverse_condition (cond_code);
10986 if (cond_code == LE)
10989 rtx tmp = gen_reg_rtx (<MODE>mode);
10990 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10991 rtx x = gen_reg_rtx (<MODE>mode);
10993 emit_insn (gen_and<mode>3 (x, op1, tmp));
10995 emit_insn (gen_ior<mode>3 (x, op1, tmp));
10999 rtx tmp = gen_reg_rtx (<MODE>mode);
11000 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11004 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11005 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11010 (define_expand "cstore<mode>4_unsigned_imm"
11011 [(use (match_operator 1 "unsigned_comparison_operator"
11012 [(match_operand:GPR 2 "gpc_reg_operand")
11013 (match_operand:GPR 3 "immediate_operand")]))
11014 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11017 bool invert = false;
11019 enum rtx_code cond_code = GET_CODE (operands[1]);
11021 rtx op0 = operands[0];
11022 rtx op1 = operands[2];
11023 HOST_WIDE_INT val = INTVAL (operands[3]);
11025 if (cond_code == GEU || cond_code == GTU)
11027 cond_code = reverse_condition (cond_code);
11031 if (cond_code == LEU)
11034 rtx tmp = gen_reg_rtx (<MODE>mode);
11035 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11036 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11037 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11038 rtx x = gen_reg_rtx (<MODE>mode);
11040 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11042 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11046 rtx tmp = gen_reg_rtx (<MODE>mode);
11047 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11051 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11052 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11057 (define_expand "cstore<mode>4"
11058 [(use (match_operator 1 "rs6000_cbranch_operator"
11059 [(match_operand:GPR 2 "gpc_reg_operand")
11060 (match_operand:GPR 3 "reg_or_short_operand")]))
11061 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11064 /* Use ISEL if the user asked for it. */
11066 rs6000_emit_sISEL (<MODE>mode, operands);
11068 /* Expanding EQ and NE directly to some machine instructions does not help
11069 but does hurt combine. So don't. */
11070 else if (GET_CODE (operands[1]) == EQ)
11071 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11072 else if (<MODE>mode == Pmode
11073 && GET_CODE (operands[1]) == NE)
11074 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11075 else if (GET_CODE (operands[1]) == NE)
11077 rtx tmp = gen_reg_rtx (<MODE>mode);
11078 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11079 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11082 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11083 etc. combinations magically work out just right. */
11084 else if (<MODE>mode == Pmode
11085 && unsigned_comparison_operator (operands[1], VOIDmode))
11086 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11087 operands[2], operands[3]));
11089 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11090 else if (<MODE>mode == SImode && Pmode == DImode)
11091 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11092 operands[2], operands[3]));
11094 /* For signed comparisons against a constant, we can do some simple
11096 else if (signed_comparison_operator (operands[1], VOIDmode)
11097 && CONST_INT_P (operands[3]))
11098 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11099 operands[2], operands[3]));
11101 /* And similarly for unsigned comparisons. */
11102 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11103 && CONST_INT_P (operands[3]))
11104 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11105 operands[2], operands[3]));
11107 /* We also do not want to use mfcr for signed comparisons. */
11108 else if (<MODE>mode == Pmode
11109 && signed_comparison_operator (operands[1], VOIDmode))
11110 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11111 operands[2], operands[3]));
11113 /* Everything else, use the mfcr brute force. */
11115 rs6000_emit_sCOND (<MODE>mode, operands);
11120 (define_expand "cstore<mode>4"
11121 [(use (match_operator 1 "rs6000_cbranch_operator"
11122 [(match_operand:FP 2 "gpc_reg_operand")
11123 (match_operand:FP 3 "gpc_reg_operand")]))
11124 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11127 rs6000_emit_sCOND (<MODE>mode, operands);
11132 (define_expand "stack_protect_set"
11133 [(match_operand 0 "memory_operand" "")
11134 (match_operand 1 "memory_operand" "")]
11137 #ifdef TARGET_THREAD_SSP_OFFSET
11138 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11139 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11140 operands[1] = gen_rtx_MEM (Pmode, addr);
11143 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11145 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11149 (define_insn "stack_protect_setsi"
11150 [(set (match_operand:SI 0 "memory_operand" "=m")
11151 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11152 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11154 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11155 [(set_attr "type" "three")
11156 (set_attr "length" "12")])
11158 (define_insn "stack_protect_setdi"
11159 [(set (match_operand:DI 0 "memory_operand" "=Y")
11160 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11161 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11163 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11164 [(set_attr "type" "three")
11165 (set_attr "length" "12")])
11167 (define_expand "stack_protect_test"
11168 [(match_operand 0 "memory_operand" "")
11169 (match_operand 1 "memory_operand" "")
11170 (match_operand 2 "" "")]
11173 rtx test, op0, op1;
11174 #ifdef TARGET_THREAD_SSP_OFFSET
11175 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11176 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11177 operands[1] = gen_rtx_MEM (Pmode, addr);
11180 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11181 test = gen_rtx_EQ (VOIDmode, op0, op1);
11182 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11186 (define_insn "stack_protect_testsi"
11187 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11188 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11189 (match_operand:SI 2 "memory_operand" "m,m")]
11191 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11192 (clobber (match_scratch:SI 3 "=&r,&r"))]
11195 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11196 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11197 [(set_attr "length" "16,20")])
11199 (define_insn "stack_protect_testdi"
11200 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11201 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11202 (match_operand:DI 2 "memory_operand" "Y,Y")]
11204 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11205 (clobber (match_scratch:DI 3 "=&r,&r"))]
11208 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11209 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11210 [(set_attr "length" "16,20")])
11213 ;; Here are the actual compare insns.
11214 (define_insn "*cmp<mode>_signed"
11215 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11216 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11217 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11219 "cmp<wd>%I2 %0,%1,%2"
11220 [(set_attr "type" "cmp")])
11222 (define_insn "*cmp<mode>_unsigned"
11223 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11224 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11225 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11227 "cmpl<wd>%I2 %0,%1,%2"
11228 [(set_attr "type" "cmp")])
11230 ;; If we are comparing a register for equality with a large constant,
11231 ;; we can do this with an XOR followed by a compare. But this is profitable
11232 ;; only if the large constant is only used for the comparison (and in this
11233 ;; case we already have a register to reuse as scratch).
11235 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11236 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11239 [(set (match_operand:SI 0 "register_operand")
11240 (match_operand:SI 1 "logical_const_operand" ""))
11241 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11243 (match_operand:SI 2 "logical_const_operand" "")]))
11244 (set (match_operand:CC 4 "cc_reg_operand" "")
11245 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11248 (if_then_else (match_operator 6 "equality_operator"
11249 [(match_dup 4) (const_int 0)])
11250 (match_operand 7 "" "")
11251 (match_operand 8 "" "")))]
11252 "peep2_reg_dead_p (3, operands[0])
11253 && peep2_reg_dead_p (4, operands[4])
11254 && REGNO (operands[0]) != REGNO (operands[5])"
11255 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11256 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11257 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11260 /* Get the constant we are comparing against, and see what it looks like
11261 when sign-extended from 16 to 32 bits. Then see what constant we could
11262 XOR with SEXTC to get the sign-extended value. */
11263 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11265 operands[1], operands[2]);
11266 HOST_WIDE_INT c = INTVAL (cnst);
11267 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11268 HOST_WIDE_INT xorv = c ^ sextc;
11270 operands[9] = GEN_INT (xorv);
11271 operands[10] = GEN_INT (sextc);
11274 ;; The following two insns don't exist as single insns, but if we provide
11275 ;; them, we can swap an add and compare, which will enable us to overlap more
11276 ;; of the required delay between a compare and branch. We generate code for
11277 ;; them by splitting.
11280 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11281 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11282 (match_operand:SI 2 "short_cint_operand" "i")))
11283 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11284 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11287 [(set_attr "length" "8")])
11290 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11291 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11292 (match_operand:SI 2 "u_short_cint_operand" "i")))
11293 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11294 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11297 [(set_attr "length" "8")])
11300 [(set (match_operand:CC 3 "cc_reg_operand" "")
11301 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11302 (match_operand:SI 2 "short_cint_operand" "")))
11303 (set (match_operand:SI 0 "gpc_reg_operand" "")
11304 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11306 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11307 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11310 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11311 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11312 (match_operand:SI 2 "u_short_cint_operand" "")))
11313 (set (match_operand:SI 0 "gpc_reg_operand" "")
11314 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11316 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11317 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11319 ;; Only need to compare second words if first words equal
11320 (define_insn "*cmp<mode>_internal1"
11321 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11322 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11323 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11324 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11325 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11326 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11327 [(set_attr "type" "fpcompare")
11328 (set_attr "length" "12")])
11330 (define_insn_and_split "*cmp<mode>_internal2"
11331 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11332 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11333 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11334 (clobber (match_scratch:DF 3 "=d"))
11335 (clobber (match_scratch:DF 4 "=d"))
11336 (clobber (match_scratch:DF 5 "=d"))
11337 (clobber (match_scratch:DF 6 "=d"))
11338 (clobber (match_scratch:DF 7 "=d"))
11339 (clobber (match_scratch:DF 8 "=d"))
11340 (clobber (match_scratch:DF 9 "=d"))
11341 (clobber (match_scratch:DF 10 "=d"))
11342 (clobber (match_scratch:GPR 11 "=b"))]
11343 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11344 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11346 "&& reload_completed"
11347 [(set (match_dup 3) (match_dup 14))
11348 (set (match_dup 4) (match_dup 15))
11349 (set (match_dup 9) (abs:DF (match_dup 5)))
11350 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11351 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11352 (label_ref (match_dup 12))
11354 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11355 (set (pc) (label_ref (match_dup 13)))
11357 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11358 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11359 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11360 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11363 REAL_VALUE_TYPE rv;
11364 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11365 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11367 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11368 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11369 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11370 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11371 operands[12] = gen_label_rtx ();
11372 operands[13] = gen_label_rtx ();
11374 operands[14] = force_const_mem (DFmode,
11375 const_double_from_real_value (rv, DFmode));
11376 operands[15] = force_const_mem (DFmode,
11377 const_double_from_real_value (dconst0,
11382 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11383 operands[14] = gen_const_mem (DFmode, tocref);
11384 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11385 operands[15] = gen_const_mem (DFmode, tocref);
11386 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11387 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11391 ;; Now we have the scc insns. We can do some combinations because of the
11392 ;; way the machine works.
11394 ;; Note that this is probably faster if we can put an insn between the
11395 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11396 ;; cases the insns below which don't use an intermediate CR field will
11397 ;; be used instead.
11399 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11400 (match_operator:SI 1 "scc_comparison_operator"
11401 [(match_operand 2 "cc_reg_operand" "y")
11404 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11405 [(set (attr "type")
11406 (cond [(match_test "TARGET_MFCRF")
11407 (const_string "mfcrf")
11409 (const_string "mfcr")))
11410 (set_attr "length" "8")])
11412 ;; Same as above, but get the GT bit.
11413 (define_insn "move_from_CR_gt_bit"
11414 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11415 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11416 "TARGET_HARD_FLOAT && !TARGET_FPRS"
11417 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11418 [(set_attr "type" "mfcr")
11419 (set_attr "length" "8")])
11421 ;; Same as above, but get the OV/ORDERED bit.
11422 (define_insn "move_from_CR_ov_bit"
11423 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11424 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11427 "mfcr %0\;rlwinm %0,%0,%t1,1"
11428 [(set_attr "type" "mfcr")
11429 (set_attr "length" "8")])
11432 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11433 (match_operator:DI 1 "scc_comparison_operator"
11434 [(match_operand 2 "cc_reg_operand" "y")
11437 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11438 [(set (attr "type")
11439 (cond [(match_test "TARGET_MFCRF")
11440 (const_string "mfcrf")
11442 (const_string "mfcr")))
11443 (set_attr "length" "8")])
11446 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11447 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11448 [(match_operand 2 "cc_reg_operand" "y,y")
11451 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11452 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11455 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11457 [(set_attr "type" "shift")
11458 (set_attr "dot" "yes")
11459 (set_attr "length" "8,16")])
11462 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11463 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11464 [(match_operand 2 "cc_reg_operand" "")
11467 (set (match_operand:SI 3 "gpc_reg_operand" "")
11468 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11469 "TARGET_32BIT && reload_completed"
11470 [(set (match_dup 3)
11471 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11473 (compare:CC (match_dup 3)
11478 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11479 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11480 [(match_operand 2 "cc_reg_operand" "y")
11482 (match_operand:SI 3 "const_int_operand" "n")))]
11486 int is_bit = ccr_bit (operands[1], 1);
11487 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11490 if (is_bit >= put_bit)
11491 count = is_bit - put_bit;
11493 count = 32 - (put_bit - is_bit);
11495 operands[4] = GEN_INT (count);
11496 operands[5] = GEN_INT (put_bit);
11498 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11500 [(set (attr "type")
11501 (cond [(match_test "TARGET_MFCRF")
11502 (const_string "mfcrf")
11504 (const_string "mfcr")))
11505 (set_attr "length" "8")])
11508 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11510 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11511 [(match_operand 2 "cc_reg_operand" "y,y")
11513 (match_operand:SI 3 "const_int_operand" "n,n"))
11515 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11516 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11521 int is_bit = ccr_bit (operands[1], 1);
11522 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11525 /* Force split for non-cc0 compare. */
11526 if (which_alternative == 1)
11529 if (is_bit >= put_bit)
11530 count = is_bit - put_bit;
11532 count = 32 - (put_bit - is_bit);
11534 operands[5] = GEN_INT (count);
11535 operands[6] = GEN_INT (put_bit);
11537 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11539 [(set_attr "type" "shift")
11540 (set_attr "dot" "yes")
11541 (set_attr "length" "8,16")])
11544 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11546 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11547 [(match_operand 2 "cc_reg_operand" "")
11549 (match_operand:SI 3 "const_int_operand" ""))
11551 (set (match_operand:SI 4 "gpc_reg_operand" "")
11552 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11555 [(set (match_dup 4)
11556 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11559 (compare:CC (match_dup 4)
11564 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11567 (define_insn_and_split "eq<mode>3"
11568 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11569 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11570 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11571 (clobber (match_scratch:GPR 3 "=r"))
11572 (clobber (match_scratch:GPR 4 "=r"))]
11576 [(set (match_dup 4)
11577 (clz:GPR (match_dup 3)))
11579 (lshiftrt:GPR (match_dup 4)
11582 operands[3] = rs6000_emit_eqne (<MODE>mode,
11583 operands[1], operands[2], operands[3]);
11585 if (GET_CODE (operands[4]) == SCRATCH)
11586 operands[4] = gen_reg_rtx (<MODE>mode);
11588 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11590 [(set (attr "length")
11591 (if_then_else (match_test "operands[2] == const0_rtx")
11593 (const_string "12")))])
11595 (define_insn_and_split "ne<mode>3"
11596 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11597 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11598 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11599 (clobber (match_scratch:P 3 "=r"))
11600 (clobber (match_scratch:P 4 "=r"))
11601 (clobber (reg:P CA_REGNO))]
11605 [(parallel [(set (match_dup 4)
11606 (plus:P (match_dup 3)
11608 (set (reg:P CA_REGNO)
11609 (ne:P (match_dup 3)
11611 (parallel [(set (match_dup 0)
11612 (plus:P (plus:P (not:P (match_dup 4))
11615 (clobber (reg:P CA_REGNO))])]
11617 operands[3] = rs6000_emit_eqne (<MODE>mode,
11618 operands[1], operands[2], operands[3]);
11620 if (GET_CODE (operands[4]) == SCRATCH)
11621 operands[4] = gen_reg_rtx (<MODE>mode);
11623 [(set (attr "length")
11624 (if_then_else (match_test "operands[2] == const0_rtx")
11626 (const_string "12")))])
11628 (define_insn_and_split "*neg_eq_<mode>"
11629 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11630 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11631 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11632 (clobber (match_scratch:P 3 "=r"))
11633 (clobber (match_scratch:P 4 "=r"))
11634 (clobber (reg:P CA_REGNO))]
11638 [(parallel [(set (match_dup 4)
11639 (plus:P (match_dup 3)
11641 (set (reg:P CA_REGNO)
11642 (ne:P (match_dup 3)
11644 (parallel [(set (match_dup 0)
11645 (plus:P (reg:P CA_REGNO)
11647 (clobber (reg:P CA_REGNO))])]
11649 operands[3] = rs6000_emit_eqne (<MODE>mode,
11650 operands[1], operands[2], operands[3]);
11652 if (GET_CODE (operands[4]) == SCRATCH)
11653 operands[4] = gen_reg_rtx (<MODE>mode);
11655 [(set (attr "length")
11656 (if_then_else (match_test "operands[2] == const0_rtx")
11658 (const_string "12")))])
11660 (define_insn_and_split "*neg_ne_<mode>"
11661 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11662 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11663 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11664 (clobber (match_scratch:P 3 "=r"))
11665 (clobber (match_scratch:P 4 "=r"))
11666 (clobber (reg:P CA_REGNO))]
11670 [(parallel [(set (match_dup 4)
11671 (neg:P (match_dup 3)))
11672 (set (reg:P CA_REGNO)
11673 (eq:P (match_dup 3)
11675 (parallel [(set (match_dup 0)
11676 (plus:P (reg:P CA_REGNO)
11678 (clobber (reg:P CA_REGNO))])]
11680 operands[3] = rs6000_emit_eqne (<MODE>mode,
11681 operands[1], operands[2], operands[3]);
11683 if (GET_CODE (operands[4]) == SCRATCH)
11684 operands[4] = gen_reg_rtx (<MODE>mode);
11686 [(set (attr "length")
11687 (if_then_else (match_test "operands[2] == const0_rtx")
11689 (const_string "12")))])
11691 (define_insn_and_split "*plus_eq_<mode>"
11692 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11693 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11694 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11695 (match_operand:P 3 "gpc_reg_operand" "r")))
11696 (clobber (match_scratch:P 4 "=r"))
11697 (clobber (match_scratch:P 5 "=r"))
11698 (clobber (reg:P CA_REGNO))]
11702 [(parallel [(set (match_dup 5)
11703 (neg:P (match_dup 4)))
11704 (set (reg:P CA_REGNO)
11705 (eq:P (match_dup 4)
11707 (parallel [(set (match_dup 0)
11708 (plus:P (match_dup 3)
11710 (clobber (reg:P CA_REGNO))])]
11712 operands[4] = rs6000_emit_eqne (<MODE>mode,
11713 operands[1], operands[2], operands[4]);
11715 if (GET_CODE (operands[5]) == SCRATCH)
11716 operands[5] = gen_reg_rtx (<MODE>mode);
11718 [(set (attr "length")
11719 (if_then_else (match_test "operands[2] == const0_rtx")
11721 (const_string "12")))])
11723 (define_insn_and_split "*plus_ne_<mode>"
11724 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11725 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11726 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11727 (match_operand:P 3 "gpc_reg_operand" "r")))
11728 (clobber (match_scratch:P 4 "=r"))
11729 (clobber (match_scratch:P 5 "=r"))
11730 (clobber (reg:P CA_REGNO))]
11734 [(parallel [(set (match_dup 5)
11735 (plus:P (match_dup 4)
11737 (set (reg:P CA_REGNO)
11738 (ne:P (match_dup 4)
11740 (parallel [(set (match_dup 0)
11741 (plus:P (match_dup 3)
11743 (clobber (reg:P CA_REGNO))])]
11745 operands[4] = rs6000_emit_eqne (<MODE>mode,
11746 operands[1], operands[2], operands[4]);
11748 if (GET_CODE (operands[5]) == SCRATCH)
11749 operands[5] = gen_reg_rtx (<MODE>mode);
11751 [(set (attr "length")
11752 (if_then_else (match_test "operands[2] == const0_rtx")
11754 (const_string "12")))])
11756 (define_insn_and_split "*minus_eq_<mode>"
11757 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11758 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11759 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11760 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11761 (clobber (match_scratch:P 4 "=r"))
11762 (clobber (match_scratch:P 5 "=r"))
11763 (clobber (reg:P CA_REGNO))]
11767 [(parallel [(set (match_dup 5)
11768 (plus:P (match_dup 4)
11770 (set (reg:P CA_REGNO)
11771 (ne:P (match_dup 4)
11773 (parallel [(set (match_dup 0)
11774 (plus:P (plus:P (match_dup 3)
11777 (clobber (reg:P CA_REGNO))])]
11779 operands[4] = rs6000_emit_eqne (<MODE>mode,
11780 operands[1], operands[2], operands[4]);
11782 if (GET_CODE (operands[5]) == SCRATCH)
11783 operands[5] = gen_reg_rtx (<MODE>mode);
11785 [(set (attr "length")
11786 (if_then_else (match_test "operands[2] == const0_rtx")
11788 (const_string "12")))])
11790 (define_insn_and_split "*minus_ne_<mode>"
11791 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11792 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11793 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11794 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11795 (clobber (match_scratch:P 4 "=r"))
11796 (clobber (match_scratch:P 5 "=r"))
11797 (clobber (reg:P CA_REGNO))]
11801 [(parallel [(set (match_dup 5)
11802 (neg:P (match_dup 4)))
11803 (set (reg:P CA_REGNO)
11804 (eq:P (match_dup 4)
11806 (parallel [(set (match_dup 0)
11807 (plus:P (plus:P (match_dup 3)
11810 (clobber (reg:P CA_REGNO))])]
11812 operands[4] = rs6000_emit_eqne (<MODE>mode,
11813 operands[1], operands[2], operands[4]);
11815 if (GET_CODE (operands[5]) == SCRATCH)
11816 operands[5] = gen_reg_rtx (<MODE>mode);
11818 [(set (attr "length")
11819 (if_then_else (match_test "operands[2] == const0_rtx")
11821 (const_string "12")))])
11823 (define_insn_and_split "*eqsi3_ext<mode>"
11824 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11825 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11826 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11827 (clobber (match_scratch:SI 3 "=r"))
11828 (clobber (match_scratch:SI 4 "=r"))]
11832 [(set (match_dup 4)
11833 (clz:SI (match_dup 3)))
11836 (lshiftrt:SI (match_dup 4)
11839 operands[3] = rs6000_emit_eqne (SImode,
11840 operands[1], operands[2], operands[3]);
11842 if (GET_CODE (operands[4]) == SCRATCH)
11843 operands[4] = gen_reg_rtx (SImode);
11845 [(set (attr "length")
11846 (if_then_else (match_test "operands[2] == const0_rtx")
11848 (const_string "12")))])
11850 (define_insn_and_split "*nesi3_ext<mode>"
11851 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11852 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11853 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11854 (clobber (match_scratch:SI 3 "=r"))
11855 (clobber (match_scratch:SI 4 "=r"))
11856 (clobber (match_scratch:EXTSI 5 "=r"))]
11860 [(set (match_dup 4)
11861 (clz:SI (match_dup 3)))
11864 (lshiftrt:SI (match_dup 4)
11867 (xor:EXTSI (match_dup 5)
11870 operands[3] = rs6000_emit_eqne (SImode,
11871 operands[1], operands[2], operands[3]);
11873 if (GET_CODE (operands[4]) == SCRATCH)
11874 operands[4] = gen_reg_rtx (SImode);
11875 if (GET_CODE (operands[5]) == SCRATCH)
11876 operands[5] = gen_reg_rtx (<MODE>mode);
11878 [(set (attr "length")
11879 (if_then_else (match_test "operands[2] == const0_rtx")
11880 (const_string "12")
11881 (const_string "16")))])
11883 ;; Define both directions of branch and return. If we need a reload
11884 ;; register, we'd rather use CR0 since it is much easier to copy a
11885 ;; register CC value to there.
11889 (if_then_else (match_operator 1 "branch_comparison_operator"
11891 "cc_reg_operand" "y")
11893 (label_ref (match_operand 0 "" ""))
11898 return output_cbranch (operands[1], \"%l0\", 0, insn);
11900 [(set_attr "type" "branch")])
11904 (if_then_else (match_operator 0 "branch_comparison_operator"
11906 "cc_reg_operand" "y")
11913 return output_cbranch (operands[0], NULL, 0, insn);
11915 [(set_attr "type" "jmpreg")
11916 (set_attr "length" "4")])
11920 (if_then_else (match_operator 1 "branch_comparison_operator"
11922 "cc_reg_operand" "y")
11925 (label_ref (match_operand 0 "" ""))))]
11929 return output_cbranch (operands[1], \"%l0\", 1, insn);
11931 [(set_attr "type" "branch")])
11935 (if_then_else (match_operator 0 "branch_comparison_operator"
11937 "cc_reg_operand" "y")
11944 return output_cbranch (operands[0], NULL, 1, insn);
11946 [(set_attr "type" "jmpreg")
11947 (set_attr "length" "4")])
11949 ;; Logic on condition register values.
11951 ; This pattern matches things like
11952 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11953 ; (eq:SI (reg:CCFP 68) (const_int 0)))
11955 ; which are generated by the branch logic.
11956 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11958 (define_insn "*cceq_ior_compare"
11959 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11960 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11961 [(match_operator:SI 2
11962 "branch_positive_comparison_operator"
11964 "cc_reg_operand" "y,y")
11966 (match_operator:SI 4
11967 "branch_positive_comparison_operator"
11969 "cc_reg_operand" "0,y")
11973 "cr%q1 %E0,%j2,%j4"
11974 [(set_attr "type" "cr_logical,delayed_cr")])
11976 ; Why is the constant -1 here, but 1 in the previous pattern?
11977 ; Because ~1 has all but the low bit set.
11979 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11980 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11981 [(not:SI (match_operator:SI 2
11982 "branch_positive_comparison_operator"
11984 "cc_reg_operand" "y,y")
11986 (match_operator:SI 4
11987 "branch_positive_comparison_operator"
11989 "cc_reg_operand" "0,y")
11993 "cr%q1 %E0,%j2,%j4"
11994 [(set_attr "type" "cr_logical,delayed_cr")])
11996 (define_insn "*cceq_rev_compare"
11997 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11998 (compare:CCEQ (match_operator:SI 1
11999 "branch_positive_comparison_operator"
12001 "cc_reg_operand" "0,y")
12006 [(set_attr "type" "cr_logical,delayed_cr")])
12008 ;; If we are comparing the result of two comparisons, this can be done
12009 ;; using creqv or crxor.
12011 (define_insn_and_split ""
12012 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12013 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12014 [(match_operand 2 "cc_reg_operand" "y")
12016 (match_operator 3 "branch_comparison_operator"
12017 [(match_operand 4 "cc_reg_operand" "y")
12022 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12026 int positive_1, positive_2;
12028 positive_1 = branch_positive_comparison_operator (operands[1],
12029 GET_MODE (operands[1]));
12030 positive_2 = branch_positive_comparison_operator (operands[3],
12031 GET_MODE (operands[3]));
12034 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12035 GET_CODE (operands[1])),
12037 operands[2], const0_rtx);
12038 else if (GET_MODE (operands[1]) != SImode)
12039 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12040 operands[2], const0_rtx);
12043 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12044 GET_CODE (operands[3])),
12046 operands[4], const0_rtx);
12047 else if (GET_MODE (operands[3]) != SImode)
12048 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12049 operands[4], const0_rtx);
12051 if (positive_1 == positive_2)
12053 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12054 operands[5] = constm1_rtx;
12058 operands[5] = const1_rtx;
12062 ;; Unconditional branch and return.
12064 (define_insn "jump"
12066 (label_ref (match_operand 0 "" "")))]
12069 [(set_attr "type" "branch")])
12071 (define_insn "<return_str>return"
12075 [(set_attr "type" "jmpreg")])
12077 (define_expand "indirect_jump"
12078 [(set (pc) (match_operand 0 "register_operand" ""))])
12080 (define_insn "*indirect_jump<mode>"
12081 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12086 [(set_attr "type" "jmpreg")])
12088 ;; Table jump for switch statements:
12089 (define_expand "tablejump"
12090 [(use (match_operand 0 "" ""))
12091 (use (label_ref (match_operand 1 "" "")))]
12096 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12098 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12102 (define_expand "tablejumpsi"
12103 [(set (match_dup 3)
12104 (plus:SI (match_operand:SI 0 "" "")
12106 (parallel [(set (pc) (match_dup 3))
12107 (use (label_ref (match_operand 1 "" "")))])]
12110 { operands[0] = force_reg (SImode, operands[0]);
12111 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12112 operands[3] = gen_reg_rtx (SImode);
12115 (define_expand "tablejumpdi"
12116 [(set (match_dup 4)
12117 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12119 (plus:DI (match_dup 4)
12121 (parallel [(set (pc) (match_dup 3))
12122 (use (label_ref (match_operand 1 "" "")))])]
12125 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12126 operands[3] = gen_reg_rtx (DImode);
12127 operands[4] = gen_reg_rtx (DImode);
12130 (define_insn "*tablejump<mode>_internal1"
12132 (match_operand:P 0 "register_operand" "c,*l"))
12133 (use (label_ref (match_operand 1 "" "")))]
12138 [(set_attr "type" "jmpreg")])
12141 [(unspec [(const_int 0)] UNSPEC_NOP)]
12145 (define_insn "group_ending_nop"
12146 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12150 if (rs6000_cpu_attr == CPU_POWER6)
12151 return \"ori 1,1,0\";
12152 return \"ori 2,2,0\";
12155 ;; Define the subtract-one-and-jump insns, starting with the template
12156 ;; so loop.c knows what to generate.
12158 (define_expand "doloop_end"
12159 [(use (match_operand 0 "" "")) ; loop pseudo
12160 (use (match_operand 1 "" ""))] ; label
12166 if (GET_MODE (operands[0]) != DImode)
12168 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12172 if (GET_MODE (operands[0]) != SImode)
12174 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12179 (define_expand "ctr<mode>"
12180 [(parallel [(set (pc)
12181 (if_then_else (ne (match_operand:P 0 "register_operand" "")
12183 (label_ref (match_operand 1 "" ""))
12186 (plus:P (match_dup 0)
12188 (clobber (match_scratch:CC 2 ""))
12189 (clobber (match_scratch:P 3 ""))])]
12193 ;; We need to be able to do this for any operand, including MEM, or we
12194 ;; will cause reload to blow up since we don't allow output reloads on
12196 ;; For the length attribute to be calculated correctly, the
12197 ;; label MUST be operand 0.
12199 (define_insn "*ctr<mode>_internal1"
12201 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12203 (label_ref (match_operand 0 "" ""))
12205 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
12206 (plus:P (match_dup 1)
12208 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12209 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12213 if (which_alternative != 0)
12215 else if (get_attr_length (insn) == 4)
12216 return \"bdnz %l0\";
12218 return \"bdz $+8\;b %l0\";
12220 [(set_attr "type" "branch")
12221 (set_attr "length" "*,16,20,20")])
12223 (define_insn "*ctr<mode>_internal2"
12225 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12228 (label_ref (match_operand 0 "" ""))))
12229 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
12230 (plus:P (match_dup 1)
12232 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12233 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12237 if (which_alternative != 0)
12239 else if (get_attr_length (insn) == 4)
12240 return \"bdz %l0\";
12242 return \"bdnz $+8\;b %l0\";
12244 [(set_attr "type" "branch")
12245 (set_attr "length" "*,16,20,20")])
12247 ;; Similar but use EQ
12249 (define_insn "*ctr<mode>_internal5"
12251 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12253 (label_ref (match_operand 0 "" ""))
12255 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
12256 (plus:P (match_dup 1)
12258 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12259 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12263 if (which_alternative != 0)
12265 else if (get_attr_length (insn) == 4)
12266 return \"bdz %l0\";
12268 return \"bdnz $+8\;b %l0\";
12270 [(set_attr "type" "branch")
12271 (set_attr "length" "*,16,20,20")])
12273 (define_insn "*ctr<mode>_internal6"
12275 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12278 (label_ref (match_operand 0 "" ""))))
12279 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
12280 (plus:P (match_dup 1)
12282 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12283 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12287 if (which_alternative != 0)
12289 else if (get_attr_length (insn) == 4)
12290 return \"bdnz %l0\";
12292 return \"bdz $+8\;b %l0\";
12294 [(set_attr "type" "branch")
12295 (set_attr "length" "*,16,20,20")])
12297 ;; Now the splitters if we could not allocate the CTR register
12301 (if_then_else (match_operator 2 "comparison_operator"
12302 [(match_operand:P 1 "gpc_reg_operand" "")
12304 (match_operand 5 "" "")
12305 (match_operand 6 "" "")))
12306 (set (match_operand:P 0 "int_reg_operand" "")
12307 (plus:P (match_dup 1) (const_int -1)))
12308 (clobber (match_scratch:CC 3 ""))
12309 (clobber (match_scratch:P 4 ""))]
12311 [(set (match_dup 3)
12312 (compare:CC (match_dup 1)
12315 (plus:P (match_dup 1)
12317 (set (pc) (if_then_else (match_dup 7)
12321 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12322 operands[3], const0_rtx); }")
12326 (if_then_else (match_operator 2 "comparison_operator"
12327 [(match_operand:P 1 "gpc_reg_operand" "")
12329 (match_operand 5 "" "")
12330 (match_operand 6 "" "")))
12331 (set (match_operand:P 0 "nonimmediate_operand" "")
12332 (plus:P (match_dup 1) (const_int -1)))
12333 (clobber (match_scratch:CC 3 ""))
12334 (clobber (match_scratch:P 4 ""))]
12335 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12336 [(set (match_dup 3)
12337 (compare:CC (match_dup 1)
12340 (plus:P (match_dup 1)
12344 (set (pc) (if_then_else (match_dup 7)
12348 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12349 operands[3], const0_rtx); }")
12351 (define_insn "trap"
12352 [(trap_if (const_int 1) (const_int 0))]
12355 [(set_attr "type" "trap")])
12357 (define_expand "ctrap<mode>4"
12358 [(trap_if (match_operator 0 "ordered_comparison_operator"
12359 [(match_operand:GPR 1 "register_operand")
12360 (match_operand:GPR 2 "reg_or_short_operand")])
12361 (match_operand 3 "zero_constant" ""))]
12366 [(trap_if (match_operator 0 "ordered_comparison_operator"
12367 [(match_operand:GPR 1 "register_operand" "r")
12368 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12371 "t<wd>%V0%I2 %1,%2"
12372 [(set_attr "type" "trap")])
12374 ;; Insns related to generating the function prologue and epilogue.
12376 (define_expand "prologue"
12377 [(use (const_int 0))]
12380 rs6000_emit_prologue ();
12381 if (!TARGET_SCHED_PROLOG)
12382 emit_insn (gen_blockage ());
12386 (define_insn "*movesi_from_cr_one"
12387 [(match_parallel 0 "mfcr_operation"
12388 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12389 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12390 (match_operand 3 "immediate_operand" "n")]
12391 UNSPEC_MOVESI_FROM_CR))])]
12397 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12399 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12400 operands[4] = GEN_INT (mask);
12401 output_asm_insn (\"mfcr %1,%4\", operands);
12405 [(set_attr "type" "mfcrf")])
12407 (define_insn "movesi_from_cr"
12408 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12409 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12410 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12411 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12412 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12413 UNSPEC_MOVESI_FROM_CR))]
12416 [(set_attr "type" "mfcr")])
12418 (define_insn "*crsave"
12419 [(match_parallel 0 "crsave_operation"
12420 [(set (match_operand:SI 1 "memory_operand" "=m")
12421 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12424 [(set_attr "type" "store")])
12426 (define_insn "*stmw"
12427 [(match_parallel 0 "stmw_operation"
12428 [(set (match_operand:SI 1 "memory_operand" "=m")
12429 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12432 [(set_attr "type" "store")
12433 (set_attr "update" "yes")
12434 (set_attr "indexed" "yes")])
12436 ; The following comment applies to:
12440 ; return_and_restore_gpregs*
12441 ; return_and_restore_fpregs*
12442 ; return_and_restore_fpregs_aix*
12444 ; The out-of-line save / restore functions expects one input argument.
12445 ; Since those are not standard call_insn's, we must avoid using
12446 ; MATCH_OPERAND for that argument. That way the register rename
12447 ; optimization will not try to rename this register.
12448 ; Each pattern is repeated for each possible register number used in
12449 ; various ABIs (r11, r1, and for some functions r12)
12451 (define_insn "*save_gpregs_<mode>_r11"
12452 [(match_parallel 0 "any_parallel_operand"
12453 [(clobber (reg:P 65))
12454 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12456 (set (match_operand:P 2 "memory_operand" "=m")
12457 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12460 [(set_attr "type" "branch")
12461 (set_attr "length" "4")])
12463 (define_insn "*save_gpregs_<mode>_r12"
12464 [(match_parallel 0 "any_parallel_operand"
12465 [(clobber (reg:P 65))
12466 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12468 (set (match_operand:P 2 "memory_operand" "=m")
12469 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12472 [(set_attr "type" "branch")
12473 (set_attr "length" "4")])
12475 (define_insn "*save_gpregs_<mode>_r1"
12476 [(match_parallel 0 "any_parallel_operand"
12477 [(clobber (reg:P 65))
12478 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12480 (set (match_operand:P 2 "memory_operand" "=m")
12481 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12484 [(set_attr "type" "branch")
12485 (set_attr "length" "4")])
12487 (define_insn "*save_fpregs_<mode>_r11"
12488 [(match_parallel 0 "any_parallel_operand"
12489 [(clobber (reg:P 65))
12490 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12492 (set (match_operand:DF 2 "memory_operand" "=m")
12493 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12496 [(set_attr "type" "branch")
12497 (set_attr "length" "4")])
12499 (define_insn "*save_fpregs_<mode>_r12"
12500 [(match_parallel 0 "any_parallel_operand"
12501 [(clobber (reg:P 65))
12502 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12504 (set (match_operand:DF 2 "memory_operand" "=m")
12505 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12508 [(set_attr "type" "branch")
12509 (set_attr "length" "4")])
12511 (define_insn "*save_fpregs_<mode>_r1"
12512 [(match_parallel 0 "any_parallel_operand"
12513 [(clobber (reg:P 65))
12514 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12516 (set (match_operand:DF 2 "memory_operand" "=m")
12517 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12520 [(set_attr "type" "branch")
12521 (set_attr "length" "4")])
12523 ; This is to explain that changes to the stack pointer should
12524 ; not be moved over loads from or stores to stack memory.
12525 (define_insn "stack_tie"
12526 [(match_parallel 0 "tie_operand"
12527 [(set (mem:BLK (reg 1)) (const_int 0))])]
12530 [(set_attr "length" "0")])
12532 (define_expand "epilogue"
12533 [(use (const_int 0))]
12536 if (!TARGET_SCHED_PROLOG)
12537 emit_insn (gen_blockage ());
12538 rs6000_emit_epilogue (FALSE);
12542 ; On some processors, doing the mtcrf one CC register at a time is
12543 ; faster (like on the 604e). On others, doing them all at once is
12544 ; faster; for instance, on the 601 and 750.
12546 (define_expand "movsi_to_cr_one"
12547 [(set (match_operand:CC 0 "cc_reg_operand" "")
12548 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12549 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12551 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12553 (define_insn "*movsi_to_cr"
12554 [(match_parallel 0 "mtcrf_operation"
12555 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12556 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12557 (match_operand 3 "immediate_operand" "n")]
12558 UNSPEC_MOVESI_TO_CR))])]
12564 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12565 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12566 operands[4] = GEN_INT (mask);
12567 return \"mtcrf %4,%2\";
12569 [(set_attr "type" "mtcr")])
12571 (define_insn "*mtcrfsi"
12572 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12573 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12574 (match_operand 2 "immediate_operand" "n")]
12575 UNSPEC_MOVESI_TO_CR))]
12576 "GET_CODE (operands[0]) == REG
12577 && CR_REGNO_P (REGNO (operands[0]))
12578 && GET_CODE (operands[2]) == CONST_INT
12579 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12581 [(set_attr "type" "mtcr")])
12583 ; The load-multiple instructions have similar properties.
12584 ; Note that "load_multiple" is a name known to the machine-independent
12585 ; code that actually corresponds to the PowerPC load-string.
12587 (define_insn "*lmw"
12588 [(match_parallel 0 "lmw_operation"
12589 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12590 (match_operand:SI 2 "memory_operand" "m"))])]
12593 [(set_attr "type" "load")
12594 (set_attr "update" "yes")
12595 (set_attr "indexed" "yes")
12596 (set_attr "cell_micro" "always")])
12598 (define_insn "*return_internal_<mode>"
12600 (use (match_operand:P 0 "register_operand" "lc"))]
12603 [(set_attr "type" "jmpreg")])
12605 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12606 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
12608 ; The following comment applies to:
12612 ; return_and_restore_gpregs*
12613 ; return_and_restore_fpregs*
12614 ; return_and_restore_fpregs_aix*
12616 ; The out-of-line save / restore functions expects one input argument.
12617 ; Since those are not standard call_insn's, we must avoid using
12618 ; MATCH_OPERAND for that argument. That way the register rename
12619 ; optimization will not try to rename this register.
12620 ; Each pattern is repeated for each possible register number used in
12621 ; various ABIs (r11, r1, and for some functions r12)
12623 (define_insn "*restore_gpregs_<mode>_r11"
12624 [(match_parallel 0 "any_parallel_operand"
12625 [(clobber (match_operand:P 1 "register_operand" "=l"))
12626 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12628 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12629 (match_operand:P 4 "memory_operand" "m"))])]
12632 [(set_attr "type" "branch")
12633 (set_attr "length" "4")])
12635 (define_insn "*restore_gpregs_<mode>_r12"
12636 [(match_parallel 0 "any_parallel_operand"
12637 [(clobber (match_operand:P 1 "register_operand" "=l"))
12638 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12640 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12641 (match_operand:P 4 "memory_operand" "m"))])]
12644 [(set_attr "type" "branch")
12645 (set_attr "length" "4")])
12647 (define_insn "*restore_gpregs_<mode>_r1"
12648 [(match_parallel 0 "any_parallel_operand"
12649 [(clobber (match_operand:P 1 "register_operand" "=l"))
12650 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12652 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12653 (match_operand:P 4 "memory_operand" "m"))])]
12656 [(set_attr "type" "branch")
12657 (set_attr "length" "4")])
12659 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12660 [(match_parallel 0 "any_parallel_operand"
12662 (clobber (match_operand:P 1 "register_operand" "=l"))
12663 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12665 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12666 (match_operand:P 4 "memory_operand" "m"))])]
12669 [(set_attr "type" "branch")
12670 (set_attr "length" "4")])
12672 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12673 [(match_parallel 0 "any_parallel_operand"
12675 (clobber (match_operand:P 1 "register_operand" "=l"))
12676 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12678 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12679 (match_operand:P 4 "memory_operand" "m"))])]
12682 [(set_attr "type" "branch")
12683 (set_attr "length" "4")])
12685 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12686 [(match_parallel 0 "any_parallel_operand"
12688 (clobber (match_operand:P 1 "register_operand" "=l"))
12689 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12691 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12692 (match_operand:P 4 "memory_operand" "m"))])]
12695 [(set_attr "type" "branch")
12696 (set_attr "length" "4")])
12698 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12699 [(match_parallel 0 "any_parallel_operand"
12701 (clobber (match_operand:P 1 "register_operand" "=l"))
12702 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12704 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12705 (match_operand:DF 4 "memory_operand" "m"))])]
12708 [(set_attr "type" "branch")
12709 (set_attr "length" "4")])
12711 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12712 [(match_parallel 0 "any_parallel_operand"
12714 (clobber (match_operand:P 1 "register_operand" "=l"))
12715 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12717 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12718 (match_operand:DF 4 "memory_operand" "m"))])]
12721 [(set_attr "type" "branch")
12722 (set_attr "length" "4")])
12724 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12725 [(match_parallel 0 "any_parallel_operand"
12727 (clobber (match_operand:P 1 "register_operand" "=l"))
12728 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12730 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12731 (match_operand:DF 4 "memory_operand" "m"))])]
12734 [(set_attr "type" "branch")
12735 (set_attr "length" "4")])
12737 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12738 [(match_parallel 0 "any_parallel_operand"
12740 (use (match_operand:P 1 "register_operand" "l"))
12741 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12743 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12744 (match_operand:DF 4 "memory_operand" "m"))])]
12747 [(set_attr "type" "branch")
12748 (set_attr "length" "4")])
12750 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12751 [(match_parallel 0 "any_parallel_operand"
12753 (use (match_operand:P 1 "register_operand" "l"))
12754 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12756 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12757 (match_operand:DF 4 "memory_operand" "m"))])]
12760 [(set_attr "type" "branch")
12761 (set_attr "length" "4")])
12763 ; This is used in compiling the unwind routines.
12764 (define_expand "eh_return"
12765 [(use (match_operand 0 "general_operand" ""))]
12770 emit_insn (gen_eh_set_lr_si (operands[0]));
12772 emit_insn (gen_eh_set_lr_di (operands[0]));
12776 ; We can't expand this before we know where the link register is stored.
12777 (define_insn "eh_set_lr_<mode>"
12778 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12780 (clobber (match_scratch:P 1 "=&b"))]
12785 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12786 (clobber (match_scratch 1 ""))]
12791 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12795 (define_insn "prefetch"
12796 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12797 (match_operand:SI 1 "const_int_operand" "n")
12798 (match_operand:SI 2 "const_int_operand" "n"))]
12802 if (GET_CODE (operands[0]) == REG)
12803 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12804 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12806 [(set_attr "type" "load")])
12808 ;; Handle -fsplit-stack.
12810 (define_expand "split_stack_prologue"
12814 rs6000_expand_split_stack_prologue ();
12818 (define_expand "load_split_stack_limit"
12819 [(set (match_operand 0)
12820 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12823 emit_insn (gen_rtx_SET (operands[0],
12824 gen_rtx_UNSPEC (Pmode,
12825 gen_rtvec (1, const0_rtx),
12826 UNSPEC_STACK_CHECK)));
12830 (define_insn "load_split_stack_limit_di"
12831 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12832 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12834 "ld %0,-0x7040(13)"
12835 [(set_attr "type" "load")
12836 (set_attr "update" "no")
12837 (set_attr "indexed" "no")])
12839 (define_insn "load_split_stack_limit_si"
12840 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12841 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12843 "lwz %0,-0x7020(2)"
12844 [(set_attr "type" "load")
12845 (set_attr "update" "no")
12846 (set_attr "indexed" "no")])
12848 ;; A return instruction which the middle-end doesn't see.
12849 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
12850 ;; after the call to __morestack.
12851 (define_insn "split_stack_return"
12852 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
12855 [(set_attr "type" "jmpreg")])
12857 ;; If there are operand 0 bytes available on the stack, jump to
12859 (define_expand "split_stack_space_check"
12860 [(set (match_dup 2)
12861 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12863 (minus (reg STACK_POINTER_REGNUM)
12864 (match_operand 0)))
12865 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12866 (set (pc) (if_then_else
12867 (geu (match_dup 4) (const_int 0))
12868 (label_ref (match_operand 1))
12872 rs6000_split_stack_space_check (operands[0], operands[1]);
12876 (define_insn "bpermd_<mode>"
12877 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12878 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12879 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12882 [(set_attr "type" "popcnt")])
12885 ;; Builtin fma support. Handle
12886 ;; Note that the conditions for expansion are in the FMA_F iterator.
12888 (define_expand "fma<mode>4"
12889 [(set (match_operand:FMA_F 0 "register_operand" "")
12891 (match_operand:FMA_F 1 "register_operand" "")
12892 (match_operand:FMA_F 2 "register_operand" "")
12893 (match_operand:FMA_F 3 "register_operand" "")))]
12897 (define_insn "*fma<mode>4_fpr"
12898 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12900 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12901 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12902 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12903 "TARGET_<MODE>_FPR"
12905 fmadd<Ftrad> %0,%1,%2,%3
12906 xsmadda<Fvsx> %x0,%x1,%x2
12907 xsmaddm<Fvsx> %x0,%x1,%x3"
12908 [(set_attr "type" "fp")
12909 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12911 ; Altivec only has fma and nfms.
12912 (define_expand "fms<mode>4"
12913 [(set (match_operand:FMA_F 0 "register_operand" "")
12915 (match_operand:FMA_F 1 "register_operand" "")
12916 (match_operand:FMA_F 2 "register_operand" "")
12917 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12918 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12921 (define_insn "*fms<mode>4_fpr"
12922 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12924 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12925 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12926 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12927 "TARGET_<MODE>_FPR"
12929 fmsub<Ftrad> %0,%1,%2,%3
12930 xsmsuba<Fvsx> %x0,%x1,%x2
12931 xsmsubm<Fvsx> %x0,%x1,%x3"
12932 [(set_attr "type" "fp")
12933 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12935 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12936 (define_expand "fnma<mode>4"
12937 [(set (match_operand:FMA_F 0 "register_operand" "")
12940 (match_operand:FMA_F 1 "register_operand" "")
12941 (match_operand:FMA_F 2 "register_operand" "")
12942 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12943 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12946 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12947 (define_expand "fnms<mode>4"
12948 [(set (match_operand:FMA_F 0 "register_operand" "")
12951 (match_operand:FMA_F 1 "register_operand" "")
12952 (match_operand:FMA_F 2 "register_operand" "")
12953 (match_operand:FMA_F 3 "register_operand" ""))))]
12954 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12957 ; Not an official optab name, but used from builtins.
12958 (define_expand "nfma<mode>4"
12959 [(set (match_operand:FMA_F 0 "register_operand" "")
12962 (match_operand:FMA_F 1 "register_operand" "")
12963 (match_operand:FMA_F 2 "register_operand" "")
12964 (match_operand:FMA_F 3 "register_operand" ""))))]
12965 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12968 (define_insn "*nfma<mode>4_fpr"
12969 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12972 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12973 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12974 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12975 "TARGET_<MODE>_FPR"
12977 fnmadd<Ftrad> %0,%1,%2,%3
12978 xsnmadda<Fvsx> %x0,%x1,%x2
12979 xsnmaddm<Fvsx> %x0,%x1,%x3"
12980 [(set_attr "type" "fp")
12981 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12983 ; Not an official optab name, but used from builtins.
12984 (define_expand "nfms<mode>4"
12985 [(set (match_operand:FMA_F 0 "register_operand" "")
12988 (match_operand:FMA_F 1 "register_operand" "")
12989 (match_operand:FMA_F 2 "register_operand" "")
12990 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12994 (define_insn "*nfmssf4_fpr"
12995 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12998 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12999 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13001 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13002 "TARGET_<MODE>_FPR"
13004 fnmsub<Ftrad> %0,%1,%2,%3
13005 xsnmsuba<Fvsx> %x0,%x1,%x2
13006 xsnmsubm<Fvsx> %x0,%x1,%x3"
13007 [(set_attr "type" "fp")
13008 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13011 (define_expand "rs6000_get_timebase"
13012 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13015 if (TARGET_POWERPC64)
13016 emit_insn (gen_rs6000_mftb_di (operands[0]));
13018 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13022 (define_insn "rs6000_get_timebase_ppc32"
13023 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13024 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13025 (clobber (match_scratch:SI 1 "=r"))
13026 (clobber (match_scratch:CC 2 "=y"))]
13027 "!TARGET_POWERPC64"
13029 if (WORDS_BIG_ENDIAN)
13032 return "mfspr %0,269\;"
13040 return "mftbu %0\;"
13049 return "mfspr %L0,269\;"
13057 return "mftbu %L0\;"
13064 [(set_attr "length" "20")])
13066 (define_insn "rs6000_mftb_<mode>"
13067 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13068 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13072 return "mfspr %0,268";
13078 (define_insn "rs6000_mffs"
13079 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13080 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13081 "TARGET_HARD_FLOAT && TARGET_FPRS"
13084 (define_insn "rs6000_mtfsf"
13085 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13086 (match_operand:DF 1 "gpc_reg_operand" "d")]
13088 "TARGET_HARD_FLOAT && TARGET_FPRS"
13092 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13093 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13094 ;; register that is being loaded. The fused ops must be physically adjacent.
13096 ;; There are two parts to addis fusion. The support for fused TOCs occur
13097 ;; before register allocation, and is meant to reduce the lifetime for the
13098 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13099 ;; to use the register that is being load. The peephole2 then gathers any
13100 ;; other fused possibilities that it can find after register allocation. If
13101 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13103 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13104 ;; before register allocation, so that we can avoid allocating a temporary base
13105 ;; register that won't be used, and that we try to load into base registers,
13106 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13107 ;; (addis followed by load) even on power8.
13110 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13111 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13112 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13113 [(parallel [(set (match_dup 0) (match_dup 2))
13114 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13115 (use (match_dup 3))
13116 (clobber (scratch:DI))])]
13118 operands[2] = fusion_wrap_memory_address (operands[1]);
13119 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13122 (define_insn "*toc_fusionload_<mode>"
13123 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13124 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13125 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13126 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13127 (clobber (match_scratch:DI 3 "=X,&b"))]
13128 "TARGET_TOC_FUSION_INT"
13130 if (base_reg_operand (operands[0], <MODE>mode))
13131 return emit_fusion_gpr_load (operands[0], operands[1]);
13133 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13135 [(set_attr "type" "load")
13136 (set_attr "length" "8")])
13138 (define_insn "*toc_fusionload_di"
13139 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13140 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13141 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13142 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13143 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13144 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13145 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13147 if (base_reg_operand (operands[0], DImode))
13148 return emit_fusion_gpr_load (operands[0], operands[1]);
13150 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13152 [(set_attr "type" "load")
13153 (set_attr "length" "8")])
13156 ;; Find cases where the addis that feeds into a load instruction is either used
13157 ;; once or is the same as the target register, and replace it with the fusion
13161 [(set (match_operand:P 0 "base_reg_operand" "")
13162 (match_operand:P 1 "fusion_gpr_addis" ""))
13163 (set (match_operand:INT1 2 "base_reg_operand" "")
13164 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13166 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13170 expand_fusion_gpr_load (operands);
13174 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13177 (define_insn "fusion_gpr_load_<mode>"
13178 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13179 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13180 UNSPEC_FUSION_GPR))]
13183 return emit_fusion_gpr_load (operands[0], operands[1]);
13185 [(set_attr "type" "load")
13186 (set_attr "length" "8")])
13189 ;; ISA 3.0 (power9) fusion support
13190 ;; Merge addis with floating load/store to FPRs (or GPRs).
13192 [(set (match_operand:P 0 "base_reg_operand" "")
13193 (match_operand:P 1 "fusion_gpr_addis" ""))
13194 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13195 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13196 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13197 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13200 expand_fusion_p9_load (operands);
13205 [(set (match_operand:P 0 "base_reg_operand" "")
13206 (match_operand:P 1 "fusion_gpr_addis" ""))
13207 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13208 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13209 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13210 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13213 expand_fusion_p9_store (operands);
13218 [(set (match_operand:SDI 0 "int_reg_operand" "")
13219 (match_operand:SDI 1 "upper16_cint_operand" ""))
13221 (ior:SDI (match_dup 0)
13222 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13224 [(set (match_dup 0)
13225 (unspec:SDI [(match_dup 1)
13226 (match_dup 2)] UNSPEC_FUSION_P9))])
13229 [(set (match_operand:SDI 0 "int_reg_operand" "")
13230 (match_operand:SDI 1 "upper16_cint_operand" ""))
13231 (set (match_operand:SDI 2 "int_reg_operand" "")
13232 (ior:SDI (match_dup 0)
13233 (match_operand:SDI 3 "u_short_cint_operand" "")))]
13235 && !rtx_equal_p (operands[0], operands[2])
13236 && peep2_reg_dead_p (2, operands[0])"
13237 [(set (match_dup 2)
13238 (unspec:SDI [(match_dup 1)
13239 (match_dup 3)] UNSPEC_FUSION_P9))])
13241 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13242 ;; reload). Because we want to eventually have secondary_reload generate
13243 ;; these, they have to have a single alternative that gives the register
13244 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13245 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13246 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13248 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13250 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13253 /* This insn is a secondary reload insn, which cannot have alternatives.
13254 If we are not loading up register 0, use the power8 fusion instead. */
13255 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13256 return emit_fusion_gpr_load (operands[0], operands[1]);
13258 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13260 [(set_attr "type" "load")
13261 (set_attr "length" "8")])
13263 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13264 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13266 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13268 (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
13271 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13273 [(set_attr "type" "store")
13274 (set_attr "length" "8")])
13276 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
13277 [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
13279 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13281 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13284 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13286 [(set_attr "type" "fpload")
13287 (set_attr "length" "8")])
13289 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
13290 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13292 [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
13294 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13297 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13299 [(set_attr "type" "fpstore")
13300 (set_attr "length" "8")])
13302 (define_insn "*fusion_p9_<mode>_constant"
13303 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13304 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13305 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13306 UNSPEC_FUSION_P9))]
13309 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13310 return "ori %0,%0,%2";
13312 [(set_attr "type" "two")
13313 (set_attr "length" "8")])
13316 ;; Miscellaneous ISA 2.06 (power7) instructions
13317 (define_insn "addg6s"
13318 [(set (match_operand:SI 0 "register_operand" "=r")
13319 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13320 (match_operand:SI 2 "register_operand" "r")]
13324 [(set_attr "type" "integer")
13325 (set_attr "length" "4")])
13327 (define_insn "cdtbcd"
13328 [(set (match_operand:SI 0 "register_operand" "=r")
13329 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13333 [(set_attr "type" "integer")
13334 (set_attr "length" "4")])
13336 (define_insn "cbcdtd"
13337 [(set (match_operand:SI 0 "register_operand" "=r")
13338 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13342 [(set_attr "type" "integer")
13343 (set_attr "length" "4")])
13345 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13350 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13351 (UNSPEC_DIVEO "eo")
13352 (UNSPEC_DIVEU "eu")
13353 (UNSPEC_DIVEUO "euo")])
13355 (define_insn "div<div_extend>_<mode>"
13356 [(set (match_operand:GPR 0 "register_operand" "=r")
13357 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13358 (match_operand:GPR 2 "register_operand" "r")]
13359 UNSPEC_DIV_EXTEND))]
13361 "div<wd><div_extend> %0,%1,%2"
13362 [(set_attr "type" "div")
13363 (set_attr "size" "<bits>")])
13366 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13368 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13369 (define_mode_attr FP128_64 [(TF "DF")
13374 (define_expand "unpack<mode>"
13375 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13377 [(match_operand:FMOVE128 1 "register_operand" "")
13378 (match_operand:QI 2 "const_0_to_1_operand" "")]
13379 UNSPEC_UNPACK_128BIT))]
13380 "FLOAT128_2REG_P (<MODE>mode)"
13383 (define_insn_and_split "unpack<mode>_dm"
13384 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13386 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13387 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13388 UNSPEC_UNPACK_128BIT))]
13389 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13391 "&& reload_completed"
13392 [(set (match_dup 0) (match_dup 3))]
13394 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13396 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13398 emit_note (NOTE_INSN_DELETED);
13402 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13404 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13405 (set_attr "length" "4")])
13407 (define_insn_and_split "unpack<mode>_nodm"
13408 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13410 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13411 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13412 UNSPEC_UNPACK_128BIT))]
13413 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13415 "&& reload_completed"
13416 [(set (match_dup 0) (match_dup 3))]
13418 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13420 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13422 emit_note (NOTE_INSN_DELETED);
13426 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13428 [(set_attr "type" "fp,fpstore")
13429 (set_attr "length" "4")])
13431 (define_insn_and_split "pack<mode>"
13432 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13434 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13435 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13436 UNSPEC_PACK_128BIT))]
13437 "FLOAT128_2REG_P (<MODE>mode)"
13441 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13442 [(set (match_dup 3) (match_dup 1))
13443 (set (match_dup 4) (match_dup 2))]
13445 unsigned dest_hi = REGNO (operands[0]);
13446 unsigned dest_lo = dest_hi + 1;
13448 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13449 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13451 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13452 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13454 [(set_attr "type" "fpsimple,fp")
13455 (set_attr "length" "4,8")])
13457 (define_insn "unpack<mode>"
13458 [(set (match_operand:DI 0 "register_operand" "=d,d")
13459 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13460 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13461 UNSPEC_UNPACK_128BIT))]
13462 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13464 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13465 return ASM_COMMENT_START " xxpermdi to same register";
13467 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13468 return "xxpermdi %x0,%x1,%x1,%3";
13470 [(set_attr "type" "vecperm")])
13472 (define_insn "pack<mode>"
13473 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13474 (unspec:FMOVE128_VSX
13475 [(match_operand:DI 1 "register_operand" "d")
13476 (match_operand:DI 2 "register_operand" "d")]
13477 UNSPEC_PACK_128BIT))]
13479 "xxpermdi %x0,%x1,%x2,0"
13480 [(set_attr "type" "vecperm")])
13484 ;; ISA 2.08 IEEE 128-bit floating point support.
13486 (define_insn "add<mode>3"
13487 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13489 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13490 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13491 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13493 [(set_attr "type" "vecfloat")
13494 (set_attr "size" "128")])
13496 (define_insn "sub<mode>3"
13497 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13499 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13500 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13501 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13503 [(set_attr "type" "vecfloat")
13504 (set_attr "size" "128")])
13506 (define_insn "mul<mode>3"
13507 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13509 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13510 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13511 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13513 [(set_attr "type" "vecfloat")
13514 (set_attr "size" "128")])
13516 (define_insn "div<mode>3"
13517 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13519 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13520 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13521 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13523 [(set_attr "type" "vecdiv")
13524 (set_attr "size" "128")])
13526 (define_insn "sqrt<mode>2"
13527 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13529 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13530 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13532 [(set_attr "type" "vecdiv")
13533 (set_attr "size" "128")])
13535 (define_expand "copysign<mode>3"
13536 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13537 (use (match_operand:IEEE128 1 "altivec_register_operand"))
13538 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13539 "FLOAT128_IEEE_P (<MODE>mode)"
13541 if (TARGET_FLOAT128_HW)
13542 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13546 rtx tmp = gen_reg_rtx (<MODE>mode);
13547 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13548 operands[2], tmp));
13553 (define_insn "copysign<mode>3_hard"
13554 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13556 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13557 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13559 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13560 "xscpsgnqp %0,%2,%1"
13561 [(set_attr "type" "vecmove")
13562 (set_attr "size" "128")])
13564 (define_insn "copysign<mode>3_soft"
13565 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13567 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13568 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13569 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
13571 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13572 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13573 [(set_attr "type" "veccomplex")
13574 (set_attr "length" "8")])
13576 (define_insn "neg<mode>2_hw"
13577 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13579 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13580 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13582 [(set_attr "type" "vecmove")
13583 (set_attr "size" "128")])
13586 (define_insn "abs<mode>2_hw"
13587 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13589 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13590 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13592 [(set_attr "type" "vecmove")
13593 (set_attr "size" "128")])
13596 (define_insn "*nabs<mode>2_hw"
13597 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13600 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13601 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13603 [(set_attr "type" "vecmove")
13604 (set_attr "size" "128")])
13606 ;; Initially don't worry about doing fusion
13607 (define_insn "*fma<mode>4_hw"
13608 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13610 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13611 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13612 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13613 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13614 "xsmaddqp %0,%1,%2"
13615 [(set_attr "type" "vecfloat")
13616 (set_attr "size" "128")])
13618 (define_insn "*fms<mode>4_hw"
13619 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13621 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13622 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13624 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13625 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13626 "xsmsubqp %0,%1,%2"
13627 [(set_attr "type" "vecfloat")
13628 (set_attr "size" "128")])
13630 (define_insn "*nfma<mode>4_hw"
13631 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13634 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13635 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13636 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13637 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13638 "xsnmaddqp %0,%1,%2"
13639 [(set_attr "type" "vecfloat")
13640 (set_attr "size" "128")])
13642 (define_insn "*nfms<mode>4_hw"
13643 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13646 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13647 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13649 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13650 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13651 "xsnmsubqp %0,%1,%2"
13652 [(set_attr "type" "vecfloat")
13653 (set_attr "size" "128")])
13655 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13656 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13657 (float_extend:IEEE128
13658 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13659 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13661 [(set_attr "type" "vecfloat")
13662 (set_attr "size" "128")])
13664 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13665 ;; point is a simple copy.
13666 (define_insn_and_split "extendkftf2"
13667 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13668 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13669 "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13673 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13676 emit_note (NOTE_INSN_DELETED);
13679 [(set_attr "type" "*,veclogical")
13680 (set_attr "length" "0,4")])
13682 (define_insn_and_split "trunctfkf2"
13683 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13684 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13685 "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13689 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13692 emit_note (NOTE_INSN_DELETED);
13695 [(set_attr "type" "*,veclogical")
13696 (set_attr "length" "0,4")])
13698 (define_insn "trunc<mode>df2_hw"
13699 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13701 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13702 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13704 [(set_attr "type" "vecfloat")
13705 (set_attr "size" "128")])
13707 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13708 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13710 (define_insn_and_split "trunc<mode>sf2_hw"
13711 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13713 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13714 (clobber (match_scratch:DF 2 "=v"))]
13715 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13718 [(set (match_dup 2)
13719 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13721 (float_truncate:SF (match_dup 2)))]
13723 if (GET_CODE (operands[2]) == SCRATCH)
13724 operands[2] = gen_reg_rtx (DFmode);
13726 [(set_attr "type" "vecfloat")
13727 (set_attr "length" "8")])
13729 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13730 ;; allowed in the traditional floating point registers. Use V2DImode so that
13731 ;; we can get a value in an Altivec register.
13733 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13734 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13735 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13736 (clobber (match_scratch:V2DI 2 "=v,v"))]
13737 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13742 convert_float128_to_int (operands, <CODE>);
13745 [(set_attr "length" "8")
13746 (set_attr "type" "mftgpr,fpstore")])
13748 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13749 [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13750 (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13751 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13752 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13757 convert_float128_to_int (operands, <CODE>);
13760 [(set_attr "length" "8")
13761 (set_attr "type" "mftgpr,vecsimple,fpstore")])
13763 (define_insn_and_split "float<uns>_<mode>si2_hw"
13764 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13765 (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13766 (clobber (match_scratch:V2DI 2 "=v,v"))]
13767 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13772 convert_int_to_float128 (operands, <CODE>);
13775 [(set_attr "length" "8")
13776 (set_attr "type" "vecfloat")])
13778 (define_insn_and_split "float<uns>_<mode>di2_hw"
13779 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13780 (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13781 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13782 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13787 convert_int_to_float128 (operands, <CODE>);
13790 [(set_attr "length" "8")
13791 (set_attr "type" "vecfloat")])
13793 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13794 (define_insn "*xscvqp<su>wz_<mode>"
13795 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13798 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13799 UNSPEC_IEEE128_CONVERT))]
13800 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13801 "xscvqp<su>wz %0,%1"
13802 [(set_attr "type" "vecfloat")
13803 (set_attr "size" "128")])
13805 (define_insn "*xscvqp<su>dz_<mode>"
13806 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13809 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13810 UNSPEC_IEEE128_CONVERT))]
13811 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13812 "xscvqp<su>dz %0,%1"
13813 [(set_attr "type" "vecfloat")
13814 (set_attr "size" "128")])
13816 (define_insn "*xscv<su>dqp_<mode>"
13817 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13819 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13820 UNSPEC_IEEE128_CONVERT)))]
13821 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13822 "xscv<su>dqp %0,%1"
13823 [(set_attr "type" "vecfloat")
13824 (set_attr "size" "128")])
13826 (define_insn "*ieee128_mfvsrd_64bit"
13827 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13828 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13829 UNSPEC_IEEE128_MOVE))]
13830 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13835 [(set_attr "type" "mftgpr,fpstore,veclogical")])
13838 (define_insn "*ieee128_mfvsrd_32bit"
13839 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13840 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13841 UNSPEC_IEEE128_MOVE))]
13842 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13846 [(set_attr "type" "fpstore,veclogical")])
13848 (define_insn "*ieee128_mfvsrwz"
13849 [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13850 (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13851 UNSPEC_IEEE128_MOVE))]
13852 "TARGET_FLOAT128_HW"
13856 [(set_attr "type" "mftgpr,fpstore")])
13858 ;; 0 says do sign-extension, 1 says zero-extension
13859 (define_insn "*ieee128_mtvsrw"
13860 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13861 (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13862 (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13863 UNSPEC_IEEE128_MOVE))]
13864 "TARGET_FLOAT128_HW"
13870 [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13873 (define_insn "*ieee128_mtvsrd_64bit"
13874 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13875 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13876 UNSPEC_IEEE128_MOVE))]
13877 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13882 [(set_attr "type" "mffgpr,fpload,veclogical")])
13884 (define_insn "*ieee128_mtvsrd_32bit"
13885 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
13886 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
13887 UNSPEC_IEEE128_MOVE))]
13888 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13892 [(set_attr "type" "fpload,veclogical")])
13894 ;; IEEE 128-bit instructions with round to odd semantics
13895 (define_insn "*trunc<mode>df2_odd"
13896 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13897 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13898 UNSPEC_ROUND_TO_ODD))]
13899 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13901 [(set_attr "type" "vecfloat")
13902 (set_attr "size" "128")])
13904 ;; IEEE 128-bit comparisons
13905 (define_insn "*cmp<mode>_hw"
13906 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13907 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13908 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13909 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13910 "xscmpuqp %0,%1,%2"
13911 [(set_attr "type" "veccmp")
13912 (set_attr "size" "128")])
13916 (include "sync.md")
13917 (include "vector.md")
13919 (include "altivec.md")
13922 (include "paired.md")
13923 (include "crypto.md")