;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
;; Copyright (C) 1990-2013 Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
;; This file is part of GCC.
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; .
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
;;
;; REGNOS
;;
(define_constants
[(FIRST_GPR_REGNO 0)
(STACK_POINTER_REGNUM 1)
(TOC_REGNUM 2)
(STATIC_CHAIN_REGNUM 11)
(HARD_FRAME_POINTER_REGNUM 31)
(LAST_GPR_REGNO 31)
(FIRST_FPR_REGNO 32)
(LAST_FPR_REGNO 63)
(LR_REGNO 65)
(CTR_REGNO 66)
(ARG_POINTER_REGNUM 67)
(CR0_REGNO 68)
(CR1_REGNO 69)
(CR2_REGNO 70)
(CR3_REGNO 71)
(CR4_REGNO 72)
(CR5_REGNO 73)
(CR6_REGNO 74)
(CR7_REGNO 75)
(MAX_CR_REGNO 75)
(CA_REGNO 76)
(FIRST_ALTIVEC_REGNO 77)
(LAST_ALTIVEC_REGNO 108)
(VRSAVE_REGNO 109)
(VSCR_REGNO 110)
(SPE_ACC_REGNO 111)
(SPEFSCR_REGNO 112)
(FRAME_POINTER_REGNUM 113)
(TFHAR_REGNO 114)
(TFIAR_REGNO 115)
(TEXASR_REGNO 116)
; ABI defined stack offsets for storing the TOC pointer with AIX calls.
(TOC_SAVE_OFFSET_32BIT 20)
(TOC_SAVE_OFFSET_64BIT 40)
; Function TOC offset in the AIX function descriptor.
(AIX_FUNC_DESC_TOC_32BIT 4)
(AIX_FUNC_DESC_TOC_64BIT 8)
; Static chain offset in the AIX function descriptor.
(AIX_FUNC_DESC_SC_32BIT 8)
(AIX_FUNC_DESC_SC_64BIT 16)
])
;;
;; UNSPEC usage
;;
(define_c_enum "unspec"
[UNSPEC_FRSP ; frsp for POWER machines
UNSPEC_PROBE_STACK ; probe stack memory reference
UNSPEC_TOCPTR ; address of a word pointing to the TOC
UNSPEC_TOC ; address of the TOC (more-or-less)
UNSPEC_MOVSI_GOT
UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
UNSPEC_FCTIWZ
UNSPEC_FRIM
UNSPEC_FRIN
UNSPEC_FRIP
UNSPEC_FRIZ
UNSPEC_LD_MPIC ; load_macho_picbase
UNSPEC_MPIC_CORRECT ; macho_correct_pic
UNSPEC_TLSGD
UNSPEC_TLSLD
UNSPEC_MOVESI_FROM_CR
UNSPEC_MOVESI_TO_CR
UNSPEC_TLSDTPREL
UNSPEC_TLSDTPRELHA
UNSPEC_TLSDTPRELLO
UNSPEC_TLSGOTDTPREL
UNSPEC_TLSTPREL
UNSPEC_TLSTPRELHA
UNSPEC_TLSTPRELLO
UNSPEC_TLSGOTTPREL
UNSPEC_TLSTLS
UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
UNSPEC_MV_CR_GT ; move_from_CR_gt_bit
UNSPEC_STFIWX
UNSPEC_POPCNTB
UNSPEC_FRES
UNSPEC_SP_SET
UNSPEC_SP_TEST
UNSPEC_SYNC
UNSPEC_LWSYNC
UNSPEC_SYNC_OP
UNSPEC_ATOMIC
UNSPEC_CMPXCHG
UNSPEC_XCHG
UNSPEC_AND
UNSPEC_DLMZB
UNSPEC_DLMZB_CR
UNSPEC_DLMZB_STRLEN
UNSPEC_RSQRT
UNSPEC_TOCREL
UNSPEC_MACHOPIC_OFFSET
UNSPEC_BPERM
UNSPEC_COPYSIGN
UNSPEC_PARITY
UNSPEC_FCTIW
UNSPEC_FCTID
UNSPEC_LFIWAX
UNSPEC_LFIWZX
UNSPEC_FCTIWUZ
UNSPEC_GRP_END_NOP
UNSPEC_P8V_FMRGOW
UNSPEC_P8V_MTVSRWZ
UNSPEC_P8V_RELOAD_FROM_GPR
UNSPEC_P8V_MTVSRD
UNSPEC_P8V_XXPERMDI
UNSPEC_P8V_RELOAD_FROM_VSX
])
;;
;; UNSPEC_VOLATILE usage
;;
(define_c_enum "unspecv"
[UNSPECV_BLOCK
UNSPECV_LL ; load-locked
UNSPECV_SC ; store-conditional
UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
UNSPECV_EH_RR ; eh_reg_restore
UNSPECV_ISYNC ; isync instruction
UNSPECV_MFTB ; move from time base
])
;; Define an insn type attribute. This is used in function unit delay
;; computations.
(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,vecdouble,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr,isel,popcnt,crypto,htm"
(const_string "integer"))
;; Define floating point instruction sub-types for use with Xfpu.md
(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"))
;; Length (in bytes).
; '(pc)' in the following doesn't include the instruction itself; it is
; calculated as if the instruction had zero size.
(define_attr "length" ""
(if_then_else (eq_attr "type" "branch")
(if_then_else (and (ge (minus (match_dup 0) (pc))
(const_int -32768))
(lt (minus (match_dup 0) (pc))
(const_int 32764)))
(const_int 4)
(const_int 8))
(const_int 4)))
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in rs6000-opts.h.
(define_attr "cpu"
"ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
ppc750,ppc7400,ppc7450,
ppc403,ppc405,ppc440,ppc476,
ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
power4,power5,power6,power7,power8,
rs64a,mpccore,cell,ppca2,titan"
(const (symbol_ref "rs6000_cpu_attr")))
;; If this instruction is microcoded on the CELL processor
; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
(define_attr "cell_micro" "not,conditional,always"
(if_then_else (eq_attr "type" "compare,delayed_compare,imul_compare,lmul_compare,load_ext,load_ext_ux,var_shift_rotate,var_delayed_compare")
(const_string "always")
(const_string "not")))
(automata_option "ndfa")
(include "rs64.md")
(include "mpc.md")
(include "40x.md")
(include "440.md")
(include "476.md")
(include "601.md")
(include "603.md")
(include "6xx.md")
(include "7xx.md")
(include "7450.md")
(include "8540.md")
(include "e300c2c3.md")
(include "e500mc.md")
(include "e500mc64.md")
(include "e5500.md")
(include "e6500.md")
(include "power4.md")
(include "power5.md")
(include "power6.md")
(include "power7.md")
(include "power8.md")
(include "cell.md")
(include "xfpu.md")
(include "a2.md")
(include "titan.md")
(include "predicates.md")
(include "constraints.md")
(include "darwin.md")
;; Mode iterators
; This mode iterator allows :GPR to be used to indicate the allowable size
; of whole values in GPRs.
(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
; Any supported integer mode.
(define_mode_iterator INT [QI HI SI DI TI PTI])
; Any supported integer mode that fits in one register.
(define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
; extend modes for DImode
(define_mode_iterator QHSI [QI HI SI])
; QImode or HImode for small atomic ops
(define_mode_iterator QHI [QI HI])
; HImode or SImode for sign extended fusion ops
(define_mode_iterator HSI [HI SI])
; SImode or DImode, even if DImode doesn't fit in GPRs.
(define_mode_iterator SDI [SI DI])
; The size of a pointer. Also, the size of the value that a record-condition
; (one with a '.') will compare; and the size used for arithmetic carries.
(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
; PTImode is GPR only)
(define_mode_iterator TI2 [TI PTI])
; Any hardware-supported floating-point mode
(define_mode_iterator FP [
(SF "TARGET_HARD_FLOAT
&& ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
(DF "TARGET_HARD_FLOAT
&& ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
(TF "!TARGET_IEEEQUAD
&& TARGET_HARD_FLOAT
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
&& TARGET_LONG_DOUBLE_128")
(DD "TARGET_DFP")
(TD "TARGET_DFP")])
; Any fma capable floating-point mode.
(define_mode_iterator FMA_F [
(SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
(DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
|| VECTOR_UNIT_VSX_P (DFmode)")
(V2SF "TARGET_PAIRED_FLOAT")
(V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
(V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
])
; Floating point move iterators to combine binary and decimal moves
(define_mode_iterator FMOVE32 [SF SD])
(define_mode_iterator FMOVE64 [DF DD])
(define_mode_iterator FMOVE64X [DI DF DD])
(define_mode_iterator FMOVE128 [(TF "!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128")
(TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
; Iterators for 128 bit types for direct move
(define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE")
(V16QI "")
(V8HI "")
(V4SI "")
(V4SF "")
(V2DI "")
(V2DF "")])
; Whether a floating point move is ok, don't allow SD without hardware FP
(define_mode_attr fmove_ok [(SF "")
(DF "")
(SD "TARGET_HARD_FLOAT && TARGET_FPRS")
(DD "")])
; Convert REAL_VALUE to the appropriate bits
(define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
(DF "REAL_VALUE_TO_TARGET_DOUBLE")
(SD "REAL_VALUE_TO_TARGET_DECIMAL32")
(DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
; Definitions for load to 32-bit fpr register
(define_mode_attr f32_lr [(SF "f") (SD "wz")])
(define_mode_attr f32_lm [(SF "m") (SD "Z")])
(define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
(define_mode_attr f32_lv [(SF "lxsspx %0,%y1") (SD "lxsiwzx %0,%y1")])
; Definitions for store from 32-bit fpr register
(define_mode_attr f32_sr [(SF "f") (SD "wx")])
(define_mode_attr f32_sm [(SF "m") (SD "Z")])
(define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
(define_mode_attr f32_sv [(SF "stxsspx %1,%y0") (SD "stxsiwzx %1,%y0")])
; Definitions for 32-bit fpr direct move
(define_mode_attr f32_dm [(SF "wn") (SD "wm")])
; These modes do not fit in integer registers in 32-bit mode.
; but on e500v2, the gpr are 64 bit registers
(define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
; Iterator for reciprocal estimate instructions
(define_mode_iterator RECIPF [SF DF V4SF V2DF])
; Iterator for just SF/DF
(define_mode_iterator SFDF [SF DF])
; Conditional returns.
(define_code_iterator any_return [return simple_return])
(define_code_attr return_pred [(return "direct_return ()")
(simple_return "1")])
(define_code_attr return_str [(return "") (simple_return "simple_")])
; Various instructions that come in SI and DI forms.
; A generic w/d attribute, for things like cmpw/cmpd.
(define_mode_attr wd [(QI "b")
(HI "h")
(SI "w")
(DI "d")
(V16QI "b")
(V8HI "h")
(V4SI "w")
(V2DI "d")])
; DImode bits
(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
;; ISEL/ISEL64 target selection
(define_mode_attr sel [(SI "") (DI "64")])
;; Suffix for reload patterns
(define_mode_attr ptrsize [(SI "32bit")
(DI "64bit")])
(define_mode_attr tptrsize [(SI "TARGET_32BIT")
(DI "TARGET_64BIT")])
(define_mode_attr mptrsize [(SI "si")
(DI "di")])
(define_mode_attr ptrload [(SI "lwz")
(DI "ld")])
(define_mode_attr ptrm [(SI "m")
(DI "Y")])
(define_mode_attr rreg [(SF "f")
(DF "ws")
(V4SF "wf")
(V2DF "wd")])
(define_mode_attr rreg2 [(SF "f")
(DF "d")])
(define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
(DF "TARGET_FCFID")])
(define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
(DF "TARGET_E500_DOUBLE")])
(define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
(DF "TARGET_DOUBLE_FLOAT")])
;; Mode iterator for logical operations on 128-bit types
(define_mode_iterator BOOL_128 [TI
PTI
(V16QI "TARGET_ALTIVEC")
(V8HI "TARGET_ALTIVEC")
(V4SI "TARGET_ALTIVEC")
(V4SF "TARGET_ALTIVEC")
(V2DI "TARGET_ALTIVEC")
(V2DF "TARGET_ALTIVEC")])
;; For the GPRs we use 3 constraints for register outputs, two that are the
;; same as the output register, and a third where the output register is an
;; early clobber, so we don't have to deal with register overlaps. For the
;; vector types, we prefer to use the vector registers. For TI mode, allow
;; either.
;; Mode attribute for boolean operation register constraints for output
(define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
(PTI "&r,r,r")
(V16QI "wa,v,&?r,?r,?r")
(V8HI "wa,v,&?r,?r,?r")
(V4SI "wa,v,&?r,?r,?r")
(V4SF "wa,v,&?r,?r,?r")
(V2DI "wa,v,&?r,?r,?r")
(V2DF "wa,v,&?r,?r,?r")])
;; Mode attribute for boolean operation register constraints for operand1
(define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
(PTI "r,0,r")
(V16QI "wa,v,r,0,r")
(V8HI "wa,v,r,0,r")
(V4SI "wa,v,r,0,r")
(V4SF "wa,v,r,0,r")
(V2DI "wa,v,r,0,r")
(V2DF "wa,v,r,0,r")])
;; Mode attribute for boolean operation register constraints for operand2
(define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
(PTI "r,r,0")
(V16QI "wa,v,r,r,0")
(V8HI "wa,v,r,r,0")
(V4SI "wa,v,r,r,0")
(V4SF "wa,v,r,r,0")
(V2DI "wa,v,r,r,0")
(V2DF "wa,v,r,r,0")])
;; Mode attribute for boolean operation register constraints for operand1
;; for one_cmpl. To simplify things, we repeat the constraint where 0
;; is used for operand1 or operand2
(define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
(PTI "r,0,0")
(V16QI "wa,v,r,0,0")
(V8HI "wa,v,r,0,0")
(V4SI "wa,v,r,0,0")
(V4SF "wa,v,r,0,0")
(V2DI "wa,v,r,0,0")
(V2DF "wa,v,r,0,0")])
;; Mode attribute for the clobber of CC0 for AND expansion.
;; For the 128-bit types, we never do AND immediate, but we need to
;; get the correct number of X's for the number of operands.
(define_mode_attr BOOL_REGS_AND_CR0 [(TI "X,X,X,X,X")
(PTI "X,X,X")
(V16QI "X,X,X,X,X")
(V8HI "X,X,X,X,X")
(V4SI "X,X,X,X,X")
(V4SF "X,X,X,X,X")
(V2DI "X,X,X,X,X")
(V2DF "X,X,X,X,X")])
;; Start with fixed-point load and store insns. Here we put only the more
;; complex forms. Basic data transfer is done later.
(define_expand "zero_extenddi2"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "")))]
"TARGET_POWERPC64"
"")
(define_insn "*zero_extenddi2_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (match_operand:QHSI 1 "reg_or_mem_operand" "m,r")))]
"TARGET_POWERPC64 && (mode != SImode || !TARGET_LFIWZX)"
"@
lz%U1%X1 %0,%1
rldicl %0,%1,0,"
[(set_attr_alternative "type"
[(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_u")
(const_string "load")))
(const_string "*")])])
(define_insn "*zero_extenddi2_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
"TARGET_64BIT"
"@
rldicl. %2,%1,0,
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 2 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 2)
(zero_extend:DI (match_dup 1)))
(set (match_dup 0)
(compare:CC (match_dup 2)
(const_int 0)))]
"")
(define_insn "*zero_extenddi2_internal3"
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (match_dup 1)))]
"TARGET_64BIT"
"@
rldicl. %0,%1,0,
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(zero_extend:DI (match_dup 1)))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0)
(zero_extend:DI (match_dup 1)))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*zero_extendsidi2_lfiwzx"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,??wm,!wz,!wm")
(zero_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
"TARGET_POWERPC64 && TARGET_LFIWZX"
"@
lwz%U1%X1 %0,%1
rldicl %0,%1,0,32
mtvsrwz %x0,%1
lfiwzx %0,%y1
lxsiwzx %x0,%y1"
[(set_attr_alternative "type"
[(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_u")
(const_string "load")))
(const_string "*")
(const_string "mffgpr")
(const_string "fpload")
(const_string "fpload")])])
(define_insn "extendqidi2"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")))]
"TARGET_POWERPC64"
"extsb %0,%1"
[(set_attr "type" "exts")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
"TARGET_64BIT"
"@
extsb. %2,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 2 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 2)
(sign_extend:DI (match_dup 1)))
(set (match_dup 0)
(compare:CC (match_dup 2)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(sign_extend:DI (match_dup 1)))]
"TARGET_64BIT"
"@
extsb. %0,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(sign_extend:DI (match_dup 1)))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0)
(sign_extend:DI (match_dup 1)))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_expand "extendhidi2"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
"TARGET_POWERPC64"
"")
(define_insn ""
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
"TARGET_POWERPC64 && rs6000_gen_cell_microcode"
"@
lha%U1%X1 %0,%1
extsh %0,%1"
[(set_attr_alternative "type"
[(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ext_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_ext_u")
(const_string "load_ext")))
(const_string "exts")])])
(define_insn ""
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r")))]
"TARGET_POWERPC64 && !rs6000_gen_cell_microcode"
"extsh %0,%1"
[(set_attr "type" "exts")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
"TARGET_64BIT"
"@
extsh. %2,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 2 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 2)
(sign_extend:DI (match_dup 1)))
(set (match_dup 0)
(compare:CC (match_dup 2)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(sign_extend:DI (match_dup 1)))]
"TARGET_64BIT"
"@
extsh. %0,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(sign_extend:DI (match_dup 1)))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0)
(sign_extend:DI (match_dup 1)))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_expand "extendsidi2"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
"TARGET_POWERPC64"
"")
(define_insn "*extendsidi2_lfiwax"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,??wm,!wl,!wm")
(sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r,r,Z,Z")))]
"TARGET_POWERPC64 && TARGET_LFIWAX"
"@
lwa%U1%X1 %0,%1
extsw %0,%1
mtvsrwa %x0,%1
lfiwax %0,%y1
lxsiwax %x0,%y1"
[(set_attr_alternative "type"
[(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ext_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_ext_u")
(const_string "load_ext")))
(const_string "exts")
(const_string "mffgpr")
(const_string "fpload")
(const_string "fpload")])])
(define_insn "*extendsidi2_nocell"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r")))]
"TARGET_POWERPC64 && rs6000_gen_cell_microcode && !TARGET_LFIWAX"
"@
lwa%U1%X1 %0,%1
extsw %0,%1"
[(set_attr_alternative "type"
[(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ext_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_ext_u")
(const_string "load_ext")))
(const_string "exts")])])
(define_insn "*extendsidi2_nocell"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")))]
"TARGET_POWERPC64 && !rs6000_gen_cell_microcode"
"extsw %0,%1"
[(set_attr "type" "exts")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
"TARGET_64BIT"
"@
extsw. %2,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 2 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 2)
(sign_extend:DI (match_dup 1)))
(set (match_dup 0)
(compare:CC (match_dup 2)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(sign_extend:DI (match_dup 1)))]
"TARGET_64BIT"
"@
extsw. %0,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(sign_extend:DI (match_dup 1)))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0)
(sign_extend:DI (match_dup 1)))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_expand "zero_extendqisi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")))]
""
"")
(define_insn ""
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
""
"@
lbz%U1%X1 %0,%1
rlwinm %0,%1,0,0xff"
[(set_attr_alternative "type"
[(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_u")
(const_string "load")))
(const_string "*")])])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 2 "=r,r"))]
""
"@
andi. %2,%1,0xff
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 2 ""))]
"reload_completed"
[(set (match_dup 2)
(zero_extend:SI (match_dup 1)))
(set (match_dup 0)
(compare:CC (match_dup 2)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(zero_extend:SI (match_dup 1)))]
""
"@
andi. %0,%1,0xff
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (match_dup 1)))]
"reload_completed"
[(set (match_dup 0)
(zero_extend:SI (match_dup 1)))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "extendqisi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))]
""
"extsb %0,%1"
[(set_attr "type" "exts")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 2 "=r,r"))]
""
"@
extsb. %2,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 2 ""))]
"reload_completed"
[(set (match_dup 2)
(sign_extend:SI (match_dup 1)))
(set (match_dup 0)
(compare:CC (match_dup 2)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(sign_extend:SI (match_dup 1)))]
""
"@
extsb. %0,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(sign_extend:SI (match_dup 1)))]
"reload_completed"
[(set (match_dup 0)
(sign_extend:SI (match_dup 1)))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
(zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
""
"@
lbz%U1%X1 %0,%1
rlwinm %0,%1,0,0xff"
[(set_attr_alternative "type"
[(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_u")
(const_string "load")))
(const_string "*")])])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:HI 2 "=r,r"))]
""
"@
andi. %2,%1,0xff
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:HI 2 ""))]
"reload_completed"
[(set (match_dup 2)
(zero_extend:HI (match_dup 1)))
(set (match_dup 0)
(compare:CC (match_dup 2)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
(zero_extend:HI (match_dup 1)))]
""
"@
andi. %0,%1,0xff
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:HI 0 "gpc_reg_operand" "")
(zero_extend:HI (match_dup 1)))]
"reload_completed"
[(set (match_dup 0)
(zero_extend:HI (match_dup 1)))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "extendqihi2"
[(set (match_operand:HI 0 "gpc_reg_operand" "=r")
(sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))]
""
"extsb %0,%1"
[(set_attr "type" "exts")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:HI 2 "=r,r"))]
""
"@
extsb. %2,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:HI 2 ""))]
"reload_completed"
[(set (match_dup 2)
(sign_extend:HI (match_dup 1)))
(set (match_dup 0)
(compare:CC (match_dup 2)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
(sign_extend:HI (match_dup 1)))]
""
"@
extsb. %0,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:HI 0 "gpc_reg_operand" "")
(sign_extend:HI (match_dup 1)))]
"reload_completed"
[(set (match_dup 0)
(sign_extend:HI (match_dup 1)))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_expand "zero_extendhisi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
""
"")
(define_insn ""
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
""
"@
lhz%U1%X1 %0,%1
rlwinm %0,%1,0,0xffff"
[(set_attr_alternative "type"
[(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_u")
(const_string "load")))
(const_string "*")])])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 2 "=r,r"))]
""
"@
andi. %2,%1,0xffff
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 2 ""))]
"reload_completed"
[(set (match_dup 2)
(zero_extend:SI (match_dup 1)))
(set (match_dup 0)
(compare:CC (match_dup 2)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(zero_extend:SI (match_dup 1)))]
""
"@
andi. %0,%1,0xffff
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (match_dup 1)))]
"reload_completed"
[(set (match_dup 0)
(zero_extend:SI (match_dup 1)))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_expand "extendhisi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
""
"")
(define_insn ""
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
"rs6000_gen_cell_microcode"
"@
lha%U1%X1 %0,%1
extsh %0,%1"
[(set_attr_alternative "type"
[(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ext_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_ext_u")
(const_string "load_ext")))
(const_string "exts")])])
(define_insn ""
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r")))]
"!rs6000_gen_cell_microcode"
"extsh %0,%1"
[(set_attr "type" "exts")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 2 "=r,r"))]
""
"@
extsh. %2,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 2 ""))]
"reload_completed"
[(set (match_dup 2)
(sign_extend:SI (match_dup 1)))
(set (match_dup 0)
(compare:CC (match_dup 2)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(sign_extend:SI (match_dup 1)))]
""
"@
extsh. %0,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(sign_extend:SI (match_dup 1)))]
"reload_completed"
[(set (match_dup 0)
(sign_extend:SI (match_dup 1)))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
;; IBM 405, 440, 464 and 476 half-word multiplication operations.
(define_insn "*macchwc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (plus:SI (mult:SI (ashiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))
(sign_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "r")))
(match_operand:SI 4 "gpc_reg_operand" "0"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(plus:SI (mult:SI (ashiftrt:SI
(match_dup 2)
(const_int 16))
(sign_extend:SI
(match_dup 1)))
(match_dup 4)))]
"TARGET_MULHW"
"macchw. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*macchw"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(plus:SI (mult:SI (ashiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))
(sign_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "r")))
(match_operand:SI 3 "gpc_reg_operand" "0")))]
"TARGET_MULHW"
"macchw %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*macchwuc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (plus:SI (mult:SI (lshiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))
(zero_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "r")))
(match_operand:SI 4 "gpc_reg_operand" "0"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(plus:SI (mult:SI (lshiftrt:SI
(match_dup 2)
(const_int 16))
(zero_extend:SI
(match_dup 1)))
(match_dup 4)))]
"TARGET_MULHW"
"macchwu. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*macchwu"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(plus:SI (mult:SI (lshiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))
(zero_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "r")))
(match_operand:SI 3 "gpc_reg_operand" "0")))]
"TARGET_MULHW"
"macchwu %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*machhwc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (plus:SI (mult:SI (ashiftrt:SI
(match_operand:SI 1 "gpc_reg_operand" "%r")
(const_int 16))
(ashiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16)))
(match_operand:SI 4 "gpc_reg_operand" "0"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(plus:SI (mult:SI (ashiftrt:SI
(match_dup 1)
(const_int 16))
(ashiftrt:SI
(match_dup 2)
(const_int 16)))
(match_dup 4)))]
"TARGET_MULHW"
"machhw. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*machhw"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(plus:SI (mult:SI (ashiftrt:SI
(match_operand:SI 1 "gpc_reg_operand" "%r")
(const_int 16))
(ashiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16)))
(match_operand:SI 3 "gpc_reg_operand" "0")))]
"TARGET_MULHW"
"machhw %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*machhwuc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (plus:SI (mult:SI (lshiftrt:SI
(match_operand:SI 1 "gpc_reg_operand" "%r")
(const_int 16))
(lshiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16)))
(match_operand:SI 4 "gpc_reg_operand" "0"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(plus:SI (mult:SI (lshiftrt:SI
(match_dup 1)
(const_int 16))
(lshiftrt:SI
(match_dup 2)
(const_int 16)))
(match_dup 4)))]
"TARGET_MULHW"
"machhwu. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*machhwu"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(plus:SI (mult:SI (lshiftrt:SI
(match_operand:SI 1 "gpc_reg_operand" "%r")
(const_int 16))
(lshiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16)))
(match_operand:SI 3 "gpc_reg_operand" "0")))]
"TARGET_MULHW"
"machhwu %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*maclhwc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (plus:SI (mult:SI (sign_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "%r"))
(sign_extend:SI
(match_operand:HI 2 "gpc_reg_operand" "r")))
(match_operand:SI 4 "gpc_reg_operand" "0"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(plus:SI (mult:SI (sign_extend:SI
(match_dup 1))
(sign_extend:SI
(match_dup 2)))
(match_dup 4)))]
"TARGET_MULHW"
"maclhw. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*maclhw"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(plus:SI (mult:SI (sign_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "%r"))
(sign_extend:SI
(match_operand:HI 2 "gpc_reg_operand" "r")))
(match_operand:SI 3 "gpc_reg_operand" "0")))]
"TARGET_MULHW"
"maclhw %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*maclhwuc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (plus:SI (mult:SI (zero_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "%r"))
(zero_extend:SI
(match_operand:HI 2 "gpc_reg_operand" "r")))
(match_operand:SI 4 "gpc_reg_operand" "0"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(plus:SI (mult:SI (zero_extend:SI
(match_dup 1))
(zero_extend:SI
(match_dup 2)))
(match_dup 4)))]
"TARGET_MULHW"
"maclhwu. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*maclhwu"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(plus:SI (mult:SI (zero_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "%r"))
(zero_extend:SI
(match_operand:HI 2 "gpc_reg_operand" "r")))
(match_operand:SI 3 "gpc_reg_operand" "0")))]
"TARGET_MULHW"
"maclhwu %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*nmacchwc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
(mult:SI (ashiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))
(sign_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "r"))))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(minus:SI (match_dup 4)
(mult:SI (ashiftrt:SI
(match_dup 2)
(const_int 16))
(sign_extend:SI
(match_dup 1)))))]
"TARGET_MULHW"
"nmacchw. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*nmacchw"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
(mult:SI (ashiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))
(sign_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "r")))))]
"TARGET_MULHW"
"nmacchw %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*nmachhwc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
(mult:SI (ashiftrt:SI
(match_operand:SI 1 "gpc_reg_operand" "%r")
(const_int 16))
(ashiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(minus:SI (match_dup 4)
(mult:SI (ashiftrt:SI
(match_dup 1)
(const_int 16))
(ashiftrt:SI
(match_dup 2)
(const_int 16)))))]
"TARGET_MULHW"
"nmachhw. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*nmachhw"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
(mult:SI (ashiftrt:SI
(match_operand:SI 1 "gpc_reg_operand" "%r")
(const_int 16))
(ashiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16)))))]
"TARGET_MULHW"
"nmachhw %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*nmaclhwc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
(mult:SI (sign_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "%r"))
(sign_extend:SI
(match_operand:HI 2 "gpc_reg_operand" "r"))))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(minus:SI (match_dup 4)
(mult:SI (sign_extend:SI
(match_dup 1))
(sign_extend:SI
(match_dup 2)))))]
"TARGET_MULHW"
"nmaclhw. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*nmaclhw"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
(mult:SI (sign_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "%r"))
(sign_extend:SI
(match_operand:HI 2 "gpc_reg_operand" "r")))))]
"TARGET_MULHW"
"nmaclhw %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*mulchwc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (mult:SI (ashiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))
(sign_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "r")))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mult:SI (ashiftrt:SI
(match_dup 2)
(const_int 16))
(sign_extend:SI
(match_dup 1))))]
"TARGET_MULHW"
"mulchw. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*mulchw"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mult:SI (ashiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))
(sign_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "r"))))]
"TARGET_MULHW"
"mulchw %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*mulchwuc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (mult:SI (lshiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))
(zero_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "r")))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mult:SI (lshiftrt:SI
(match_dup 2)
(const_int 16))
(zero_extend:SI
(match_dup 1))))]
"TARGET_MULHW"
"mulchwu. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*mulchwu"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mult:SI (lshiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))
(zero_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "r"))))]
"TARGET_MULHW"
"mulchwu %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*mulhhwc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (mult:SI (ashiftrt:SI
(match_operand:SI 1 "gpc_reg_operand" "%r")
(const_int 16))
(ashiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16)))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mult:SI (ashiftrt:SI
(match_dup 1)
(const_int 16))
(ashiftrt:SI
(match_dup 2)
(const_int 16))))]
"TARGET_MULHW"
"mulhhw. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*mulhhw"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mult:SI (ashiftrt:SI
(match_operand:SI 1 "gpc_reg_operand" "%r")
(const_int 16))
(ashiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))))]
"TARGET_MULHW"
"mulhhw %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*mulhhwuc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (mult:SI (lshiftrt:SI
(match_operand:SI 1 "gpc_reg_operand" "%r")
(const_int 16))
(lshiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16)))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mult:SI (lshiftrt:SI
(match_dup 1)
(const_int 16))
(lshiftrt:SI
(match_dup 2)
(const_int 16))))]
"TARGET_MULHW"
"mulhhwu. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*mulhhwu"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mult:SI (lshiftrt:SI
(match_operand:SI 1 "gpc_reg_operand" "%r")
(const_int 16))
(lshiftrt:SI
(match_operand:SI 2 "gpc_reg_operand" "r")
(const_int 16))))]
"TARGET_MULHW"
"mulhhwu %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*mullhwc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (mult:SI (sign_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "%r"))
(sign_extend:SI
(match_operand:HI 2 "gpc_reg_operand" "r")))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mult:SI (sign_extend:SI
(match_dup 1))
(sign_extend:SI
(match_dup 2))))]
"TARGET_MULHW"
"mullhw. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*mullhw"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mult:SI (sign_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "%r"))
(sign_extend:SI
(match_operand:HI 2 "gpc_reg_operand" "r"))))]
"TARGET_MULHW"
"mullhw %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*mullhwuc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (mult:SI (zero_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "%r"))
(zero_extend:SI
(match_operand:HI 2 "gpc_reg_operand" "r")))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mult:SI (zero_extend:SI
(match_dup 1))
(zero_extend:SI
(match_dup 2))))]
"TARGET_MULHW"
"mullhwu. %0,%1,%2"
[(set_attr "type" "imul3")])
(define_insn "*mullhwu"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mult:SI (zero_extend:SI
(match_operand:HI 1 "gpc_reg_operand" "%r"))
(zero_extend:SI
(match_operand:HI 2 "gpc_reg_operand" "r"))))]
"TARGET_MULHW"
"mullhwu %0,%1,%2"
[(set_attr "type" "imul3")])
;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
(define_insn "dlmzb"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "gpc_reg_operand" "r")]
UNSPEC_DLMZB_CR))
(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec:SI [(match_dup 1)
(match_dup 2)]
UNSPEC_DLMZB))]
"TARGET_DLMZB"
"dlmzb. %0,%1,%2")
(define_expand "strlensi"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(unspec:SI [(match_operand:BLK 1 "general_operand" "")
(match_operand:QI 2 "const_int_operand" "")
(match_operand 3 "const_int_operand" "")]
UNSPEC_DLMZB_STRLEN))
(clobber (match_scratch:CC 4 "=x"))]
"TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
{
rtx result = operands[0];
rtx src = operands[1];
rtx search_char = operands[2];
rtx align = operands[3];
rtx addr, scratch_string, word1, word2, scratch_dlmzb;
rtx loop_label, end_label, mem, cr0, cond;
if (search_char != const0_rtx
|| GET_CODE (align) != CONST_INT
|| INTVAL (align) < 8)
FAIL;
word1 = gen_reg_rtx (SImode);
word2 = gen_reg_rtx (SImode);
scratch_dlmzb = gen_reg_rtx (SImode);
scratch_string = gen_reg_rtx (Pmode);
loop_label = gen_label_rtx ();
end_label = gen_label_rtx ();
addr = force_reg (Pmode, XEXP (src, 0));
emit_move_insn (scratch_string, addr);
emit_label (loop_label);
mem = change_address (src, SImode, scratch_string);
emit_move_insn (word1, mem);
emit_move_insn (word2, adjust_address (mem, SImode, 4));
cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
emit_jump_insn (gen_rtx_SET (VOIDmode,
pc_rtx,
gen_rtx_IF_THEN_ELSE (VOIDmode,
cond,
gen_rtx_LABEL_REF
(VOIDmode,
end_label),
pc_rtx)));
emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
emit_jump_insn (gen_rtx_SET (VOIDmode,
pc_rtx,
gen_rtx_LABEL_REF (VOIDmode, loop_label)));
emit_barrier ();
emit_label (end_label);
emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
emit_insn (gen_subsi3 (result, scratch_string, addr));
emit_insn (gen_subsi3 (result, result, const1_rtx));
DONE;
})
;; Fixed-point arithmetic insns.
(define_expand "add3"
[(set (match_operand:SDI 0 "gpc_reg_operand" "")
(plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
(match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
""
{
if (mode == DImode && ! TARGET_POWERPC64)
{
if (non_short_cint_operand (operands[2], DImode))
FAIL;
}
else if (GET_CODE (operands[2]) == CONST_INT
&& ! add_operand (operands[2], mode))
{
rtx tmp = ((!can_create_pseudo_p ()
|| rtx_equal_p (operands[0], operands[1]))
? operands[0] : gen_reg_rtx (mode));
HOST_WIDE_INT val = INTVAL (operands[2]);
HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
HOST_WIDE_INT rest = trunc_int_for_mode (val - low, mode);
if (mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
FAIL;
/* The ordering here is important for the prolog expander.
When space is allocated from the stack, adding 'low' first may
produce a temporary deallocation (which would be bad). */
emit_insn (gen_add3 (tmp, operands[1], GEN_INT (rest)));
emit_insn (gen_add3 (operands[0], tmp, GEN_INT (low)));
DONE;
}
})
;; Discourage ai/addic because of carry but provide it in an alternative
;; allowing register zero as source.
(define_insn "*add3_internal1"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,?r,r")
(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,r,b")
(match_operand:GPR 2 "add_operand" "r,I,I,L")))]
"!DECIMAL_FLOAT_MODE_P (GET_MODE (operands[0])) && !DECIMAL_FLOAT_MODE_P (GET_MODE (operands[1]))"
"@
add %0,%1,%2
addi %0,%1,%2
addic %0,%1,%2
addis %0,%1,%v2"
[(set_attr "length" "4,4,4,4")])
(define_insn "addsi3_high"
[(set (match_operand:SI 0 "gpc_reg_operand" "=b")
(plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(high:SI (match_operand 2 "" ""))))]
"TARGET_MACHO && !TARGET_64BIT"
"addis %0,%1,ha16(%2)"
[(set_attr "length" "4")])
(define_insn "*add3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r")
(match_operand:P 2 "reg_or_short_operand" "r,I,r,I"))
(const_int 0)))
(clobber (match_scratch:P 3 "=r,r,r,r"))]
""
"@
add. %3,%1,%2
addic. %3,%1,%2
#
#"
[(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
(match_operand:GPR 2 "reg_or_short_operand" ""))
(const_int 0)))
(clobber (match_scratch:GPR 3 ""))]
"reload_completed"
[(set (match_dup 3)
(plus:GPR (match_dup 1)
(match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*add3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r")
(match_operand:P 2 "reg_or_short_operand" "r,I,r,I"))
(const_int 0)))
(set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r")
(plus:P (match_dup 1)
(match_dup 2)))]
""
"@
add. %0,%1,%2
addic. %0,%1,%2
#
#"
[(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
(compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "")
(match_operand:P 2 "reg_or_short_operand" ""))
(const_int 0)))
(set (match_operand:P 0 "gpc_reg_operand" "")
(plus:P (match_dup 1) (match_dup 2)))]
"reload_completed"
[(set (match_dup 0)
(plus:P (match_dup 1)
(match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
;; Split an add that we can't do in one insn into two insns, each of which
;; does one 16-bit part. This is used by combine. Note that the low-order
;; add should be last in case the result gets used in an address.
(define_split
[(set (match_operand:GPR 0 "gpc_reg_operand" "")
(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
(match_operand:GPR 2 "non_add_cint_operand" "")))]
""
[(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
(set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
{
HOST_WIDE_INT val = INTVAL (operands[2]);
HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
HOST_WIDE_INT rest = trunc_int_for_mode (val - low, mode);
operands[4] = GEN_INT (low);
if (mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
operands[3] = GEN_INT (rest);
else if (can_create_pseudo_p ())
{
operands[3] = gen_reg_rtx (DImode);
emit_move_insn (operands[3], operands[2]);
emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
DONE;
}
else
FAIL;
})
(define_expand "one_cmpl2"
[(set (match_operand:SDI 0 "gpc_reg_operand" "")
(not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
""
{
if (mode == DImode && !TARGET_POWERPC64)
{
rs6000_split_logical (operands, NOT, false, false, false, NULL_RTX);
DONE;
}
})
(define_insn "*one_cmpl2"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
""
"nor %0,%1,%1")
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:P 2 "=r,r"))]
""
"@
nor. %2,%1,%1
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:P 2 ""))]
"reload_completed"
[(set (match_dup 2)
(not:P (match_dup 1)))
(set (match_dup 0)
(compare:CC (match_dup 2)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
(compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
(not:P (match_dup 1)))]
""
"@
nor. %0,%1,%1
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:P 0 "gpc_reg_operand" "")
(not:P (match_dup 1)))]
"reload_completed"
[(set (match_dup 0)
(not:P (match_dup 1)))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
(minus:GPR (match_operand:GPR 1 "reg_or_short_operand" "r,I")
(match_operand:GPR 2 "gpc_reg_operand" "r,r")))]
""
"@
subf %0,%2,%1
subfic %0,%2,%1")
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "r,r")
(match_operand:P 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:P 3 "=r,r"))]
""
"@
subf. %3,%2,%1
#"
[(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
(compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "")
(match_operand:P 2 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:P 3 ""))]
"reload_completed"
[(set (match_dup 3)
(minus:P (match_dup 1)
(match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "r,r")
(match_operand:P 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
(minus:P (match_dup 1)
(match_dup 2)))]
""
"@
subf. %0,%2,%1
#"
[(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
(compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "")
(match_operand:P 2 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:P 0 "gpc_reg_operand" "")
(minus:P (match_dup 1)
(match_dup 2)))]
"reload_completed"
[(set (match_dup 0)
(minus:P (match_dup 1)
(match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_expand "sub3"
[(set (match_operand:SDI 0 "gpc_reg_operand" "")
(minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
(match_operand:SDI 2 "reg_or_sub_cint_operand" "")))]
""
"
{
if (GET_CODE (operands[2]) == CONST_INT)
{
emit_insn (gen_add3 (operands[0], operands[1],
negate_rtx (mode, operands[2])));
DONE;
}
}")
(define_expand "neg2"
[(set (match_operand:SDI 0 "gpc_reg_operand" "")
(neg:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
""
"")
(define_insn "*neg2_internal"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
""
"neg %0,%1")
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:P 2 "=r,r"))]
""
"@
neg. %2,%1
#"
[(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:P 2 ""))]
"reload_completed"
[(set (match_dup 2)
(neg:P (match_dup 1)))
(set (match_dup 0)
(compare:CC (match_dup 2)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
(neg:P (match_dup 1)))]
""
"@
neg. %0,%1
#"
[(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:P 0 "gpc_reg_operand" "")
(neg:P (match_dup 1)))]
"reload_completed"
[(set (match_dup 0)
(neg:P (match_dup 1)))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "clz2"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
""
"cntlz %0,%1"
[(set_attr "type" "cntlz")])
(define_expand "ctz2"
[(set (match_dup 2)
(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
(parallel [(set (match_dup 3) (and:GPR (match_dup 1)
(match_dup 2)))
(clobber (scratch:CC))])
(set (match_dup 4) (clz:GPR (match_dup 3)))
(set (match_operand:GPR 0 "gpc_reg_operand" "")
(minus:GPR (match_dup 5) (match_dup 4)))]
""
{
operands[2] = gen_reg_rtx (mode);
operands[3] = gen_reg_rtx (mode);
operands[4] = gen_reg_rtx (mode);
operands[5] = GEN_INT (GET_MODE_BITSIZE (mode) - 1);
})
(define_expand "ffs2"
[(set (match_dup 2)
(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
(parallel [(set (match_dup 3) (and:GPR (match_dup 1)
(match_dup 2)))
(clobber (scratch:CC))])
(set (match_dup 4) (clz:GPR (match_dup 3)))
(set (match_operand:GPR 0 "gpc_reg_operand" "")
(minus:GPR (match_dup 5) (match_dup 4)))]
""
{
operands[2] = gen_reg_rtx (mode);
operands[3] = gen_reg_rtx (mode);
operands[4] = gen_reg_rtx (mode);
operands[5] = GEN_INT (GET_MODE_BITSIZE (mode));
})
(define_insn "popcntb2"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
UNSPEC_POPCNTB))]
"TARGET_POPCNTB"
"popcntb %0,%1"
[(set_attr "length" "4")
(set_attr "type" "popcnt")])
(define_insn "popcntd2"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
"TARGET_POPCNTD"
"popcnt %0,%1"
[(set_attr "length" "4")
(set_attr "type" "popcnt")])
(define_expand "popcount2"
[(set (match_operand:GPR 0 "gpc_reg_operand" "")
(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
"TARGET_POPCNTB || TARGET_POPCNTD"
{
rs6000_emit_popcount (operands[0], operands[1]);
DONE;
})
(define_insn "parity2_cmpb"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
"TARGET_CMPB && TARGET_POPCNTB"
"prty %0,%1"
[(set_attr "length" "4")
(set_attr "type" "popcnt")])
(define_expand "parity2"
[(set (match_operand:GPR 0 "gpc_reg_operand" "")
(parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
"TARGET_POPCNTB"
{
rs6000_emit_parity (operands[0], operands[1]);
DONE;
})
;; Since the hardware zeros the upper part of the register, save generating the
;; AND immediate if we are converting to unsigned
(define_insn "*bswaphi2_extenddi"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(zero_extend:DI
(bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
"TARGET_POWERPC64"
"lhbrx %0,%y1"
[(set_attr "length" "4")
(set_attr "type" "load")])
(define_insn "*bswaphi2_extendsi"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(zero_extend:SI
(bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
""
"lhbrx %0,%y1"
[(set_attr "length" "4")
(set_attr "type" "load")])
(define_expand "bswaphi2"
[(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
(bswap:HI
(match_operand:HI 1 "reg_or_mem_operand" "")))
(clobber (match_scratch:SI 2 ""))])]
""
{
if (!REG_P (operands[0]) && !REG_P (operands[1]))
operands[1] = force_reg (HImode, operands[1]);
})
(define_insn "bswaphi2_internal"
[(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
(bswap:HI
(match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
(clobber (match_scratch:SI 2 "=X,X,&r"))]
""
"@
lhbrx %0,%y1
sthbrx %1,%y0
#"
[(set_attr "length" "4,4,12")
(set_attr "type" "load,store,*")])
;; We are always BITS_BIG_ENDIAN, so the (const_int 16) below is
;; correct for -mlittle as well as -mbig.
(define_split
[(set (match_operand:HI 0 "gpc_reg_operand" "")
(bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
(clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
"reload_completed"
[(set (match_dup 3)
(zero_extract:SI (match_dup 4)
(const_int 8)
(const_int 16)))
(set (match_dup 2)
(and:SI (ashift:SI (match_dup 4)
(const_int 8))
(const_int 65280))) ;; 0xff00
(set (match_dup 3)
(ior:SI (match_dup 3)
(match_dup 2)))]
"
{
operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
}")
(define_insn "*bswapsi2_extenddi"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(zero_extend:DI
(bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
"TARGET_POWERPC64"
"lwbrx %0,%y1"
[(set_attr "length" "4")
(set_attr "type" "load")])
(define_expand "bswapsi2"
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(bswap:SI
(match_operand:SI 1 "reg_or_mem_operand" "")))]
""
{
if (!REG_P (operands[0]) && !REG_P (operands[1]))
operands[1] = force_reg (SImode, operands[1]);
})
(define_insn "*bswapsi2_internal"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
(bswap:SI
(match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
""
"@
lwbrx %0,%y1
stwbrx %1,%y0
#"
[(set_attr "length" "4,4,12")
(set_attr "type" "load,store,*")])
;; We are always BITS_BIG_ENDIAN, so the bit positions below in
;; zero_extract insns do not change for -mlittle.
(define_split
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
"reload_completed"
[(set (match_dup 0)
(rotate:SI (match_dup 1) (const_int 8)))
(set (zero_extract:SI (match_dup 0)
(const_int 8)
(const_int 0))
(match_dup 1))
(set (zero_extract:SI (match_dup 0)
(const_int 8)
(const_int 16))
(rotate:SI (match_dup 1)
(const_int 16)))]
"")
(define_expand "bswapdi2"
[(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
(bswap:DI
(match_operand:DI 1 "reg_or_mem_operand" "")))
(clobber (match_scratch:DI 2 ""))
(clobber (match_scratch:DI 3 ""))
(clobber (match_scratch:DI 4 ""))])]
""
{
if (!REG_P (operands[0]) && !REG_P (operands[1]))
operands[1] = force_reg (DImode, operands[1]);
if (!TARGET_POWERPC64)
{
/* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
that uses 64-bit registers needs the same scratch registers as 64-bit
mode. */
emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
DONE;
}
})
;; Power7/cell has ldbrx/stdbrx, so use it directly
(define_insn "*bswapdi2_ldbrx"
[(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
(clobber (match_scratch:DI 2 "=X,X,&r"))
(clobber (match_scratch:DI 3 "=X,X,&r"))
(clobber (match_scratch:DI 4 "=X,X,&r"))]
"TARGET_POWERPC64 && TARGET_LDBRX
&& (REG_P (operands[0]) || REG_P (operands[1]))"
"@
ldbrx %0,%y1
stdbrx %1,%y0
#"
[(set_attr "length" "4,4,36")
(set_attr "type" "load,store,*")])
;; Non-power7/cell, fall back to use lwbrx/stwbrx
(define_insn "*bswapdi2_64bit"
[(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
(clobber (match_scratch:DI 2 "=&b,&b,&r"))
(clobber (match_scratch:DI 3 "=&r,&r,&r"))
(clobber (match_scratch:DI 4 "=&r,X,&r"))]
"TARGET_POWERPC64 && !TARGET_LDBRX
&& (REG_P (operands[0]) || REG_P (operands[1]))"
"#"
[(set_attr "length" "16,12,36")])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
(clobber (match_operand:DI 2 "gpc_reg_operand" ""))
(clobber (match_operand:DI 3 "gpc_reg_operand" ""))
(clobber (match_operand:DI 4 "gpc_reg_operand" ""))]
"TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
[(const_int 0)]
"
{
rtx dest = operands[0];
rtx src = operands[1];
rtx op2 = operands[2];
rtx op3 = operands[3];
rtx op4 = operands[4];
rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
BYTES_BIG_ENDIAN ? 4 : 0);
rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode,
BYTES_BIG_ENDIAN ? 4 : 0);
rtx addr1;
rtx addr2;
rtx word_high;
rtx word_low;
addr1 = XEXP (src, 0);
if (GET_CODE (addr1) == PLUS)
{
emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
if (TARGET_AVOID_XFORM)
{
emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
addr2 = op2;
}
else
addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
}
else if (TARGET_AVOID_XFORM)
{
emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
addr2 = op2;
}
else
{
emit_move_insn (op2, GEN_INT (4));
addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
}
if (BYTES_BIG_ENDIAN)
{
word_high = change_address (src, SImode, addr1);
word_low = change_address (src, SImode, addr2);
}
else
{
word_high = change_address (src, SImode, addr2);
word_low = change_address (src, SImode, addr1);
}
emit_insn (gen_bswapsi2 (op3_32, word_low));
emit_insn (gen_bswapsi2 (op4_32, word_high));
emit_insn (gen_ashldi3 (dest, op3, GEN_INT (32)));
emit_insn (gen_iordi3 (dest, dest, op4));
}")
(define_split
[(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
(clobber (match_operand:DI 2 "gpc_reg_operand" ""))
(clobber (match_operand:DI 3 "gpc_reg_operand" ""))
(clobber (match_operand:DI 4 "" ""))]
"TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
[(const_int 0)]
"
{
rtx dest = operands[0];
rtx src = operands[1];
rtx op2 = operands[2];
rtx op3 = operands[3];
rtx src_si = simplify_gen_subreg (SImode, src, DImode,
BYTES_BIG_ENDIAN ? 4 : 0);
rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
BYTES_BIG_ENDIAN ? 4 : 0);
rtx addr1;
rtx addr2;
rtx word_high;
rtx word_low;
addr1 = XEXP (dest, 0);
if (GET_CODE (addr1) == PLUS)
{
emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
if (TARGET_AVOID_XFORM)
{
emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
addr2 = op2;
}
else
addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
}
else if (TARGET_AVOID_XFORM)
{
emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
addr2 = op2;
}
else
{
emit_move_insn (op2, GEN_INT (4));
addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
}
emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
if (BYTES_BIG_ENDIAN)
{
word_high = change_address (dest, SImode, addr1);
word_low = change_address (dest, SImode, addr2);
}
else
{
word_high = change_address (dest, SImode, addr2);
word_low = change_address (dest, SImode, addr1);
}
emit_insn (gen_bswapsi2 (word_high, src_si));
emit_insn (gen_bswapsi2 (word_low, op3_si));
}")
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
(clobber (match_operand:DI 2 "gpc_reg_operand" ""))
(clobber (match_operand:DI 3 "gpc_reg_operand" ""))
(clobber (match_operand:DI 4 "" ""))]
"TARGET_POWERPC64 && reload_completed"
[(const_int 0)]
"
{
rtx dest = operands[0];
rtx src = operands[1];
rtx op2 = operands[2];
rtx op3 = operands[3];
int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
emit_insn (gen_bswapsi2 (dest_si, src_si));
emit_insn (gen_bswapsi2 (op3_si, op2_si));
emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
emit_insn (gen_iordi3 (dest, dest, op3));
}")
(define_insn "bswapdi2_32bit"
[(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
(clobber (match_scratch:SI 2 "=&b,&b,X"))]
"!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
"#"
[(set_attr "length" "16,12,36")])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
(clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
"!TARGET_POWERPC64 && reload_completed"
[(const_int 0)]
"
{
rtx dest = operands[0];
rtx src = operands[1];
rtx op2 = operands[2];
rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
rtx addr1;
rtx addr2;
rtx word1;
rtx word2;
addr1 = XEXP (src, 0);
if (GET_CODE (addr1) == PLUS)
{
emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
if (TARGET_AVOID_XFORM)
{
emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
addr2 = op2;
}
else
addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
}
else if (TARGET_AVOID_XFORM)
{
emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
addr2 = op2;
}
else
{
emit_move_insn (op2, GEN_INT (4));
addr2 = gen_rtx_PLUS (SImode, op2, addr1);
}
word1 = change_address (src, SImode, addr1);
word2 = change_address (src, SImode, addr2);
emit_insn (gen_bswapsi2 (dest2, word1));
emit_insn (gen_bswapsi2 (dest1, word2));
}")
(define_split
[(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
(clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
"!TARGET_POWERPC64 && reload_completed"
[(const_int 0)]
"
{
rtx dest = operands[0];
rtx src = operands[1];
rtx op2 = operands[2];
rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
rtx addr1;
rtx addr2;
rtx word1;
rtx word2;
addr1 = XEXP (dest, 0);
if (GET_CODE (addr1) == PLUS)
{
emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
if (TARGET_AVOID_XFORM)
{
emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
addr2 = op2;
}
else
addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
}
else if (TARGET_AVOID_XFORM)
{
emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
addr2 = op2;
}
else
{
emit_move_insn (op2, GEN_INT (4));
addr2 = gen_rtx_PLUS (SImode, op2, addr1);
}
word1 = change_address (dest, SImode, addr1);
word2 = change_address (dest, SImode, addr2);
emit_insn (gen_bswapsi2 (word2, src1));
emit_insn (gen_bswapsi2 (word1, src2));
}")
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
(clobber (match_operand:SI 2 "" ""))]
"!TARGET_POWERPC64 && reload_completed"
[(const_int 0)]
"
{
rtx dest = operands[0];
rtx src = operands[1];
rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
emit_insn (gen_bswapsi2 (dest1, src2));
emit_insn (gen_bswapsi2 (dest2, src1));
}")
(define_insn "mulsi3"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "reg_or_short_operand" "r,I")))]
""
"@
mullw %0,%1,%2
mulli %0,%1,%2"
[(set (attr "type")
(cond [(match_operand:SI 2 "s8bit_cint_operand" "")
(const_string "imul3")
(match_operand:SI 2 "short_cint_operand" "")
(const_string "imul2")]
(const_string "imul")))])
(define_insn "*mulsi3_internal1"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
""
"@
mullw. %3,%1,%2
#"
[(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"reload_completed"
[(set (match_dup 3)
(mult:SI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*mulsi3_internal2"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(mult:SI (match_dup 1) (match_dup 2)))]
""
"@
mullw. %0,%1,%2
#"
[(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(mult:SI (match_dup 1) (match_dup 2)))]
"reload_completed"
[(set (match_dup 0)
(mult:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "udiv3"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
(match_operand:GPR 2 "gpc_reg_operand" "r")))]
""
"divu %0,%1,%2"
[(set (attr "type")
(cond [(match_operand:SI 0 "" "")
(const_string "idiv")]
(const_string "ldiv")))])
;; For powers of two we can do srai/aze for divide and then adjust for
;; modulus. If it isn't a power of two, force operands into register and do
;; a normal divide.
(define_expand "div3"
[(set (match_operand:GPR 0 "gpc_reg_operand" "")
(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
(match_operand:GPR 2 "reg_or_cint_operand" "")))]
""
{
if (GET_CODE (operands[2]) != CONST_INT
|| INTVAL (operands[2]) <= 0
|| exact_log2 (INTVAL (operands[2])) < 0)
operands[2] = force_reg (mode, operands[2]);
})
(define_insn "*div3"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
(match_operand:GPR 2 "gpc_reg_operand" "r")))]
""
"div %0,%1,%2"
[(set (attr "type")
(cond [(match_operand:SI 0 "" "")
(const_string "idiv")]
(const_string "ldiv")))])
(define_expand "mod3"
[(use (match_operand:GPR 0 "gpc_reg_operand" ""))
(use (match_operand:GPR 1 "gpc_reg_operand" ""))
(use (match_operand:GPR 2 "reg_or_cint_operand" ""))]
""
"
{
int i;
rtx temp1;
rtx temp2;
if (GET_CODE (operands[2]) != CONST_INT
|| INTVAL (operands[2]) <= 0
|| (i = exact_log2 (INTVAL (operands[2]))) < 0)
FAIL;
temp1 = gen_reg_rtx (mode);
temp2 = gen_reg_rtx (mode);
emit_insn (gen_div3 (temp1, operands[1], operands[2]));
emit_insn (gen_ashl3 (temp2, temp1, GEN_INT (i)));
emit_insn (gen_sub3 (operands[0], operands[1], temp2));
DONE;
}")
(define_insn ""
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
(match_operand:GPR 2 "exact_log2_cint_operand" "N")))]
""
"srai %0,%1,%p2\;addze %0,%0"
[(set_attr "type" "two")
(set_attr "length" "8")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r")
(match_operand:P 2 "exact_log2_cint_operand" "N,N"))
(const_int 0)))
(clobber (match_scratch:P 3 "=r,r"))]
""
"@
srai %3,%1,%p2\;addze. %3,%3
#"
[(set_attr "type" "compare")
(set_attr "length" "8,12")
(set_attr "cell_micro" "not")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
(match_operand:GPR 2 "exact_log2_cint_operand"
""))
(const_int 0)))
(clobber (match_scratch:GPR 3 ""))]
"reload_completed"
[(set (match_dup 3)
(div: (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r")
(match_operand:P 2 "exact_log2_cint_operand" "N,N"))
(const_int 0)))
(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
(div:P (match_dup 1) (match_dup 2)))]
""
"@
srai %0,%1,%p2\;addze. %0,%0
#"
[(set_attr "type" "compare")
(set_attr "length" "8,12")
(set_attr "cell_micro" "not")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
(match_operand:GPR 2 "exact_log2_cint_operand"
""))
(const_int 0)))
(set (match_operand:GPR 0 "gpc_reg_operand" "")
(div:GPR (match_dup 1) (match_dup 2)))]
"reload_completed"
[(set (match_dup 0)
(div: (match_dup 1) (match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
;; Logical instructions
;; The logical instructions are mostly combined by using match_operator,
;; but the plain AND insns are somewhat different because there is no
;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
;; those rotate-and-mask operations. Thus, the AND insns come first.
(define_expand "andsi3"
[(parallel
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(and:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "and_operand" "")))
(clobber (match_scratch:CC 3 ""))])]
""
"")
(define_insn "andsi3_mc"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
(match_operand:SI 2 "and_operand" "?r,T,K,L")))
(clobber (match_scratch:CC 3 "=X,X,x,x"))]
"rs6000_gen_cell_microcode"
"@
and %0,%1,%2
rlwinm %0,%1,0,%m2,%M2
andi. %0,%1,%b2
andis. %0,%1,%u2"
[(set_attr "type" "*,*,fast_compare,fast_compare")])
(define_insn "andsi3_nomc"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "and_operand" "?r,T")))
(clobber (match_scratch:CC 3 "=X,X"))]
"!rs6000_gen_cell_microcode"
"@
and %0,%1,%2
rlwinm %0,%1,0,%m2,%M2")
(define_insn "andsi3_internal0_nomc"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "and_operand" "?r,T")))]
"!rs6000_gen_cell_microcode"
"@
and %0,%1,%2
rlwinm %0,%1,0,%m2,%M2")
;; Note to set cr's other than cr0 we do the and immediate and then
;; the test again -- this avoids a mfcr which on the higher end
;; machines causes an execution serialization
(define_insn "*andsi3_internal2_mc"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
(match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r"))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
"TARGET_32BIT && rs6000_gen_cell_microcode"
"@
and. %3,%1,%2
andi. %3,%1,%b2
andis. %3,%1,%u2
rlwinm. %3,%1,0,%m2,%M2
#
#
#
#"
[(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\
compare,compare,compare,compare")
(set_attr "length" "4,4,4,4,8,8,8,8")])
(define_insn "*andsi3_internal3_mc"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
(match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r"))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
"TARGET_64BIT && rs6000_gen_cell_microcode"
"@
#
andi. %3,%1,%b2
andis. %3,%1,%u2
rlwinm. %3,%1,0,%m2,%M2
#
#
#
#"
[(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\
compare,compare,compare")
(set_attr "length" "8,4,4,4,8,8,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
(match_operand:GPR 2 "and_operand" ""))
(const_int 0)))
(clobber (match_scratch:GPR 3 ""))
(clobber (match_scratch:CC 4 ""))]
"reload_completed"
[(parallel [(set (match_dup 3)
(and: (match_dup 1)
(match_dup 2)))
(clobber (match_dup 4))])
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
;; We don't have a 32 bit "and. rt,ra,rb" for ppc64. cr is set from the
;; whole 64 bit reg, and we don't know what is in the high 32 bits.
(define_split
[(set (match_operand:CC 0 "cc_reg_operand" "")
(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))
(clobber (match_scratch:CC 4 ""))]
"TARGET_POWERPC64 && reload_completed"
[(parallel [(set (match_dup 3)
(and:SI (match_dup 1)
(match_dup 2)))
(clobber (match_dup 4))])
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*andsi3_internal4"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
(match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r")
(and:SI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
"TARGET_32BIT && rs6000_gen_cell_microcode"
"@
and. %0,%1,%2
andi. %0,%1,%b2
andis. %0,%1,%u2
rlwinm. %0,%1,0,%m2,%M2
#
#
#
#"
[(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\
compare,compare,compare,compare")
(set_attr "length" "4,4,4,4,8,8,8,8")])
(define_insn "*andsi3_internal5_mc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
(match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r")
(and:SI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
"TARGET_64BIT && rs6000_gen_cell_microcode"
"@
#
andi. %0,%1,%b2
andis. %0,%1,%u2
rlwinm. %0,%1,0,%m2,%M2
#
#
#
#"
[(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\
compare,compare,compare")
(set_attr "length" "8,4,4,4,8,8,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "and_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(and:SI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:CC 4 ""))]
"reload_completed"
[(parallel [(set (match_dup 0)
(and:SI (match_dup 1)
(match_dup 2)))
(clobber (match_dup 4))])
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 3 "cc_reg_operand" "")
(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(and:SI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:CC 4 ""))]
"TARGET_POWERPC64 && reload_completed"
[(parallel [(set (match_dup 0)
(and:SI (match_dup 1)
(match_dup 2)))
(clobber (match_dup 4))])
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
;; Handle the PowerPC64 rlwinm corner case
(define_insn_and_split "*andsi3_internal6"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(and:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "mask_operand_wrap" "i")))]
"TARGET_POWERPC64"
"#"
"TARGET_POWERPC64"
[(set (match_dup 0)
(and:SI (rotate:SI (match_dup 1) (match_dup 3))
(match_dup 4)))
(set (match_dup 0)
(rotate:SI (match_dup 0) (match_dup 5)))]
"
{
int mb = extract_MB (operands[2]);
int me = extract_ME (operands[2]);
operands[3] = GEN_INT (me + 1);
operands[5] = GEN_INT (32 - (me + 1));
operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
}"
[(set_attr "length" "8")])
(define_expand "iorsi3"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_logical_cint_operand" "")))]
""
"
{
if (GET_CODE (operands[2]) == CONST_INT
&& ! logical_operand (operands[2], SImode))
{
HOST_WIDE_INT value = INTVAL (operands[2]);
rtx tmp = ((!can_create_pseudo_p ()
|| rtx_equal_p (operands[0], operands[1]))
? operands[0] : gen_reg_rtx (SImode));
emit_insn (gen_iorsi3 (tmp, operands[1],
GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
emit_insn (gen_iorsi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
DONE;
}
}")
(define_expand "xorsi3"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_logical_cint_operand" "")))]
""
"
{
if (GET_CODE (operands[2]) == CONST_INT
&& ! logical_operand (operands[2], SImode))
{
HOST_WIDE_INT value = INTVAL (operands[2]);
rtx tmp = ((!can_create_pseudo_p ()
|| rtx_equal_p (operands[0], operands[1]))
? operands[0] : gen_reg_rtx (SImode));
emit_insn (gen_xorsi3 (tmp, operands[1],
GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
emit_insn (gen_xorsi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
DONE;
}
}")
(define_insn "*boolsi3_internal1"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
(match_operator:SI 3 "boolean_or_operator"
[(match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
(match_operand:SI 2 "logical_operand" "r,K,L")]))]
""
"@
%q3 %0,%1,%2
%q3i %0,%1,%b2
%q3is %0,%1,%u2")
(define_insn "*boolsi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (match_operator:SI 4 "boolean_or_operator"
[(match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
"TARGET_32BIT"
"@
%q4. %3,%1,%2
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operator:SI 4 "boolean_operator"
[(match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "gpc_reg_operand" "")])
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"TARGET_32BIT && reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*boolsi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (match_operator:SI 4 "boolean_operator"
[(match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
"TARGET_32BIT"
"@
%q4. %0,%1,%2
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operator:SI 4 "boolean_operator"
[(match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "gpc_reg_operand" "")])
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(match_dup 4))]
"TARGET_32BIT && reload_completed"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
;; Split a logical operation that we can't do in one insn into two insns,
;; each of which does one 16-bit part. This is used by combine.
(define_split
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(match_operator:SI 3 "boolean_or_operator"
[(match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "non_logical_cint_operand" "")]))]
""
[(set (match_dup 0) (match_dup 4))
(set (match_dup 0) (match_dup 5))]
"
{
rtx i;
i = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
operands[1], i);
i = GEN_INT (INTVAL (operands[2]) & 0xffff);
operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
operands[0], i);
}")
(define_insn "*boolcsi3_internal1"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(match_operator:SI 3 "boolean_operator"
[(not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
(match_operand:SI 2 "gpc_reg_operand" "r")]))]
""
"%q3 %0,%2,%1")
(define_insn "*boolcsi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (match_operator:SI 4 "boolean_operator"
[(not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(match_operand:SI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
"TARGET_32BIT"
"@
%q4. %3,%2,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operator:SI 4 "boolean_operator"
[(not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
(match_operand:SI 2 "gpc_reg_operand" "")])
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"TARGET_32BIT && reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*boolcsi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (match_operator:SI 4 "boolean_operator"
[(not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r"))
(match_operand:SI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
"TARGET_32BIT"
"@
%q4. %0,%2,%1
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operator:SI 4 "boolean_operator"
[(not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
(match_operand:SI 2 "gpc_reg_operand" "")])
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(match_dup 4))]
"TARGET_32BIT && reload_completed"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*boolccsi3_internal1"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(match_operator:SI 3 "boolean_operator"
[(not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
(not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))]))]
""
"%q3 %0,%1,%2")
(define_insn "*boolccsi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (match_operator:SI 4 "boolean_operator"
[(not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))])
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
"TARGET_32BIT"
"@
%q4. %3,%1,%2
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operator:SI 4 "boolean_operator"
[(not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
(not:SI (match_operand:SI 2 "gpc_reg_operand" ""))])
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"TARGET_32BIT && reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*boolccsi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (match_operator:SI 4 "boolean_operator"
[(not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r"))
(not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))])
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
"TARGET_32BIT"
"@
%q4. %0,%1,%2
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operator:SI 4 "boolean_operator"
[(not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
(not:SI (match_operand:SI 2 "gpc_reg_operand" ""))])
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(match_dup 4))]
"TARGET_32BIT && reload_completed"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
;; Rotate and shift insns, in all their variants. These support shifts,
;; field inserts and extracts, and various combinations thereof.
(define_expand "insv"
[(set (zero_extract (match_operand 0 "gpc_reg_operand" "")
(match_operand:SI 1 "const_int_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand 3 "gpc_reg_operand" ""))]
""
"
{
/* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
compiler if the address of the structure is taken later. Likewise, do
not handle invalid E500 subregs. */
if (GET_CODE (operands[0]) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD
|| ((TARGET_E500_DOUBLE || TARGET_SPE)
&& invalid_e500_subreg (operands[0], GET_MODE (operands[0])))))
FAIL;
if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode)
emit_insn (gen_insvdi_internal (operands[0], operands[1], operands[2],
operands[3]));
else
emit_insn (gen_insvsi_internal (operands[0], operands[1], operands[2],
operands[3]));
DONE;
}")
(define_insn "insvsi_internal"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
(match_operand:SI 1 "const_int_operand" "i")
(match_operand:SI 2 "const_int_operand" "i"))
(match_operand:SI 3 "gpc_reg_operand" "r"))]
""
"*
{
int start = INTVAL (operands[2]) & 31;
int size = INTVAL (operands[1]) & 31;
operands[4] = GEN_INT (32 - start - size);
operands[1] = GEN_INT (start + size - 1);
return \"rlwimi %0,%3,%h4,%h2,%h1\";
}"
[(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal1"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
(match_operand:SI 1 "const_int_operand" "i")
(match_operand:SI 2 "const_int_operand" "i"))
(rotate:SI (match_operand:SI 3 "gpc_reg_operand" "r")
(match_operand:SI 4 "const_int_operand" "i")))]
"(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
"*
{
int shift = INTVAL (operands[4]) & 31;
int start = INTVAL (operands[2]) & 31;
int size = INTVAL (operands[1]) & 31;
operands[4] = GEN_INT (shift - start - size);
operands[1] = GEN_INT (start + size - 1);
return \"rlwimi %0,%3,%h4,%h2,%h1\";
}"
[(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal2"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
(match_operand:SI 1 "const_int_operand" "i")
(match_operand:SI 2 "const_int_operand" "i"))
(ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
(match_operand:SI 4 "const_int_operand" "i")))]
"(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
"*
{
int shift = INTVAL (operands[4]) & 31;
int start = INTVAL (operands[2]) & 31;
int size = INTVAL (operands[1]) & 31;
operands[4] = GEN_INT (32 - shift - start - size);
operands[1] = GEN_INT (start + size - 1);
return \"rlwimi %0,%3,%h4,%h2,%h1\";
}"
[(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal3"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
(match_operand:SI 1 "const_int_operand" "i")
(match_operand:SI 2 "const_int_operand" "i"))
(lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
(match_operand:SI 4 "const_int_operand" "i")))]
"(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
"*
{
int shift = INTVAL (operands[4]) & 31;
int start = INTVAL (operands[2]) & 31;
int size = INTVAL (operands[1]) & 31;
operands[4] = GEN_INT (32 - shift - start - size);
operands[1] = GEN_INT (start + size - 1);
return \"rlwimi %0,%3,%h4,%h2,%h1\";
}"
[(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal4"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
(match_operand:SI 1 "const_int_operand" "i")
(match_operand:SI 2 "const_int_operand" "i"))
(zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r")
(match_operand:SI 4 "const_int_operand" "i")
(match_operand:SI 5 "const_int_operand" "i")))]
"INTVAL (operands[4]) >= INTVAL (operands[1])"
"*
{
int extract_start = INTVAL (operands[5]) & 31;
int extract_size = INTVAL (operands[4]) & 31;
int insert_start = INTVAL (operands[2]) & 31;
int insert_size = INTVAL (operands[1]) & 31;
/* Align extract field with insert field */
operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size);
operands[1] = GEN_INT (insert_start + insert_size - 1);
return \"rlwimi %0,%3,%h5,%h2,%h1\";
}"
[(set_attr "type" "insert_word")])
;; combine patterns for rlwimi
(define_insn "*insvsi_internal5"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(ior:SI (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
(match_operand:SI 1 "mask_operand" "i"))
(and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i"))
(match_operand:SI 5 "mask_operand" "i"))))]
"INTVAL(operands[1]) == ~INTVAL(operands[5])"
"*
{
int me = extract_ME(operands[5]);
int mb = extract_MB(operands[5]);
operands[4] = GEN_INT(32 - INTVAL(operands[2]));
operands[2] = GEN_INT(mb);
operands[1] = GEN_INT(me);
return \"rlwimi %0,%3,%h4,%h2,%h1\";
}"
[(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal6"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(ior:SI (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i"))
(match_operand:SI 5 "mask_operand" "i"))
(and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
(match_operand:SI 1 "mask_operand" "i"))))]
"INTVAL(operands[1]) == ~INTVAL(operands[5])"
"*
{
int me = extract_ME(operands[5]);
int mb = extract_MB(operands[5]);
operands[4] = GEN_INT(32 - INTVAL(operands[2]));
operands[2] = GEN_INT(mb);
operands[1] = GEN_INT(me);
return \"rlwimi %0,%3,%h4,%h2,%h1\";
}"
[(set_attr "type" "insert_word")])
(define_insn "insvdi_internal"
[(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
(match_operand:SI 1 "const_int_operand" "i")
(match_operand:SI 2 "const_int_operand" "i"))
(match_operand:DI 3 "gpc_reg_operand" "r"))]
"TARGET_POWERPC64"
"*
{
int start = INTVAL (operands[2]) & 63;
int size = INTVAL (operands[1]) & 63;
operands[1] = GEN_INT (64 - start - size);
return \"rldimi %0,%3,%H1,%H2\";
}"
[(set_attr "type" "insert_dword")])
(define_insn "*insvdi_internal2"
[(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
(match_operand:SI 1 "const_int_operand" "i")
(match_operand:SI 2 "const_int_operand" "i"))
(ashiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
(match_operand:SI 4 "const_int_operand" "i")))]
"TARGET_POWERPC64
&& insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
"*
{
int shift = INTVAL (operands[4]) & 63;
int start = (INTVAL (operands[2]) & 63) - 32;
int size = INTVAL (operands[1]) & 63;
operands[4] = GEN_INT (64 - shift - start - size);
operands[2] = GEN_INT (start);
operands[1] = GEN_INT (start + size - 1);
return \"rlwimi %0,%3,%h4,%h2,%h1\";
}")
(define_insn "*insvdi_internal3"
[(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
(match_operand:SI 1 "const_int_operand" "i")
(match_operand:SI 2 "const_int_operand" "i"))
(lshiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
(match_operand:SI 4 "const_int_operand" "i")))]
"TARGET_POWERPC64
&& insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
"*
{
int shift = INTVAL (operands[4]) & 63;
int start = (INTVAL (operands[2]) & 63) - 32;
int size = INTVAL (operands[1]) & 63;
operands[4] = GEN_INT (64 - shift - start - size);
operands[2] = GEN_INT (start);
operands[1] = GEN_INT (start + size - 1);
return \"rlwimi %0,%3,%h4,%h2,%h1\";
}")
(define_expand "extzv"
[(set (match_operand 0 "gpc_reg_operand" "")
(zero_extract (match_operand 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
""
"
{
/* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
compiler if the address of the structure is taken later. */
if (GET_CODE (operands[0]) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
FAIL;
if (TARGET_POWERPC64 && GET_MODE (operands[1]) == DImode)
emit_insn (gen_extzvdi_internal (operands[0], operands[1], operands[2],
operands[3]));
else
emit_insn (gen_extzvsi_internal (operands[0], operands[1], operands[2],
operands[3]));
DONE;
}")
(define_insn "extzvsi_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i")
(match_operand:SI 3 "const_int_operand" "i")))]
""
"*
{
int start = INTVAL (operands[3]) & 31;
int size = INTVAL (operands[2]) & 31;
if (start + size >= 32)
operands[3] = const0_rtx;
else
operands[3] = GEN_INT (start + size);
return \"rlwinm %0,%1,%3,%s2,31\";
}")
(define_insn "*extzvsi_internal1"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i")
(match_operand:SI 3 "const_int_operand" "i,i"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=r,r"))]
""
"*
{
int start = INTVAL (operands[3]) & 31;
int size = INTVAL (operands[2]) & 31;
/* Force split for non-cc0 compare. */
if (which_alternative == 1)
return \"#\";
/* If the bit-field being tested fits in the upper or lower half of a
word, it is possible to use andiu. or andil. to test it. This is
useful because the condition register set-use delay is smaller for
andi[ul]. than for rlinm. This doesn't work when the starting bit
position is 0 because the LT and GT bits may be set wrong. */
if ((start > 0 && start + size <= 16) || start >= 16)
{
operands[3] = GEN_INT (((1 << (16 - (start & 15)))
- (1 << (16 - (start & 15) - size))));
if (start < 16)
return \"andis. %4,%1,%3\";
else
return \"andi. %4,%1,%3\";
}
if (start + size >= 32)
operands[3] = const0_rtx;
else
operands[3] = GEN_INT (start + size);
return \"rlwinm. %4,%1,%3,%s2,31\";
}"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
"reload_completed"
[(set (match_dup 4)
(zero_extract:SI (match_dup 1) (match_dup 2)
(match_dup 3)))
(set (match_dup 0)
(compare:CC (match_dup 4)
(const_int 0)))]
"")
(define_insn "*extzvsi_internal2"
[(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i")
(match_operand:SI 3 "const_int_operand" "i,i"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
""
"*
{
int start = INTVAL (operands[3]) & 31;
int size = INTVAL (operands[2]) & 31;
/* Force split for non-cc0 compare. */
if (which_alternative == 1)
return \"#\";
/* Since we are using the output value, we can't ignore any need for
a shift. The bit-field must end at the LSB. */
if (start >= 16 && start + size == 32)
{
operands[3] = GEN_INT ((1 << size) - 1);
return \"andi. %0,%1,%3\";
}
if (start + size >= 32)
operands[3] = const0_rtx;
else
operands[3] = GEN_INT (start + size);
return \"rlwinm. %0,%1,%3,%s2,31\";
}"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
"reload_completed"
[(set (match_dup 0)
(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))
(set (match_dup 4)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "extzvdi_internal"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i")
(match_operand:SI 3 "const_int_operand" "i")))]
"TARGET_POWERPC64"
"*
{
int start = INTVAL (operands[3]) & 63;
int size = INTVAL (operands[2]) & 63;
if (start + size >= 64)
operands[3] = const0_rtx;
else
operands[3] = GEN_INT (start + size);
operands[2] = GEN_INT (64 - size);
return \"rldicl %0,%1,%3,%2\";
}")
(define_insn "*extzvdi_internal1"
[(set (match_operand:CC 0 "gpc_reg_operand" "=x")
(compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i")
(match_operand:SI 3 "const_int_operand" "i"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r"))]
"TARGET_64BIT && rs6000_gen_cell_microcode"
"*
{
int start = INTVAL (operands[3]) & 63;
int size = INTVAL (operands[2]) & 63;
if (start + size >= 64)
operands[3] = const0_rtx;
else
operands[3] = GEN_INT (start + size);
operands[2] = GEN_INT (64 - size);
return \"rldicl. %4,%1,%3,%2\";
}"
[(set_attr "type" "compare")])
(define_insn "*extzvdi_internal2"
[(set (match_operand:CC 4 "gpc_reg_operand" "=x")
(compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i")
(match_operand:SI 3 "const_int_operand" "i"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
"TARGET_64BIT && rs6000_gen_cell_microcode"
"*
{
int start = INTVAL (operands[3]) & 63;
int size = INTVAL (operands[2]) & 63;
if (start + size >= 64)
operands[3] = const0_rtx;
else
operands[3] = GEN_INT (start + size);
operands[2] = GEN_INT (64 - size);
return \"rldicl. %0,%1,%3,%2\";
}"
[(set_attr "type" "compare")])
(define_insn "rotlsi3"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
""
"@
rlwnm %0,%1,%2,0xffffffff
rlwinm %0,%1,%h2,0xffffffff"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotlsi3_64"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i"))))]
"TARGET_64BIT"
"@
rlwnm %0,%1,%2,0xffffffff
rlwinm %0,%1,%h2,0xffffffff"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotlsi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r"))]
""
"@
rlwnm. %3,%1,%2,0xffffffff
rlwinm. %3,%1,%h2,0xffffffff
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"reload_completed"
[(set (match_dup 3)
(rotate:SI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*rotlsi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(rotate:SI (match_dup 1) (match_dup 2)))]
""
"@
rlwnm. %0,%1,%2,0xffffffff
rlwinm. %0,%1,%h2,0xffffffff
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(rotate:SI (match_dup 1) (match_dup 2)))]
"reload_completed"
[(set (match_dup 0)
(rotate:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*rotlsi3_internal4"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i"))
(match_operand:SI 3 "mask_operand" "n,n")))]
""
"@
rlwnm %0,%1,%2,%m3,%M3
rlwinm %0,%1,%h2,%m3,%M3"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotlsi3_internal5"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (and:SI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(match_operand:SI 3 "mask_operand" "n,n,n,n"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=r,r,r,r"))]
""
"@
rlwnm. %4,%1,%2,%m3,%M3
rlwinm. %4,%1,%h2,%m3,%M3
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (and:SI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(match_operand:SI 3 "mask_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
"reload_completed"
[(set (match_dup 4)
(and:SI (rotate:SI (match_dup 1)
(match_dup 2))
(match_dup 3)))
(set (match_dup 0)
(compare:CC (match_dup 4)
(const_int 0)))]
"")
(define_insn "*rotlsi3_internal6"
[(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (and:SI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(match_operand:SI 3 "mask_operand" "n,n,n,n"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
""
"@
rlwnm. %0,%1,%2,%m3,%M3
rlwinm. %0,%1,%h2,%m3,%M3
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (and:SI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(match_operand:SI 3 "mask_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"reload_completed"
[(set (match_dup 0)
(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*rotlsi3_internal7le"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(zero_extend:SI
(subreg:QI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
"!BYTES_BIG_ENDIAN"
"rlw%I2nm %0,%1,%h2,0xff"
[(set (attr "cell_micro")
(if_then_else (match_operand:SI 2 "const_int_operand" "")
(const_string "not")
(const_string "always")))])
(define_insn "*rotlsi3_internal7be"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(zero_extend:SI
(subreg:QI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_cint_operand" "ri")) 3)))]
"BYTES_BIG_ENDIAN"
"rlw%I2nm %0,%1,%h2,0xff"
[(set (attr "cell_micro")
(if_then_else (match_operand:SI 2 "const_int_operand" "")
(const_string "not")
(const_string "always")))])
(define_insn "*rotlsi3_internal8le"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:SI
(subreg:QI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r"))]
"!BYTES_BIG_ENDIAN"
"@
rlwnm. %3,%1,%2,0xff
rlwinm. %3,%1,%h2,0xff
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_insn "*rotlsi3_internal8be"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:SI
(subreg:QI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 3))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r"))]
"BYTES_BIG_ENDIAN"
"@
rlwnm. %3,%1,%2,0xff
rlwinm. %3,%1,%h2,0xff
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:SI
(subreg:QI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")) 0))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"!BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 3)
(zero_extend:SI (subreg:QI
(rotate:SI (match_dup 1)
(match_dup 2)) 0)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:SI
(subreg:QI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")) 3))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 3)
(zero_extend:SI (subreg:QI
(rotate:SI (match_dup 1)
(match_dup 2)) 3)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*rotlsi3_internal9le"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:SI
(subreg:QI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
"!BYTES_BIG_ENDIAN"
"@
rlwnm. %0,%1,%2,0xff
rlwinm. %0,%1,%h2,0xff
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_insn "*rotlsi3_internal9be"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:SI
(subreg:QI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 3))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))]
"BYTES_BIG_ENDIAN"
"@
rlwnm. %0,%1,%2,0xff
rlwinm. %0,%1,%h2,0xff
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:SI
(subreg:QI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")) 0))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
"!BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 0)
(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:SI
(subreg:QI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")) 3))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))]
"BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 0)
(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*rotlsi3_internal10le"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(zero_extend:SI
(subreg:HI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i")) 0)))]
"!BYTES_BIG_ENDIAN"
"@
rlwnm %0,%1,%2,0xffff
rlwinm %0,%1,%h2,0xffff"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotlsi3_internal10be"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(zero_extend:SI
(subreg:HI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i")) 2)))]
"BYTES_BIG_ENDIAN"
"@
rlwnm %0,%1,%2,0xffff
rlwinm %0,%1,%h2,0xffff"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotlsi3_internal11le"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:SI
(subreg:HI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r"))]
"!BYTES_BIG_ENDIAN"
"@
rlwnm. %3,%1,%2,0xffff
rlwinm. %3,%1,%h2,0xffff
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_insn "*rotlsi3_internal11be"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:SI
(subreg:HI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 2))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r"))]
"BYTES_BIG_ENDIAN"
"@
rlwnm. %3,%1,%2,0xffff
rlwinm. %3,%1,%h2,0xffff
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:SI
(subreg:HI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")) 0))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"!BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 3)
(zero_extend:SI (subreg:HI
(rotate:SI (match_dup 1)
(match_dup 2)) 0)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:SI
(subreg:HI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")) 2))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 3)
(zero_extend:SI (subreg:HI
(rotate:SI (match_dup 1)
(match_dup 2)) 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*rotlsi3_internal12le"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:SI
(subreg:HI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
"!BYTES_BIG_ENDIAN"
"@
rlwnm. %0,%1,%2,0xffff
rlwinm. %0,%1,%h2,0xffff
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_insn "*rotlsi3_internal12be"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:SI
(subreg:HI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 2))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))]
"BYTES_BIG_ENDIAN"
"@
rlwnm. %0,%1,%2,0xffff
rlwinm. %0,%1,%h2,0xffff
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:SI
(subreg:HI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")) 0))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
"!BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 0)
(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:SI
(subreg:HI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")) 2))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))]
"BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 0)
(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "ashlsi3"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
""
"@
slw %0,%1,%2
slwi %0,%1,%h2"
[(set_attr "type" "var_shift_rotate,shift")])
(define_insn "*ashlsi3_64"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI
(ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i"))))]
"TARGET_POWERPC64"
"@
slw %0,%1,%2
slwi %0,%1,%h2"
[(set_attr "type" "var_shift_rotate,shift")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r"))]
"TARGET_32BIT"
"@
slw. %3,%1,%2
slwi. %3,%1,%h2
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(ashift:SI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(ashift:SI (match_dup 1) (match_dup 2)))]
"TARGET_32BIT"
"@
slw. %0,%1,%2
slwi. %0,%1,%h2
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(ashift:SI (match_dup 1) (match_dup 2)))]
"TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(ashift:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "rlwinm"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i"))
(match_operand:SI 3 "mask_operand" "n")))]
"includes_lshift_p (operands[2], operands[3])"
"rlwinm %0,%1,%h2,%m3,%M3")
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC
(and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i"))
(match_operand:SI 3 "mask_operand" "n,n"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=r,r"))]
"includes_lshift_p (operands[2], operands[3])"
"@
rlwinm. %4,%1,%h2,%m3,%M3
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:SI 3 "mask_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
"includes_lshift_p (operands[2], operands[3]) && reload_completed"
[(set (match_dup 4)
(and:SI (ashift:SI (match_dup 1) (match_dup 2))
(match_dup 3)))
(set (match_dup 0)
(compare:CC (match_dup 4)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
(compare:CC
(and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i"))
(match_operand:SI 3 "mask_operand" "n,n"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"includes_lshift_p (operands[2], operands[3])"
"@
rlwinm. %0,%1,%h2,%m3,%M3
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:SI 3 "mask_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"includes_lshift_p (operands[2], operands[3]) && reload_completed"
[(set (match_dup 0)
(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "lshrsi3"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "O,r,i")))]
""
"@
mr %0,%1
srw %0,%1,%2
srwi %0,%1,%h2"
[(set_attr "type" "integer,var_shift_rotate,shift")])
(define_insn "*lshrsi3_64"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i"))))]
"TARGET_POWERPC64"
"@
srw %0,%1,%2
srwi %0,%1,%h2"
[(set_attr "type" "var_shift_rotate,shift")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y")
(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,r,i"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=X,r,r,X,r,r"))]
"TARGET_32BIT"
"@
mr. %1,%1
srw. %3,%1,%2
srwi. %3,%1,%h2
#
#
#"
[(set_attr "type" "fast_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,4,8,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(lshiftrt:SI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y")
(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,r,i"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
(lshiftrt:SI (match_dup 1) (match_dup 2)))]
"TARGET_32BIT"
"@
mr. %0,%1
srw. %0,%1,%2
srwi. %0,%1,%h2
#
#
#"
[(set_attr "type" "fast_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,4,8,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(lshiftrt:SI (match_dup 1) (match_dup 2)))]
"TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(lshiftrt:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i"))
(match_operand:SI 3 "mask_operand" "n")))]
"includes_rshift_p (operands[2], operands[3])"
"rlwinm %0,%1,%s2,%m3,%M3")
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC
(and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i"))
(match_operand:SI 3 "mask_operand" "n,n"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=r,r"))]
"includes_rshift_p (operands[2], operands[3])"
"@
rlwinm. %4,%1,%s2,%m3,%M3
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:SI 3 "mask_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
"includes_rshift_p (operands[2], operands[3]) && reload_completed"
[(set (match_dup 4)
(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
(match_dup 3)))
(set (match_dup 0)
(compare:CC (match_dup 4)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
(compare:CC
(and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i"))
(match_operand:SI 3 "mask_operand" "n,n"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"includes_rshift_p (operands[2], operands[3])"
"@
rlwinm. %0,%1,%s2,%m3,%M3
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:SI 3 "mask_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"includes_rshift_p (operands[2], operands[3]) && reload_completed"
[(set (match_dup 0)
(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*lshiftrt_internal1le"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(zero_extend:SI
(subreg:QI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i")) 0)))]
"!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
"rlwinm %0,%1,%s2,0xff")
(define_insn "*lshiftrt_internal1be"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(zero_extend:SI
(subreg:QI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i")) 3)))]
"BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
"rlwinm %0,%1,%s2,0xff")
(define_insn "*lshiftrt_internal2le"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC
(zero_extend:SI
(subreg:QI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i")) 0))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
"!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
"@
rlwinm. %3,%1,%s2,0xff
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_insn "*lshiftrt_internal2be"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC
(zero_extend:SI
(subreg:QI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i")) 3))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
"BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
"@
rlwinm. %3,%1,%s2,0xff
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(zero_extend:SI
(subreg:QI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" "")) 0))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
[(set (match_dup 3)
(zero_extend:SI (subreg:QI
(lshiftrt:SI (match_dup 1)
(match_dup 2)) 0)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(zero_extend:SI
(subreg:QI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" "")) 3))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
[(set (match_dup 3)
(zero_extend:SI (subreg:QI
(lshiftrt:SI (match_dup 1)
(match_dup 2)) 3)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*lshiftrt_internal3le"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC
(zero_extend:SI
(subreg:QI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i")) 0))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
"!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
"@
rlwinm. %0,%1,%s2,0xff
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_insn "*lshiftrt_internal3be"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC
(zero_extend:SI
(subreg:QI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i")) 3))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))]
"BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
"@
rlwinm. %0,%1,%s2,0xff
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(zero_extend:SI
(subreg:QI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" "")) 0))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
"!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
[(set (match_dup 0)
(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(zero_extend:SI
(subreg:QI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" "")) 3))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))]
"BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
[(set (match_dup 0)
(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*lshiftrt_internal4le"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(zero_extend:SI
(subreg:HI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i")) 0)))]
"!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
"rlwinm %0,%1,%s2,0xffff")
(define_insn "*lshiftrt_internal4be"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(zero_extend:SI
(subreg:HI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i")) 2)))]
"BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
"rlwinm %0,%1,%s2,0xffff")
(define_insn "*lshiftrt_internal5le"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC
(zero_extend:SI
(subreg:HI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i")) 0))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
"!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
"@
rlwinm. %3,%1,%s2,0xffff
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_insn "*lshiftrt_internal5be"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC
(zero_extend:SI
(subreg:HI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i")) 2))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
"BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
"@
rlwinm. %3,%1,%s2,0xffff
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(zero_extend:SI
(subreg:HI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" "")) 0))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
[(set (match_dup 3)
(zero_extend:SI (subreg:HI
(lshiftrt:SI (match_dup 1)
(match_dup 2)) 0)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(zero_extend:SI
(subreg:HI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" "")) 2))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
[(set (match_dup 3)
(zero_extend:SI (subreg:HI
(lshiftrt:SI (match_dup 1)
(match_dup 2)) 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*lshiftrt_internal5le"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC
(zero_extend:SI
(subreg:HI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i")) 0))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
"!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
"@
rlwinm. %0,%1,%s2,0xffff
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_insn "*lshiftrt_internal5be"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC
(zero_extend:SI
(subreg:HI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i")) 2))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))]
"BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
"@
rlwinm. %0,%1,%s2,0xffff
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(zero_extend:SI
(subreg:HI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" "")) 0))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
"!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
[(set (match_dup 0)
(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(zero_extend:SI
(subreg:HI
(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" "")) 2))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))]
"BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
[(set (match_dup 0)
(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "ashrsi3"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
""
"@
sraw %0,%1,%2
srawi %0,%1,%h2"
[(set_attr "type" "var_shift_rotate,shift")])
(define_insn "*ashrsi3_64"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(sign_extend:DI
(ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i"))))]
"TARGET_POWERPC64"
"@
sraw %0,%1,%2
srawi %0,%1,%h2"
[(set_attr "type" "var_shift_rotate,shift")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r"))]
""
"@
sraw. %3,%1,%2
srawi. %3,%1,%h2
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
"reload_completed"
[(set (match_dup 3)
(ashiftrt:SI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn ""
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(ashiftrt:SI (match_dup 1) (match_dup 2)))]
""
"@
sraw. %0,%1,%2
srawi. %0,%1,%h2
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
;; Builtins to replace a division to generate FRE reciprocal estimate
;; instructions and the necessary fixup instructions
(define_expand "recip3"
[(match_operand:RECIPF 0 "gpc_reg_operand" "")
(match_operand:RECIPF 1 "gpc_reg_operand" "")
(match_operand:RECIPF 2 "gpc_reg_operand" "")]
"RS6000_RECIP_HAVE_RE_P (mode)"
{
rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
DONE;
})
;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
;; hardware division. This is only done before register allocation and with
;; -ffast-math. This must appear before the divsf3/divdf3 insns.
(define_split
[(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
(div:RECIPF (match_operand 1 "gpc_reg_operand" "")
(match_operand 2 "gpc_reg_operand" "")))]
"RS6000_RECIP_AUTO_RE_P (mode)
&& can_create_pseudo_p () && optimize_insn_for_speed_p ()
&& flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
[(const_int 0)]
{
rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
DONE;
})
;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
;; appropriate fixup.
(define_expand "rsqrt2"
[(match_operand:RECIPF 0 "gpc_reg_operand" "")
(match_operand:RECIPF 1 "gpc_reg_operand" "")]
"RS6000_RECIP_HAVE_RSQRTE_P (mode)"
{
rs6000_emit_swrsqrt (operands[0], operands[1]);
DONE;
})
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(ashiftrt:SI (match_dup 1) (match_dup 2)))]
"reload_completed"
[(set (match_dup 0)
(ashiftrt:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
;; Floating-point insns, excluding normal data motion.
;;
;; PowerPC has a full set of single-precision floating point instructions.
;;
;; For the POWER architecture, we pretend that we have both SFmode and
;; DFmode insns, while, in fact, all fp insns are actually done in double.
;; The only conversions we will do will be when storing to memory. In that
;; case, we will use the "frsp" instruction before storing.
;;
;; Note that when we store into a single-precision memory location, we need to
;; use the frsp insn first. If the register being stored isn't dead, we
;; need a scratch register for the frsp. But this is difficult when the store
;; is done by reload. It is not incorrect to do the frsp on the register in
;; this case, we just lose precision that we would have otherwise gotten but
;; is not guaranteed. Perhaps this should be tightened up at some point.
(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"")
(define_insn_and_split "*extendsfdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d")
(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"@
#
fmr %0,%1
lfs%U1%X1 %0,%1"
"&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
[(const_int 0)]
{
emit_note (NOTE_INSN_DELETED);
DONE;
}
[(set_attr_alternative "type"
[(const_string "fp")
(const_string "fp")
(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "fpload_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "fpload_u")
(const_string "fpload")))])])
(define_expand "truncdfsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"")
(define_insn "*truncdfsf2_fpr"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"frsp %0,%1"
[(set_attr "type" "fp")])
(define_expand "negsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(neg:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
"")
(define_insn "*negsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fneg %0,%1"
[(set_attr "type" "fp")])
(define_expand "abssf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(abs:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
"")
(define_insn "*abssf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fabs %0,%1"
[(set_attr "type" "fp")])
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fnabs %0,%1"
[(set_attr "type" "fp")])
(define_expand "addsf3"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
"")
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
(match_operand:SF 2 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fadds %0,%1,%2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_s")])
(define_expand "subsf3"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
"")
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 2 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fsubs %0,%1,%2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_s")])
(define_expand "mulsf3"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
"")
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
(match_operand:SF 2 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fmuls %0,%1,%2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_mul_s")])
(define_expand "divsf3"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(div:SF (match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
"")
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 2 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
"fdivs %0,%1,%2"
[(set_attr "type" "sdiv")])
(define_insn "fres"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
"TARGET_FRES"
"fres %0,%1"
[(set_attr "type" "fp")])
; builtin fmaf support
(define_insn "*fmasf4_fpr"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(fma:SF (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 2 "gpc_reg_operand" "f")
(match_operand:SF 3 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fmadds %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_s")])
(define_insn "*fmssf4_fpr"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(fma:SF (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 2 "gpc_reg_operand" "f")
(neg:SF (match_operand:SF 3 "gpc_reg_operand" "f"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fmsubs %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_s")])
(define_insn "*nfmasf4_fpr"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(neg:SF (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 2 "gpc_reg_operand" "f")
(match_operand:SF 3 "gpc_reg_operand" "f"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fnmadds %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_s")])
(define_insn "*nfmssf4_fpr"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(neg:SF (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 2 "gpc_reg_operand" "f")
(neg:SF (match_operand:SF 3 "gpc_reg_operand" "f")))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fnmsubs %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_s")])
(define_expand "sqrtsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
"(TARGET_PPC_GPOPT || TARGET_XILINX_FPU)
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
&& !TARGET_SIMPLE_FPU"
"")
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
"(TARGET_PPC_GPOPT || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT
&& TARGET_FPRS && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
"fsqrts %0,%1"
[(set_attr "type" "ssqrt")])
(define_insn "*rsqrtsf_internal1"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")]
UNSPEC_RSQRT))]
"TARGET_FRSQRTES"
"frsqrtes %0,%1"
[(set_attr "type" "fp")])
;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
;; builtins.c and optabs.c that are not correct for IBM long double
;; when little-endian.
(define_expand "signbittf2"
[(set (match_dup 2)
(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
(set (match_dup 3)
(subreg:DI (match_dup 2) 0))
(set (match_dup 4)
(match_dup 5))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(match_dup 6))]
"!TARGET_IEEEQUAD
&& TARGET_HARD_FLOAT
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
&& TARGET_LONG_DOUBLE_128"
{
operands[2] = gen_reg_rtx (DFmode);
operands[3] = gen_reg_rtx (DImode);
if (TARGET_POWERPC64)
{
operands[4] = gen_reg_rtx (DImode);
operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
operands[6] = gen_rtx_SUBREG (SImode, operands[4],
WORDS_BIG_ENDIAN ? 4 : 0);
}
else
{
operands[4] = gen_reg_rtx (SImode);
operands[5] = gen_rtx_SUBREG (SImode, operands[3],
WORDS_BIG_ENDIAN ? 0 : 4);
operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
}
})
(define_expand "copysign3"
[(set (match_dup 3)
(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
(set (match_dup 4)
(neg:SFDF (abs:SFDF (match_dup 1))))
(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
(match_dup 5))
(match_dup 3)
(match_dup 4)))]
"TARGET_HARD_FLOAT && TARGET_FPRS &&
&& ((TARGET_PPC_GFXOPT
&& !HONOR_NANS (mode)
&& !HONOR_SIGNED_ZEROS (mode))
|| TARGET_CMPB
|| VECTOR_UNIT_VSX_P (mode))"
{
if (TARGET_CMPB || VECTOR_UNIT_VSX_P (mode))
{
emit_insn (gen_copysign3_fcpsgn (operands[0], operands[1],
operands[2]));
DONE;
}
operands[3] = gen_reg_rtx (mode);
operands[4] = gen_reg_rtx (mode);
operands[5] = CONST0_RTX (mode);
})
;; Use an unspec rather providing an if-then-else in RTL, to prevent the
;; compiler from optimizing -0.0
(define_insn "copysign3_fcpsgn"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")
(match_operand:SFDF 2 "gpc_reg_operand" "")]
UNSPEC_COPYSIGN))]
"TARGET_CMPB && !VECTOR_UNIT_VSX_P (mode)"
"fcpsgn %0,%2,%1"
[(set_attr "type" "fp")])
;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
;; fsel instruction and some auxiliary computations. Then we just have a
;; single DEFINE_INSN for fsel and the define_splits to make them if made by
;; combine.
(define_expand "smaxsf3"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" ""))
(match_dup 1)
(match_dup 2)))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_SINGLE_FLOAT && !flag_trapping_math"
"{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
(define_expand "sminsf3"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" ""))
(match_dup 2)
(match_dup 1)))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_SINGLE_FLOAT && !flag_trapping_math"
"{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
(define_split
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(match_operator:SF 3 "min_max_operator"
[(match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" "")]))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_SINGLE_FLOAT && !flag_trapping_math"
[(const_int 0)]
"
{ rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
operands[1], operands[2]);
DONE;
}")
(define_expand "movcc"
[(set (match_operand:GPR 0 "gpc_reg_operand" "")
(if_then_else:GPR (match_operand 1 "comparison_operator" "")
(match_operand:GPR 2 "gpc_reg_operand" "")
(match_operand:GPR 3 "gpc_reg_operand" "")))]
"TARGET_ISEL"
"
{
if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
DONE;
else
FAIL;
}")
;; We use the BASE_REGS for the isel input operands because, if rA is
;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
;; because we may switch the operands and rB may end up being rA.
;;
;; We need 2 patterns: an unsigned and a signed pattern. We could
;; leave out the mode in operand 4 and use one pattern, but reload can
;; change the mode underneath our feet and then gets confused trying
;; to reload the value.
(define_insn "isel_signed_"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
(if_then_else:GPR
(match_operator 1 "scc_comparison_operator"
[(match_operand:CC 4 "cc_reg_operand" "y,y")
(const_int 0)])
(match_operand:GPR 2 "reg_or_cint_operand" "O,b")
(match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
"TARGET_ISEL"
"*
{ return output_isel (operands); }"
[(set_attr "type" "isel")
(set_attr "length" "4")])
(define_insn "isel_unsigned_"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
(if_then_else:GPR
(match_operator 1 "scc_comparison_operator"
[(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
(const_int 0)])
(match_operand:GPR 2 "reg_or_cint_operand" "O,b")
(match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
"TARGET_ISEL"
"*
{ return output_isel (operands); }"
[(set_attr "type" "isel")
(set_attr "length" "4")])
;; These patterns can be useful for combine; they let combine know that
;; isel can handle reversed comparisons so long as the operands are
;; registers.
(define_insn "*isel_reversed_signed_"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(if_then_else:GPR
(match_operator 1 "scc_rev_comparison_operator"
[(match_operand:CC 4 "cc_reg_operand" "y")
(const_int 0)])
(match_operand:GPR 2 "gpc_reg_operand" "b")
(match_operand:GPR 3 "gpc_reg_operand" "b")))]
"TARGET_ISEL"
"*
{ return output_isel (operands); }"
[(set_attr "type" "isel")
(set_attr "length" "4")])
(define_insn "*isel_reversed_unsigned_"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(if_then_else:GPR
(match_operator 1 "scc_rev_comparison_operator"
[(match_operand:CCUNS 4 "cc_reg_operand" "y")
(const_int 0)])
(match_operand:GPR 2 "gpc_reg_operand" "b")
(match_operand:GPR 3 "gpc_reg_operand" "b")))]
"TARGET_ISEL"
"*
{ return output_isel (operands); }"
[(set_attr "type" "isel")
(set_attr "length" "4")])
(define_expand "movsfcc"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(if_then_else:SF (match_operand 1 "comparison_operator" "")
(match_operand:SF 2 "gpc_reg_operand" "")
(match_operand:SF 3 "gpc_reg_operand" "")))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"
{
if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
DONE;
else
FAIL;
}")
(define_insn "*fselsfsf4"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 4 "zero_fp_constant" "F"))
(match_operand:SF 2 "gpc_reg_operand" "f")
(match_operand:SF 3 "gpc_reg_operand" "f")))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fsel %0,%1,%2,%3"
[(set_attr "type" "fp")])
(define_insn "*fseldfsf4"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
(match_operand:DF 4 "zero_fp_constant" "F"))
(match_operand:SF 2 "gpc_reg_operand" "f")
(match_operand:SF 3 "gpc_reg_operand" "f")))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
"fsel %0,%1,%2,%3"
[(set_attr "type" "fp")])
(define_expand "negdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"")
(define_insn "*negdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fneg %0,%1"
[(set_attr "type" "fp")])
(define_expand "absdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"")
(define_insn "*absdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(abs:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fabs %0,%1"
[(set_attr "type" "fp")])
(define_insn "*nabsdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fnabs %0,%1"
[(set_attr "type" "fp")])
(define_expand "adddf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(plus:DF (match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"")
(define_insn "*adddf3_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(plus:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
(match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fadd %0,%1,%2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_d")])
(define_expand "subdf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"")
(define_insn "*subdf3_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(minus:DF (match_operand:DF 1 "gpc_reg_operand" "d")
(match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fsub %0,%1,%2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_d")])
(define_expand "muldf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(mult:DF (match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"")
(define_insn "*muldf3_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
(match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fmul %0,%1,%2"
[(set_attr "type" "dmul")
(set_attr "fp_type" "fp_mul_d")])
(define_expand "divdf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(div:DF (match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT
&& ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)
&& !TARGET_SIMPLE_FPU"
"")
(define_insn "*divdf3_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(div:DF (match_operand:DF 1 "gpc_reg_operand" "d")
(match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fdiv %0,%1,%2"
[(set_attr "type" "ddiv")])
(define_insn "*fred_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
"TARGET_FRE && !VECTOR_UNIT_VSX_P (DFmode)"
"fre %0,%1"
[(set_attr "type" "fp")])
(define_insn "*rsqrtdf_internal1"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
UNSPEC_RSQRT))]
"TARGET_FRSQRTE && !VECTOR_UNIT_VSX_P (DFmode)"
"frsqrte %0,%1"
[(set_attr "type" "fp")])
; builtin fma support
(define_insn "*fmadf4_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(fma:DF (match_operand:DF 1 "gpc_reg_operand" "f")
(match_operand:DF 2 "gpc_reg_operand" "f")
(match_operand:DF 3 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& VECTOR_UNIT_NONE_P (DFmode)"
"fmadd %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_d")])
(define_insn "*fmsdf4_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(fma:DF (match_operand:DF 1 "gpc_reg_operand" "f")
(match_operand:DF 2 "gpc_reg_operand" "f")
(neg:DF (match_operand:DF 3 "gpc_reg_operand" "f"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& VECTOR_UNIT_NONE_P (DFmode)"
"fmsub %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_d")])
(define_insn "*nfmadf4_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(neg:DF (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f")
(match_operand:DF 2 "gpc_reg_operand" "f")
(match_operand:DF 3 "gpc_reg_operand" "f"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& VECTOR_UNIT_NONE_P (DFmode)"
"fnmadd %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_d")])
(define_insn "*nfmsdf4_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(neg:DF (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f")
(match_operand:DF 2 "gpc_reg_operand" "f")
(neg:DF (match_operand:DF 3 "gpc_reg_operand" "f")))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& VECTOR_UNIT_NONE_P (DFmode)"
"fnmsub %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_d")])
(define_expand "sqrtdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
"TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"")
(define_insn "*sqrtdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
"TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fsqrt %0,%1"
[(set_attr "type" "dsqrt")])
;; The conditional move instructions allow us to perform max and min
;; operations even when
(define_expand "smaxdf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" ""))
(match_dup 1)
(match_dup 2)))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !flag_trapping_math"
"{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
(define_expand "smindf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" ""))
(match_dup 2)
(match_dup 1)))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !flag_trapping_math"
"{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
(define_split
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(match_operator:DF 3 "min_max_operator"
[(match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" "")]))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !flag_trapping_math"
[(const_int 0)]
"
{ rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
operands[1], operands[2]);
DONE;
}")
(define_expand "movdfcc"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(if_then_else:DF (match_operand 1 "comparison_operator" "")
(match_operand:DF 2 "gpc_reg_operand" "")
(match_operand:DF 3 "gpc_reg_operand" "")))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"
{
if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
DONE;
else
FAIL;
}")
(define_insn "*fseldfdf4"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
(match_operand:DF 4 "zero_fp_constant" "F"))
(match_operand:DF 2 "gpc_reg_operand" "d")
(match_operand:DF 3 "gpc_reg_operand" "d")))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"fsel %0,%1,%2,%3"
[(set_attr "type" "fp")])
(define_insn "*fselsfdf4"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 4 "zero_fp_constant" "F"))
(match_operand:DF 2 "gpc_reg_operand" "d")
(match_operand:DF 3 "gpc_reg_operand" "d")))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
"fsel %0,%1,%2,%3"
[(set_attr "type" "fp")])
;; Conversions to and from floating-point.
; We don't define lfiwax/lfiwzx with the normal definition, because we
; don't want to support putting SImode in FPR registers.
(define_insn "lfiwax"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d,wm,!wm")
(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
UNSPEC_LFIWAX))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
"@
lfiwax %0,%y1
lxsiwax %x0,%y1
mtvsrwa %x0,%1"
[(set_attr "type" "fpload,fpload,mffgpr")])
; This split must be run before register allocation because it allocates the
; memory slot that is needed to move values to/from the FPR. We don't allocate
; it earlier to allow for the combiner to merge insns together where it might
; not be needed and also in case the insns are deleted as dead code.
(define_insn_and_split "floatsi2_lfiwax"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
(float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
(clobber (match_scratch:DI 2 "=d"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
&& && can_create_pseudo_p ()"
"#"
""
[(pc)]
"
{
rtx dest = operands[0];
rtx src = operands[1];
rtx tmp;
if (!MEM_P (src) && TARGET_POWERPC64
&& (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
tmp = convert_to_mode (DImode, src, false);
else
{
tmp = operands[2];
if (GET_CODE (tmp) == SCRATCH)
tmp = gen_reg_rtx (DImode);
if (MEM_P (src))
{
src = rs6000_address_for_fpconvert (src);
emit_insn (gen_lfiwax (tmp, src));
}
else
{
rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
emit_move_insn (stack, src);
emit_insn (gen_lfiwax (tmp, stack));
}
}
emit_insn (gen_floatdi2 (dest, tmp));
DONE;
}"
[(set_attr "length" "12")
(set_attr "type" "fpload")])
(define_insn_and_split "floatsi2_lfiwax_mem"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,")
(float:SFDF
(sign_extend:DI
(match_operand:SI 1 "memory_operand" "Z,Z"))))
(clobber (match_scratch:DI 2 "=0,d"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
&& "
"#"
""
[(pc)]
"
{
operands[1] = rs6000_address_for_fpconvert (operands[1]);
if (GET_CODE (operands[2]) == SCRATCH)
operands[2] = gen_reg_rtx (DImode);
emit_insn (gen_lfiwax (operands[2], operands[1]));
emit_insn (gen_floatdi2 (operands[0], operands[2]));
DONE;
}"
[(set_attr "length" "8")
(set_attr "type" "fpload")])
(define_insn "lfiwzx"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d,wm,!wm")
(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
UNSPEC_LFIWZX))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
"@
lfiwzx %0,%y1
lxsiwzx %x0,%y1
mtvsrwz %x0,%1"
[(set_attr "type" "fpload,fpload,mftgpr")])
(define_insn_and_split "floatunssi2_lfiwzx"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
(unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
(clobber (match_scratch:DI 2 "=d"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
&& "
"#"
""
[(pc)]
"
{
rtx dest = operands[0];
rtx src = operands[1];
rtx tmp;
if (!MEM_P (src) && TARGET_POWERPC64
&& (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
tmp = convert_to_mode (DImode, src, true);
else
{
tmp = operands[2];
if (GET_CODE (tmp) == SCRATCH)
tmp = gen_reg_rtx (DImode);
if (MEM_P (src))
{
src = rs6000_address_for_fpconvert (src);
emit_insn (gen_lfiwzx (tmp, src));
}
else
{
rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
emit_move_insn (stack, src);
emit_insn (gen_lfiwzx (tmp, stack));
}
}
emit_insn (gen_floatdi2 (dest, tmp));
DONE;
}"
[(set_attr "length" "12")
(set_attr "type" "fpload")])
(define_insn_and_split "floatunssi2_lfiwzx_mem"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,")
(unsigned_float:SFDF
(zero_extend:DI
(match_operand:SI 1 "memory_operand" "Z,Z"))))
(clobber (match_scratch:DI 2 "=0,d"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
&& "
"#"
""
[(pc)]
"
{
operands[1] = rs6000_address_for_fpconvert (operands[1]);
if (GET_CODE (operands[2]) == SCRATCH)
operands[2] = gen_reg_rtx (DImode);
emit_insn (gen_lfiwzx (operands[2], operands[1]));
emit_insn (gen_floatdi2 (operands[0], operands[2]));
DONE;
}"
[(set_attr "length" "8")
(set_attr "type" "fpload")])
; For each of these conversions, there is a define_expand, a define_insn
; with a '#' template, and a define_split (with C code). The idea is
; to allow constant folding with the template of the define_insn,
; then to have the insns split later (between sched1 and final).
(define_expand "floatsidf2"
[(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
(use (match_dup 2))
(use (match_dup 3))
(clobber (match_dup 4))
(clobber (match_dup 5))
(clobber (match_dup 6))])]
"TARGET_HARD_FLOAT
&& ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"
{
if (TARGET_E500_DOUBLE)
{
if (!REG_P (operands[1]))
operands[1] = force_reg (SImode, operands[1]);
emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
DONE;
}
else if (TARGET_LFIWAX && TARGET_FCFID)
{
emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
DONE;
}
else if (TARGET_FCFID)
{
rtx dreg = operands[1];
if (!REG_P (dreg))
dreg = force_reg (SImode, dreg);
dreg = convert_to_mode (DImode, dreg, false);
emit_insn (gen_floatdidf2 (operands[0], dreg));
DONE;
}
if (!REG_P (operands[1]))
operands[1] = force_reg (SImode, operands[1]);
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
operands[5] = gen_reg_rtx (DFmode);
operands[6] = gen_reg_rtx (SImode);
}")
(define_insn_and_split "*floatsidf2_internal"
[(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
(float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
(use (match_operand:SI 2 "gpc_reg_operand" "r"))
(use (match_operand:DF 3 "gpc_reg_operand" "d"))
(clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
(clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
(clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
"! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"#"
""
[(pc)]
"
{
rtx lowword, highword;
gcc_assert (MEM_P (operands[4]));
highword = adjust_address (operands[4], SImode, 0);
lowword = adjust_address (operands[4], SImode, 4);
if (! WORDS_BIG_ENDIAN)
{
rtx tmp;
tmp = highword; highword = lowword; lowword = tmp;
}
emit_insn (gen_xorsi3 (operands[6], operands[1],
GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
emit_move_insn (lowword, operands[6]);
emit_move_insn (highword, operands[2]);
emit_move_insn (operands[5], operands[4]);
emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
DONE;
}"
[(set_attr "length" "24")
(set_attr "type" "fp")])
;; If we don't have a direct conversion to single precision, don't enable this
;; conversion for 32-bit without fast math, because we don't have the insn to
;; generate the fixup swizzle to avoid double rounding problems.
(define_expand "floatunssisf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
&& (!TARGET_FPRS
|| (TARGET_FPRS
&& ((TARGET_FCFIDUS && TARGET_LFIWZX)
|| (TARGET_DOUBLE_FLOAT && TARGET_FCFID
&& (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
"
{
if (!TARGET_FPRS)
{
if (!REG_P (operands[1]))
operands[1] = force_reg (SImode, operands[1]);
}
else if (TARGET_LFIWZX && TARGET_FCFIDUS)
{
emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
DONE;
}
else
{
rtx dreg = operands[1];
if (!REG_P (dreg))
dreg = force_reg (SImode, dreg);
dreg = convert_to_mode (DImode, dreg, true);
emit_insn (gen_floatdisf2 (operands[0], dreg));
DONE;
}
}")
(define_expand "floatunssidf2"
[(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
(unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
(use (match_dup 2))
(use (match_dup 3))
(clobber (match_dup 4))
(clobber (match_dup 5))])]
"TARGET_HARD_FLOAT
&& ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"
{
if (TARGET_E500_DOUBLE)
{
if (!REG_P (operands[1]))
operands[1] = force_reg (SImode, operands[1]);
emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
DONE;
}
else if (TARGET_LFIWZX && TARGET_FCFID)
{
emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
DONE;
}
else if (TARGET_FCFID)
{
rtx dreg = operands[1];
if (!REG_P (dreg))
dreg = force_reg (SImode, dreg);
dreg = convert_to_mode (DImode, dreg, true);
emit_insn (gen_floatdidf2 (operands[0], dreg));
DONE;
}
if (!REG_P (operands[1]))
operands[1] = force_reg (SImode, operands[1]);
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
operands[5] = gen_reg_rtx (DFmode);
}")
(define_insn_and_split "*floatunssidf2_internal"
[(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
(use (match_operand:SI 2 "gpc_reg_operand" "r"))
(use (match_operand:DF 3 "gpc_reg_operand" "d"))
(clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
(clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
"! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !(TARGET_FCFID && TARGET_POWERPC64)"
"#"
""
[(pc)]
"
{
rtx lowword, highword;
gcc_assert (MEM_P (operands[4]));
highword = adjust_address (operands[4], SImode, 0);
lowword = adjust_address (operands[4], SImode, 4);
if (! WORDS_BIG_ENDIAN)
{
rtx tmp;
tmp = highword; highword = lowword; lowword = tmp;
}
emit_move_insn (lowword, operands[1]);
emit_move_insn (highword, operands[2]);
emit_move_insn (operands[5], operands[4]);
emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
DONE;
}"
[(set_attr "length" "20")
(set_attr "type" "fp")])
(define_expand "fix_truncsi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && ) || )"
"
{
if (!)
{
rtx tmp, stack;
if (TARGET_STFIWX)
emit_insn (gen_fix_truncsi2_stfiwx (operands[0], operands[1]));
else
{
tmp = gen_reg_rtx (DImode);
stack = rs6000_allocate_stack_temp (DImode, true, false);
emit_insn (gen_fix_truncsi2_internal (operands[0], operands[1],
tmp, stack));
}
DONE;
}
}")
; Like the convert to float patterns, this insn must be split before
; register allocation so that it can allocate the memory slot if it
; needed
(define_insn_and_split "fix_truncsi2_stfiwx"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
(clobber (match_scratch:DI 2 "=d"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& (mode != SFmode || TARGET_SINGLE_FLOAT)
&& TARGET_STFIWX && can_create_pseudo_p ()"
"#"
""
[(pc)]
{
rtx dest = operands[0];
rtx src = operands[1];
rtx tmp = operands[2];
if (GET_CODE (tmp) == SCRATCH)
tmp = gen_reg_rtx (DImode);
emit_insn (gen_fctiwz_ (tmp, src));
if (MEM_P (dest))
{
dest = rs6000_address_for_fpconvert (dest);
emit_insn (gen_stfiwx (dest, tmp));
DONE;
}
else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
{
dest = gen_lowpart (DImode, dest);
emit_move_insn (dest, tmp);
DONE;
}
else
{
rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
emit_insn (gen_stfiwx (stack, tmp));
emit_move_insn (dest, stack);
DONE;
}
}
[(set_attr "length" "12")
(set_attr "type" "fp")])
(define_insn_and_split "fix_truncsi2_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,")))
(clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
(clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"#"
""
[(pc)]
"
{
rtx lowword;
gcc_assert (MEM_P (operands[3]));
lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
emit_insn (gen_fctiwz_ (operands[2], operands[1]));
emit_move_insn (operands[3], operands[2]);
emit_move_insn (operands[0], lowword);
DONE;
}"
[(set_attr "length" "16")
(set_attr "type" "fp")])
(define_expand "fix_truncdi2"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
&& TARGET_FCFID"
"")
(define_insn "*fix_truncdi2_fctidz"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
&& TARGET_FCFID && !VECTOR_UNIT_VSX_P (mode)"
"fctidz %0,%1"
[(set_attr "type" "fp")])
(define_expand "fixuns_truncsi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT
&& ((TARGET_FPRS && && TARGET_FCTIWUZ && TARGET_STFIWX)
|| )"
"
{
if (!)
{
emit_insn (gen_fixuns_truncsi2_stfiwx (operands[0], operands[1]));
DONE;
}
}")
(define_insn_and_split "fixuns_truncsi2_stfiwx"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
(clobber (match_scratch:DI 2 "=d"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && && TARGET_FCTIWUZ
&& TARGET_STFIWX && can_create_pseudo_p ()"
"#"
""
[(pc)]
{
rtx dest = operands[0];
rtx src = operands[1];
rtx tmp = operands[2];
if (GET_CODE (tmp) == SCRATCH)
tmp = gen_reg_rtx (DImode);
emit_insn (gen_fctiwuz_ (tmp, src));
if (MEM_P (dest))
{
dest = rs6000_address_for_fpconvert (dest);
emit_insn (gen_stfiwx (dest, tmp));
DONE;
}
else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
{
dest = gen_lowpart (DImode, dest);
emit_move_insn (dest, tmp);
DONE;
}
else
{
rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
emit_insn (gen_stfiwx (stack, tmp));
emit_move_insn (dest, stack);
DONE;
}
}
[(set_attr "length" "12")
(set_attr "type" "fp")])
(define_expand "fixuns_truncdi2"
[(set (match_operand:DI 0 "register_operand" "")
(unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
"TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (mode))"
"")
(define_insn "*fixuns_truncdi2_fctiduz"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
(unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
&& TARGET_FCTIDUZ && !VECTOR_UNIT_VSX_P (mode)"
"fctiduz %0,%1"
[(set_attr "type" "fp")])
; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
; rather than (set (subreg:SI (reg)) (fix:SI ...))
; because the first makes it clear that operand 0 is not live
; before the instruction.
(define_insn "fctiwz_"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
(unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))]
UNSPEC_FCTIWZ))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"fctiwz %0,%1"
[(set_attr "type" "fp")])
(define_insn "fctiwuz_"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
(unspec:DI [(unsigned_fix:SI
(match_operand:SFDF 1 "gpc_reg_operand" ""))]
UNSPEC_FCTIWUZ))]
"TARGET_HARD_FLOAT && TARGET_FPRS && && TARGET_FCTIWUZ"
"fctiwuz %0,%1"
[(set_attr "type" "fp")])
;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
;; since the friz instruction does not truncate the value if the floating
;; point value is < LONG_MIN or > LONG_MAX.
(define_insn "*friz"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
&& !VECTOR_UNIT_VSX_P (DFmode) && flag_unsafe_math_optimizations
&& !flag_trapping_math && TARGET_FRIZ"
"friz %0,%1"
[(set_attr "type" "fp")])
;; Since FCTIWZ doesn't sign extend the upper bits, we have to do a store and a
;; load to properly sign extend the value, but at least doing a store, load
;; into a GPR to sign extend, a store from the GPR and a load back into the FPR
;; if we have 32-bit memory ops
(define_insn_and_split "*round322_fprs"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
(float:SFDF
(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
(clobber (match_scratch:DI 2 "=d"))
(clobber (match_scratch:DI 3 "=d"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
&& can_create_pseudo_p ()"
"#"
""
[(pc)]
{
rtx dest = operands[0];
rtx src = operands[1];
rtx tmp1 = operands[2];
rtx tmp2 = operands[3];
rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
if (GET_CODE (tmp1) == SCRATCH)
tmp1 = gen_reg_rtx (DImode);
if (GET_CODE (tmp2) == SCRATCH)
tmp2 = gen_reg_rtx (DImode);
emit_insn (gen_fctiwz_ (tmp1, src));
emit_insn (gen_stfiwx (stack, tmp1));
emit_insn (gen_lfiwax (tmp2, stack));
emit_insn (gen_floatdi2 (dest, tmp2));
DONE;
}
[(set_attr "type" "fpload")
(set_attr "length" "16")])
(define_insn_and_split "*roundu322_fprs"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
(unsigned_float:SFDF
(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
(clobber (match_scratch:DI 2 "=d"))
(clobber (match_scratch:DI 3 "=d"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU
&& can_create_pseudo_p ()"
"#"
""
[(pc)]
{
rtx dest = operands[0];
rtx src = operands[1];
rtx tmp1 = operands[2];
rtx tmp2 = operands[3];
rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
if (GET_CODE (tmp1) == SCRATCH)
tmp1 = gen_reg_rtx (DImode);
if (GET_CODE (tmp2) == SCRATCH)
tmp2 = gen_reg_rtx (DImode);
emit_insn (gen_fctiwuz_ (tmp1, src));
emit_insn (gen_stfiwx (stack, tmp1));
emit_insn (gen_lfiwzx (tmp2, stack));
emit_insn (gen_floatdi2 (dest, tmp2));
DONE;
}
[(set_attr "type" "fpload")
(set_attr "length" "16")])
;; No VSX equivalent to fctid
(define_insn "lrintdi2"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
(unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "")]
UNSPEC_FCTID))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && "
"fctid %0,%1"
[(set_attr "type" "fp")])
(define_expand "btrunc2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
UNSPEC_FRIZ))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && "
"")
(define_insn "*btrunc2_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
UNSPEC_FRIZ))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS &&
&& !VECTOR_UNIT_VSX_P (mode)"
"friz %0,%1"
[(set_attr "type" "fp")])
(define_expand "ceil2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
UNSPEC_FRIP))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && "
"")
(define_insn "*ceil2_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
UNSPEC_FRIP))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS &&
&& !VECTOR_UNIT_VSX_P (mode)"
"frip %0,%1"
[(set_attr "type" "fp")])
(define_expand "floor2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
UNSPEC_FRIM))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && "
"")
(define_insn "*floor2_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
UNSPEC_FRIM))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS &&
&& !VECTOR_UNIT_VSX_P (mode)"
"frim %0,%1"
[(set_attr "type" "fp")])
;; No VSX equivalent to frin
(define_insn "round2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
UNSPEC_FRIN))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && "
"frin %0,%1"
[(set_attr "type" "fp")])
; An UNSPEC is used so we don't have to support SImode in FP registers.
(define_insn "stfiwx"
[(set (match_operand:SI 0 "memory_operand" "=Z")
(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
UNSPEC_STFIWX))]
"TARGET_PPC_GFXOPT"
"stfiwx %1,%y0"
[(set_attr "type" "fpstore")])
;; If we don't have a direct conversion to single precision, don't enable this
;; conversion for 32-bit without fast math, because we don't have the insn to
;; generate the fixup swizzle to avoid double rounding problems.
(define_expand "floatsisf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
&& (!TARGET_FPRS
|| (TARGET_FPRS
&& ((TARGET_FCFIDS && TARGET_LFIWAX)
|| (TARGET_DOUBLE_FLOAT && TARGET_FCFID
&& (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
"
{
if (!TARGET_FPRS)
{
if (!REG_P (operands[1]))
operands[1] = force_reg (SImode, operands[1]);
}
else if (TARGET_FCFIDS && TARGET_LFIWAX)
{
emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
DONE;
}
else if (TARGET_FCFID && TARGET_LFIWAX)
{
rtx dfreg = gen_reg_rtx (DFmode);
emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
emit_insn (gen_truncdfsf2 (operands[0], dfreg));
DONE;
}
else
{
rtx dreg = operands[1];
if (!REG_P (dreg))
dreg = force_reg (SImode, dreg);
dreg = convert_to_mode (DImode, dreg, false);
emit_insn (gen_floatdisf2 (operands[0], dreg));
DONE;
}
}")
(define_expand "floatdidf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
"TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
"")
(define_insn "*floatdidf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(float:DF (match_operand:DI 1 "gpc_reg_operand" "d")))]
"TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fcfid %0,%1"
[(set_attr "type" "fp")])
; Allow the combiner to merge source memory operands to the conversion so that
; the optimizer/register allocator doesn't try to load the value too early in a
; GPR and then use store/load to move it to a FPR and suffer from a store-load
; hit. We will split after reload to avoid the trip through the GPRs
(define_insn_and_split "*floatdidf2_mem"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(float:DF (match_operand:DI 1 "memory_operand" "m")))
(clobber (match_scratch:DI 2 "=d"))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
"#"
"&& reload_completed"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (float:DF (match_dup 2)))]
""
[(set_attr "length" "8")
(set_attr "type" "fpload")])
(define_expand "floatunsdidf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(unsigned_float:DF
(match_operand:DI 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
"")
(define_insn "*floatunsdidf2_fcfidu"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FCFIDU && !VECTOR_UNIT_VSX_P (DFmode)"
"fcfidu %0,%1"
[(set_attr "type" "fp")
(set_attr "length" "4")])
(define_insn_and_split "*floatunsdidf2_mem"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(unsigned_float:DF (match_operand:DI 1 "memory_operand" "m")))
(clobber (match_scratch:DI 2 "=d"))]
"TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
"#"
"&& reload_completed"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
""
[(set_attr "length" "8")
(set_attr "type" "fpload")])
(define_expand "floatdisf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
"TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
&& (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
"
{
if (!TARGET_FCFIDS)
{
rtx val = operands[1];
if (!flag_unsafe_math_optimizations)
{
rtx label = gen_label_rtx ();
val = gen_reg_rtx (DImode);
emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
emit_label (label);
}
emit_insn (gen_floatdisf2_internal1 (operands[0], val));
DONE;
}
}")
(define_insn "floatdisf2_fcfids"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
&& TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
"fcfids %0,%1"
[(set_attr "type" "fp")])
(define_insn_and_split "*floatdisf2_mem"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(float:SF (match_operand:DI 1 "memory_operand" "m")))
(clobber (match_scratch:DI 2 "=f"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
&& TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
"#"
"&& reload_completed"
[(pc)]
"
{
emit_move_insn (operands[2], operands[1]);
emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
DONE;
}"
[(set_attr "length" "8")])
;; This is not IEEE compliant if rounding mode is "round to nearest".
;; If the DI->DF conversion is inexact, then it's possible to suffer
;; from double rounding.
;; Instead of creating a new cpu type for two FP operations, just use fp
(define_insn_and_split "floatdisf2_internal1"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
(clobber (match_scratch:DF 2 "=d"))]
"TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"#"
"&& reload_completed"
[(set (match_dup 2)
(float:DF (match_dup 1)))
(set (match_dup 0)
(float_truncate:SF (match_dup 2)))]
""
[(set_attr "length" "8")
(set_attr "type" "fp")])
;; Twiddles bits to avoid double rounding.
;; Bits that might be truncated when converting to DFmode are replaced
;; by a bit that won't be lost at that stage, but is below the SFmode
;; rounding position.
(define_expand "floatdisf2_internal2"
[(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
(const_int 53)))
(parallel [(set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
(const_int 2047)))
(clobber (scratch:CC))])
(set (match_dup 3) (plus:DI (match_dup 3)
(const_int 1)))
(set (match_dup 0) (plus:DI (match_dup 0)
(const_int 2047)))
(set (match_dup 4) (compare:CCUNS (match_dup 3)
(const_int 2)))
(set (match_dup 0) (ior:DI (match_dup 0)
(match_dup 1)))
(parallel [(set (match_dup 0) (and:DI (match_dup 0)
(const_int -2048)))
(clobber (scratch:CC))])
(set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
(label_ref (match_operand:DI 2 "" ""))
(pc)))
(set (match_dup 0) (match_dup 1))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"
{
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (CCUNSmode);
}")
(define_expand "floatunsdisf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
&& TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
"")
(define_insn "floatunsdisf2_fcfidus"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
&& TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
"fcfidus %0,%1"
[(set_attr "type" "fp")])
(define_insn_and_split "*floatunsdisf2_mem"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(unsigned_float:SF (match_operand:DI 1 "memory_operand" "m")))
(clobber (match_scratch:DI 2 "=f"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
&& TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
"#"
"&& reload_completed"
[(pc)]
"
{
emit_move_insn (operands[2], operands[1]);
emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
DONE;
}"
[(set_attr "length" "8")
(set_attr "type" "fpload")])
;; Define the DImode operations that can be done in a small number
;; of instructions. The & constraints are to prevent the register
;; allocator from allocating registers that overlap with the inputs
;; (for example, having an input in 7,8 and an output in 6,7). We
;; also allow for the output being the same as one of the inputs.
(define_insn "*adddi3_noppc64"
[(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
(plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
(match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
"! TARGET_POWERPC64"
"*
{
if (WORDS_BIG_ENDIAN)
return (GET_CODE (operands[2])) != CONST_INT
? \"addc %L0,%L1,%L2\;adde %0,%1,%2\"
: \"addic %L0,%L1,%2\;add%G2e %0,%1\";
else
return (GET_CODE (operands[2])) != CONST_INT
? \"addc %0,%1,%2\;adde %L0,%L1,%L2\"
: \"addic %0,%1,%2\;add%G2e %L0,%L1\";
}"
[(set_attr "type" "two")
(set_attr "length" "8")])
(define_insn "*subdi3_noppc64"
[(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
(minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I")
(match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))]
"! TARGET_POWERPC64"
"*
{
if (WORDS_BIG_ENDIAN)
return (GET_CODE (operands[1]) != CONST_INT)
? \"subfc %L0,%L2,%L1\;subfe %0,%2,%1\"
: \"subfic %L0,%L2,%1\;subf%G1e %0,%2\";
else
return (GET_CODE (operands[1]) != CONST_INT)
? \"subfc %0,%2,%1\;subfe %L0,%L2,%L1\"
: \"subfic %0,%2,%1\;subf%G1e %L0,%L2\";
}"
[(set_attr "type" "two")
(set_attr "length" "8")])
(define_insn "*negdi2_noppc64"
[(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
(neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))]
"! TARGET_POWERPC64"
"*
{
return (WORDS_BIG_ENDIAN)
? \"subfic %L0,%L1,0\;subfze %0,%1\"
: \"subfic %0,%1,0\;subfze %L0,%L1\";
}"
[(set_attr "type" "two")
(set_attr "length" "8")])
(define_insn "mulsidi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
(mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
(sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
"! TARGET_POWERPC64"
{
return (WORDS_BIG_ENDIAN)
? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\"
: \"mulhw %L0,%1,%2\;mullw %0,%1,%2\";
}
[(set_attr "type" "imul")
(set_attr "length" "8")])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
(sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
"! TARGET_POWERPC64 && reload_completed"
[(set (match_dup 3)
(truncate:SI
(lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
(sign_extend:DI (match_dup 2)))
(const_int 32))))
(set (match_dup 4)
(mult:SI (match_dup 1)
(match_dup 2)))]
"
{
int endian = (WORDS_BIG_ENDIAN == 0);
operands[3] = operand_subword (operands[0], endian, 0, DImode);
operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
}")
(define_insn "umulsidi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
(mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
(zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
"! TARGET_POWERPC64"
"*
{
return (WORDS_BIG_ENDIAN)
? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\"
: \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\";
}"
[(set_attr "type" "imul")
(set_attr "length" "8")])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
(zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
"! TARGET_POWERPC64 && reload_completed"
[(set (match_dup 3)
(truncate:SI
(lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
(zero_extend:DI (match_dup 2)))
(const_int 32))))
(set (match_dup 4)
(mult:SI (match_dup 1)
(match_dup 2)))]
"
{
int endian = (WORDS_BIG_ENDIAN == 0);
operands[3] = operand_subword (operands[0], endian, 0, DImode);
operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
}")
(define_insn "smulsi3_highpart"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(truncate:SI
(lshiftrt:DI (mult:DI (sign_extend:DI
(match_operand:SI 1 "gpc_reg_operand" "%r"))
(sign_extend:DI
(match_operand:SI 2 "gpc_reg_operand" "r")))
(const_int 32))))]
""
"mulhw %0,%1,%2"
[(set_attr "type" "imul")])
(define_insn "umulsi3_highpart"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(truncate:SI
(lshiftrt:DI (mult:DI (zero_extend:DI
(match_operand:SI 1 "gpc_reg_operand" "%r"))
(zero_extend:DI
(match_operand:SI 2 "gpc_reg_operand" "r")))
(const_int 32))))]
""
"mulhwu %0,%1,%2"
[(set_attr "type" "imul")])
;; Shift by a variable amount is too complex to be worth open-coding. We
;; just handle shifts by constants.
(define_insn "ashrdi3_no_power"
[(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "M,i")))]
"!TARGET_POWERPC64"
"*
{
switch (which_alternative)
{
default:
gcc_unreachable ();
case 0:
if (WORDS_BIG_ENDIAN)
return \"srawi %0,%1,31\;srawi %L0,%1,%h2\";
else
return \"srawi %L0,%L1,31\;srawi %0,%L1,%h2\";
case 1:
if (WORDS_BIG_ENDIAN)
return \"srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2\";
else
return \"srwi %0,%1,%h2\;insrwi %0,%L1,%h2,0\;srawi %L0,%L1,%h2\";
}
}"
[(set_attr "type" "two,three")
(set_attr "length" "8,12")])
(define_insn "*ashrdisi3_noppc64be"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(const_int 32)) 4))]
"TARGET_32BIT && !TARGET_POWERPC64 && WORDS_BIG_ENDIAN"
"*
{
if (REGNO (operands[0]) == REGNO (operands[1]))
return \"\";
else
return \"mr %0,%1\";
}"
[(set_attr "length" "4")])
;; PowerPC64 DImode operations.
(define_insn "muldi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
(match_operand:DI 2 "reg_or_short_operand" "r,I")))]
"TARGET_POWERPC64"
"@
mulld %0,%1,%2
mulli %0,%1,%2"
[(set (attr "type")
(cond [(match_operand:SI 2 "s8bit_cint_operand" "")
(const_string "imul3")
(match_operand:SI 2 "short_cint_operand" "")
(const_string "imul2")]
(const_string "lmul")))])
(define_insn "*muldi3_internal1"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
(match_operand:DI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
"TARGET_POWERPC64"
"@
mulld. %3,%1,%2
#"
[(set_attr "type" "lmul_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 3)
(mult:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*muldi3_internal2"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
(match_operand:DI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(mult:DI (match_dup 1) (match_dup 2)))]
"TARGET_POWERPC64"
"@
mulld. %0,%1,%2
#"
[(set_attr "type" "lmul_compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "gpc_reg_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(mult:DI (match_dup 1) (match_dup 2)))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0)
(mult:DI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "smuldi3_highpart"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(truncate:DI
(lshiftrt:TI (mult:TI (sign_extend:TI
(match_operand:DI 1 "gpc_reg_operand" "%r"))
(sign_extend:TI
(match_operand:DI 2 "gpc_reg_operand" "r")))
(const_int 64))))]
"TARGET_POWERPC64"
"mulhd %0,%1,%2"
[(set_attr "type" "lmul")])
(define_insn "umuldi3_highpart"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(truncate:DI
(lshiftrt:TI (mult:TI (zero_extend:TI
(match_operand:DI 1 "gpc_reg_operand" "%r"))
(zero_extend:TI
(match_operand:DI 2 "gpc_reg_operand" "r")))
(const_int 64))))]
"TARGET_POWERPC64"
"mulhdu %0,%1,%2"
[(set_attr "type" "lmul")])
(define_expand "mulditi3"
[(set (match_operand:TI 0 "gpc_reg_operand")
(mult:TI (sign_extend:TI (match_operand:DI 1 "gpc_reg_operand"))
(sign_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))]
"TARGET_POWERPC64"
{
rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode);
emit_insn (gen_muldi3 (l, operands[1], operands[2]));
emit_insn (gen_smuldi3_highpart (h, operands[1], operands[2]));
emit_move_insn (gen_lowpart (DImode, operands[0]), l);
emit_move_insn (gen_highpart (DImode, operands[0]), h);
DONE;
})
(define_expand "umulditi3"
[(set (match_operand:TI 0 "gpc_reg_operand")
(mult:TI (zero_extend:TI (match_operand:DI 1 "gpc_reg_operand"))
(zero_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))]
"TARGET_POWERPC64"
{
rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode);
emit_insn (gen_muldi3 (l, operands[1], operands[2]));
emit_insn (gen_umuldi3_highpart (h, operands[1], operands[2]));
emit_move_insn (gen_lowpart (DImode, operands[0]), l);
emit_move_insn (gen_highpart (DImode, operands[0]), h);
DONE;
})
(define_insn "rotldi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i")))]
"TARGET_POWERPC64"
"@
rldcl %0,%1,%2,0
rldicl %0,%1,%H2,0"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotldi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r"))]
"TARGET_64BIT"
"@
rldcl. %3,%1,%2,0
rldicl. %3,%1,%H2,0
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 3)
(rotate:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*rotldi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(rotate:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT"
"@
rldcl. %0,%1,%2,0
rldicl. %0,%1,%H2,0
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(rotate:DI (match_dup 1) (match_dup 2)))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0)
(rotate:DI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*rotldi3_internal4"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i"))
(match_operand:DI 3 "mask64_operand" "n,n")))]
"TARGET_POWERPC64"
"@
rldc%B3 %0,%1,%2,%S3
rldic%B3 %0,%1,%H2,%S3"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotldi3_internal5"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (and:DI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i"))
(match_operand:DI 3 "mask64_operand" "n,n,n,n"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r,r,r,r"))]
"TARGET_64BIT"
"@
rldc%B3. %4,%1,%2,%S3
rldic%B3. %4,%1,%H2,%S3
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (and:DI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" ""))
(match_operand:DI 3 "mask64_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 4 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 4)
(and:DI (rotate:DI (match_dup 1)
(match_dup 2))
(match_dup 3)))
(set (match_dup 0)
(compare:CC (match_dup 4)
(const_int 0)))]
"")
(define_insn "*rotldi3_internal6"
[(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (and:DI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i"))
(match_operand:DI 3 "mask64_operand" "n,n,n,n"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"TARGET_64BIT"
"@
rldc%B3. %0,%1,%2,%S3
rldic%B3. %0,%1,%H2,%S3
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (and:DI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" ""))
(match_operand:DI 3 "mask64_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0)
(and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*rotldi3_internal7le"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI
(subreg:QI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))]
"TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
"@
rldcl %0,%1,%2,56
rldicl %0,%1,%H2,56"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotldi3_internal7be"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI
(subreg:QI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i")) 7)))]
"TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
"@
rldcl %0,%1,%2,56
rldicl %0,%1,%H2,56"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotldi3_internal8le"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:DI
(subreg:QI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r"))]
"TARGET_64BIT && !BYTES_BIG_ENDIAN"
"@
rldcl. %3,%1,%2,56
rldicl. %3,%1,%H2,56
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_insn "*rotldi3_internal8be"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:DI
(subreg:QI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 7))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r"))]
"TARGET_64BIT && BYTES_BIG_ENDIAN"
"@
rldcl. %3,%1,%2,56
rldicl. %3,%1,%H2,56
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI
(subreg:QI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")) 0))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 3)
(zero_extend:DI (subreg:QI
(rotate:DI (match_dup 1)
(match_dup 2)) 0)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI
(subreg:QI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")) 7))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 3)
(zero_extend:DI (subreg:QI
(rotate:DI (match_dup 1)
(match_dup 2)) 7)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*rotldi3_internal9le"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:DI
(subreg:QI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
"TARGET_64BIT && !BYTES_BIG_ENDIAN"
"@
rldcl. %0,%1,%2,56
rldicl. %0,%1,%H2,56
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_insn "*rotldi3_internal9be"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:DI
(subreg:QI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 7))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))]
"TARGET_64BIT && BYTES_BIG_ENDIAN"
"@
rldcl. %0,%1,%2,56
rldicl. %0,%1,%H2,56
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI
(subreg:QI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")) 0))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
"TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 0)
(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI
(subreg:QI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")) 7))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))]
"TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 0)
(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*rotldi3_internal10le"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI
(subreg:HI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))]
"TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
"@
rldcl %0,%1,%2,48
rldicl %0,%1,%H2,48"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotldi3_internal10be"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI
(subreg:HI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i")) 6)))]
"TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
"@
rldcl %0,%1,%2,48
rldicl %0,%1,%H2,48"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotldi3_internal11le"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:DI
(subreg:HI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r"))]
"TARGET_64BIT && !BYTES_BIG_ENDIAN"
"@
rldcl. %3,%1,%2,48
rldicl. %3,%1,%H2,48
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_insn "*rotldi3_internal11be"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:DI
(subreg:HI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 6))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r"))]
"TARGET_64BIT && BYTES_BIG_ENDIAN"
"@
rldcl. %3,%1,%2,48
rldicl. %3,%1,%H2,48
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI
(subreg:HI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")) 0))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 3)
(zero_extend:DI (subreg:HI
(rotate:DI (match_dup 1)
(match_dup 2)) 0)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI
(subreg:HI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")) 6))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 3)
(zero_extend:DI (subreg:HI
(rotate:DI (match_dup 1)
(match_dup 2)) 6)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*rotldi3_internal12le"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:DI
(subreg:HI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
"TARGET_64BIT && !BYTES_BIG_ENDIAN"
"@
rldcl. %0,%1,%2,48
rldicl. %0,%1,%H2,48
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_insn "*rotldi3_internal12be"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:DI
(subreg:HI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 6))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))]
"TARGET_64BIT && BYTES_BIG_ENDIAN"
"@
rldcl. %0,%1,%2,48
rldicl. %0,%1,%H2,48
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI
(subreg:HI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")) 0))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
"TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 0)
(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI
(subreg:HI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")) 6))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))]
"TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 0)
(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*rotldi3_internal13le"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI
(subreg:SI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))]
"TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
"@
rldcl %0,%1,%2,32
rldicl %0,%1,%H2,32"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotldi3_internal13be"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI
(subreg:SI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i")) 4)))]
"TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
"@
rldcl %0,%1,%2,32
rldicl %0,%1,%H2,32"
[(set_attr "type" "var_shift_rotate,integer")])
(define_insn "*rotldi3_internal14le"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:DI
(subreg:SI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r"))]
"TARGET_64BIT && !BYTES_BIG_ENDIAN"
"@
rldcl. %3,%1,%2,32
rldicl. %3,%1,%H2,32
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_insn "*rotldi3_internal14be"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:DI
(subreg:SI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 4))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r"))]
"TARGET_64BIT && BYTES_BIG_ENDIAN"
"@
rldcl. %3,%1,%2,32
rldicl. %3,%1,%H2,32
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI
(subreg:SI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")) 0))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 3)
(zero_extend:DI (subreg:SI
(rotate:DI (match_dup 1)
(match_dup 2)) 0)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI
(subreg:SI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")) 4))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 3)
(zero_extend:DI (subreg:SI
(rotate:DI (match_dup 1)
(match_dup 2)) 4)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*rotldi3_internal15le"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:DI
(subreg:SI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
"TARGET_64BIT && !BYTES_BIG_ENDIAN"
"@
rldcl. %0,%1,%2,32
rldicl. %0,%1,%H2,32
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_insn "*rotldi3_internal15be"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (zero_extend:DI
(subreg:SI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 4))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))]
"TARGET_64BIT && BYTES_BIG_ENDIAN"
"@
rldcl. %0,%1,%2,32
rldicl. %0,%1,%H2,32
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI
(subreg:SI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")) 0))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
"TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 0)
(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (zero_extend:DI
(subreg:SI
(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")) 4))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))]
"TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
[(set (match_dup 0)
(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_expand "ashldi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")))]
"TARGET_POWERPC64"
"")
(define_insn "*ashldi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
"TARGET_POWERPC64"
"@
sld %0,%1,%2
sldi %0,%1,%H2"
[(set_attr "type" "var_shift_rotate,shift")])
(define_insn "*ashldi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r"))]
"TARGET_64BIT"
"@
sld. %3,%1,%2
sldi. %3,%1,%H2
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
(compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 3)
(ashift:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*ashldi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(ashift:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT"
"@
sld. %0,%1,%2
sldi. %0,%1,%H2
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
(compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(ashift:DI (match_dup 1) (match_dup 2)))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0)
(ashift:DI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*ashldi3_internal4"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i"))
(match_operand:DI 3 "const_int_operand" "n")))]
"TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
"rldic %0,%1,%H2,%W3")
(define_insn "ashldi3_internal5"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC
(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i"))
(match_operand:DI 3 "const_int_operand" "n,n"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r,r"))]
"TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
"@
rldic. %4,%1,%H2,%W3
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:DI 3 "const_int_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 4 ""))]
"TARGET_POWERPC64 && reload_completed
&& includes_rldic_lshift_p (operands[2], operands[3])"
[(set (match_dup 4)
(and:DI (ashift:DI (match_dup 1) (match_dup 2))
(match_dup 3)))
(set (match_dup 0)
(compare:CC (match_dup 4)
(const_int 0)))]
"")
(define_insn "*ashldi3_internal6"
[(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
(compare:CC
(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i"))
(match_operand:DI 3 "const_int_operand" "n,n"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
"@
rldic. %0,%1,%H2,%W3
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:DI 3 "const_int_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"TARGET_POWERPC64 && reload_completed
&& includes_rldic_lshift_p (operands[2], operands[3])"
[(set (match_dup 0)
(and:DI (ashift:DI (match_dup 1) (match_dup 2))
(match_dup 3)))
(set (match_dup 4)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*ashldi3_internal7"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "const_int_operand" "i"))
(match_operand:DI 3 "mask64_operand" "n")))]
"TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
"rldicr %0,%1,%H2,%S3")
(define_insn "ashldi3_internal8"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC
(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i"))
(match_operand:DI 3 "mask64_operand" "n,n"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r,r"))]
"TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
"@
rldicr. %4,%1,%H2,%S3
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:DI 3 "mask64_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 4 ""))]
"TARGET_POWERPC64 && reload_completed
&& includes_rldicr_lshift_p (operands[2], operands[3])"
[(set (match_dup 4)
(and:DI (ashift:DI (match_dup 1) (match_dup 2))
(match_dup 3)))
(set (match_dup 0)
(compare:CC (match_dup 4)
(const_int 0)))]
"")
(define_insn "*ashldi3_internal9"
[(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
(compare:CC
(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "i,i"))
(match_operand:DI 3 "mask64_operand" "n,n"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
"@
rldicr. %0,%1,%H2,%S3
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
(compare:CC
(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:DI 3 "mask64_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
"TARGET_POWERPC64 && reload_completed
&& includes_rldicr_lshift_p (operands[2], operands[3])"
[(set (match_dup 0)
(and:DI (ashift:DI (match_dup 1) (match_dup 2))
(match_dup 3)))
(set (match_dup 4)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_expand "lshrdi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")))]
"TARGET_POWERPC64"
"")
(define_insn "*lshrdi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
"TARGET_POWERPC64"
"@
srd %0,%1,%2
srdi %0,%1,%H2"
[(set_attr "type" "var_shift_rotate,shift")])
(define_insn "*lshrdi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r"))]
"TARGET_64BIT "
"@
srd. %3,%1,%2
srdi. %3,%1,%H2
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 3)
(lshiftrt:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*lshrdi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(lshiftrt:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT"
"@
srd. %0,%1,%2
srdi. %0,%1,%H2
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(lshiftrt:DI (match_dup 1) (match_dup 2)))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0)
(lshiftrt:DI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_expand "ashrdi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")))]
""
"
{
if (TARGET_POWERPC64)
;
else if (GET_CODE (operands[2]) == CONST_INT)
{
emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2]));
DONE;
}
else
FAIL;
}")
(define_insn "*ashrdi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
"TARGET_POWERPC64"
"@
srad %0,%1,%2
sradi %0,%1,%H2"
[(set_attr "type" "var_shift_rotate,shift")])
(define_insn "*ashrdi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r"))]
"TARGET_64BIT"
"@
srad. %3,%1,%2
sradi. %3,%1,%H2
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
(compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 3)
(ashiftrt:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*ashrdi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT"
"@
srad. %0,%1,%2
sradi. %0,%1,%H2
#
#"
[(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
(set_attr "length" "4,4,8,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
(compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0)
(ashiftrt:DI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_expand "anddi3"
[(parallel
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(and:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")))
(clobber (match_scratch:CC 3 ""))])]
""
{
if (!TARGET_POWERPC64)
{
rtx cc = gen_rtx_SCRATCH (CCmode);
rs6000_split_logical (operands, AND, false, false, false, cc);
DONE;
}
else if (!and64_2_operand (operands[2], DImode))
operands[2] = force_reg (DImode, operands[2]);
})
(define_insn "anddi3_mc"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
(and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r")
(match_operand:DI 2 "and64_2_operand" "?r,S,T,K,J,t")))
(clobber (match_scratch:CC 3 "=X,X,X,x,x,X"))]
"TARGET_POWERPC64 && rs6000_gen_cell_microcode"
"@
and %0,%1,%2
rldic%B2 %0,%1,0,%S2
rlwinm %0,%1,0,%m2,%M2
andi. %0,%1,%b2
andis. %0,%1,%u2
#"
[(set_attr "type" "*,*,*,fast_compare,fast_compare,*")
(set_attr "length" "4,4,4,4,4,8")])
(define_insn "anddi3_nomc"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r")
(match_operand:DI 2 "and64_2_operand" "?r,S,T,t")))
(clobber (match_scratch:CC 3 "=X,X,X,X"))]
"TARGET_POWERPC64 && !rs6000_gen_cell_microcode"
"@
and %0,%1,%2
rldic%B2 %0,%1,0,%S2
rlwinm %0,%1,0,%m2,%M2
#"
[(set_attr "length" "4,4,4,8")])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(and:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "mask64_2_operand" "")))
(clobber (match_scratch:CC 3 ""))]
"TARGET_POWERPC64
&& (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode))
&& !mask_operand (operands[2], DImode)
&& !mask64_operand (operands[2], DImode)"
[(set (match_dup 0)
(and:DI (rotate:DI (match_dup 1)
(match_dup 4))
(match_dup 5)))
(set (match_dup 0)
(and:DI (rotate:DI (match_dup 0)
(match_dup 6))
(match_dup 7)))]
{
build_mask64_2_operands (operands[2], &operands[4]);
})
(define_insn "*anddi3_internal2_mc"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y")
(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r")
(match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r,r,r,r,r"))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,x,x,X"))]
"TARGET_64BIT && rs6000_gen_cell_microcode"
"@
and. %3,%1,%2
rldic%B2. %3,%1,0,%S2
rlwinm. %3,%1,0,%m2,%M2
andi. %3,%1,%b2
andis. %3,%1,%u2
#
#
#
#
#
#
#"
[(set_attr "type" "fast_compare,compare,delayed_compare,fast_compare,\
fast_compare,compare,compare,compare,compare,compare,\
compare,compare")
(set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
(define_split
[(set (match_operand:CC 0 "cc_reg_operand" "")
(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "mask64_2_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))
(clobber (match_scratch:CC 4 ""))]
"TARGET_64BIT && reload_completed
&& (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode))
&& !mask_operand (operands[2], DImode)
&& !mask64_operand (operands[2], DImode)"
[(set (match_dup 3)
(and:DI (rotate:DI (match_dup 1)
(match_dup 5))
(match_dup 6)))
(parallel [(set (match_dup 0)
(compare:CC (and:DI (rotate:DI (match_dup 3)
(match_dup 7))
(match_dup 8))
(const_int 0)))
(clobber (match_dup 3))])]
"
{
build_mask64_2_operands (operands[2], &operands[5]);
}")
(define_insn "*anddi3_internal3_mc"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y")
(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r")
(match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r,r,r")
(and:DI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,x,x,X"))]
"TARGET_64BIT && rs6000_gen_cell_microcode"
"@
and. %0,%1,%2
rldic%B2. %0,%1,0,%S2
rlwinm. %0,%1,0,%m2,%M2
andi. %0,%1,%b2
andis. %0,%1,%u2
#
#
#
#
#
#
#"
[(set_attr "type" "fast_compare,compare,delayed_compare,fast_compare,\
fast_compare,compare,compare,compare,compare,compare,\
compare,compare")
(set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "and64_2_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(and:DI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:CC 4 ""))]
"TARGET_64BIT && reload_completed"
[(parallel [(set (match_dup 0)
(and:DI (match_dup 1) (match_dup 2)))
(clobber (match_dup 4))])
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_split
[(set (match_operand:CC 3 "cc_reg_operand" "")
(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "mask64_2_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(and:DI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:CC 4 ""))]
"TARGET_64BIT && reload_completed
&& (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode))
&& !mask_operand (operands[2], DImode)
&& !mask64_operand (operands[2], DImode)"
[(set (match_dup 0)
(and:DI (rotate:DI (match_dup 1)
(match_dup 5))
(match_dup 6)))
(parallel [(set (match_dup 3)
(compare:CC (and:DI (rotate:DI (match_dup 0)
(match_dup 7))
(match_dup 8))
(const_int 0)))
(set (match_dup 0)
(and:DI (rotate:DI (match_dup 0)
(match_dup 7))
(match_dup 8)))])]
"
{
build_mask64_2_operands (operands[2], &operands[5]);
}")
(define_expand "iordi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")))]
""
{
if (!TARGET_POWERPC64)
{
rs6000_split_logical (operands, IOR, false, false, false, NULL_RTX);
DONE;
}
else if (!reg_or_logical_cint_operand (operands[2], DImode))
operands[2] = force_reg (DImode, operands[2]);
else if (non_logical_cint_operand (operands[2], DImode))
{
HOST_WIDE_INT value;
rtx tmp = ((!can_create_pseudo_p ()
|| rtx_equal_p (operands[0], operands[1]))
? operands[0] : gen_reg_rtx (DImode));
value = INTVAL (operands[2]);
emit_insn (gen_iordi3 (tmp, operands[1],
GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
DONE;
}
})
(define_expand "xordi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "reg_or_cint_operand" "")))]
""
{
if (!TARGET_POWERPC64)
{
rs6000_split_logical (operands, XOR, false, false, false, NULL_RTX);
DONE;
}
else if (!reg_or_logical_cint_operand (operands[2], DImode))
operands[2] = force_reg (DImode, operands[2]);
if (non_logical_cint_operand (operands[2], DImode))
{
HOST_WIDE_INT value;
rtx tmp = ((!can_create_pseudo_p ()
|| rtx_equal_p (operands[0], operands[1]))
? operands[0] : gen_reg_rtx (DImode));
value = INTVAL (operands[2]);
emit_insn (gen_xordi3 (tmp, operands[1],
GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
DONE;
}
})
(define_insn "*booldi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
(match_operator:DI 3 "boolean_or_operator"
[(match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
(match_operand:DI 2 "logical_operand" "r,K,JF")]))]
"TARGET_POWERPC64"
"@
%q3 %0,%1,%2
%q3i %0,%1,%b2
%q3is %0,%1,%u2")
(define_insn "*booldi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (match_operator:DI 4 "boolean_or_operator"
[(match_operand:DI 1 "gpc_reg_operand" "%r,r")
(match_operand:DI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
"TARGET_64BIT"
"@
%q4. %3,%1,%2
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operator:DI 4 "boolean_operator"
[(match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "gpc_reg_operand" "")])
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*booldi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (match_operator:DI 4 "boolean_or_operator"
[(match_operand:DI 1 "gpc_reg_operand" "%r,r")
(match_operand:DI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
"TARGET_64BIT"
"@
%q4. %0,%1,%2
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operator:DI 4 "boolean_operator"
[(match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "gpc_reg_operand" "")])
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_dup 4))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
;; Split a logical operation that we can't do in one insn into two insns,
;; each of which does one 16-bit part. This is used by combine.
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operator:DI 3 "boolean_or_operator"
[(match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "non_logical_cint_operand" "")]))]
"TARGET_POWERPC64"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 0) (match_dup 5))]
"
{
rtx i3,i4;
i3 = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
i4 = GEN_INT (INTVAL (operands[2]) & 0xffff);
operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
operands[1], i3);
operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
operands[0], i4);
}")
(define_insn "*boolcdi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(match_operator:DI 3 "boolean_operator"
[(not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
(match_operand:DI 2 "gpc_reg_operand" "r")]))]
"TARGET_POWERPC64"
"%q3 %0,%2,%1")
(define_insn "*boolcdi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (match_operator:DI 4 "boolean_operator"
[(not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
(match_operand:DI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
"TARGET_64BIT"
"@
%q4. %3,%2,%1
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operator:DI 4 "boolean_operator"
[(not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
(match_operand:DI 2 "gpc_reg_operand" "")])
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*boolcdi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (match_operator:DI 4 "boolean_operator"
[(not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r"))
(match_operand:DI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
"TARGET_64BIT"
"@
%q4. %0,%2,%1
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operator:DI 4 "boolean_operator"
[(not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
(match_operand:DI 2 "gpc_reg_operand" "")])
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_dup 4))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*boolccdi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(match_operator:DI 3 "boolean_operator"
[(not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
(not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))]))]
"TARGET_POWERPC64"
"%q3 %0,%1,%2")
(define_insn "*boolccdi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (match_operator:DI 4 "boolean_operator"
[(not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
(not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))])
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
"TARGET_64BIT"
"@
%q4. %3,%1,%2
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operator:DI 4 "boolean_operator"
[(not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
(not:DI (match_operand:DI 2 "gpc_reg_operand" ""))])
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0)
(compare:CC (match_dup 3)
(const_int 0)))]
"")
(define_insn "*boolccdi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (match_operator:DI 4 "boolean_operator"
[(not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r"))
(not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))])
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
"TARGET_64BIT"
"@
%q4. %0,%1,%2
#"
[(set_attr "type" "fast_compare,compare")
(set_attr "length" "4,8")])
(define_split
[(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operator:DI 4 "boolean_operator"
[(not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
(not:DI (match_operand:DI 2 "gpc_reg_operand" ""))])
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_dup 4))]
"TARGET_POWERPC64 && reload_completed"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
;; Eqv operation.
(define_insn "*eqv3"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(not:GPR
(xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
(match_operand:GPR 2 "gpc_reg_operand" "r"))))]
""
"eqv %0,%1,%2"
[(set_attr "type" "integer")
(set_attr "length" "4")])
;; 128-bit logical operations expanders
(define_expand "and3"
[(parallel [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
(and:BOOL_128
(match_operand:BOOL_128 1 "vlogical_operand" "")
(match_operand:BOOL_128 2 "vlogical_operand" "")))
(clobber (match_scratch:CC 3 ""))])]
""
"")
(define_expand "ior3"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
(ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
(match_operand:BOOL_128 2 "vlogical_operand" "")))]
""
"")
(define_expand "xor3"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
(xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
(match_operand:BOOL_128 2 "vlogical_operand" "")))]
""
"")
(define_expand "one_cmpl2"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
(not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
""
"")
(define_expand "nor3"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
(and:BOOL_128
(not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
(not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
""
"")
(define_expand "andc3"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
(and:BOOL_128
(not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
(match_operand:BOOL_128 1 "vlogical_operand" "")))]
""
"")
;; Power8 vector logical instructions.
(define_expand "eqv3"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
(not:BOOL_128
(xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
(match_operand:BOOL_128 2 "vlogical_operand" ""))))]
"mode == TImode || mode == PTImode || TARGET_P8_VECTOR"
"")
;; Rewrite nand into canonical form
(define_expand "nand3"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
(ior:BOOL_128
(not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
(not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
"mode == TImode || mode == PTImode || TARGET_P8_VECTOR"
"")
;; The canonical form is to have the negated element first, so we need to
;; reverse arguments.
(define_expand "orc3"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "")
(ior:BOOL_128
(not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
(match_operand:BOOL_128 1 "vlogical_operand" "")))]
"mode == TImode || mode == PTImode || TARGET_P8_VECTOR"
"")
;; 128-bit logical operations insns and split operations
(define_insn_and_split "*and3_internal"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "=")
(and:BOOL_128
(match_operand:BOOL_128 1 "vlogical_operand" "%")
(match_operand:BOOL_128 2 "vlogical_operand" "")))
(clobber (match_scratch:CC 3 ""))]
""
{
if (TARGET_VSX && vsx_register_operand (operands[0], mode))
return "xxland %x0,%x1,%x2";
if (TARGET_ALTIVEC && altivec_register_operand (operands[0], mode))
return "vand %0,%1,%2";
return "#";
}
"reload_completed && int_reg_operand (operands[0], mode)"
[(const_int 0)]
{
rs6000_split_logical (operands, AND, false, false, false, operands[3]);
DONE;
}
[(set (attr "type")
(if_then_else
(match_test "vsx_register_operand (operands[0], mode)")
(const_string "vecsimple")
(const_string "integer")))
(set (attr "length")
(if_then_else
(match_test "vsx_register_operand (operands[0], mode)")
(const_string "4")
(if_then_else
(match_test "TARGET_POWERPC64")
(const_string "8")
(const_string "16"))))])
;; 128-bit IOR/XOR
(define_insn_and_split "*bool3_internal"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "=")
(match_operator:BOOL_128 3 "boolean_or_operator"
[(match_operand:BOOL_128 1 "vlogical_operand" "%")
(match_operand:BOOL_128 2 "vlogical_operand" "")]))]
""
{
if (TARGET_VSX && vsx_register_operand (operands[0], mode))
return "xxl%q3 %x0,%x1,%x2";
if (TARGET_ALTIVEC && altivec_register_operand (operands[0], mode))
return "v%q3 %0,%1,%2";
return "#";
}
"reload_completed && int_reg_operand (operands[0], mode)"
[(const_int 0)]
{
rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false,
NULL_RTX);
DONE;
}
[(set (attr "type")
(if_then_else
(match_test "vsx_register_operand (operands[0], mode)")
(const_string "vecsimple")
(const_string "integer")))
(set (attr "length")
(if_then_else
(match_test "vsx_register_operand (operands[0], mode)")
(const_string "4")
(if_then_else
(match_test "TARGET_POWERPC64")
(const_string "8")
(const_string "16"))))])
;; 128-bit ANDC/ORC
(define_insn_and_split "*boolc3_internal1"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "=")
(match_operator:BOOL_128 3 "boolean_operator"
[(not:BOOL_128
(match_operand:BOOL_128 2 "vlogical_operand" ""))
(match_operand:BOOL_128 1 "vlogical_operand" "")]))]
"TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
{
if (TARGET_VSX && vsx_register_operand (operands[0], mode))
return "xxl%q3 %x0,%x1,%x2";
if (TARGET_ALTIVEC && altivec_register_operand (operands[0], mode))
return "v%q3 %0,%1,%2";
return "#";
}
"(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
&& reload_completed && int_reg_operand (operands[0], mode)"
[(const_int 0)]
{
rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false,
NULL_RTX);
DONE;
}
[(set (attr "type")
(if_then_else
(match_test "vsx_register_operand (operands[0], mode)")
(const_string "vecsimple")
(const_string "integer")))
(set (attr "length")
(if_then_else
(match_test "vsx_register_operand (operands[0], mode)")
(const_string "4")
(if_then_else
(match_test "TARGET_POWERPC64")
(const_string "8")
(const_string "16"))))])
(define_insn_and_split "*boolc3_internal2"
[(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
(match_operator:TI2 3 "boolean_operator"
[(not:TI2
(match_operand:TI2 1 "int_reg_operand" "r,0,r"))
(match_operand:TI2 2 "int_reg_operand" "r,r,0")]))]
"!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
"#"
"reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
[(const_int 0)]
{
rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false,
NULL_RTX);
DONE;
}
[(set_attr "type" "integer")
(set (attr "length")
(if_then_else
(match_test "TARGET_POWERPC64")
(const_string "8")
(const_string "16")))])
;; 128-bit NAND/NOR
(define_insn_and_split "*boolcc3_internal1"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "=")
(match_operator:BOOL_128 3 "boolean_operator"
[(not:BOOL_128
(match_operand:BOOL_128 1 "vlogical_operand" ""))
(not:BOOL_128
(match_operand:BOOL_128 2 "vlogical_operand" ""))]))]
"TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
{
if (TARGET_VSX && vsx_register_operand (operands[0], mode))
return "xxl%q3 %x0,%x1,%x2";
if (TARGET_ALTIVEC && altivec_register_operand (operands[0], mode))
return "v%q3 %0,%1,%2";
return "#";
}
"(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
&& reload_completed && int_reg_operand (operands[0], mode)"
[(const_int 0)]
{
rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true,
NULL_RTX);
DONE;
}
[(set (attr "type")
(if_then_else
(match_test "vsx_register_operand (operands[0], mode)")
(const_string "vecsimple")
(const_string "integer")))
(set (attr "length")
(if_then_else
(match_test "vsx_register_operand (operands[0], mode)")
(const_string "4")
(if_then_else
(match_test "TARGET_POWERPC64")
(const_string "8")
(const_string "16"))))])
(define_insn_and_split "*boolcc3_internal2"
[(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
(match_operator:TI2 3 "boolean_operator"
[(not:TI2
(match_operand:TI2 1 "int_reg_operand" "r,0,r"))
(not:TI2
(match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
"!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
"#"
"reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
[(const_int 0)]
{
rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true,
NULL_RTX);
DONE;
}
[(set_attr "type" "integer")
(set (attr "length")
(if_then_else
(match_test "TARGET_POWERPC64")
(const_string "8")
(const_string "16")))])
;; 128-bit EQV
(define_insn_and_split "*eqv3_internal1"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "=")
(not:BOOL_128
(xor:BOOL_128
(match_operand:BOOL_128 1 "vlogical_operand" "")
(match_operand:BOOL_128 2 "vlogical_operand" ""))))]
"TARGET_P8_VECTOR"
{
if (vsx_register_operand (operands[0], mode))
return "xxleqv %x0,%x1,%x2";
return "#";
}
"TARGET_P8_VECTOR && reload_completed
&& int_reg_operand (operands[0], mode)"
[(const_int 0)]
{
rs6000_split_logical (operands, XOR, true, false, false, NULL_RTX);
DONE;
}
[(set (attr "type")
(if_then_else
(match_test "vsx_register_operand (operands[0], mode)")
(const_string "vecsimple")
(const_string "integer")))
(set (attr "length")
(if_then_else
(match_test "vsx_register_operand (operands[0], mode)")
(const_string "4")
(if_then_else
(match_test "TARGET_POWERPC64")
(const_string "8")
(const_string "16"))))])
(define_insn_and_split "*eqv3_internal2"
[(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
(not:TI2
(xor:TI2
(match_operand:TI2 1 "int_reg_operand" "r,0,r")
(match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
"!TARGET_P8_VECTOR"
"#"
"reload_completed && !TARGET_P8_VECTOR"
[(const_int 0)]
{
rs6000_split_logical (operands, XOR, true, false, false, NULL_RTX);
DONE;
}
[(set_attr "type" "integer")
(set (attr "length")
(if_then_else
(match_test "TARGET_POWERPC64")
(const_string "8")
(const_string "16")))])
;; 128-bit one's complement
(define_insn_and_split "*one_cmpl3_internal"
[(set (match_operand:BOOL_128 0 "vlogical_operand" "=")
(not:BOOL_128
(match_operand:BOOL_128 1 "vlogical_operand" "")))]
""
{
if (TARGET_VSX && vsx_register_operand (operands[0], mode))
return "xxlnor %x0,%x1,%x1";
if (TARGET_ALTIVEC && altivec_register_operand (operands[0], mode))
return "vnor %0,%1,%1";
return "#";
}
"reload_completed && int_reg_operand (operands[0], mode)"
[(const_int 0)]
{
rs6000_split_logical (operands, NOT, false, false, false, NULL_RTX);
DONE;
}
[(set (attr "type")
(if_then_else
(match_test "vsx_register_operand (operands[0], mode)")
(const_string "vecsimple")
(const_string "integer")))
(set (attr "length")
(if_then_else
(match_test "vsx_register_operand (operands[0], mode)")
(const_string "4")
(if_then_else
(match_test "TARGET_POWERPC64")
(const_string "8")
(const_string "16"))))])
;; Now define ways of moving data around.
;; Set up a register with a value from the GOT table
(define_expand "movsi_got"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(unspec:SI [(match_operand:SI 1 "got_operand" "")
(match_dup 2)] UNSPEC_MOVSI_GOT))]
"DEFAULT_ABI == ABI_V4 && flag_pic == 1"
"
{
if (GET_CODE (operands[1]) == CONST)
{
rtx offset = const0_rtx;
HOST_WIDE_INT value;
operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
value = INTVAL (offset);
if (value != 0)
{
rtx tmp = (!can_create_pseudo_p ()
? operands[0]
: gen_reg_rtx (Pmode));
emit_insn (gen_movsi_got (tmp, operands[1]));
emit_insn (gen_addsi3 (operands[0], tmp, offset));
DONE;
}
}
operands[2] = rs6000_got_register (operands[1]);
}")
(define_insn "*movsi_got_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
(match_operand:SI 2 "gpc_reg_operand" "b")]
UNSPEC_MOVSI_GOT))]
"DEFAULT_ABI == ABI_V4 && flag_pic == 1"
"lwz %0,%a1@got(%2)"
[(set_attr "type" "load")])
;; Used by sched, shorten_branches and final when the GOT pseudo reg
;; didn't get allocated to a hard register.
(define_split
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
(match_operand:SI 2 "memory_operand" "")]
UNSPEC_MOVSI_GOT))]
"DEFAULT_ABI == ABI_V4
&& flag_pic == 1
&& (reload_in_progress || reload_completed)"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
UNSPEC_MOVSI_GOT))]
"")
;; For SI, we special-case integers that can't be loaded in one insn. We
;; do the load 16-bits at a time. We could do this by loading from memory,
;; and this is even supposed to be faster, but it is simpler not to get
;; integers in the TOC.
(define_insn "movsi_low"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand 2 "" ""))))]
"TARGET_MACHO && ! TARGET_64BIT"
"lwz %0,lo16(%2)(%1)"
[(set_attr "type" "load")
(set_attr "length" "4")])
(define_insn "*movsi_internal1"
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
(match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
"!TARGET_SINGLE_FPU &&
(gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
"@
mr %0,%1
la %0,%a1
lwz%U1%X1 %0,%1
stw%U0%X0 %1,%0
li %0,%1
lis %0,%v1
#
mf%1 %0
mt%0 %1
mt%0 %1
nop"
[(set_attr_alternative "type"
[(const_string "*")
(const_string "*")
(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_u")
(const_string "load")))
(if_then_else
(match_test "update_indexed_address_mem (operands[0], VOIDmode)")
(const_string "store_ux")
(if_then_else
(match_test "update_address_mem (operands[0], VOIDmode)")
(const_string "store_u")
(const_string "store")))
(const_string "*")
(const_string "*")
(const_string "*")
(const_string "mfjmpr")
(const_string "mtjmpr")
(const_string "*")
(const_string "*")])
(set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
(define_insn "*movsi_internal1_single"
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
(match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
"TARGET_SINGLE_FPU &&
(gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
"@
mr %0,%1
la %0,%a1
lwz%U1%X1 %0,%1
stw%U0%X0 %1,%0
li %0,%1
lis %0,%v1
#
mf%1 %0
mt%0 %1
mt%0 %1
nop
stfs%U0%X0 %1,%0
lfs%U1%X1 %0,%1"
[(set_attr_alternative "type"
[(const_string "*")
(const_string "*")
(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_u")
(const_string "load")))
(if_then_else
(match_test "update_indexed_address_mem (operands[0], VOIDmode)")
(const_string "store_ux")
(if_then_else
(match_test "update_address_mem (operands[0], VOIDmode)")
(const_string "store_u")
(const_string "store")))
(const_string "*")
(const_string "*")
(const_string "*")
(const_string "mfjmpr")
(const_string "mtjmpr")
(const_string "*")
(const_string "*")
(if_then_else
(match_test "update_indexed_address_mem (operands[0], VOIDmode)")
(const_string "fpstore_ux")
(if_then_else
(match_test "update_address_mem (operands[0], VOIDmode)")
(const_string "fpstore_u")
(const_string "fpstore")))
(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "fpload_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "fpload_u")
(const_string "fpload")))])
(set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
;; Split a load of a large constant into the appropriate two-insn
;; sequence.
(define_split
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(match_operand:SI 1 "const_int_operand" ""))]
"(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
&& (INTVAL (operands[1]) & 0xffff) != 0"
[(set (match_dup 0)
(match_dup 2))
(set (match_dup 0)
(ior:SI (match_dup 0)
(match_dup 3)))]
"
{ rtx tem = rs6000_emit_set_const (operands[0], SImode, operands[1], 2);
if (tem == operands[0])
DONE;
else
FAIL;
}")
(define_insn "*mov_internal2"
[(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
(compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
(const_int 0)))
(set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
""
"@
cmpi %2,%0,0
mr. %0,%1
#"
[(set_attr "type" "cmp,fast_compare,cmp")
(set_attr "length" "4,4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
(compare:CC (match_operand:P 1 "gpc_reg_operand" "")
(const_int 0)))
(set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
"reload_completed"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
(define_insn "*movhi_internal"
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
(match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
"gpc_reg_operand (operands[0], HImode)
|| gpc_reg_operand (operands[1], HImode)"
"@
mr %0,%1
lhz%U1%X1 %0,%1
sth%U0%X0 %1,%0
li %0,%w1
mf%1 %0
mt%0 %1
nop"
[(set_attr_alternative "type"
[(const_string "*")
(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_u")
(const_string "load")))
(if_then_else
(match_test "update_indexed_address_mem (operands[0], VOIDmode)")
(const_string "store_ux")
(if_then_else
(match_test "update_address_mem (operands[0], VOIDmode)")
(const_string "store_u")
(const_string "store")))
(const_string "*")
(const_string "mfjmpr")
(const_string "mtjmpr")
(const_string "*")])])
(define_expand "mov"
[(set (match_operand:INT 0 "general_operand" "")
(match_operand:INT 1 "any_operand" ""))]
""
"{ rs6000_emit_move (operands[0], operands[1], mode); DONE; }")
(define_insn "*movqi_internal"
[(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
(match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
"gpc_reg_operand (operands[0], QImode)
|| gpc_reg_operand (operands[1], QImode)"
"@
mr %0,%1
lbz%U1%X1 %0,%1
stb%U0%X0 %1,%0
li %0,%1
mf%1 %0
mt%0 %1
nop"
[(set_attr_alternative "type"
[(const_string "*")
(if_then_else
(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
(const_string "load_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_u")
(const_string "load")))
(if_then_else
(match_test "update_indexed_address_mem (operands[0], VOIDmode)")
(const_string "store_ux")
(if_then_else
(match_test "update_address_mem (operands[0], VOIDmode)")
(const_string "store_u")
(const_string "store")))
(const_string "*")
(const_string "mfjmpr")
(const_string "mtjmpr")
(const_string "*")])])
;; Here is how to move condition codes around. When we store CC data in
;; an integer register or memory, we store just the high-order 4 bits.
;; This lets us not shift in the most common case of CR0.
(define_expand "movcc"
[(set (match_operand:CC 0 "nonimmediate_operand" "")
(match_operand:CC 1 "nonimmediate_operand" ""))]
""
"")
(define_insn "*movcc_internal1"
[(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
(match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
"register_operand (operands[0], CCmode)
|| register_operand (operands[1], CCmode)"
"@
mcrf %0,%1
mtcrf 128,%1
rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
crxor %0,%0,%0
mfcr %0%Q1
mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
mr %0,%1
li %0,%1
mf%1 %0
mt%0 %1
lwz%U1%X1 %0,%1
stw%U0%X0 %1,%0"
[(set (attr "type")
(cond [(eq_attr "alternative" "0,3")
(const_string "cr_logical")
(eq_attr "alternative" "1,2")
(const_string "mtcr")
(eq_attr "alternative" "6,7")
(const_string "integer")
(eq_attr "alternative" "8")
(const_string "mfjmpr")
(eq_attr "alternative" "9")
(const_string "mtjmpr")
(eq_attr "alternative" "10")
(if_then_else
(match_test "update_indexed_address_mem (operands[1],
VOIDmode)")
(const_string "load_ux")
(if_then_else
(match_test "update_address_mem (operands[1], VOIDmode)")
(const_string "load_u")
(const_string "load")))
(eq_attr "alternative" "11")
(if_then_else
(match_test "update_indexed_address_mem (operands[0],
VOIDmode)")
(const_string "store_ux")
(if_then_else
(match_test "update_address_mem (operands[0], VOIDmode)")
(const_string "store_u")
(const_string "store")))
(match_test "TARGET_MFCRF")
(const_string "mfcrf")
]
(const_string "mfcr")))
(set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
;; For floating-point, we normally deal with the floating-point registers
;; unless -msoft-float is used. The sole exception is that parameter passing
;; can produce floating-point values in fixed-point registers. Unless the
;; value is a simple constant or already in memory, we deal with this by
;; allocating memory and copying the value explicitly via that memory location.
;; Move 32-bit binary/decimal floating point
(define_expand "mov"
[(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
(match_operand:FMOVE32 1 "any_operand" ""))]
"