;; GCC machine description for IA-32 and x86-64.
;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
;; Free Software Foundation, Inc.
;; Mostly by William Schelter.
;; x86_64 support added by Jan Hubicka
UNSPEC_INDNTPOFF
UNSPEC_PLTOFF
UNSPEC_MACHOPIC_OFFSET
+ UNSPEC_PCREL
;; Prologue support
UNSPEC_STACK_ALLOC
UNSPEC_SET_RIP
UNSPEC_SET_GOT_OFFSET
UNSPEC_MEMORY_BLOCKAGE
+ UNSPEC_STACK_CHECK
;; TLS support
UNSPEC_TP
UNSPEC_TLS_GD
UNSPEC_TLS_LD_BASE
UNSPEC_TLSDESC
+ UNSPEC_TLS_IE_SUN
;; Other random patterns
UNSPEC_SCAS
UNSPEC_LD_MPIC ; load_macho_picbase
UNSPEC_TRUNC_NOOP
UNSPEC_DIV_ALREADY_SPLIT
- UNSPEC_NOPS
+ UNSPEC_CALL_NEEDS_VZEROUPPER
;; For SSE/MMX support:
UNSPEC_FIX_NOTRUNC
UNSPEC_PCMPISTR
;; For FMA4 support
- UNSPEC_FMA4_INTRINSIC
- UNSPEC_FMA4_FMADDSUB
- UNSPEC_FMA4_FMSUBADD
+ UNSPEC_FMADDSUB
UNSPEC_XOP_UNSIGNED_CMP
UNSPEC_XOP_TRUEFALSE
UNSPEC_XOP_PERMUTE
UNSPEC_VTESTP
UNSPEC_VCVTPH2PS
UNSPEC_VCVTPS2PH
+
+ ;; For BMI support
+ UNSPEC_BEXTR
+
+ ;; For RDRAND support
+ UNSPEC_RDRAND
])
(define_c_enum "unspecv" [
UNSPECV_LOCK
UNSPECV_PROLOGUE_USE
UNSPECV_CLD
+ UNSPECV_NOPS
UNSPECV_VZEROALL
UNSPECV_VZEROUPPER
UNSPECV_RDTSC
UNSPECV_RDGSBASE
UNSPECV_WRFSBASE
UNSPECV_WRGSBASE
- UNSPECV_RDRAND
+ UNSPECV_SPLIT_STACK_RETURN
])
+;; Constants to represent rounding modes in the ROUND instruction
+(define_constants
+ [(ROUND_FLOOR 0x1)
+ (ROUND_CEIL 0x2)
+ (ROUND_TRUNC 0x3)
+ (ROUND_MXCSR 0x4)
+ (ROUND_NO_EXC 0x8)
+ ])
+
;; Constants to represent pcomtrue/pcomfalse variants
(define_constants
[(PCOM_FALSE 0)
\f
;; Processor type.
-(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
- generic64,amdfam10,bdver1"
+(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
+ atom,generic64,amdfam10,bdver1,btver1"
(const (symbol_ref "ix86_schedule")))
;; A basic instruction type. Refinements due to arguments to be
;; Set when REX opcode prefix is used.
(define_attr "prefix_rex" ""
- (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
+ (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
(const_int 0)
(and (eq_attr "mode" "DI")
(and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
;; Mapping of unsigned max and min
(define_code_iterator umaxmin [umax umin])
-;; Mapping of signed/unsigned max and min
-(define_code_iterator maxmin [smax smin umax umin])
-
;; Base name for integer and FP insn mnemonic
(define_code_attr maxmin_int [(smax "maxs") (smin "mins")
(umax "maxu") (umin "minu")])
(include "ppro.md")
(include "k6.md")
(include "athlon.md")
+(include "bdver1.md")
(include "geode.md")
(include "atom.md")
+(include "core2.md")
\f
;; Operand and operator predicates and constraints
[(set_attr "length" "1")
(set_attr "athlon_decode" "vector")
(set_attr "amdfam10_decode" "direct")
+ (set_attr "bdver1_decode" "direct")
(set_attr "mode" "SI")])
;; Pentium Pro can do steps 1 through 3 in one go.
]
(const_string "0")))
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "direct")])
+ (set_attr "amdfam10_decode" "direct")
+ (set_attr "bdver1_decode" "double")])
(define_insn "*cmpfp_i_sse"
[(set (reg:CCFP FLAGS_REG)
(const_string "1")
(const_string "0")))
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "direct")])
+ (set_attr "amdfam10_decode" "direct")
+ (set_attr "bdver1_decode" "double")])
(define_insn "*cmpfp_i_i387"
[(set (reg:CCFP FLAGS_REG)
]
(const_string "XF")))
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "direct")])
+ (set_attr "amdfam10_decode" "direct")
+ (set_attr "bdver1_decode" "double")])
(define_insn "*cmpfp_iu_mixed"
[(set (reg:CCFPU FLAGS_REG)
]
(const_string "0")))
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "direct")])
+ (set_attr "amdfam10_decode" "direct")
+ (set_attr "bdver1_decode" "double")])
(define_insn "*cmpfp_iu_sse"
[(set (reg:CCFPU FLAGS_REG)
(const_string "1")
(const_string "0")))
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "direct")])
+ (set_attr "amdfam10_decode" "direct")
+ (set_attr "bdver1_decode" "double")])
(define_insn "*cmpfp_iu_387"
[(set (reg:CCFPU FLAGS_REG)
]
(const_string "XF")))
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "direct")])
+ (set_attr "amdfam10_decode" "direct")
+ (set_attr "bdver1_decode" "direct")])
\f
;; Push/pop instructions.
+(define_insn "*push<mode>2"
+ [(set (match_operand:DWI 0 "push_operand" "=<")
+ (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
+ ""
+ "#")
+
+(define_split
+ [(set (match_operand:TI 0 "push_operand" "")
+ (match_operand:TI 1 "general_operand" ""))]
+ "TARGET_64BIT && reload_completed
+ && !SSE_REG_P (operands[1])"
+ [(const_int 0)]
+ "ix86_split_long_move (operands); DONE;")
+
(define_insn "*pushdi2_rex64"
[(set (match_operand:DI 0 "push_operand" "=<,!<")
(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2) (match_dup 3))]
{
- split_di (&operands[1], 1, &operands[2], &operands[3]);
+ split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
operands[1] = gen_lowpart (DImode, operands[2]);
operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2) (match_dup 3))]
{
- split_di (&operands[1], 1, &operands[2], &operands[3]);
+ split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
operands[1] = gen_lowpart (DImode, operands[2]);
operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
GEN_INT (4)));
})
-(define_insn "*pushdi2"
- [(set (match_operand:DI 0 "push_operand" "=<")
- (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
- "!TARGET_64BIT"
- "#")
-
(define_split
[(set (match_operand:DI 0 "push_operand" "")
(match_operand:DI 1 "general_operand" ""))]
&& !x86_64_immediate_operand (operands[1], DImode) && 1"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
- "split_di (&operands[0], 2, &operands[2], &operands[4]);")
+ "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
(define_split
[(set (match_operand:DI 0 "memory_operand" "")
&& !x86_64_immediate_operand (operands[1], DImode)"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
- "split_di (&operands[0], 2, &operands[2], &operands[4]);")
+ "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
(define_insn "*movdi_internal"
[(set (match_operand:DI 0 "nonimmediate_operand"
(set_attr "mode" "<MODE>")
(set_attr "pent_pair" "np")
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "double")])
+ (set_attr "amdfam10_decode" "double")
+ (set_attr "bdver1_decode" "double")])
(define_insn "*swap<mode>_1"
[(set (match_operand:SWI12 0 "register_operand" "+r")
(set_attr "mode" "SI")
(set_attr "pent_pair" "np")
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "double")])
+ (set_attr "amdfam10_decode" "double")
+ (set_attr "bdver1_decode" "double")])
;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
;; is disabled for AMDFAM10
(zero_extend:DI (match_dup 0)))]
"TARGET_64BIT"
[(set (match_dup 4) (const_int 0))]
- "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+ "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
;; %%% Kill me once multi-word ops are sane.
(define_insn "zero_extendsidi2_1"
"!TARGET_64BIT && reload_completed
&& true_regnum (operands[0]) == true_regnum (operands[1])"
[(set (match_dup 4) (const_int 0))]
- "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+ "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
(define_split
[(set (match_operand:DI 0 "nonimmediate_operand" "")
&& !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
[(set (match_dup 3) (match_dup 1))
(set (match_dup 4) (const_int 0))]
- "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+ "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
(define_insn "zero_extend<mode>di2"
[(set (match_operand:DI 0 "register_operand" "=r")
(parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
(clobber (reg:CC FLAGS_REG))])
(set (match_dup 4) (match_dup 1))]
- "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+ "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
;; Extend to memory case when source register does not die.
(define_split
"reload_completed"
[(const_int 0)]
{
- split_di (&operands[0], 1, &operands[3], &operands[4]);
+ split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
emit_move_insn (operands[3], operands[1]);
"reload_completed"
[(const_int 0)]
{
- split_di (&operands[0], 1, &operands[3], &operands[4]);
+ split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
if (true_regnum (operands[3]) != true_regnum (operands[1]))
emit_move_insn (operands[3], operands[1]);
real_ldexp (&TWO31r, &dconst1, 31);
two31 = const_double_from_real_value (TWO31r, mode);
- two31 = ix86_build_const_vector (mode, true, two31);
+ two31 = ix86_build_const_vector (vecmode, true, two31);
operands[2] = force_reg (vecmode, two31);
})
(set_attr "prefix_rex" "1")
(set_attr "mode" "<MODE>")
(set_attr "athlon_decode" "double,vector")
- (set_attr "amdfam10_decode" "double,double")])
+ (set_attr "amdfam10_decode" "double,double")
+ (set_attr "bdver1_decode" "double,double")])
(define_insn "fix_trunc<mode>si_sse"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODE>")
(set_attr "athlon_decode" "double,vector")
- (set_attr "amdfam10_decode" "double,double")])
+ (set_attr "amdfam10_decode" "double,double")
+ (set_attr "bdver1_decode" "double,double")])
;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
(define_peephole2
[(set (attr "length")
(symbol_ref "ix86_attr_length_address_default (insn) + 2"))
(set_attr "mode" "HI")
- (set_attr "unit" "i387")])
+ (set_attr "unit" "i387")
+ (set_attr "bdver1_decode" "vector")])
(define_insn "x86_fldcw_1"
[(set (reg:HI FPCR_REG)
(set_attr "mode" "HI")
(set_attr "unit" "i387")
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "vector")])
+ (set_attr "amdfam10_decode" "vector")
+ (set_attr "bdver1_decode" "vector")])
\f
;; Conversion between fixed point and floating point.
(set_attr "unit" "*,i387,*,*,*")
(set_attr "athlon_decode" "*,*,double,direct,double")
(set_attr "amdfam10_decode" "*,*,vector,double,double")
+ (set_attr "bdver1_decode" "*,*,double,direct,double")
(set_attr "fp_int_src" "true")])
(define_insn "*floatsi<mode>2_vector_mixed"
(set_attr "unit" "i387,*")
(set_attr "athlon_decode" "*,direct")
(set_attr "amdfam10_decode" "*,double")
+ (set_attr "bdver1_decode" "*,direct")
(set_attr "fp_int_src" "true")])
(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
(set_attr "unit" "*,i387,*,*")
(set_attr "athlon_decode" "*,*,double,direct")
(set_attr "amdfam10_decode" "*,*,vector,double")
+ (set_attr "bdver1_decode" "*,*,double,direct")
(set_attr "fp_int_src" "true")])
(define_split
(set_attr "unit" "i387,*,*")
(set_attr "athlon_decode" "*,double,direct")
(set_attr "amdfam10_decode" "*,vector,double")
+ (set_attr "bdver1_decode" "*,double,direct")
(set_attr "fp_int_src" "true")])
(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
(const_string "*")))
(set_attr "athlon_decode" "*,direct")
(set_attr "amdfam10_decode" "*,double")
+ (set_attr "bdver1_decode" "*,direct")
(set_attr "fp_int_src" "true")])
(define_insn "*floatsi<mode>2_vector_sse_with_temp"
(set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
(set_attr "athlon_decode" "double,direct,double")
(set_attr "amdfam10_decode" "vector,double,double")
+ (set_attr "bdver1_decode" "double,direct,double")
(set_attr "fp_int_src" "true")])
(define_insn "*floatsi<mode>2_vector_sse"
(set_attr "mode" "<MODE>")
(set_attr "athlon_decode" "direct")
(set_attr "amdfam10_decode" "double")
+ (set_attr "bdver1_decode" "direct")
(set_attr "fp_int_src" "true")])
(define_split
(set_attr "mode" "<MODEF:MODE>")
(set_attr "athlon_decode" "double,direct")
(set_attr "amdfam10_decode" "vector,double")
+ (set_attr "bdver1_decode" "double,direct")
(set_attr "fp_int_src" "true")])
(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
(const_string "*")))
(set_attr "athlon_decode" "double,direct")
(set_attr "amdfam10_decode" "vector,double")
+ (set_attr "bdver1_decode" "double,direct")
(set_attr "fp_int_src" "true")])
(define_split
(const_string "*")))
(set_attr "athlon_decode" "direct")
(set_attr "amdfam10_decode" "double")
+ (set_attr "bdver1_decode" "direct")
(set_attr "fp_int_src" "true")])
(define_split
(ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
(match_dup 5))))
(clobber (reg:CC FLAGS_REG))])]
- "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
+ "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
(define_insn "*add<mode>3_cc"
[(set (reg:CC FLAGS_REG)
(ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
(match_dup 5))))
(clobber (reg:CC FLAGS_REG))])]
- "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
+ "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
(define_insn "*sub<mode>_1"
[(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
;; IMUL reg32/64, mem32/64, imm32 VectorPath
;; IMUL reg32/64, reg32/64 Direct
;; IMUL reg32/64, mem32/64 Direct
+;;
+;; On BDVER1, all above IMULs use DirectPath
(define_insn "*mul<mode>3_1"
[(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
(match_operand 1 "memory_operand" ""))
(const_string "vector")]
(const_string "direct")))
+ (set_attr "bdver1_decode" "direct")
(set_attr "mode" "<MODE>")])
(define_insn "*mulsi3_1_zext"
(match_operand 1 "memory_operand" ""))
(const_string "vector")]
(const_string "direct")))
+ (set_attr "bdver1_decode" "direct")
(set_attr "mode" "SI")])
;; On AMDFAM10
;; IMUL reg16, mem16, imm16 VectorPath
;; IMUL reg16, reg16 Direct
;; IMUL reg16, mem16 Direct
+;;
+;; On BDVER1, all HI MULs use DoublePath
(define_insn "*mulhi3_1"
[(set (match_operand:HI 0 "register_operand" "=r,r,r")
(cond [(eq_attr "alternative" "0,1")
(const_string "vector")]
(const_string "direct")))
+ (set_attr "bdver1_decode" "double")
(set_attr "mode" "HI")])
-;;On AMDFAM10
+;;On AMDFAM10 and BDVER1
;; MUL reg8 Direct
;; MUL mem8 Direct
(const_string "vector")
(const_string "direct")))
(set_attr "amdfam10_decode" "direct")
+ (set_attr "bdver1_decode" "direct")
(set_attr "mode" "QI")])
(define_expand "<u>mul<mode><dwi>3"
(const_string "vector")
(const_string "double")))
(set_attr "amdfam10_decode" "double")
+ (set_attr "bdver1_decode" "direct")
(set_attr "mode" "<MODE>")])
(define_insn "*<u>mulqihi3_1"
(const_string "vector")
(const_string "direct")))
(set_attr "amdfam10_decode" "direct")
+ (set_attr "bdver1_decode" "direct")
(set_attr "mode" "QI")])
(define_expand "<s>mul<mode>3_highpart"
(const_string "vector")
(const_string "double")))
(set_attr "amdfam10_decode" "double")
+ (set_attr "bdver1_decode" "direct")
(set_attr "mode" "DI")])
(define_insn "*<s>mulsi3_highpart_1"
(const_string "vector")
(const_string "double")))
(set_attr "amdfam10_decode" "double")
+ (set_attr "bdver1_decode" "direct")
(set_attr "mode" "SI")])
(define_insn "*<s>mulsi3_highpart_zext"
(const_string "vector")
(const_string "double")))
(set_attr "amdfam10_decode" "double")
+ (set_attr "bdver1_decode" "direct")
(set_attr "mode" "SI")])
;; The patterns that match these are at the end of this file.
[(set (match_dup 2)
(neg:DWIH (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
- "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
+ "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
(define_insn "*neg<mode>2_1"
[(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
(set_attr "prefix_0f" "1")
(set_attr "mode" "DI")
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "vector")])
+ (set_attr "amdfam10_decode" "vector")
+ (set_attr "bdver1_decode" "vector")])
(define_insn "x86_shld"
[(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
(set_attr "mode" "SI")
(set_attr "pent_pair" "np")
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "vector")])
+ (set_attr "amdfam10_decode" "vector")
+ (set_attr "bdver1_decode" "vector")])
(define_expand "x86_shift<mode>_adj_1"
[(set (reg:CCZ FLAGS_REG)
DONE;
})
+;; Avoid useless masking of count operand.
+(define_insn_and_split "*ashl<mode>3_mask"
+ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
+ (ashift:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "0")
+ (subreg:QI
+ (and:SI
+ (match_operand:SI 2 "nonimmediate_operand" "c")
+ (match_operand:SI 3 "const_int_operand" "n")) 0)))
+ (clobber (reg:CC FLAGS_REG))]
+ "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
+ && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
+ == GET_MODE_BITSIZE (<MODE>mode)-1"
+ "#"
+ "&& 1"
+ [(parallel [(set (match_dup 0)
+ (ashift:SWI48 (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC FLAGS_REG))])]
+{
+ if (can_create_pseudo_p ())
+ operands [2] = force_reg (SImode, operands[2]);
+
+ operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
+}
+ [(set_attr "type" "ishift")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "*ashl<mode>3_1"
[(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
(define_insn "*ashl<mode>3_cconly"
[(set (reg FLAGS_REG)
(compare
- (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
+ (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
(match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
(const_int 0)))
(clobber (match_scratch:SWI 0 "=<r>"))]
|| (operands[2] == const1_rtx
&& (TARGET_SHIFT1
|| TARGET_DOUBLE_WITH_ADD)))
- && ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
+ && ix86_match_ccmode (insn, CCGOCmode)"
{
switch (get_attr_type (insn))
{
""
"ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
+;; Avoid useless masking of count operand.
+(define_insn_and_split "*<shiftrt_insn><mode>3_mask"
+ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
+ (any_shiftrt:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "0")
+ (subreg:QI
+ (and:SI
+ (match_operand:SI 2 "nonimmediate_operand" "c")
+ (match_operand:SI 3 "const_int_operand" "n")) 0)))
+ (clobber (reg:CC FLAGS_REG))]
+ "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
+ && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
+ == GET_MODE_BITSIZE (<MODE>mode)-1"
+ "#"
+ "&& 1"
+ [(parallel [(set (match_dup 0)
+ (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC FLAGS_REG))])]
+{
+ if (can_create_pseudo_p ())
+ operands [2] = force_reg (SImode, operands[2]);
+
+ operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
+}
+ [(set_attr "type" "ishift")
+ (set_attr "mode" "<MODE>")])
+
(define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
[(set (match_operand:DWI 0 "register_operand" "=r")
(any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
(set_attr "prefix_0f" "1")
(set_attr "mode" "DI")
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "vector")])
+ (set_attr "amdfam10_decode" "vector")
+ (set_attr "bdver1_decode" "vector")])
(define_insn "x86_shrd"
[(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
(set_attr "mode" "SI")
(set_attr "pent_pair" "np")
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "vector")])
+ (set_attr "amdfam10_decode" "vector")
+ (set_attr "bdver1_decode" "vector")])
(define_insn "ashrdi3_cvt"
[(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
[(set (reg FLAGS_REG)
(compare
(any_shiftrt:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "0")
+ (match_operand:SWI 1 "register_operand" "0")
(match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
(const_int 0)))
(clobber (match_scratch:SWI 0 "=<r>"))]
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& TARGET_SHIFT1))
- && ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+ && ix86_match_ccmode (insn, CCGOCmode)"
{
if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
""
"ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
+;; Avoid useless masking of count operand.
+(define_insn_and_split "*<rotate_insn><mode>3_mask"
+ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
+ (any_rotate:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "0")
+ (subreg:QI
+ (and:SI
+ (match_operand:SI 2 "nonimmediate_operand" "c")
+ (match_operand:SI 3 "const_int_operand" "n")) 0)))
+ (clobber (reg:CC FLAGS_REG))]
+ "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
+ && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
+ == GET_MODE_BITSIZE (<MODE>mode)-1"
+ "#"
+ "&& 1"
+ [(parallel [(set (match_dup 0)
+ (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC FLAGS_REG))])]
+{
+ if (can_create_pseudo_p ())
+ operands [2] = force_reg (SImode, operands[2]);
+
+ operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
+}
+ [(set_attr "type" "rotate")
+ (set_attr "mode" "<MODE>")])
+
;; Implement rotation using two double-precision
;; shift instructions and a scratch register.
{
operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
- split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
+ split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
})
(define_insn_and_split "ix86_rotr<dwi>3_doubleword"
{
operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
- split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
+ split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
})
(define_insn "*<rotate_insn><mode>3_1"
DONE;
})
+(define_insn_and_split "*call_pop_0_vzeroupper"
+ [(parallel
+ [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
+ (match_operand:SI 1 "" ""))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 2 "immediate_operand" "")))])
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
+ [(set_attr "type" "call")])
+
(define_insn "*call_pop_0"
[(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
(match_operand:SI 1 "" ""))
}
[(set_attr "type" "call")])
+(define_insn_and_split "*call_pop_1_vzeroupper"
+ [(parallel
+ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
+ (match_operand:SI 1 "" ""))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 2 "immediate_operand" "i")))])
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
+ [(set_attr "type" "call")])
+
(define_insn "*call_pop_1"
[(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
(match_operand:SI 1 "" ""))
}
[(set_attr "type" "call")])
+(define_insn_and_split "*sibcall_pop_1_vzeroupper"
+ [(parallel
+ [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
+ (match_operand:SI 1 "" ""))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 2 "immediate_operand" "i,i")))])
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
+ [(set_attr "type" "call")])
+
(define_insn "*sibcall_pop_1"
[(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
(match_operand:SI 1 "" ""))
DONE;
})
+(define_insn_and_split "*call_0_vzeroupper"
+ [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
+ (match_operand 1 "" ""))
+ (unspec [(match_operand 2 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
+ [(set_attr "type" "call")])
+
(define_insn "*call_0"
[(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
(match_operand 1 "" ""))]
""
-{
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P0";
- else
- return "call\t%P0";
-}
+ { return ix86_output_call_insn (insn, operands[0], 0); }
+ [(set_attr "type" "call")])
+
+(define_insn_and_split "*call_1_vzeroupper"
+ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
+ (match_operand 1 "" ""))
+ (unspec [(match_operand 2 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
[(set_attr "type" "call")])
(define_insn "*call_1"
[(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
(match_operand 1 "" ""))]
"!TARGET_64BIT && !SIBLING_CALL_P (insn)"
-{
- if (constant_call_address_operand (operands[0], Pmode))
- return "call\t%P0";
- return "call\t%A0";
-}
+ { return ix86_output_call_insn (insn, operands[0], 0); }
+ [(set_attr "type" "call")])
+
+(define_insn_and_split "*sibcall_1_vzeroupper"
+ [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
+ (match_operand 1 "" ""))
+ (unspec [(match_operand 2 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
[(set_attr "type" "call")])
(define_insn "*sibcall_1"
[(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
(match_operand 1 "" ""))]
"!TARGET_64BIT && SIBLING_CALL_P (insn)"
- "@
- jmp\t%P0
- jmp\t%A0"
+ { return ix86_output_call_insn (insn, operands[0], 0); }
+ [(set_attr "type" "call")])
+
+(define_insn_and_split "*call_1_rex64_vzeroupper"
+ [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
+ (match_operand 1 "" ""))
+ (unspec [(match_operand 2 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
+ && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
[(set_attr "type" "call")])
(define_insn "*call_1_rex64"
(match_operand 1 "" ""))]
"TARGET_64BIT && !SIBLING_CALL_P (insn)
&& ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
-{
- if (constant_call_address_operand (operands[0], Pmode))
- return "call\t%P0";
- return "call\t%A0";
-}
+ { return ix86_output_call_insn (insn, operands[0], 0); }
+ [(set_attr "type" "call")])
+
+(define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
+ [(parallel
+ [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
+ (match_operand 1 "" ""))
+ (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
+ (clobber (reg:TI XMM6_REG))
+ (clobber (reg:TI XMM7_REG))
+ (clobber (reg:TI XMM8_REG))
+ (clobber (reg:TI XMM9_REG))
+ (clobber (reg:TI XMM10_REG))
+ (clobber (reg:TI XMM11_REG))
+ (clobber (reg:TI XMM12_REG))
+ (clobber (reg:TI XMM13_REG))
+ (clobber (reg:TI XMM14_REG))
+ (clobber (reg:TI XMM15_REG))
+ (clobber (reg:DI SI_REG))
+ (clobber (reg:DI DI_REG))])
+ (unspec [(match_operand 2 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
[(set_attr "type" "call")])
(define_insn "*call_1_rex64_ms_sysv"
(clobber (reg:DI SI_REG))
(clobber (reg:DI DI_REG))]
"TARGET_64BIT && !SIBLING_CALL_P (insn)"
-{
- if (constant_call_address_operand (operands[0], Pmode))
- return "call\t%P0";
- return "call\t%A0";
-}
+ { return ix86_output_call_insn (insn, operands[0], 0); }
+ [(set_attr "type" "call")])
+
+(define_insn_and_split "*call_1_rex64_large_vzeroupper"
+ [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
+ (match_operand 1 "" ""))
+ (unspec [(match_operand 2 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
[(set_attr "type" "call")])
(define_insn "*call_1_rex64_large"
[(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
(match_operand 1 "" ""))]
"TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "call\t%A0"
+ { return ix86_output_call_insn (insn, operands[0], 0); }
+ [(set_attr "type" "call")])
+
+(define_insn_and_split "*sibcall_1_rex64_vzeroupper"
+ [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
+ (match_operand 1 "" ""))
+ (unspec [(match_operand 2 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
[(set_attr "type" "call")])
(define_insn "*sibcall_1_rex64"
[(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
(match_operand 1 "" ""))]
"TARGET_64BIT && SIBLING_CALL_P (insn)"
- "@
- jmp\t%P0
- jmp\t%A0"
+ { return ix86_output_call_insn (insn, operands[0], 0); }
[(set_attr "type" "call")])
;; Call subroutine, returning value in operand 0
;; Generate nops. Operand 0 is the number of nops, up to 8.
(define_insn "nops"
- [(unspec [(match_operand 0 "const_int_operand" "")]
- UNSPEC_NOPS)]
+ [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
+ UNSPECV_NOPS)]
"reload_completed"
{
- switch (INTVAL (operands[0]))
- {
- case 1:
- return "nop";
- case 2:
- return "nop; nop";
- case 3:
- return "nop; nop; nop";
- case 4:
- return "nop; nop; nop; nop";
- case 5:
- return "nop; nop; nop; nop; nop";
- case 6:
- return "nop; nop; nop; nop; nop; nop";
- case 7:
- return "nop; nop; nop; nop; nop; nop; nop";
- case 8:
- return "nop; nop; nop; nop; nop; nop; nop; nop";
- default:
- gcc_unreachable ();
- break;
- }
+ int num = INTVAL (operands[0]);
+
+ gcc_assert (num >= 1 && num <= 8);
+
+ while (num--)
+ fputs ("\tnop\n", asm_out_file);
+
+ return "";
}
[(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
(set_attr "length_immediate" "0")
(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT"
- { return output_set_got (operands[0], NULL_RTX); }
+ "* return output_set_got (operands[0], NULL_RTX);"
[(set_attr "type" "multi")
(set_attr "length" "12")])
UNSPEC_SET_GOT))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT"
- { return output_set_got (operands[0], operands[1]); }
+ "* return output_set_got (operands[0], operands[1]);"
[(set_attr "type" "multi")
(set_attr "length" "12")])
"leave"
[(set_attr "type" "leave")])
\f
+;; Handle -fsplit-stack.
+
+(define_expand "split_stack_prologue"
+ [(const_int 0)]
+ ""
+{
+ ix86_expand_split_stack_prologue ();
+ DONE;
+})
+
+;; In order to support the call/return predictor, we use a return
+;; instruction which the middle-end doesn't see.
+(define_insn "split_stack_return"
+ [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
+ UNSPECV_SPLIT_STACK_RETURN)]
+ ""
+{
+ if (operands[0] == const0_rtx)
+ return "ret";
+ else
+ return "ret\t%0";
+}
+ [(set_attr "atom_unit" "jeu")
+ (set_attr "modrm" "0")
+ (set (attr "length")
+ (if_then_else (match_operand:SI 0 "const0_operand" "")
+ (const_int 1)
+ (const_int 3)))
+ (set (attr "length_immediate")
+ (if_then_else (match_operand:SI 0 "const0_operand" "")
+ (const_int 0)
+ (const_int 2)))])
+
+;; If there are operand 0 bytes available on the stack, jump to
+;; operand 1.
+
+(define_expand "split_stack_space_check"
+ [(set (pc) (if_then_else
+ (ltu (minus (reg SP_REG)
+ (match_operand 0 "register_operand" ""))
+ (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
+ (label_ref (match_operand 1 "" ""))
+ (pc)))]
+ ""
+{
+ rtx reg, size, limit;
+
+ reg = gen_reg_rtx (Pmode);
+ size = force_reg (Pmode, operands[0]);
+ emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
+ limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_STACK_CHECK);
+ limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
+ ix86_expand_branch (GEU, reg, limit, operands[1]);
+
+ DONE;
+})
+\f
;; Bit manipulation instructions.
(define_expand "ffs<mode>2"
(set_attr "mode" "<MODE>")])
(define_insn "ctz<mode>2"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
+ [(set (match_operand:SWI248 0 "register_operand" "=r")
+ (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
(clobber (reg:CC FLAGS_REG))]
""
- "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
+{
+ if (TARGET_BMI)
+ return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
+ else
+ return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
+}
[(set_attr "type" "alu1")
(set_attr "prefix_0f" "1")
+ (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
(set_attr "mode" "<MODE>")])
(define_expand "clz<mode>2"
[(set (match_operand:SWI248 0 "register_operand" "=r")
(clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_ABM"
+ "TARGET_ABM || TARGET_BMI"
"lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
[(set_attr "prefix_rep" "1")
(set_attr "type" "bitmanip")
(set_attr "mode" "<MODE>")])
-(define_insn "bsr_rex64"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (const_int 63)
- (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
+;; BMI instructions.
+(define_insn "*bmi_andn_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (and:SWI48
+ (not:SWI48
+ (match_operand:SWI48 1 "register_operand" "r"))
+ (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "bsr{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "DI")])
+ "TARGET_BMI"
+ "andn\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
-(define_insn "bsr"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (const_int 31)
- (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
+(define_insn "bmi_bextr_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (match_operand:SWI48 2 "register_operand" "r")]
+ UNSPEC_BEXTR))
(clobber (reg:CC FLAGS_REG))]
- ""
- "bsr{l}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "SI")])
+ "TARGET_BMI"
+ "bextr\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
-(define_insn "*bsrhi"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (minus:HI (const_int 15)
- (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
+(define_insn "*bmi_blsi_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (and:SWI48
+ (neg:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
+ (match_dup 1)))
(clobber (reg:CC FLAGS_REG))]
- ""
- "bsr{w}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "HI")])
+ "TARGET_BMI"
+ "blsi\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
-(define_insn "popcount<mode>2"
- [(set (match_operand:SWI248 0 "register_operand" "=r")
- (popcount:SWI248
+(define_insn "*bmi_blsmsk_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (xor:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int -1))
+ (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_BMI"
+ "blsmsk\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*bmi_blsr_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (and:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int -1))
+ (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_BMI"
+ "blsr\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+;; TBM instructions.
+(define_insn "tbm_bextri_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (zero_extract:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (match_operand:SWI48 2 "const_0_to_255_operand" "n")
+ (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_TBM"
+{
+ operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
+ return "bextr\t{%2, %1, %0|%0, %1, %2}";
+}
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*tbm_blcfill_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (and:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int 1))
+ (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_TBM"
+ "blcfill\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*tbm_blci_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (ior:SWI48
+ (not:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int 1)))
+ (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_TBM"
+ "blci\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*tbm_blcic_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (and:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int 1))
+ (not:SWI48
+ (match_dup 1))))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_TBM"
+ "blcic\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*tbm_blcmsk_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (xor:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int 1))
+ (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_TBM"
+ "blcmsk\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*tbm_blcs_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (ior:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int 1))
+ (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_TBM"
+ "blcs\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*tbm_blsfill_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (ior:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int -1))
+ (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_TBM"
+ "blsfill\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*tbm_blsic_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (ior:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int -1))
+ (not:SWI48
+ (match_dup 1))))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_TBM"
+ "blsic\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*tbm_t1mskc_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (ior:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int 1))
+ (not:SWI48
+ (match_dup 1))))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_TBM"
+ "t1mskc\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*tbm_tzmsk_<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (and:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int -1))
+ (not:SWI48
+ (match_dup 1))))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_TBM"
+ "tzmsk\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "bsr_rex64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (minus:DI (const_int 63)
+ (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT"
+ "bsr{q}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "mode" "DI")])
+
+(define_insn "bsr"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI (const_int 31)
+ (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
+ (clobber (reg:CC FLAGS_REG))]
+ ""
+ "bsr{l}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "mode" "SI")])
+
+(define_insn "*bsrhi"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (minus:HI (const_int 15)
+ (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
+ (clobber (reg:CC FLAGS_REG))]
+ ""
+ "bsr{w}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "mode" "HI")])
+
+(define_insn "popcount<mode>2"
+ [(set (match_operand:SWI248 0 "register_operand" "=r")
+ (popcount:SWI248
(match_operand:SWI248 1 "nonimmediate_operand" "rm")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_POPCNT"
(set_attr "memory" "load")
(set_attr "imm_disp" "false")])
+;; The Sun linker took the AMD64 TLS spec literally and can only handle
+;; %rax as destination of the initial executable code sequence.
+(define_insn "tls_initial_exec_64_sun"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (unspec:DI
+ [(match_operand:DI 1 "tls_symbolic_operand" "")]
+ UNSPEC_TLS_IE_SUN))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT && TARGET_SUN_TLS"
+ "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
+ [(set_attr "type" "multi")])
+
;; GNU2 TLS patterns can be split.
(define_expand "tls_dynamic_gnu2_32"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")
(set_attr "athlon_decode" "direct")
- (set_attr "amdfam10_decode" "direct")])
+ (set_attr "amdfam10_decode" "direct")
+ (set_attr "bdver1_decode" "direct")])
(define_insn "sqrt_extend<mode>xf2_i387"
[(set (match_operand:XF 0 "register_operand" "=f")
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")
(set_attr "athlon_decode" "direct")
- (set_attr "amdfam10_decode" "direct")])
+ (set_attr "amdfam10_decode" "direct")
+ (set_attr "bdver1_decode" "direct")])
(define_insn "*rsqrtsf2_sse"
[(set (match_operand:SF 0 "register_operand" "=x")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODE>")
(set_attr "athlon_decode" "*")
- (set_attr "amdfam10_decode" "*")])
+ (set_attr "amdfam10_decode" "*")
+ (set_attr "bdver1_decode" "*")])
(define_expand "sqrt<mode>2"
[(set (match_operand:MODEF 0 "register_operand" "")
FAIL;
if (TARGET_ROUND)
emit_insn (gen_sse4_1_round<mode>2
- (operands[0], operands[1], GEN_INT (0x04)));
+ (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
else
ix86_expand_rint (operand0, operand1);
}
FAIL;
if (TARGET_ROUND)
emit_insn (gen_sse4_1_round<mode>2
- (operands[0], operands[1], GEN_INT (0x01)));
+ (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
else if (TARGET_64BIT || (<MODE>mode != DFmode))
ix86_expand_floorceil (operand0, operand1, true);
else
{
if (TARGET_ROUND)
emit_insn (gen_sse4_1_round<mode>2
- (operands[0], operands[1], GEN_INT (0x02)));
+ (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
else if (optimize_insn_for_size_p ())
FAIL;
else if (TARGET_64BIT || (<MODE>mode != DFmode))
{
if (TARGET_ROUND)
emit_insn (gen_sse4_1_round<mode>2
- (operands[0], operands[1], GEN_INT (0x03)));
+ (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
else if (optimize_insn_for_size_p ())
FAIL;
else if (TARGET_64BIT || (<MODE>mode != DFmode))
DONE;
})
-(define_expand "signbit<mode>2"
+(define_expand "signbitxf2"
+ [(use (match_operand:SI 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387"
+{
+ rtx scratch = gen_reg_rtx (HImode);
+
+ emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
+ emit_insn (gen_andsi3 (operands[0],
+ gen_lowpart (SImode, scratch), GEN_INT (0x200)));
+ DONE;
+})
+
+(define_insn "movmsk_df"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI
+ [(match_operand:DF 1 "register_operand" "x")]
+ UNSPEC_MOVMSK))]
+ "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
+ "%vmovmskpd\t{%1, %0|%0, %1}"
+ [(set_attr "type" "ssemov")
+ (set_attr "prefix" "maybe_vex")
+ (set_attr "mode" "DF")])
+
+;; Use movmskpd in SSE mode to avoid store forwarding stall
+;; for 32bit targets and movq+shrq sequence for 64bit targets.
+(define_expand "signbitdf2"
[(use (match_operand:SI 0 "register_operand" ""))
- (use (match_operand:X87MODEF 1 "register_operand" ""))]
+ (use (match_operand:DF 1 "register_operand" ""))]
"TARGET_USE_FANCY_MATH_387
- && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
+ || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
{
- rtx mask = GEN_INT (0x0200);
+ if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
+ {
+ emit_insn (gen_movmsk_df (operands[0], operands[1]));
+ emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
+ }
+ else
+ {
+ rtx scratch = gen_reg_rtx (HImode);
+
+ emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
+ emit_insn (gen_andsi3 (operands[0],
+ gen_lowpart (SImode, scratch), GEN_INT (0x200)));
+ }
+ DONE;
+})
+(define_expand "signbitsf2"
+ [(use (match_operand:SI 0 "register_operand" ""))
+ (use (match_operand:SF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+ && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
+{
rtx scratch = gen_reg_rtx (HImode);
- emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
- emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
+ emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
+ emit_insn (gen_andsi3 (operands[0],
+ gen_lowpart (SImode, scratch), GEN_INT (0x200)));
DONE;
})
\f
(set_attr "length_immediate" "0")
(set_attr "modrm" "0")])
-(define_expand "movmemsi"
+(define_expand "movmem<mode>"
[(use (match_operand:BLK 0 "memory_operand" ""))
(use (match_operand:BLK 1 "memory_operand" ""))
- (use (match_operand:SI 2 "nonmemory_operand" ""))
- (use (match_operand:SI 3 "const_int_operand" ""))
+ (use (match_operand:SWI48 2 "nonmemory_operand" ""))
+ (use (match_operand:SWI48 3 "const_int_operand" ""))
(use (match_operand:SI 4 "const_int_operand" ""))
(use (match_operand:SI 5 "const_int_operand" ""))]
""
FAIL;
})
-(define_expand "movmemdi"
- [(use (match_operand:BLK 0 "memory_operand" ""))
- (use (match_operand:BLK 1 "memory_operand" ""))
- (use (match_operand:DI 2 "nonmemory_operand" ""))
- (use (match_operand:DI 3 "const_int_operand" ""))
- (use (match_operand:SI 4 "const_int_operand" ""))
- (use (match_operand:SI 5 "const_int_operand" ""))]
- "TARGET_64BIT"
-{
- if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
- operands[4], operands[5]))
- DONE;
- else
- FAIL;
-})
-
;; Most CPUs don't like single string operations
;; Handle this case here to simplify previous expander.
"TARGET_64BIT"
"movsq"
[(set_attr "type" "str")
- (set_attr "mode" "DI")
- (set_attr "memory" "both")])
+ (set_attr "memory" "both")
+ (set_attr "mode" "DI")])
(define_insn "*strmovsi_1"
- [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
- (mem:SI (match_operand:SI 3 "register_operand" "1")))
- (set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (match_dup 2)
- (const_int 4)))
- (set (match_operand:SI 1 "register_operand" "=S")
- (plus:SI (match_dup 3)
- (const_int 4)))]
- "!TARGET_64BIT"
- "movs{l|d}"
- [(set_attr "type" "str")
- (set_attr "mode" "SI")
- (set_attr "memory" "both")])
-
-(define_insn "*strmovsi_rex_1"
- [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
- (mem:SI (match_operand:DI 3 "register_operand" "1")))
- (set (match_operand:DI 0 "register_operand" "=D")
- (plus:DI (match_dup 2)
- (const_int 4)))
- (set (match_operand:DI 1 "register_operand" "=S")
- (plus:DI (match_dup 3)
- (const_int 4)))]
- "TARGET_64BIT"
+ [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
+ (mem:SI (match_operand:P 3 "register_operand" "1")))
+ (set (match_operand:P 0 "register_operand" "=D")
+ (plus:P (match_dup 2)
+ (const_int 4)))
+ (set (match_operand:P 1 "register_operand" "=S")
+ (plus:P (match_dup 3)
+ (const_int 4)))]
+ ""
"movs{l|d}"
[(set_attr "type" "str")
- (set_attr "mode" "SI")
- (set_attr "memory" "both")])
-
-(define_insn "*strmovhi_1"
- [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
- (mem:HI (match_operand:SI 3 "register_operand" "1")))
- (set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (match_dup 2)
- (const_int 2)))
- (set (match_operand:SI 1 "register_operand" "=S")
- (plus:SI (match_dup 3)
- (const_int 2)))]
- "!TARGET_64BIT"
- "movsw"
- [(set_attr "type" "str")
(set_attr "memory" "both")
- (set_attr "mode" "HI")])
+ (set_attr "mode" "SI")])
-(define_insn "*strmovhi_rex_1"
- [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
- (mem:HI (match_operand:DI 3 "register_operand" "1")))
- (set (match_operand:DI 0 "register_operand" "=D")
- (plus:DI (match_dup 2)
- (const_int 2)))
- (set (match_operand:DI 1 "register_operand" "=S")
- (plus:DI (match_dup 3)
- (const_int 2)))]
- "TARGET_64BIT"
+(define_insn "*strmovhi_1"
+ [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
+ (mem:HI (match_operand:P 3 "register_operand" "1")))
+ (set (match_operand:P 0 "register_operand" "=D")
+ (plus:P (match_dup 2)
+ (const_int 2)))
+ (set (match_operand:P 1 "register_operand" "=S")
+ (plus:P (match_dup 3)
+ (const_int 2)))]
+ ""
"movsw"
[(set_attr "type" "str")
(set_attr "memory" "both")
(set_attr "mode" "HI")])
(define_insn "*strmovqi_1"
- [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
- (mem:QI (match_operand:SI 3 "register_operand" "1")))
- (set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (match_dup 2)
- (const_int 1)))
- (set (match_operand:SI 1 "register_operand" "=S")
- (plus:SI (match_dup 3)
- (const_int 1)))]
- "!TARGET_64BIT"
- "movsb"
- [(set_attr "type" "str")
- (set_attr "memory" "both")
- (set_attr "mode" "QI")])
-
-(define_insn "*strmovqi_rex_1"
- [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
- (mem:QI (match_operand:DI 3 "register_operand" "1")))
- (set (match_operand:DI 0 "register_operand" "=D")
- (plus:DI (match_dup 2)
- (const_int 1)))
- (set (match_operand:DI 1 "register_operand" "=S")
- (plus:DI (match_dup 3)
- (const_int 1)))]
- "TARGET_64BIT"
+ [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
+ (mem:QI (match_operand:P 3 "register_operand" "1")))
+ (set (match_operand:P 0 "register_operand" "=D")
+ (plus:P (match_dup 2)
+ (const_int 1)))
+ (set (match_operand:P 1 "register_operand" "=S")
+ (plus:P (match_dup 3)
+ (const_int 1)))]
+ ""
"movsb"
[(set_attr "type" "str")
(set_attr "memory" "both")
- (set_attr "prefix_rex" "0")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "QI")])
(define_expand "rep_mov"
(set_attr "mode" "DI")])
(define_insn "*rep_movsi"
- [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
- (set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
- (const_int 2))
- (match_operand:SI 3 "register_operand" "0")))
- (set (match_operand:SI 1 "register_operand" "=S")
- (plus:SI (ashift:SI (match_dup 5) (const_int 2))
- (match_operand:SI 4 "register_operand" "1")))
- (set (mem:BLK (match_dup 3))
- (mem:BLK (match_dup 4)))
- (use (match_dup 5))]
- "!TARGET_64BIT"
- "rep{%;} movs{l|d}"
- [(set_attr "type" "str")
- (set_attr "prefix_rep" "1")
- (set_attr "memory" "both")
- (set_attr "mode" "SI")])
-
-(define_insn "*rep_movsi_rex64"
- [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
- (set (match_operand:DI 0 "register_operand" "=D")
- (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
- (const_int 2))
- (match_operand:DI 3 "register_operand" "0")))
- (set (match_operand:DI 1 "register_operand" "=S")
- (plus:DI (ashift:DI (match_dup 5) (const_int 2))
- (match_operand:DI 4 "register_operand" "1")))
+ [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
+ (set (match_operand:P 0 "register_operand" "=D")
+ (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
+ (const_int 2))
+ (match_operand:P 3 "register_operand" "0")))
+ (set (match_operand:P 1 "register_operand" "=S")
+ (plus:P (ashift:P (match_dup 5) (const_int 2))
+ (match_operand:P 4 "register_operand" "1")))
(set (mem:BLK (match_dup 3))
(mem:BLK (match_dup 4)))
(use (match_dup 5))]
- "TARGET_64BIT"
+ ""
"rep{%;} movs{l|d}"
[(set_attr "type" "str")
(set_attr "prefix_rep" "1")
(set_attr "mode" "SI")])
(define_insn "*rep_movqi"
- [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
- (set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (match_operand:SI 3 "register_operand" "0")
- (match_operand:SI 5 "register_operand" "2")))
- (set (match_operand:SI 1 "register_operand" "=S")
- (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
- (set (mem:BLK (match_dup 3))
- (mem:BLK (match_dup 4)))
- (use (match_dup 5))]
- "!TARGET_64BIT"
- "rep{%;} movsb"
- [(set_attr "type" "str")
- (set_attr "prefix_rep" "1")
- (set_attr "memory" "both")
- (set_attr "mode" "SI")])
-
-(define_insn "*rep_movqi_rex64"
- [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
- (set (match_operand:DI 0 "register_operand" "=D")
- (plus:DI (match_operand:DI 3 "register_operand" "0")
- (match_operand:DI 5 "register_operand" "2")))
- (set (match_operand:DI 1 "register_operand" "=S")
- (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
+ [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
+ (set (match_operand:P 0 "register_operand" "=D")
+ (plus:P (match_operand:P 3 "register_operand" "0")
+ (match_operand:P 5 "register_operand" "2")))
+ (set (match_operand:P 1 "register_operand" "=S")
+ (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
(set (mem:BLK (match_dup 3))
(mem:BLK (match_dup 4)))
(use (match_dup 5))]
- "TARGET_64BIT"
+ ""
"rep{%;} movsb"
[(set_attr "type" "str")
(set_attr "prefix_rep" "1")
(set_attr "memory" "both")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "QI")])
-(define_expand "setmemsi"
+(define_expand "setmem<mode>"
[(use (match_operand:BLK 0 "memory_operand" ""))
- (use (match_operand:SI 1 "nonmemory_operand" ""))
+ (use (match_operand:SWI48 1 "nonmemory_operand" ""))
(use (match_operand 2 "const_int_operand" ""))
(use (match_operand 3 "const_int_operand" ""))
(use (match_operand:SI 4 "const_int_operand" ""))
FAIL;
})
-(define_expand "setmemdi"
- [(use (match_operand:BLK 0 "memory_operand" ""))
- (use (match_operand:DI 1 "nonmemory_operand" ""))
- (use (match_operand 2 "const_int_operand" ""))
- (use (match_operand 3 "const_int_operand" ""))
- (use (match_operand 4 "const_int_operand" ""))
- (use (match_operand 5 "const_int_operand" ""))]
- "TARGET_64BIT"
-{
- if (ix86_expand_setmem (operands[0], operands[1],
- operands[2], operands[3],
- operands[4], operands[5]))
- DONE;
- else
- FAIL;
-})
-
;; Most CPUs don't like single string operations
;; Handle this case here to simplify previous expander.
(set_attr "mode" "DI")])
(define_insn "*strsetsi_1"
- [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
- (match_operand:SI 2 "register_operand" "a"))
- (set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (match_dup 1)
- (const_int 4)))]
- "!TARGET_64BIT"
- "stos{l|d}"
- [(set_attr "type" "str")
- (set_attr "memory" "store")
- (set_attr "mode" "SI")])
-
-(define_insn "*strsetsi_rex_1"
- [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
+ [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
(match_operand:SI 2 "register_operand" "a"))
- (set (match_operand:DI 0 "register_operand" "=D")
- (plus:DI (match_dup 1)
- (const_int 4)))]
- "TARGET_64BIT"
+ (set (match_operand:P 0 "register_operand" "=D")
+ (plus:P (match_dup 1)
+ (const_int 4)))]
+ ""
"stos{l|d}"
[(set_attr "type" "str")
(set_attr "memory" "store")
(set_attr "mode" "SI")])
(define_insn "*strsethi_1"
- [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
+ [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
(match_operand:HI 2 "register_operand" "a"))
- (set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (match_dup 1)
- (const_int 2)))]
- "!TARGET_64BIT"
- "stosw"
- [(set_attr "type" "str")
- (set_attr "memory" "store")
- (set_attr "mode" "HI")])
-
-(define_insn "*strsethi_rex_1"
- [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
- (match_operand:HI 2 "register_operand" "a"))
- (set (match_operand:DI 0 "register_operand" "=D")
- (plus:DI (match_dup 1)
- (const_int 2)))]
- "TARGET_64BIT"
+ (set (match_operand:P 0 "register_operand" "=D")
+ (plus:P (match_dup 1)
+ (const_int 2)))]
+ ""
"stosw"
[(set_attr "type" "str")
(set_attr "memory" "store")
(set_attr "mode" "HI")])
(define_insn "*strsetqi_1"
- [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
+ [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
(match_operand:QI 2 "register_operand" "a"))
- (set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (match_dup 1)
- (const_int 1)))]
- "!TARGET_64BIT"
- "stosb"
- [(set_attr "type" "str")
- (set_attr "memory" "store")
- (set_attr "mode" "QI")])
-
-(define_insn "*strsetqi_rex_1"
- [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
- (match_operand:QI 2 "register_operand" "a"))
- (set (match_operand:DI 0 "register_operand" "=D")
- (plus:DI (match_dup 1)
- (const_int 1)))]
- "TARGET_64BIT"
+ (set (match_operand:P 0 "register_operand" "=D")
+ (plus:P (match_dup 1)
+ (const_int 1)))]
+ ""
"stosb"
[(set_attr "type" "str")
(set_attr "memory" "store")
- (set_attr "prefix_rex" "0")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "QI")])
(define_expand "rep_stos"
(set_attr "mode" "DI")])
(define_insn "*rep_stossi"
- [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
- (set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
- (const_int 2))
- (match_operand:SI 3 "register_operand" "0")))
+ [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
+ (set (match_operand:P 0 "register_operand" "=D")
+ (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
+ (const_int 2))
+ (match_operand:P 3 "register_operand" "0")))
(set (mem:BLK (match_dup 3))
(const_int 0))
(use (match_operand:SI 2 "register_operand" "a"))
(use (match_dup 4))]
- "!TARGET_64BIT"
- "rep{%;} stos{l|d}"
- [(set_attr "type" "str")
- (set_attr "prefix_rep" "1")
- (set_attr "memory" "store")
- (set_attr "mode" "SI")])
-
-(define_insn "*rep_stossi_rex64"
- [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
- (set (match_operand:DI 0 "register_operand" "=D")
- (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
- (const_int 2))
- (match_operand:DI 3 "register_operand" "0")))
- (set (mem:BLK (match_dup 3))
- (const_int 0))
- (use (match_operand:SI 2 "register_operand" "a"))
- (use (match_dup 4))]
- "TARGET_64BIT"
+ ""
"rep{%;} stos{l|d}"
[(set_attr "type" "str")
(set_attr "prefix_rep" "1")
(set_attr "mode" "SI")])
(define_insn "*rep_stosqi"
- [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
- (set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (match_operand:SI 3 "register_operand" "0")
- (match_operand:SI 4 "register_operand" "1")))
- (set (mem:BLK (match_dup 3))
- (const_int 0))
- (use (match_operand:QI 2 "register_operand" "a"))
- (use (match_dup 4))]
- "!TARGET_64BIT"
- "rep{%;} stosb"
- [(set_attr "type" "str")
- (set_attr "prefix_rep" "1")
- (set_attr "memory" "store")
- (set_attr "mode" "QI")])
-
-(define_insn "*rep_stosqi_rex64"
- [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
- (set (match_operand:DI 0 "register_operand" "=D")
- (plus:DI (match_operand:DI 3 "register_operand" "0")
- (match_operand:DI 4 "register_operand" "1")))
+ [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
+ (set (match_operand:P 0 "register_operand" "=D")
+ (plus:P (match_operand:P 3 "register_operand" "0")
+ (match_operand:P 4 "register_operand" "1")))
(set (mem:BLK (match_dup 3))
(const_int 0))
(use (match_operand:QI 2 "register_operand" "a"))
(use (match_dup 4))]
- "TARGET_64BIT"
+ ""
"rep{%;} stosb"
[(set_attr "type" "str")
(set_attr "prefix_rep" "1")
(set_attr "memory" "store")
- (set_attr "prefix_rex" "0")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "QI")])
(define_expand "cmpstrnsi"
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
""
- "operands[1] = gen_reg_rtx (QImode);
- operands[2] = gen_reg_rtx (QImode);")
+{
+ operands[1] = gen_reg_rtx (QImode);
+ operands[2] = gen_reg_rtx (QImode);
+})
;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
;; zero. Emit extra code to make sure that a zero-length compare is EQ.
(define_insn "*cmpstrnqi_nz_1"
[(set (reg:CC FLAGS_REG)
- (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
- (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
- (use (match_operand:SI 6 "register_operand" "2"))
+ (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
+ (mem:BLK (match_operand:P 5 "register_operand" "1"))))
+ (use (match_operand:P 6 "register_operand" "2"))
(use (match_operand:SI 3 "immediate_operand" "i"))
- (clobber (match_operand:SI 0 "register_operand" "=S"))
- (clobber (match_operand:SI 1 "register_operand" "=D"))
- (clobber (match_operand:SI 2 "register_operand" "=c"))]
- "!TARGET_64BIT"
- "repz{%;} cmpsb"
- [(set_attr "type" "str")
- (set_attr "mode" "QI")
- (set_attr "prefix_rep" "1")])
-
-(define_insn "*cmpstrnqi_nz_rex_1"
- [(set (reg:CC FLAGS_REG)
- (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
- (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
- (use (match_operand:DI 6 "register_operand" "2"))
- (use (match_operand:SI 3 "immediate_operand" "i"))
- (clobber (match_operand:DI 0 "register_operand" "=S"))
- (clobber (match_operand:DI 1 "register_operand" "=D"))
- (clobber (match_operand:DI 2 "register_operand" "=c"))]
- "TARGET_64BIT"
+ (clobber (match_operand:P 0 "register_operand" "=S"))
+ (clobber (match_operand:P 1 "register_operand" "=D"))
+ (clobber (match_operand:P 2 "register_operand" "=c"))]
+ ""
"repz{%;} cmpsb"
[(set_attr "type" "str")
(set_attr "mode" "QI")
- (set_attr "prefix_rex" "0")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
+ (const_string "0")
+ (const_string "*")))
(set_attr "prefix_rep" "1")])
;; The same, but the count is not known to not be zero.
(define_insn "*cmpstrnqi_1"
[(set (reg:CC FLAGS_REG)
- (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
- (const_int 0))
- (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
- (mem:BLK (match_operand:SI 5 "register_operand" "1")))
- (const_int 0)))
- (use (match_operand:SI 3 "immediate_operand" "i"))
- (use (reg:CC FLAGS_REG))
- (clobber (match_operand:SI 0 "register_operand" "=S"))
- (clobber (match_operand:SI 1 "register_operand" "=D"))
- (clobber (match_operand:SI 2 "register_operand" "=c"))]
- "!TARGET_64BIT"
- "repz{%;} cmpsb"
- [(set_attr "type" "str")
- (set_attr "mode" "QI")
- (set_attr "prefix_rep" "1")])
-
-(define_insn "*cmpstrnqi_rex_1"
- [(set (reg:CC FLAGS_REG)
- (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
+ (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
(const_int 0))
- (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
- (mem:BLK (match_operand:DI 5 "register_operand" "1")))
+ (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
+ (mem:BLK (match_operand:P 5 "register_operand" "1")))
(const_int 0)))
(use (match_operand:SI 3 "immediate_operand" "i"))
(use (reg:CC FLAGS_REG))
- (clobber (match_operand:DI 0 "register_operand" "=S"))
- (clobber (match_operand:DI 1 "register_operand" "=D"))
- (clobber (match_operand:DI 2 "register_operand" "=c"))]
- "TARGET_64BIT"
+ (clobber (match_operand:P 0 "register_operand" "=S"))
+ (clobber (match_operand:P 1 "register_operand" "=D"))
+ (clobber (match_operand:P 2 "register_operand" "=c"))]
+ ""
"repz{%;} cmpsb"
[(set_attr "type" "str")
(set_attr "mode" "QI")
- (set_attr "prefix_rex" "0")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
+ (const_string "0")
+ (const_string "*")))
(set_attr "prefix_rep" "1")])
-(define_expand "strlensi"
- [(set (match_operand:SI 0 "register_operand" "")
- (unspec:SI [(match_operand:BLK 1 "general_operand" "")
- (match_operand:QI 2 "immediate_operand" "")
- (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
- ""
-{
- if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
- DONE;
- else
- FAIL;
-})
-
-(define_expand "strlendi"
- [(set (match_operand:DI 0 "register_operand" "")
- (unspec:DI [(match_operand:BLK 1 "general_operand" "")
- (match_operand:QI 2 "immediate_operand" "")
- (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
+(define_expand "strlen<mode>"
+ [(set (match_operand:SWI48x 0 "register_operand" "")
+ (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
+ (match_operand:QI 2 "immediate_operand" "")
+ (match_operand 3 "immediate_operand" "")]
+ UNSPEC_SCAS))]
""
{
if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
})
(define_expand "strlenqi_1"
- [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
+ [(parallel [(set (match_operand 0 "register_operand" "")
+ (match_operand 2 "" ""))
(clobber (match_operand 1 "register_operand" ""))
(clobber (reg:CC FLAGS_REG))])]
""
"ix86_current_function_needs_cld = 1;")
(define_insn "*strlenqi_1"
- [(set (match_operand:SI 0 "register_operand" "=&c")
- (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
- (match_operand:QI 2 "register_operand" "a")
- (match_operand:SI 3 "immediate_operand" "i")
- (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
- (clobber (match_operand:SI 1 "register_operand" "=D"))
+ [(set (match_operand:P 0 "register_operand" "=&c")
+ (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
+ (match_operand:QI 2 "register_operand" "a")
+ (match_operand:P 3 "immediate_operand" "i")
+ (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
+ (clobber (match_operand:P 1 "register_operand" "=D"))
(clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT"
- "repnz{%;} scasb"
- [(set_attr "type" "str")
- (set_attr "mode" "QI")
- (set_attr "prefix_rep" "1")])
-
-(define_insn "*strlenqi_rex_1"
- [(set (match_operand:DI 0 "register_operand" "=&c")
- (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
- (match_operand:QI 2 "register_operand" "a")
- (match_operand:DI 3 "immediate_operand" "i")
- (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
- (clobber (match_operand:DI 1 "register_operand" "=D"))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
+ ""
"repnz{%;} scasb"
[(set_attr "type" "str")
(set_attr "mode" "QI")
- (set_attr "prefix_rex" "0")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
+ (const_string "0")
+ (const_string "*")))
(set_attr "prefix_rep" "1")])
;; Peephole optimizations to clean up after cmpstrn*. This should be
|| (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
"if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
-(define_insn "*movsfcc_1_387"
- [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
- (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
+(define_insn "*movxfcc_1"
+ [(set (match_operand:XF 0 "register_operand" "=f,f")
+ (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
[(reg FLAGS_REG) (const_int 0)])
- (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
- (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
- "TARGET_80387 && TARGET_CMOVE
+ (match_operand:XF 2 "register_operand" "f,0")
+ (match_operand:XF 3 "register_operand" "0,f")))]
+ "TARGET_80387 && TARGET_CMOVE"
+ "@
+ fcmov%F1\t{%2, %0|%0, %2}
+ fcmov%f1\t{%3, %0|%0, %3}"
+ [(set_attr "type" "fcmov")
+ (set_attr "mode" "XF")])
+
+(define_insn "*movdfcc_1_rex64"
+ [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
+ (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
+ [(reg FLAGS_REG) (const_int 0)])
+ (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
+ (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
+ "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
&& !(MEM_P (operands[2]) && MEM_P (operands[3]))"
"@
fcmov%F1\t{%2, %0|%0, %2}
cmov%O2%C1\t{%2, %0|%0, %2}
cmov%O2%c1\t{%3, %0|%0, %3}"
[(set_attr "type" "fcmov,fcmov,icmov,icmov")
- (set_attr "mode" "SF,SF,SI,SI")])
+ (set_attr "mode" "DF,DF,DI,DI")])
(define_insn "*movdfcc_1"
[(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
#
#"
[(set_attr "type" "fcmov,fcmov,multi,multi")
- (set_attr "mode" "DF")])
-
-(define_insn "*movdfcc_1_rex64"
- [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
- (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
- (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
- "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
- && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
- "@
- fcmov%F1\t{%2, %0|%0, %2}
- fcmov%f1\t{%3, %0|%0, %3}
- cmov%O2%C1\t{%2, %0|%0, %2}
- cmov%O2%c1\t{%3, %0|%0, %3}"
- [(set_attr "type" "fcmov,fcmov,icmov,icmov")
- (set_attr "mode" "DF")])
+ (set_attr "mode" "DF,DF,DI,DI")])
(define_split
[(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
(match_dup 7)
(match_dup 8)))]
{
- split_di (&operands[2], 2, &operands[5], &operands[7]);
- split_di (&operands[0], 1, &operands[2], &operands[3]);
+ split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
+ split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
})
-(define_insn "*movxfcc_1"
- [(set (match_operand:XF 0 "register_operand" "=f,f")
- (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
+(define_insn "*movsfcc_1_387"
+ [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
+ (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
[(reg FLAGS_REG) (const_int 0)])
- (match_operand:XF 2 "register_operand" "f,0")
- (match_operand:XF 3 "register_operand" "0,f")))]
- "TARGET_80387 && TARGET_CMOVE"
+ (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
+ (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
+ "TARGET_80387 && TARGET_CMOVE
+ && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
"@
fcmov%F1\t{%2, %0|%0, %2}
- fcmov%f1\t{%3, %0|%0, %3}"
- [(set_attr "type" "fcmov")
- (set_attr "mode" "XF")])
+ fcmov%f1\t{%3, %0|%0, %3}
+ cmov%O2%C1\t{%2, %0|%0, %2}
+ cmov%O2%c1\t{%3, %0|%0, %3}"
+ [(set_attr "type" "fcmov,fcmov,icmov,icmov")
+ (set_attr "mode" "SF,SF,SI,SI")])
;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
;; the scalar versions to have only XMM registers as operands.
;;
;; in proper program order.
-(define_insn "pro_epilogue_adjust_stack_<mode>_1"
+(define_insn "pro_epilogue_adjust_stack_<mode>_add"
[(set (match_operand:P 0 "register_operand" "=r,r")
(plus:P (match_operand:P 1 "register_operand" "0,r")
- (match_operand:P 2 "<immediate_operand>" "<i>,<i>")))
+ (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))]
""
(const_string "*")))
(set_attr "mode" "<MODE>")])
-(define_insn "pro_epilogue_adjust_stack_di_2"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (plus:DI (match_operand:DI 1 "register_operand" "0,r")
- (match_operand:DI 3 "immediate_operand" "i,i")))
- (use (match_operand:DI 2 "register_operand" "r,l"))
+(define_insn "pro_epilogue_adjust_stack_<mode>_sub"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (minus:P (match_operand:P 1 "register_operand" "0")
+ (match_operand:P 2 "register_operand" "r")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))]
- "TARGET_64BIT"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_ALU:
- return "add{q}\t{%2, %0|%0, %2}";
-
- case TYPE_LEA:
- operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
- return "lea{q}\t{%a2, %0|%0, %a2}";
-
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "alu,lea")
- (set_attr "mode" "DI")])
-
-(define_insn "allocate_stack_worker_32"
- [(set (match_operand:SI 0 "register_operand" "=a")
- (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
- UNSPECV_STACK_PROBE))
- (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT && ix86_target_stack_probe ()"
- "call\t___chkstk"
- [(set_attr "type" "multi")
- (set_attr "length" "5")])
+ ""
+ "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "<MODE>")])
-(define_insn "allocate_stack_worker_64"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
+(define_insn "allocate_stack_worker_probe_<mode>"
+ [(set (match_operand:P 0 "register_operand" "=a")
+ (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
UNSPECV_STACK_PROBE))
- (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
- (clobber (reg:DI R10_REG))
- (clobber (reg:DI R11_REG))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_target_stack_probe ()"
- "call\t___chkstk"
+ "ix86_target_stack_probe ()"
+ "call\t___chkstk_ms"
[(set_attr "type" "multi")
(set_attr "length" "5")])
}
else
{
- rtx (*gen_allocate_stack_worker) (rtx, rtx);
-
+ x = copy_to_mode_reg (Pmode, operands[1]);
if (TARGET_64BIT)
- gen_allocate_stack_worker = gen_allocate_stack_worker_64;
+ emit_insn (gen_allocate_stack_worker_probe_di (x, x));
else
- gen_allocate_stack_worker = gen_allocate_stack_worker_32;
-
- x = copy_to_mode_reg (Pmode, operands[1]);
- emit_insn (gen_allocate_stack_worker (x, x));
+ emit_insn (gen_allocate_stack_worker_probe_si (x, x));
+ x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
+ stack_pointer_rtx, 0, OPTAB_DIRECT);
+ if (x != stack_pointer_rtx)
+ emit_move_insn (stack_pointer_rtx, x);
}
emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
(plus (match_dup 0)
(match_operand 4 "x86_64_general_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
- "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
+ "IN_RANGE (INTVAL (operands[2]), 1, 3)
/* Validate MODE for lea. */
&& ((!TARGET_PARTIAL_REG_STALL
&& (GET_MODE (operands[0]) == QImode
[(set (match_dup 5) (match_dup 4))
(set (match_dup 0) (match_dup 1))]
{
- enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
+ enum machine_mode op1mode = GET_MODE (operands[1]);
+ enum machine_mode mode = op1mode == DImode ? DImode : SImode;
int scale = 1 << INTVAL (operands[2]);
rtx index = gen_lowpart (Pmode, operands[1]);
rtx base = gen_lowpart (Pmode, operands[5]);
gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
operands[5] = base;
if (mode != Pmode)
- {
- operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
- operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
- }
+ operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
+ if (op1mode != Pmode)
+ operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
operands[0] = dest;
})
\f
;; Call-value patterns last so that the wildcard operand does not
;; disrupt insn-recog's switch tables.
+(define_insn_and_split "*call_value_pop_0_vzeroupper"
+ [(parallel
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
+ (match_operand:SI 2 "" "")))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 3 "immediate_operand" "")))])
+ (unspec [(match_operand 4 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
+ [(set_attr "type" "callv")])
+
(define_insn "*call_value_pop_0"
[(set (match_operand 0 "" "")
(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
(plus:SI (reg:SI SP_REG)
(match_operand:SI 3 "immediate_operand" "")))]
"!TARGET_64BIT"
-{
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P1";
- else
- return "call\t%P1";
-}
+ { return ix86_output_call_insn (insn, operands[1], 1); }
+ [(set_attr "type" "callv")])
+
+(define_insn_and_split "*call_value_pop_1_vzeroupper"
+ [(parallel
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
+ (match_operand:SI 2 "" "")))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 3 "immediate_operand" "i")))])
+ (unspec [(match_operand 4 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
[(set_attr "type" "callv")])
(define_insn "*call_value_pop_1"
(plus:SI (reg:SI SP_REG)
(match_operand:SI 3 "immediate_operand" "i")))]
"!TARGET_64BIT && !SIBLING_CALL_P (insn)"
-{
- if (constant_call_address_operand (operands[1], Pmode))
- return "call\t%P1";
- return "call\t%A1";
-}
+ { return ix86_output_call_insn (insn, operands[1], 1); }
+ [(set_attr "type" "callv")])
+
+(define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
+ [(parallel
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
+ (match_operand:SI 2 "" "")))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 3 "immediate_operand" "i,i")))])
+ (unspec [(match_operand 4 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
[(set_attr "type" "callv")])
(define_insn "*sibcall_value_pop_1"
(plus:SI (reg:SI SP_REG)
(match_operand:SI 3 "immediate_operand" "i,i")))]
"!TARGET_64BIT && SIBLING_CALL_P (insn)"
- "@
- jmp\t%P1
- jmp\t%A1"
+ { return ix86_output_call_insn (insn, operands[1], 1); }
+ [(set_attr "type" "callv")])
+
+(define_insn_and_split "*call_value_0_vzeroupper"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
+ (match_operand:SI 2 "" "")))
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
[(set_attr "type" "callv")])
(define_insn "*call_value_0"
(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
(match_operand:SI 2 "" "")))]
"!TARGET_64BIT"
-{
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P1";
- else
- return "call\t%P1";
-}
+ { return ix86_output_call_insn (insn, operands[1], 1); }
+ [(set_attr "type" "callv")])
+
+(define_insn_and_split "*call_value_0_rex64_vzeroupper"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
+ (match_operand:DI 2 "const_int_operand" "")))
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
[(set_attr "type" "callv")])
(define_insn "*call_value_0_rex64"
(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
(match_operand:DI 2 "const_int_operand" "")))]
"TARGET_64BIT"
-{
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P1";
- else
- return "call\t%P1";
-}
+ { return ix86_output_call_insn (insn, operands[1], 1); }
+ [(set_attr "type" "callv")])
+
+(define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
+ [(parallel
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
+ (match_operand:DI 2 "const_int_operand" "")))
+ (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
+ (clobber (reg:TI XMM6_REG))
+ (clobber (reg:TI XMM7_REG))
+ (clobber (reg:TI XMM8_REG))
+ (clobber (reg:TI XMM9_REG))
+ (clobber (reg:TI XMM10_REG))
+ (clobber (reg:TI XMM11_REG))
+ (clobber (reg:TI XMM12_REG))
+ (clobber (reg:TI XMM13_REG))
+ (clobber (reg:TI XMM14_REG))
+ (clobber (reg:TI XMM15_REG))
+ (clobber (reg:DI SI_REG))
+ (clobber (reg:DI DI_REG))])
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
[(set_attr "type" "callv")])
(define_insn "*call_value_0_rex64_ms_sysv"
(clobber (reg:DI SI_REG))
(clobber (reg:DI DI_REG))]
"TARGET_64BIT && !SIBLING_CALL_P (insn)"
-{
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P1";
- else
- return "call\t%P1";
-}
+ { return ix86_output_call_insn (insn, operands[1], 1); }
+ [(set_attr "type" "callv")])
+
+(define_insn_and_split "*call_value_1_vzeroupper"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
+ (match_operand:SI 2 "" "")))
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
[(set_attr "type" "callv")])
(define_insn "*call_value_1"
(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
(match_operand:SI 2 "" "")))]
"!TARGET_64BIT && !SIBLING_CALL_P (insn)"
-{
- if (constant_call_address_operand (operands[1], Pmode))
- return "call\t%P1";
- return "call\t%A1";
-}
+ { return ix86_output_call_insn (insn, operands[1], 1); }
+ [(set_attr "type" "callv")])
+
+(define_insn_and_split "*sibcall_value_1_vzeroupper"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
+ (match_operand:SI 2 "" "")))
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
[(set_attr "type" "callv")])
(define_insn "*sibcall_value_1"
(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
(match_operand:SI 2 "" "")))]
"!TARGET_64BIT && SIBLING_CALL_P (insn)"
- "@
- jmp\t%P1
- jmp\t%A1"
+ { return ix86_output_call_insn (insn, operands[1], 1); }
+ [(set_attr "type" "callv")])
+
+(define_insn_and_split "*call_value_1_rex64_vzeroupper"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
+ (match_operand:DI 2 "" "")))
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
+ && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
[(set_attr "type" "callv")])
(define_insn "*call_value_1_rex64"
(match_operand:DI 2 "" "")))]
"TARGET_64BIT && !SIBLING_CALL_P (insn)
&& ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
-{
- if (constant_call_address_operand (operands[1], Pmode))
- return "call\t%P1";
- return "call\t%A1";
-}
+ { return ix86_output_call_insn (insn, operands[1], 1); }
+ [(set_attr "type" "callv")])
+
+(define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
+ [(parallel
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
+ (match_operand:DI 2 "" "")))
+ (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
+ (clobber (reg:TI XMM6_REG))
+ (clobber (reg:TI XMM7_REG))
+ (clobber (reg:TI XMM8_REG))
+ (clobber (reg:TI XMM9_REG))
+ (clobber (reg:TI XMM10_REG))
+ (clobber (reg:TI XMM11_REG))
+ (clobber (reg:TI XMM12_REG))
+ (clobber (reg:TI XMM13_REG))
+ (clobber (reg:TI XMM14_REG))
+ (clobber (reg:TI XMM15_REG))
+ (clobber (reg:DI SI_REG))
+ (clobber (reg:DI DI_REG))])
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
[(set_attr "type" "callv")])
(define_insn "*call_value_1_rex64_ms_sysv"
(clobber (reg:DI SI_REG))
(clobber (reg:DI DI_REG))]
"TARGET_64BIT && !SIBLING_CALL_P (insn)"
-{
- if (constant_call_address_operand (operands[1], Pmode))
- return "call\t%P1";
- return "call\t%A1";
-}
+ { return ix86_output_call_insn (insn, operands[1], 1); }
+ [(set_attr "type" "callv")])
+
+(define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
+ (match_operand:DI 2 "" "")))
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
[(set_attr "type" "callv")])
(define_insn "*call_value_1_rex64_large"
(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
(match_operand:DI 2 "" "")))]
"TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "call\t%A1"
+ { return ix86_output_call_insn (insn, operands[1], 1); }
+ [(set_attr "type" "callv")])
+
+(define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
+ (match_operand:DI 2 "" "")))
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
[(set_attr "type" "callv")])
(define_insn "*sibcall_value_1_rex64"
(call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
(match_operand:DI 2 "" "")))]
"TARGET_64BIT && SIBLING_CALL_P (insn)"
- "@
- jmp\t%P1
- jmp\t%A1"
+ { return ix86_output_call_insn (insn, operands[1], 1); }
[(set_attr "type" "callv")])
\f
;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
[(set_attr "type" "other")
(set_attr "prefix_extra" "2")])
-(define_expand "rdrand<mode>"
- [(set (match_operand:SWI248 0 "register_operand" "=r")
- (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
- "TARGET_RDRND"
-{
- rtx retry_label, insn, ccc;
-
- retry_label = gen_label_rtx ();
-
- emit_label (retry_label);
-
- /* Generate rdrand. */
- emit_insn (gen_rdrand<mode>_1 (operands[0]));
-
- /* Retry if the carry flag isn't valid. */
- ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
- ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
- ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
- gen_rtx_LABEL_REF (VOIDmode, retry_label));
- insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
- JUMP_LABEL (insn) = retry_label;
-
- DONE;
-})
-
(define_insn "rdrand<mode>_1"
[(set (match_operand:SWI248 0 "register_operand" "=r")
- (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
+ (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
+ (set (reg:CCC FLAGS_REG)
+ (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
"TARGET_RDRND"
- "rdrand %0"
+ "rdrand\t%0"
[(set_attr "type" "other")
(set_attr "prefix_extra" "1")])