;; 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
;; d -- print duplicated register operand for AVX instruction.
;; D -- print condition for SSE cmp instruction.
;; P -- if PIC, print an @PLT suffix.
+;; p -- print raw symbol name.
;; X -- don't print any sort of PIC '@' suffix for a symbol.
;; & -- print some in-use local-dynamic symbol name.
;; H -- print a memory address offset by 8; used for sse high-parts
;; Y -- print condition for XOP pcom* instruction.
;; + -- print a branch hint as 'cs' or 'ds' prefix
;; ; -- print a semicolon (after prefixes due to bug in older gas).
+;; @ -- print a segment register of thread base pointer load
;; UNSPEC usage:
UNSPEC_INDNTPOFF
UNSPEC_PLTOFF
UNSPEC_MACHOPIC_OFFSET
+ UNSPEC_PCREL
;; Prologue support
UNSPEC_STACK_ALLOC
UNSPEC_SET_GOT
- UNSPEC_SSE_PROLOGUE_SAVE
UNSPEC_REG_SAVE
UNSPEC_DEF_CFA
UNSPEC_SET_RIP
UNSPEC_SET_GOT_OFFSET
UNSPEC_MEMORY_BLOCKAGE
- UNSPEC_SSE_PROLOGUE_SAVE_LOW
+ 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_REP
UNSPEC_LD_MPIC ; load_macho_picbase
UNSPEC_TRUNC_NOOP
+ UNSPEC_DIV_ALREADY_SPLIT
+ UNSPEC_CALL_NEEDS_VZEROUPPER
+ UNSPEC_PAUSE
;; 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_VPERMIL
UNSPEC_VPERMIL2
UNSPEC_VPERMIL2F128
- UNSPEC_MASKLOAD
- UNSPEC_MASKSTORE
UNSPEC_CAST
UNSPEC_VTESTP
+ UNSPEC_VCVTPH2PS
+ UNSPEC_VCVTPS2PH
+
+ ;; For BMI support
+ UNSPEC_BEXTR
+
+ ;; For RDRAND support
+ UNSPEC_RDRAND
])
(define_c_enum "unspecv" [
UNSPECV_BLOCKAGE
UNSPECV_STACK_PROBE
+ UNSPECV_PROBE_STACK_RANGE
UNSPECV_EMMS
UNSPECV_LDMXCSR
UNSPECV_STMXCSR
UNSPECV_LOCK
UNSPECV_PROLOGUE_USE
UNSPECV_CLD
+ UNSPECV_NOPS
UNSPECV_VZEROALL
UNSPECV_VZEROUPPER
UNSPECV_RDTSC
UNSPECV_RDTSCP
UNSPECV_RDPMC
- UNSPECV_VSWAPMOV
UNSPECV_LLWP_INTRINSIC
UNSPECV_SLWP_INTRINSIC
UNSPECV_LWPVAL_INTRINSIC
UNSPECV_LWPINS_INTRINSIC
+ UNSPECV_RDFSBASE
+ UNSPECV_RDGSBASE
+ UNSPECV_WRFSBASE
+ UNSPECV_WRGSBASE
+ 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
(const_int 0)
(eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
imul,icmp,push,pop")
- (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
+ (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
(eq_attr "type" "imov,test")
- (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
+ (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
(eq_attr "type" "call")
(if_then_else (match_operand 0 "constant_call_address_operand" "")
(const_int 4)
;; 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")
(if_then_else (and (eq_attr "prefix_0f" "1")
(eq_attr "prefix_extra" "0"))
(if_then_else (eq_attr "prefix_vex_w" "1")
- (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
- (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
+ (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
+ (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
(if_then_else (eq_attr "prefix_vex_w" "1")
- (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
- (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
+ (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
+ (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
;; Set when modrm byte is used.
(define_attr "modrm" ""
;; Define attribute to indicate unaligned ssemov insns
(define_attr "movu" "0,1" (const_string "0"))
+;; Used to control the "enabled" attribute on a per-instruction basis.
+(define_attr "isa" "base,noavx,avx"
+ (const_string "base"))
+
+(define_attr "enabled" ""
+ (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
+ (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
+ ]
+ (const_int 1)))
+
;; Describe a user's asm statement.
(define_asm_attributes
[(set_attr "length" "128")
(set_attr "type" "multi")])
-;; All integer comparison codes.
-(define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
-
-;; All floating-point comparison codes.
-(define_code_iterator fp_cond [unordered ordered
- uneq unge ungt unle unlt ltgt])
-
(define_code_iterator plusminus [plus minus])
(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
;; 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")])
;; Used in signed and unsigned divisions.
(define_code_iterator any_div [div udiv])
-(define_code_attr extract_code
- [(div "SIGN_EXTRACT") (udiv "ZERO_EXTRACT")])
;; Instruction prefix for signed and unsigned operations.
(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
;; Instruction suffix for integer modes.
(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
+;; Pointer size prefix for integer modes (Intel asm dialect)
+(define_mode_attr iptrsize [(QI "BYTE")
+ (HI "WORD")
+ (SI "DWORD")
+ (DI "QWORD")])
+
;; Register class for integer modes.
(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
(SI "general_operand")
(DI "x86_64_szext_general_operand")])
+;; Immediate operand predicate for integer modes.
+(define_mode_attr immediate_operand
+ [(QI "immediate_operand")
+ (HI "immediate_operand")
+ (SI "immediate_operand")
+ (DI "x86_64_immediate_operand")])
+
+;; Nonmemory operand predicate for integer modes.
+(define_mode_attr nonmemory_operand
+ [(QI "nonmemory_operand")
+ (HI "nonmemory_operand")
+ (SI "nonmemory_operand")
+ (DI "x86_64_nonmemory_operand")])
+
;; Operand predicate for shifts.
(define_mode_attr shift_operand
[(QI "nonimmediate_operand")
;; All integer modes handled by SSE cvtts?2si* operators.
(define_mode_iterator SSEMODEI24 [SI DI])
-;; SSE asm suffix for floating point modes
-(define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
+;; SSE instruction suffix for various modes
+(define_mode_attr ssemodesuffix
+ [(SF "ss") (DF "sd")
+ (V8SF "ps") (V4DF "pd")
+ (V4SF "ps") (V2DF "pd")
+ (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
+ (V8SI "si")])
+
+;; SSE vector suffix for floating point modes
+(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
;; SSE vector mode corresponding to a scalar mode
(define_mode_attr ssevecmode
(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
(compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
(match_operand:SDWIM 2 "<general_operand>" "")))
(set (pc) (if_then_else
- (match_operator 0 "comparison_operator"
+ (match_operator 0 "ordered_comparison_operator"
[(reg:CC FLAGS_REG) (const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))]
{
if (MEM_P (operands[1]) && MEM_P (operands[2]))
operands[1] = force_reg (<MODE>mode, operands[1]);
- ix86_compare_op0 = operands[1];
- ix86_compare_op1 = operands[2];
- ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ ix86_expand_branch (GET_CODE (operands[0]),
+ operands[1], operands[2], operands[3]);
DONE;
})
(compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
(match_operand:SWIM 3 "<general_operand>" "")))
(set (match_operand:QI 0 "register_operand" "")
- (match_operator 1 "comparison_operator"
+ (match_operator 1 "ordered_comparison_operator"
[(reg:CC FLAGS_REG) (const_int 0)]))]
""
{
if (MEM_P (operands[2]) && MEM_P (operands[3]))
operands[2] = force_reg (<MODE>mode, operands[2]);
- ix86_compare_op0 = operands[2];
- ix86_compare_op1 = operands[3];
- ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+ ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
+ operands[2], operands[3]);
DONE;
})
(define_expand "cmp<mode>_1"
[(set (reg:CC FLAGS_REG)
(compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
- (match_operand:SWI48 1 "<general_operand>" "")))]
- ""
- "")
+ (match_operand:SWI48 1 "<general_operand>" "")))])
(define_insn "*cmp<mode>_ccno_1"
[(set (reg FLAGS_REG)
(match_operand 0 "ext_register_operand" "")
(const_int 8)
(const_int 8)) 0)
- (match_operand:QI 1 "immediate_operand" "")))]
- ""
- "")
+ (match_operand:QI 1 "immediate_operand" "")))])
(define_insn "*cmpqi_ext_3_insn"
[(set (reg FLAGS_REG)
(pc)))]
"TARGET_80387"
{
- ix86_compare_op0 = operands[1];
- ix86_compare_op1 = operands[2];
- ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ ix86_expand_branch (GET_CODE (operands[0]),
+ operands[1], operands[2], operands[3]);
DONE;
})
(const_int 0)]))]
"TARGET_80387"
{
- ix86_compare_op0 = operands[2];
- ix86_compare_op1 = operands[3];
- ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+ ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
+ operands[2], operands[3]);
DONE;
})
(pc)))]
"TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
{
- ix86_compare_op0 = operands[1];
- ix86_compare_op1 = operands[2];
- ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ ix86_expand_branch (GET_CODE (operands[0]),
+ operands[1], operands[2], operands[3]);
DONE;
})
(const_int 0)]))]
"TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
{
- ix86_compare_op0 = operands[2];
- ix86_compare_op1 = operands[3];
- ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+ ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
+ operands[2], operands[3]);
DONE;
})
(pc)))]
""
{
- ix86_compare_op0 = operands[1];
- ix86_compare_op1 = operands[2];
- ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ ix86_expand_branch (GET_CODE (operands[0]),
+ operands[1], operands[2], operands[3]);
DONE;
})
(match_operand 3 "const0_operand" "")]))]
""
{
- ix86_compare_op0 = operands[2];
- ix86_compare_op1 = operands[3];
- ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+ ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
+ operands[2], operands[3]);
DONE;
})
UNSPEC_FNSTSW))]
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
- "* return output_fp_compare (insn, operands, 0, 0);"
+ "* return output_fp_compare (insn, operands, false, false);"
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set (attr "mode")
(match_operand:XF 2 "register_operand" "f"))]
UNSPEC_FNSTSW))]
"TARGET_80387"
- "* return output_fp_compare (insn, operands, 0, 0);"
+ "* return output_fp_compare (insn, operands, false, false);"
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set_attr "mode" "XF")])
(match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
UNSPEC_FNSTSW))]
"TARGET_80387"
- "* return output_fp_compare (insn, operands, 0, 0);"
+ "* return output_fp_compare (insn, operands, false, false);"
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set_attr "mode" "<MODE>")])
UNSPEC_FNSTSW))]
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
- "* return output_fp_compare (insn, operands, 0, 1);"
+ "* return output_fp_compare (insn, operands, false, true);"
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set (attr "mode")
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
&& (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
- "* return output_fp_compare (insn, operands, 0, 0);"
+ "* return output_fp_compare (insn, operands, false, false);"
[(set_attr "type" "multi")
(set_attr "unit" "i387")
(set_attr "fp_int_src" "true")
[(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.
"TARGET_MIX_SSE_I387
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
- "* return output_fp_compare (insn, operands, 1, 0);"
+ "* return output_fp_compare (insn, operands, true, false);"
[(set_attr "type" "fcmp,ssecomi")
(set_attr "prefix" "orig,maybe_vex")
(set (attr "mode")
]
(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)
"TARGET_SSE_MATH
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
- "* return output_fp_compare (insn, operands, 1, 0);"
+ "* return output_fp_compare (insn, operands, true, false);"
[(set_attr "type" "ssecomi")
(set_attr "prefix" "maybe_vex")
(set (attr "mode")
(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)
&& TARGET_CMOVE
&& !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
- "* return output_fp_compare (insn, operands, 1, 0);"
+ "* return output_fp_compare (insn, operands, true, false);"
[(set_attr "type" "fcmp")
(set (attr "mode")
(cond [(match_operand:SF 1 "" "")
]
(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)
"TARGET_MIX_SSE_I387
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
- "* return output_fp_compare (insn, operands, 1, 1);"
+ "* return output_fp_compare (insn, operands, true, true);"
[(set_attr "type" "fcmp,ssecomi")
(set_attr "prefix" "orig,maybe_vex")
(set (attr "mode")
]
(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)
"TARGET_SSE_MATH
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
- "* return output_fp_compare (insn, operands, 1, 1);"
+ "* return output_fp_compare (insn, operands, true, true);"
[(set_attr "type" "ssecomi")
(set_attr "prefix" "maybe_vex")
(set (attr "mode")
(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)
&& TARGET_CMOVE
&& !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
- "* return output_fp_compare (insn, operands, 1, 1);"
+ "* return output_fp_compare (insn, operands, true, true);"
[(set_attr "type" "fcmp")
(set (attr "mode")
(cond [(match_operand:SF 1 "" "")
]
(const_string "XF")))
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "direct")])
+ (set_attr "amdfam10_decode" "direct")
+ (set_attr "bdver1_decode" "direct")])
\f
-;; Move instructions.
-
-(define_expand "movoi"
- [(set (match_operand:OI 0 "nonimmediate_operand" "")
- (match_operand:OI 1 "general_operand" ""))]
- "TARGET_AVX"
- "ix86_expand_move (OImode, operands); DONE;")
+;; Push/pop instructions.
-(define_expand "movti"
- [(set (match_operand:TI 0 "nonimmediate_operand" "")
- (match_operand:TI 1 "nonimmediate_operand" ""))]
- "TARGET_64BIT || TARGET_SSE"
-{
- if (TARGET_64BIT)
- ix86_expand_move (TImode, operands);
- else if (push_operand (operands[0], TImode))
- ix86_expand_push (TImode, operands[1]);
- else
- ix86_expand_vector_move (TImode, operands);
- DONE;
-})
-
-;; This expands to what emit_move_complex would generate if we didn't
-;; have a movti pattern. Having this avoids problems with reload on
-;; 32-bit targets when SSE is present, but doesn't seem to be harmful
-;; to have around all the time.
-(define_expand "movcdi"
- [(set (match_operand:CDI 0 "nonimmediate_operand" "")
- (match_operand:CDI 1 "general_operand" ""))]
- ""
-{
- if (push_operand (operands[0], CDImode))
- emit_move_complex_push (CDImode, operands[0], operands[1]);
- else
- emit_move_complex_parts (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "mov<mode>"
- [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
- (match_operand:SWI1248x 1 "general_operand" ""))]
+(define_insn "*push<mode>2"
+ [(set (match_operand:DWI 0 "push_operand" "=<")
+ (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
""
- "ix86_expand_move (<MODE>mode, operands); DONE;")
+ "#")
-;; Push/pop instructions. They are separate since autoinc/dec is not a
-;; general_operand.
-;;
-;; %%% We don't use a post-inc memory reference because x86 is not a
-;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
-;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
-;; targets without our curiosities, and it is just as easy to represent
-;; this differently.
+(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" "=<,!<")
"TARGET_64BIT && !symbolic_operand (operands[1], DImode)
&& !x86_64_immediate_operand (operands[1], DImode)"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))]
- "")
+ (set (match_dup 0) (match_dup 2))])
;; We need to define this as both peepholer and splitter for case
;; peephole2 pass is not run.
[(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" ""))]
;; "push a byte/word". But actually we use pushl, which has the effect
;; of rounding the amount pushed up to a word.
-;; For 64BIT abi we always round up to 8 bytes.
+;; For TARGET_64BIT we always round up to 8 bytes.
(define_insn "*push<mode>2_rex64"
[(set (match_operand:SWI124 0 "push_operand" "=X")
(match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
[(set_attr "type" "push")
(set_attr "mode" "<MODE>")])
-(define_insn "popdi1"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
- (mem:DI (reg:DI SP_REG)))
- (set (reg:DI SP_REG)
- (plus:DI (reg:DI SP_REG) (const_int 8)))]
- "TARGET_64BIT"
- "pop{q}\t%0"
- [(set_attr "type" "pop")
- (set_attr "mode" "DI")])
-
-(define_insn "popsi1"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
- (mem:SI (reg:SI SP_REG)))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG) (const_int 4)))]
- "!TARGET_64BIT"
- "pop{l}\t%0"
+(define_insn "*pop<mode>1"
+ [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
+ (match_operand:P 1 "pop_operand" ">"))]
+ ""
+ "pop{<imodesuffix>}\t%0"
[(set_attr "type" "pop")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<MODE>")])
-(define_insn "*popdi1_epilogue"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
- (mem:DI (reg:DI SP_REG)))
- (set (reg:DI SP_REG)
- (plus:DI (reg:DI SP_REG) (const_int 8)))
+(define_insn "*pop<mode>1_epilogue"
+ [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
+ (match_operand:P 1 "pop_operand" ">"))
(clobber (mem:BLK (scratch)))]
- "TARGET_64BIT"
- "pop{q}\t%0"
+ ""
+ "pop{<imodesuffix>}\t%0"
[(set_attr "type" "pop")
- (set_attr "mode" "DI")])
+ (set_attr "mode" "<MODE>")])
+\f
+;; Move instructions.
-(define_insn "*popsi1_epilogue"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
- (mem:SI (reg:SI SP_REG)))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG) (const_int 4)))
- (clobber (mem:BLK (scratch)))]
- "!TARGET_64BIT"
- "pop{l}\t%0"
- [(set_attr "type" "pop")
- (set_attr "mode" "SI")])
+(define_expand "movoi"
+ [(set (match_operand:OI 0 "nonimmediate_operand" "")
+ (match_operand:OI 1 "general_operand" ""))]
+ "TARGET_AVX"
+ "ix86_expand_move (OImode, operands); DONE;")
+
+(define_expand "movti"
+ [(set (match_operand:TI 0 "nonimmediate_operand" "")
+ (match_operand:TI 1 "nonimmediate_operand" ""))]
+ "TARGET_64BIT || TARGET_SSE"
+{
+ if (TARGET_64BIT)
+ ix86_expand_move (TImode, operands);
+ else if (push_operand (operands[0], TImode))
+ ix86_expand_push (TImode, operands[1]);
+ else
+ ix86_expand_vector_move (TImode, operands);
+ DONE;
+})
+
+;; This expands to what emit_move_complex would generate if we didn't
+;; have a movti pattern. Having this avoids problems with reload on
+;; 32-bit targets when SSE is present, but doesn't seem to be harmful
+;; to have around all the time.
+(define_expand "movcdi"
+ [(set (match_operand:CDI 0 "nonimmediate_operand" "")
+ (match_operand:CDI 1 "general_operand" ""))]
+ ""
+{
+ if (push_operand (operands[0], CDImode))
+ emit_move_complex_push (CDImode, operands[0], operands[1]);
+ else
+ emit_move_complex_parts (operands[0], operands[1]);
+ DONE;
+})
+
+(define_expand "mov<mode>"
+ [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
+ (match_operand:SWI1248x 1 "general_operand" ""))]
+ ""
+ "ix86_expand_move (<MODE>mode, operands); DONE;")
(define_insn "*mov<mode>_xor"
[(set (match_operand:SWI48 0 "register_operand" "=r")
{
if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovups\t{%1, %0|%0, %1}";
- else
- return "%vmovdqu\t{%1, %0|%0, %1}";
+ else
+ return "%vmovdqu\t{%1, %0|%0, %1}";
}
else
{
if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovaps\t{%1, %0|%0, %1}";
- else
- return "%vmovdqa\t{%1, %0|%0, %1}";
+ else
+ return "%vmovdqa\t{%1, %0|%0, %1}";
}
default:
gcc_unreachable ();
{
if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovups\t{%1, %0|%0, %1}";
- else
- return "%vmovdqu\t{%1, %0|%0, %1}";
+ else
+ return "%vmovdqu\t{%1, %0|%0, %1}";
}
else
{
if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovaps\t{%1, %0|%0, %1}";
- else
- return "%vmovdqa\t{%1, %0|%0, %1}";
+ else
+ return "%vmovdqa\t{%1, %0|%0, %1}";
}
default:
gcc_unreachable ();
return "movdq2q\t{%1, %0|%0, %1}";
case TYPE_SSEMOV:
- if (TARGET_AVX)
- {
- if (get_attr_mode (insn) == MODE_TI)
- return "vmovdqa\t{%1, %0|%0, %1}";
- else
- return "vmovq\t{%1, %0|%0, %1}";
- }
-
if (get_attr_mode (insn) == MODE_TI)
- return "movdqa\t{%1, %0|%0, %1}";
- /* FALLTHRU */
+ return "%vmovdqa\t{%1, %0|%0, %1}";
+ /* Handle broken assemblers that require movd instead of movq. */
+ if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
+ return "%vmovd\t{%1, %0|%0, %1}";
+ else
+ return "%vmovq\t{%1, %0|%0, %1}";
case TYPE_MMXMOV:
- /* Moves from and into integer register is done using movd
- opcode with REX prefix. */
+ /* Handle broken assemblers that require movd instead of movq. */
if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
return "movd\t{%1, %0|%0, %1}";
- return "movq\t{%1, %0|%0, %1}";
+ else
+ return "movq\t{%1, %0|%0, %1}";
case TYPE_SSELOG1:
return "%vpxor\t%0, %d0";
"TARGET_64BIT && !symbolic_operand (operands[1], DImode)
&& !x86_64_immediate_operand (operands[1], DImode)"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))]
- "")
+ (set (match_dup 0) (match_dup 2))])
;; We need to define this as both peepholer and splitter for case
;; peephole2 pass is not run.
&& !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"
movlps\t{%1, %0|%0, %1}
movaps\t{%1, %0|%0, %1}
movlps\t{%1, %0|%0, %1}"
- [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
+ [(set (attr "isa")
+ (if_then_else (eq_attr "alternative" "9,10,11,12")
+ (const_string "noavx")
+ (const_string "base")))
+ (set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
(set (attr "prefix")
(if_then_else (eq_attr "alternative" "5,6,7,8")
- (const_string "vex")
+ (const_string "maybe_vex")
(const_string "orig")))
(set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
(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
{
if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
FAIL;
+ if (GET_CODE (operands[0]) == SUBREG
+ && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
+ FAIL;
/* Don't generate memory->memory moves, go through a register */
if (MEM_P (operands[0]) && MEM_P (operands[1]))
operands[1] = force_reg (<MODE>mode, operands[1]);
}
}
[(set (attr "type")
- (if_then_else (and (match_operand:QI 0 "register_operand" "")
- (ior (not (match_operand:QI 0 "q_regs_operand" ""))
- (ne (symbol_ref "TARGET_MOVX")
- (const_int 0))))
+ (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
+ (ne (symbol_ref "TARGET_MOVX")
+ (const_int 0)))
(const_string "imovx")
(const_string "imov")))
(set (attr "mode")
}
[(set (attr "type")
(if_then_else (and (match_operand:QI 0 "register_operand" "")
- (ior (not (match_operand:QI 0 "q_regs_operand" ""))
+ (ior (not (match_operand:QI 0 "QIreg_operand" ""))
(ne (symbol_ref "TARGET_MOVX")
(const_int 0))))
(const_string "imovx")
}
}
[(set (attr "type")
- (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
+ (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
(ne (symbol_ref "TARGET_MOVX")
(const_int 0)))
(const_string "imovx")
}
[(set (attr "type")
(if_then_else (and (match_operand:QI 0 "register_operand" "")
- (ior (not (match_operand:QI 0 "q_regs_operand" ""))
+ (ior (not (match_operand:QI 0 "QIreg_operand" ""))
(ne (symbol_ref "TARGET_MOVX")
(const_int 0))))
(const_string "imovx")
[(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
(const_int 8)
(const_int 8))
- (match_operand:SWI48 1 "nonmemory_operand" ""))]
- ""
- "")
+ (match_operand:SWI48 1 "nonmemory_operand" ""))])
(define_insn "*mov<mode>_insv_1_rex64"
[(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
[(set_attr "type" "imov")
(set_attr "mode" "QI")])
\f
-;; Floating point move instructions.
-
-(define_expand "movtf"
- [(set (match_operand:TF 0 "nonimmediate_operand" "")
- (match_operand:TF 1 "nonimmediate_operand" ""))]
- "TARGET_SSE2"
-{
- ix86_expand_move (TFmode, operands);
- DONE;
-})
-
-(define_expand "mov<mode>"
- [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
- (match_operand:X87MODEF 1 "general_operand" ""))]
- ""
- "ix86_expand_move (<MODE>mode, operands); DONE;")
+;; Floating point push instructions.
(define_insn "*pushtf"
[(set (match_operand:TF 0 "push_operand" "=<,<,<")
(define_split
[(set (match_operand:TF 0 "push_operand" "")
+ (match_operand:TF 1 "sse_reg_operand" ""))]
+ "TARGET_SSE2 && reload_completed"
+ [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
+ (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
+
+(define_split
+ [(set (match_operand:TF 0 "push_operand" "")
(match_operand:TF 1 "general_operand" ""))]
"TARGET_SSE2 && reload_completed
&& !SSE_REG_P (operands[1])"
[(const_int 0)]
"ix86_split_long_move (operands); DONE;")
-(define_split
- [(set (match_operand:TF 0 "push_operand" "")
- (match_operand:TF 1 "any_fp_register_operand" ""))]
- "TARGET_SSE2"
- [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
- (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
- "")
-
(define_insn "*pushxf"
[(set (match_operand:XF 0 "push_operand" "=<,<")
(match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
(define_split
[(set (match_operand:XF 0 "push_operand" "")
- (match_operand:XF 1 "any_fp_register_operand" ""))]
+ (match_operand:XF 1 "fp_register_operand" ""))]
"reload_completed"
[(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
(set (mem:XF (reg:P SP_REG)) (match_dup 1))]
[(set (match_operand:XF 0 "push_operand" "")
(match_operand:XF 1 "general_operand" ""))]
"reload_completed
- && !ANY_FP_REG_P (operands[1])"
+ && !FP_REG_P (operands[1])"
[(const_int 0)]
"ix86_split_long_move (operands); DONE;")
+;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
+;; Size of pushdf using integer instructions is 2+2*memory operand size
+;; On the average, pushdf using integers can be still shorter.
+
(define_insn "*pushdf"
[(set (match_operand:DF 0 "push_operand" "=<,<,<")
- (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
- "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
+ (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
+ ""
{
/* This insn should be already split before reg-stack. */
gcc_unreachable ();
(set_attr "unit" "i387,*,*")
(set_attr "mode" "DF,SI,DF")])
-;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
-;; Size of pushdf using integer instructions is 2+2*memory operand size
-;; On the average, pushdf using integers can be still shorter. Allow this
-;; pattern for optimize_size too.
-
-(define_insn "*pushdf_nointeger"
- [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
- (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
- "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
-{
- /* This insn should be already split before reg-stack. */
- gcc_unreachable ();
-}
- [(set_attr "type" "multi")
- (set_attr "unit" "i387,*,*,*")
- (set_attr "mode" "DF,SI,SI,DF")])
-
;; %%% Kill this when call knows how to work this out.
(define_split
[(set (match_operand:DF 0 "push_operand" "")
(match_operand:DF 1 "any_fp_register_operand" ""))]
"reload_completed"
[(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
- (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
- "")
+ (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
(define_split
[(set (match_operand:DF 0 "push_operand" "")
[(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
(set (mem:SF (reg:P SP_REG)) (match_dup 1))]
"operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
+\f
+;; Floating point move instructions.
+
+(define_expand "movtf"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (match_operand:TF 1 "nonimmediate_operand" ""))]
+ "TARGET_SSE2"
+{
+ ix86_expand_move (TFmode, operands);
+ DONE;
+})
+
+(define_expand "mov<mode>"
+ [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
+ (match_operand:X87MODEF 1 "general_operand" ""))]
+ ""
+ "ix86_expand_move (<MODE>mode, operands); DONE;")
(define_insn "*movtf_internal"
[(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
return "%vmovaps\t{%1, %0|%0, %1}";
else
return "%vmovdqa\t{%1, %0|%0, %1}";
+
case 2:
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vxorps\t%0, %d0";
- else
- return "%vpxor\t%0, %d0";
+ return standard_sse_constant_opcode (insn, operands[1]);
+
case 3:
case 4:
return "#";
+
default:
gcc_unreachable ();
}
"ix86_split_long_move (operands); DONE;")
(define_insn "*movxf_internal"
- [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
- (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
- "optimize_function_for_speed_p (cfun)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (reload_in_progress || reload_completed
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,Yx*r ,o")
+ (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
+ "!(MEM_P (operands[0]) && MEM_P (operands[1]))
+ && (!can_create_pseudo_p ()
+ || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| GET_CODE (operands[1]) != CONST_DOUBLE
+ || (optimize_function_for_size_p (cfun)
+ && standard_80387_constant_p (operands[1]) > 0)
|| memory_operand (operands[0], XFmode))"
{
switch (which_alternative)
case 3: case 4:
return "#";
-
default:
gcc_unreachable ();
}
[(set_attr "type" "fmov,fmov,fmov,multi,multi")
(set_attr "mode" "XF,XF,XF,SI,SI")])
-;; Do not use integer registers when optimizing for size
-(define_insn "*movxf_internal_nointeger"
- [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
- (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
- "optimize_function_for_size_p (cfun)
+(define_split
+ [(set (match_operand:XF 0 "nonimmediate_operand" "")
+ (match_operand:XF 1 "general_operand" ""))]
+ "reload_completed
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (reload_in_progress || reload_completed
- || standard_80387_constant_p (operands[1])
+ && ! (FP_REG_P (operands[0]) ||
+ (GET_CODE (operands[0]) == SUBREG
+ && FP_REG_P (SUBREG_REG (operands[0]))))
+ && ! (FP_REG_P (operands[1]) ||
+ (GET_CODE (operands[1]) == SUBREG
+ && FP_REG_P (SUBREG_REG (operands[1]))))"
+ [(const_int 0)]
+ "ix86_split_long_move (operands); DONE;")
+
+(define_insn "*movdf_internal_rex64"
+ [(set (match_operand:DF 0 "nonimmediate_operand"
+ "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
+ (match_operand:DF 1 "general_operand"
+ "fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
+ "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
+ && (!can_create_pseudo_p ()
+ || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| GET_CODE (operands[1]) != CONST_DOUBLE
- || memory_operand (operands[0], XFmode))"
-{
- switch (which_alternative)
- {
- case 0:
- case 1:
- return output_387_reg_move (insn, operands);
-
- case 2:
- return standard_80387_constant_opcode (operands[1]);
-
- case 3: case 4:
- return "#";
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "fmov,fmov,fmov,multi,multi")
- (set_attr "mode" "XF,XF,XF,SI,SI")])
-
-(define_split
- [(set (match_operand:XF 0 "nonimmediate_operand" "")
- (match_operand:XF 1 "general_operand" ""))]
- "reload_completed
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && ! (ANY_FP_REG_P (operands[0]) ||
- (GET_CODE (operands[0]) == SUBREG
- && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
- && ! (ANY_FP_REG_P (operands[1]) ||
- (GET_CODE (operands[1]) == SUBREG
- && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
- [(const_int 0)]
- "ix86_split_long_move (operands); DONE;")
-
-(define_insn "*movdf_internal_rex64"
- [(set (match_operand:DF 0 "nonimmediate_operand"
- "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
- (match_operand:DF 1 "general_operand"
- "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
- "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (reload_in_progress || reload_completed
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || (!(TARGET_SSE2 && TARGET_SSE_MATH)
- && optimize_function_for_size_p (cfun)
- && standard_80387_constant_p (operands[1]))
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || memory_operand (operands[0], DFmode))"
+ || (optimize_function_for_size_p (cfun)
+ && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
+ && standard_80387_constant_p (operands[1]) > 0)
+ || (TARGET_SSE2 && TARGET_SSE_MATH
+ && standard_sse_constant_p (operands[1]))))
+ || memory_operand (operands[0], DFmode))"
{
switch (which_alternative)
{
case 3:
case 4:
- return "#";
+ return "mov{q}\t{%1, %0|%0, %1}";
case 5:
- switch (get_attr_mode (insn))
- {
- case MODE_V4SF:
- return "%vxorps\t%0, %d0";
- case MODE_V2DF:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "%vxorps\t%0, %d0";
- else
- return "%vxorpd\t%0, %d0";
- case MODE_TI:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "%vxorps\t%0, %d0";
- else
- return "%vpxor\t%0, %d0";
- default:
- gcc_unreachable ();
- }
+ return "movabs{q}\t{%1, %0|%0, %1}";
+
case 6:
+ return "#";
+
case 7:
+ return standard_sse_constant_opcode (insn, operands[1]);
+
case 8:
+ case 9:
+ case 10:
switch (get_attr_mode (insn))
{
case MODE_V4SF:
case MODE_DI:
return "%vmovq\t{%1, %0|%0, %1}";
case MODE_DF:
- if (TARGET_AVX)
- {
- if (REG_P (operands[0]) && REG_P (operands[1]))
- return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
- else
- return "vmovsd\t{%1, %0|%0, %1}";
- }
+ if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
+ return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
else
- return "movsd\t{%1, %0|%0, %1}";
+ return "%vmovsd\t{%1, %0|%0, %1}";
case MODE_V1DF:
return "%vmovlpd\t{%1, %d0|%d0, %1}";
case MODE_V2SF:
gcc_unreachable ();
}
- case 9:
- case 10:
- return "%vmovd\t{%1, %0|%0, %1}";
+ case 11:
+ case 12:
+ /* Handle broken assemblers that require movd instead of movq. */
+ return "%vmovd\t{%1, %0|%0, %1}";
default:
gcc_unreachable();
}
}
- [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
+ [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
+ (set (attr "modrm")
+ (if_then_else
+ (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
+ (const_string "0")
+ (const_string "*")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
+ (const_string "8")
+ (const_string "*")))
(set (attr "prefix")
- (if_then_else (eq_attr "alternative" "0,1,2,3,4")
+ (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
(const_string "orig")
(const_string "maybe_vex")))
(set (attr "prefix_data16")
(set (attr "mode")
(cond [(eq_attr "alternative" "0,1,2")
(const_string "DF")
- (eq_attr "alternative" "3,4,9,10")
+ (eq_attr "alternative" "3,4,5,6,11,12")
(const_string "DI")
/* For SSE1, we have many fewer alternatives. */
(eq (symbol_ref "TARGET_SSE2") (const_int 0))
- (cond [(eq_attr "alternative" "5,6")
+ (cond [(eq_attr "alternative" "7,8")
(const_string "V4SF")
]
(const_string "V2SF"))
/* xorps is one byte shorter. */
- (eq_attr "alternative" "5")
+ (eq_attr "alternative" "7")
(cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
(const_int 0))
(const_string "V4SF")
chains, otherwise use short move to avoid extra work.
movaps encodes one byte shorter. */
- (eq_attr "alternative" "6")
+ (eq_attr "alternative" "8")
(cond
[(ne (symbol_ref "optimize_function_for_size_p (cfun)")
(const_int 0))
/* For architectures resolving dependencies on register
parts we may avoid extra work to zero out upper part
of register. */
- (eq_attr "alternative" "7")
+ (eq_attr "alternative" "9")
(if_then_else
(ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
(const_int 0))
]
(const_string "DF")))])
+;; Possible store forwarding (partial memory) stall in alternative 4.
(define_insn "*movdf_internal"
[(set (match_operand:DF 0 "nonimmediate_operand"
- "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
+ "=f,m,f,Yd*r ,o ,Y2*x,Y2*x,Y2*x,m ")
(match_operand:DF 1 "general_operand"
- "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))
- && optimize_function_for_speed_p (cfun)
- && TARGET_INTEGER_DFMODE_MOVES
- && (reload_in_progress || reload_completed
+ "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
+ "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
+ && (!can_create_pseudo_p ()
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || (!(TARGET_SSE2 && TARGET_SSE_MATH)
- && optimize_function_for_size_p (cfun)
- && standard_80387_constant_p (operands[1]))
|| GET_CODE (operands[1]) != CONST_DOUBLE
- || memory_operand (operands[0], DFmode))"
+ || (!TARGET_INTEGER_DFMODE_MOVES
+ && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
+ && standard_80387_constant_p (operands[1]) > 0)
+ || (TARGET_SSE2 && TARGET_SSE_MATH
+ && standard_sse_constant_p (operands[1])))
+ && !memory_operand (operands[0], DFmode))
+ || ((TARGET_INTEGER_DFMODE_MOVES
+ || !TARGET_MEMORY_MISMATCH_STALL)
+ && memory_operand (operands[0], DFmode)))"
{
switch (which_alternative)
{
return "#";
case 5:
- switch (get_attr_mode (insn))
- {
- case MODE_V4SF:
- return "xorps\t%0, %0";
- case MODE_V2DF:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "xorps\t%0, %0";
- else
- return "xorpd\t%0, %0";
- case MODE_TI:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "xorps\t%0, %0";
- else
- return "pxor\t%0, %0";
- default:
- gcc_unreachable ();
- }
- case 6:
- case 7:
- case 8:
- switch (get_attr_mode (insn))
- {
- case MODE_V4SF:
- return "movaps\t{%1, %0|%0, %1}";
- case MODE_V2DF:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "movaps\t{%1, %0|%0, %1}";
- else
- return "movapd\t{%1, %0|%0, %1}";
- case MODE_TI:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "movaps\t{%1, %0|%0, %1}";
- else
- return "movdqa\t{%1, %0|%0, %1}";
- case MODE_DI:
- return "movq\t{%1, %0|%0, %1}";
- case MODE_DF:
- return "movsd\t{%1, %0|%0, %1}";
- case MODE_V1DF:
- return "movlpd\t{%1, %0|%0, %1}";
- case MODE_V2SF:
- return "movlps\t{%1, %0|%0, %1}";
- default:
- gcc_unreachable ();
- }
+ return standard_sse_constant_opcode (insn, operands[1]);
- default:
- gcc_unreachable();
- }
-}
- [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
- (set (attr "prefix_data16")
- (if_then_else (eq_attr "mode" "V1DF")
- (const_string "1")
- (const_string "*")))
- (set (attr "mode")
- (cond [(eq_attr "alternative" "0,1,2")
- (const_string "DF")
- (eq_attr "alternative" "3,4")
- (const_string "SI")
-
- /* For SSE1, we have many fewer alternatives. */
- (eq (symbol_ref "TARGET_SSE2") (const_int 0))
- (cond [(eq_attr "alternative" "5,6")
- (const_string "V4SF")
- ]
- (const_string "V2SF"))
-
- /* xorps is one byte shorter. */
- (eq_attr "alternative" "5")
- (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
- (const_int 0))
- (const_string "V4SF")
- (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
- (const_int 0))
- (const_string "TI")
- ]
- (const_string "V2DF"))
-
- /* For architectures resolving dependencies on
- whole SSE registers use APD move to break dependency
- chains, otherwise use short move to avoid extra work.
-
- movaps encodes one byte shorter. */
- (eq_attr "alternative" "6")
- (cond
- [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
- (const_int 0))
- (const_string "V4SF")
- (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
- (const_int 0))
- (const_string "V2DF")
- ]
- (const_string "DF"))
- /* For architectures resolving dependencies on register
- parts we may avoid extra work to zero out upper part
- of register. */
- (eq_attr "alternative" "7")
- (if_then_else
- (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
- (const_int 0))
- (const_string "V1DF")
- (const_string "DF"))
- ]
- (const_string "DF")))])
-
-;; Moving is usually shorter when only FP registers are used. This separate
-;; movdf pattern avoids the use of integer registers for FP operations
-;; when optimizing for size.
-
-(define_insn "*movdf_internal_nointeger"
- [(set (match_operand:DF 0 "nonimmediate_operand"
- "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
- (match_operand:DF 1 "general_operand"
- "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))
- && ((optimize_function_for_size_p (cfun)
- || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
- && (reload_in_progress || reload_completed
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || (!(TARGET_SSE2 && TARGET_SSE_MATH)
- && optimize_function_for_size_p (cfun)
- && !memory_operand (operands[0], DFmode)
- && standard_80387_constant_p (operands[1]))
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || ((optimize_function_for_size_p (cfun)
- || !TARGET_MEMORY_MISMATCH_STALL
- || reload_in_progress || reload_completed)
- && memory_operand (operands[0], DFmode)))"
-{
- switch (which_alternative)
- {
- case 0:
- case 1:
- return output_387_reg_move (insn, operands);
-
- case 2:
- return standard_80387_constant_opcode (operands[1]);
-
- case 3:
- case 4:
- return "#";
- case 5:
- switch (get_attr_mode (insn))
- {
- case MODE_V4SF:
- return "%vxorps\t%0, %d0";
- case MODE_V2DF:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "%vxorps\t%0, %d0";
- else
- return "%vxorpd\t%0, %d0";
- case MODE_TI:
- if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
- return "%vxorps\t%0, %d0";
- else
- return "%vpxor\t%0, %d0";
- default:
- gcc_unreachable ();
- }
case 6:
case 7:
case 8:
case MODE_DI:
return "%vmovq\t{%1, %0|%0, %1}";
case MODE_DF:
- if (TARGET_AVX)
- {
- if (REG_P (operands[0]) && REG_P (operands[1]))
- return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
- else
- return "vmovsd\t{%1, %0|%0, %1}";
- }
+ if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
+ return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
else
- return "movsd\t{%1, %0|%0, %1}";
+ return "%vmovsd\t{%1, %0|%0, %1}";
case MODE_V1DF:
- if (TARGET_AVX)
- {
- if (REG_P (operands[0]))
- return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
- else
- return "vmovlpd\t{%1, %0|%0, %1}";
- }
+ if (TARGET_AVX && REG_P (operands[0]))
+ return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
else
- return "movlpd\t{%1, %0|%0, %1}";
+ return "%vmovlpd\t{%1, %0|%0, %1}";
case MODE_V2SF:
- if (TARGET_AVX)
- {
- if (REG_P (operands[0]))
- return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
- else
- return "vmovlps\t{%1, %0|%0, %1}";
- }
+ if (TARGET_AVX && REG_P (operands[0]))
+ return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
else
- return "movlps\t{%1, %0|%0, %1}";
+ return "%vmovlps\t{%1, %0|%0, %1}";
default:
gcc_unreachable ();
}
(match_operand:SF 1 "general_operand"
"fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (reload_in_progress || reload_completed
+ && (!can_create_pseudo_p ()
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
- && standard_80387_constant_p (operands[1]))
|| GET_CODE (operands[1]) != CONST_DOUBLE
+ || (optimize_function_for_size_p (cfun)
+ && ((!TARGET_SSE_MATH
+ && standard_80387_constant_p (operands[1]) > 0)
+ || (TARGET_SSE_MATH
+ && standard_sse_constant_p (operands[1]))))
|| memory_operand (operands[0], SFmode))"
{
switch (which_alternative)
case 3:
case 4:
return "mov{l}\t{%1, %0|%0, %1}";
+
case 5:
- if (get_attr_mode (insn) == MODE_TI)
- return "%vpxor\t%0, %d0";
- else
- return "%vxorps\t%0, %d0";
+ return standard_sse_constant_opcode (insn, operands[1]);
+
case 6:
if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovaps\t{%1, %0|%0, %1}";
else
return "%vmovss\t{%1, %d0|%d0, %1}";
case 7:
- if (TARGET_AVX)
- return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
- : "vmovss\t{%1, %0|%0, %1}";
+ if (TARGET_AVX && REG_P (operands[1]))
+ return "vmovss\t{%1, %0, %0|%0, %0, %1}";
else
- return "movss\t{%1, %0|%0, %1}";
+ return "%vmovss\t{%1, %0|%0, %1}";
case 8:
return "%vmovss\t{%1, %0|%0, %1}";
case 9: case 10: case 14: case 15:
return "movd\t{%1, %0|%0, %1}";
- case 12: case 13:
- return "%vmovd\t{%1, %0|%0, %1}";
case 11:
return "movq\t{%1, %0|%0, %1}";
+ case 12: case 13:
+ return "%vmovd\t{%1, %0|%0, %1}";
+
default:
gcc_unreachable ();
}
}
else if (FP_REG_P (r))
{
- if (!standard_80387_constant_p (c))
+ if (standard_80387_constant_p (c) < 1)
FAIL;
}
else if (MMX_REG_P (r))
}
else if (FP_REG_P (r))
{
- if (!standard_80387_constant_p (c))
+ if (standard_80387_constant_p (c) < 1)
FAIL;
}
else if (MMX_REG_P (r))
\f
;; Zero extension instructions
+(define_expand "zero_extendsidi2"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
+ ""
+{
+ if (!TARGET_64BIT)
+ {
+ emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
+ DONE;
+ }
+})
+
+(define_insn "*zero_extendsidi2_rex64"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
+ (zero_extend:DI
+ (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
+ "TARGET_64BIT"
+ "@
+ mov\t{%k1, %k0|%k0, %k1}
+ #
+ movd\t{%1, %0|%0, %1}
+ movd\t{%1, %0|%0, %1}
+ %vmovd\t{%1, %0|%0, %1}
+ %vmovd\t{%1, %0|%0, %1}"
+ [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
+ (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
+ (set_attr "prefix_0f" "0,*,*,*,*,*")
+ (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
+
+(define_split
+ [(set (match_operand:DI 0 "memory_operand" "")
+ (zero_extend:DI (match_dup 0)))]
+ "TARGET_64BIT"
+ [(set (match_dup 4) (const_int 0))]
+ "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
+
+;; %%% Kill me once multi-word ops are sane.
+(define_insn "zero_extendsidi2_1"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
+ (zero_extend:DI
+ (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
+ (clobber (reg:CC FLAGS_REG))]
+ "!TARGET_64BIT"
+ "@
+ #
+ #
+ #
+ movd\t{%1, %0|%0, %1}
+ movd\t{%1, %0|%0, %1}
+ %vmovd\t{%1, %0|%0, %1}
+ %vmovd\t{%1, %0|%0, %1}"
+ [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
+ (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
+ (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
+ (clobber (reg:CC FLAGS_REG))]
+ "!TARGET_64BIT && reload_completed
+ && true_regnum (operands[0]) == true_regnum (operands[1])"
+ [(set (match_dup 4) (const_int 0))]
+ "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
+
+(define_split
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
+ (clobber (reg:CC FLAGS_REG))]
+ "!TARGET_64BIT && reload_completed
+ && !(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_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
+
+(define_insn "zero_extend<mode>di2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
+ "TARGET_64BIT"
+ "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
+ [(set_attr "type" "imovx")
+ (set_attr "mode" "SI")])
+
(define_expand "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
""
{
if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
}
})
-(define_insn "zero_extendhisi2_and"
+(define_insn_and_split "zero_extendhisi2_and"
[(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
+ (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
"#"
- [(set_attr "type" "alu1")
- (set_attr "mode" "SI")])
-
-(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
- && optimize_function_for_speed_p (cfun)"
+ "&& reload_completed"
[(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
(clobber (reg:CC FLAGS_REG))])]
- "")
+ ""
+ [(set_attr "type" "alu1")
+ (set_attr "mode" "SI")])
(define_insn "*zero_extendhisi2_movzwl"
[(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
"!TARGET_ZERO_EXTEND_WITH_AND
|| optimize_function_for_size_p (cfun)"
"movz{wl|x}\t{%1, %0|%0, %1}"
[(set_attr "type" "imovx")
(set_attr "mode" "SI")])
-(define_expand "zero_extendqihi2"
+(define_expand "zero_extendqi<mode>2"
[(parallel
- [(set (match_operand:HI 0 "register_operand" "")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- "")
+ [(set (match_operand:SWI24 0 "register_operand" "")
+ (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
+ (clobber (reg:CC FLAGS_REG))])])
-(define_insn "*zero_extendqihi2_and"
- [(set (match_operand:HI 0 "register_operand" "=r,?&q")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
+(define_insn "*zero_extendqi<mode>2_and"
+ [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
+ (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
"#"
[(set_attr "type" "alu1")
- (set_attr "mode" "HI")])
-
-(define_insn "*zero_extendqihi2_movzbw_and"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
- "#"
- [(set_attr "type" "imovx,alu1")
- (set_attr "mode" "HI")])
-
-; zero extend to SImode here to avoid partial register stalls
-(define_insn "*zero_extendqihi2_movzbl"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
- "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
- && reload_completed"
- "movz{bl|x}\t{%1, %k0|%k0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
-
-;; For the movzbw case strip only the clobber
-(define_split
- [(set (match_operand:HI 0 "register_operand" "")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed
- && (!TARGET_ZERO_EXTEND_WITH_AND
- || optimize_function_for_size_p (cfun))
- && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
- [(set (match_operand:HI 0 "register_operand" "")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
+ (set_attr "mode" "<MODE>")])
;; When source and destination does not overlap, clear destination
;; first and then do the movb
(define_split
- [(set (match_operand:HI 0 "register_operand" "")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
+ [(set (match_operand:SWI24 0 "register_operand" "")
+ (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
+ && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
&& ANY_QI_REG_P (operands[0])
- && (TARGET_ZERO_EXTEND_WITH_AND
- && optimize_function_for_speed_p (cfun))
+ && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
&& !reg_overlap_mentioned_p (operands[0], operands[1])"
[(set (strict_low_part (match_dup 2)) (match_dup 1))]
{
ix86_expand_clear (operands[0]);
})
-;; Rest is handled by single and.
-(define_split
- [(set (match_operand:HI 0 "register_operand" "")
- (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed
- && true_regnum (operands[0]) == true_regnum (operands[1])"
- [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
- (clobber (reg:CC FLAGS_REG))])]
- "")
-
-(define_expand "zero_extendqisi2"
- [(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- "")
-
-(define_insn "*zero_extendqisi2_and"
- [(set (match_operand:SI 0 "register_operand" "=r,?&q")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
- "#"
- [(set_attr "type" "alu1")
- (set_attr "mode" "SI")])
-
-(define_insn "*zero_extendqisi2_movzbl_and"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
+(define_insn "*zero_extendqi<mode>2_movzbl_and"
+ [(set (match_operand:SWI24 0 "register_operand" "=r,r")
+ (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
"#"
[(set_attr "type" "imovx,alu1")
- (set_attr "mode" "SI")])
-
-(define_insn "*zero_extendqisi2_movzbl"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
- "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
- && reload_completed"
- "movz{bl|x}\t{%1, %0|%0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<MODE>")])
;; For the movzbl case strip only the clobber
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
+ [(set (match_operand:SWI24 0 "register_operand" "")
+ (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
&& (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
&& (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
[(set (match_dup 0)
- (zero_extend:SI (match_dup 1)))])
+ (zero_extend:SWI24 (match_dup 1)))])
-;; When source and destination does not overlap, clear destination
-;; first and then do the movb
-(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
+; zero extend to SImode to avoid partial register stalls
+(define_insn "*zero_extendqi<mode>2_movzbl"
+ [(set (match_operand:SWI24 0 "register_operand" "=r")
+ (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
"reload_completed
- && ANY_QI_REG_P (operands[0])
- && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
- && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
- && !reg_overlap_mentioned_p (operands[0], operands[1])"
- [(set (strict_low_part (match_dup 2)) (match_dup 1))]
-{
- operands[2] = gen_lowpart (QImode, operands[0]);
- ix86_expand_clear (operands[0]);
-})
+ && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
+ "movz{bl|x}\t{%1, %k0|%k0, %1}"
+ [(set_attr "type" "imovx")
+ (set_attr "mode" "SI")])
;; Rest is handled by single and.
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
+ [(set (match_operand:SWI24 0 "register_operand" "")
+ (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
&& true_regnum (operands[0]) == true_regnum (operands[1])"
- [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
- (clobber (reg:CC FLAGS_REG))])]
- "")
-
-;; %%% Kill me once multi-word ops are sane.
-(define_expand "zero_extendsidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
- ""
-{
- if (!TARGET_64BIT)
- {
- emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
- DONE;
- }
-})
-
-(define_insn "zero_extendsidi2_32"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
- (zero_extend:DI
- (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT"
- "@
- #
- #
- #
- movd\t{%1, %0|%0, %1}
- movd\t{%1, %0|%0, %1}
- %vmovd\t{%1, %0|%0, %1}
- %vmovd\t{%1, %0|%0, %1}"
- [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
- (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
- (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
-
-(define_insn "zero_extendsidi2_rex64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
- (zero_extend:DI
- (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
- "TARGET_64BIT"
- "@
- mov\t{%k1, %k0|%k0, %k1}
- #
- movd\t{%1, %0|%0, %1}
- movd\t{%1, %0|%0, %1}
- %vmovd\t{%1, %0|%0, %1}
- %vmovd\t{%1, %0|%0, %1}"
- [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
- (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
- (set_attr "prefix_0f" "0,*,*,*,*,*")
- (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
-
-(define_split
- [(set (match_operand:DI 0 "memory_operand" "")
- (zero_extend:DI (match_dup 0)))]
- "TARGET_64BIT"
- [(set (match_dup 4) (const_int 0))]
- "split_di (&operands[0], 1, &operands[3], &operands[4]);")
-
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "!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]);")
-
-(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT && reload_completed
- && !(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]);")
-
-(define_insn "zero_extendhidi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
- "TARGET_64BIT"
- "movz{wl|x}\t{%1, %k0|%k0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
-
-(define_insn "zero_extendqidi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
- "TARGET_64BIT"
- "movz{bl|x}\t{%1, %k0|%k0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
+ [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
+ (clobber (reg:CC FLAGS_REG))])])
\f
;; Sign extension instructions
(define_expand "extendsidi2"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (match_scratch:SI 2 ""))])]
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
""
{
- if (TARGET_64BIT)
+ if (!TARGET_64BIT)
{
- emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
+ emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
DONE;
}
})
-(define_insn "*extendsidi2_1"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
- (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
- "!TARGET_64BIT"
- "#")
-
-(define_insn "extendsidi2_rex64"
+(define_insn "*extendsidi2_rex64"
[(set (match_operand:DI 0 "register_operand" "=*a,r")
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
"TARGET_64BIT"
(set_attr "prefix_0f" "0")
(set_attr "modrm" "0,1")])
-(define_insn "extendhidi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
- "TARGET_64BIT"
- "movs{wq|x}\t{%1, %0|%0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "DI")])
-
-(define_insn "extendqidi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
- "TARGET_64BIT"
- "movs{bq|x}\t{%1, %0|%0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "DI")])
+(define_insn "extendsidi2_1"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
+ (clobber (reg:CC FLAGS_REG))
+ (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
+ "!TARGET_64BIT"
+ "#")
;; Extend to memory case when source register does die.
(define_split
(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]);
DONE;
})
+(define_insn "extend<mode>di2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI
+ (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
+ "TARGET_64BIT"
+ "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "imovx")
+ (set_attr "mode" "DI")])
+
(define_insn "extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=*a,r")
(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
(define_insn "*extendhisi2_zext"
[(set (match_operand:DI 0 "register_operand" "=*a,r")
(zero_extend:DI
- (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
+ (sign_extend:SI
+ (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
"TARGET_64BIT"
{
switch (get_attr_prefix_0f (insn))
(const_string "0")
(const_string "1")))])
+(define_insn "extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
+ ""
+ "movs{bl|x}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "imovx")
+ (set_attr "mode" "SI")])
+
+(define_insn "*extendqisi2_zext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
+ "TARGET_64BIT"
+ "movs{bl|x}\t{%1, %k0|%k0, %1}"
+ [(set_attr "type" "imovx")
+ (set_attr "mode" "SI")])
+
(define_insn "extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=*a,r")
(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
(if_then_else (eq_attr "prefix_0f" "0")
(const_string "0")
(const_string "1")))])
-
-(define_insn "extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
- ""
- "movs{bl|x}\t{%1, %0|%0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
-
-(define_insn "*extendqisi2_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
- "TARGET_64BIT"
- "movs{bl|x}\t{%1, %k0|%k0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
\f
;; Conversions between float and double.
-;; These are all no-ops in the model used for the 80387. So just
-;; emit moves.
+;; These are all no-ops in the model used for the 80387.
+;; So just emit moves.
;; %%% Kill these when call knows how to work out a DFmode push earlier.
-(define_insn "*dummy_extendsfdf2"
- [(set (match_operand:DF 0 "push_operand" "=<")
- (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
- "0"
- "#")
-
(define_split
[(set (match_operand:DF 0 "push_operand" "")
(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
- ""
+ "reload_completed"
[(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
(set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
-(define_insn "*dummy_extendsfxf2"
- [(set (match_operand:XF 0 "push_operand" "=<")
- (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
- "0"
- "#")
-
(define_split
[(set (match_operand:XF 0 "push_operand" "")
- (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
- ""
+ (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
+ "reload_completed"
[(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
(set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
"operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
-(define_split
- [(set (match_operand:XF 0 "push_operand" "")
- (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
- ""
- [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
- (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
- "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
-
(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "nonimmediate_operand" "")
(float_extend:DF (match_operand:SF 1 "general_operand" "")))]
"TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
{
/* ??? Needed for compress_float_constant since all fp constants
- are LEGITIMATE_CONSTANT_P. */
+ are TARGET_LEGITIMATE_CONSTANT_P. */
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
"TARGET_80387"
{
/* ??? Needed for compress_float_constant since all fp constants
- are LEGITIMATE_CONSTANT_P. */
+ are TARGET_LEGITIMATE_CONSTANT_P. */
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
if (standard_80387_constant_p (operands[1]) > 0)
(define_expand "truncdfsf2_with_temp"
[(parallel [(set (match_operand:SF 0 "" "")
(float_truncate:SF (match_operand:DF 1 "" "")))
- (clobber (match_operand:SF 2 "" ""))])]
- "")
+ (clobber (match_operand:SF 2 "" ""))])])
(define_insn "*truncdfsf_fast_mixed"
[(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
"reload_completed"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
-{
- operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
-})
+ "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
;; Conversion from XFmode to {SF,DF}mode
}
else
{
- enum ix86_stack_slot slot = (virtuals_instantiated
- ? SLOT_TEMP
- : SLOT_VIRTUAL);
+ enum ix86_stack_slot slot = (virtuals_instantiated
+ ? SLOT_TEMP
+ : SLOT_VIRTUAL);
operands[2] = assign_386_stack_local (<MODE>mode, slot);
}
})
(clobber (match_operand:MODEF 2 "memory_operand" ""))]
"TARGET_80387 && reload_completed"
[(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
- (set (match_dup 0) (match_dup 2))]
- "")
+ (set (match_dup 0) (match_dup 2))])
(define_split
[(set (match_operand:MODEF 0 "memory_operand" "")
(match_operand:XF 1 "register_operand" "")))
(clobber (match_operand:MODEF 2 "memory_operand" ""))]
"TARGET_80387"
- [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
- "")
+ [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
\f
;; Signed conversion to DImode.
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);
})
(fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
"TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
&& (!TARGET_FISTTP || TARGET_SSE_MATH)"
- "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
+ "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
[(set_attr "type" "sseicvt")
(set_attr "prefix" "maybe_vex")
(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")
(fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
"SSE_FLOAT_MODE_P (<MODE>mode)
&& (!TARGET_FISTTP || TARGET_SSE_MATH)"
- "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
+ "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
[(set_attr "type" "sseicvt")
(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 (match_operand:SSEMODEI24 2 "register_operand" "")
(fix:SSEMODEI24 (match_dup 0)))]
"TARGET_SHORTEN_X87_SSE
+ && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
&& peep2_reg_dead_p (2, operands[0])"
- [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
- "")
+ [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
;; Avoid vector decoded forms of the instruction.
(define_peephole2
(fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
"TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
- "")
+ (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
(define_peephole2
[(match_scratch:SF 2 "x")
(fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
"TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
- "")
+ (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
[(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
&& !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
&& (TARGET_64BIT || <MODE>mode != DImode))
&& TARGET_SSE_MATH)"
- "* return output_fix_trunc (insn, operands, 1);"
+ "* return output_fix_trunc (insn, operands, true);"
[(set_attr "type" "fisttp")
(set_attr "mode" "<MODE>")])
"reload_completed"
[(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
(clobber (match_dup 3))])
- (set (match_dup 0) (match_dup 2))]
- "")
+ (set (match_dup 0) (match_dup 2))])
(define_split
[(set (match_operand:X87MODEI 0 "memory_operand" "")
(clobber (match_scratch 3 ""))]
"reload_completed"
[(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
- (clobber (match_dup 3))])]
- "")
+ (clobber (match_dup 3))])])
;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& !TARGET_FISTTP
&& !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "trunc")
(set_attr "mode" "DI")])
(use (match_dup 2))
(use (match_dup 3))
(clobber (match_dup 5))])
- (set (match_dup 0) (match_dup 4))]
- "")
+ (set (match_dup 0) (match_dup 4))])
(define_split
[(set (match_operand:DI 0 "memory_operand" "")
[(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
(use (match_dup 2))
(use (match_dup 3))
- (clobber (match_dup 5))])]
- "")
+ (clobber (match_dup 5))])])
(define_insn "fix_trunc<mode>_i387"
[(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
"X87_FLOAT_MODE_P (GET_MODE (operands[1]))
&& !TARGET_FISTTP
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "trunc")
(set_attr "mode" "<MODE>")])
[(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
(use (match_dup 2))
(use (match_dup 3))])
- (set (match_dup 0) (match_dup 4))]
- "")
+ (set (match_dup 0) (match_dup 4))])
(define_split
[(set (match_operand:X87MODEI12 0 "memory_operand" "")
"reload_completed"
[(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
(use (match_dup 2))
- (use (match_dup 3))])]
- "")
+ (use (match_dup 3))])])
(define_insn "x86_fnstcw_1"
[(set (match_operand:HI 0 "memory_operand" "=m")
(unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
"TARGET_80387"
"fnstcw\t%0"
- [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
+ [(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)
(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
"TARGET_80387"
"fldcw\t%0"
- [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
+ [(set (attr "length")
+ (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
(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.
(float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
"TARGET_80387
&& (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)"
- "")
+ || TARGET_MIX_SSE_I387)")
;; Pre-reload splitter to add memory clobber to the pattern.
(define_insn_and_split "*floathi<mode>2_1"
|| TARGET_MIX_SSE_I387)
&& reload_completed"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
- "")
+ (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
(define_split
[(set (match_operand:X87MODEF 0 "register_operand" "")
&& (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
|| TARGET_MIX_SSE_I387)
&& reload_completed"
- [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
- "")
+ [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
(define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
[(set (match_operand:X87MODEF 0 "register_operand" "")
&& !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
{
rtx reg = gen_reg_rtx (XFmode);
- rtx insn;
+ rtx (*insn)(rtx, rtx);
emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
if (<X87MODEF:MODE>mode == SFmode)
- insn = gen_truncxfsf2 (operands[0], reg);
+ insn = gen_truncxfsf2;
else if (<X87MODEF:MODE>mode == DFmode)
- insn = gen_truncxfdf2 (operands[0], reg);
+ insn = gen_truncxfdf2;
else
gcc_unreachable ();
- emit_insn (insn);
+ emit_insn (insn (operands[0], reg));
DONE;
}
})
(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
&& (SSE_REG_P (operands[0])
|| (GET_CODE (operands[0]) == SUBREG
&& SSE_REG_P (operands[0])))"
- [(set (match_dup 0) (float:MODEF (match_dup 1)))]
- "")
+ [(set (match_dup 0) (float:MODEF (match_dup 1)))])
(define_split
[(set (match_operand:MODEF 0 "register_operand" "")
|| (GET_CODE (operands[0]) == SUBREG
&& SSE_REG_P (operands[0])))"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (float:MODEF (match_dup 2)))]
- "")
+ (set (match_dup 0) (float:MODEF (match_dup 2)))])
(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
[(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
&& (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
"@
fild%Z1\t%1
- %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
- %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
+ %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
+ %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
[(set_attr "type" "fmov,sseicvt,sseicvt")
(set_attr "prefix" "orig,maybe_vex,maybe_vex")
(set_attr "mode" "<MODEF:MODE>")
(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"
&& !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
"@
fild%Z1\t%1
- %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
+ %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
[(set_attr "type" "fmov,sseicvt")
(set_attr "prefix" "orig,maybe_vex")
(set_attr "mode" "<MODEF:MODE>")
(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
CONST0_RTX (V4SImode), operands[2]));
}
emit_insn
- (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
+ (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
DONE;
})
emit_insn (gen_sse2_loadld (operands[4],
CONST0_RTX (V4SImode), operands[1]));
emit_insn
- (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
+ (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
DONE;
})
else
gcc_unreachable ();
emit_insn
- (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
+ (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
DONE;
})
emit_insn (gen_sse2_loadld (operands[4],
CONST0_RTX (V4SImode), operands[1]));
emit_insn
- (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
+ (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
DONE;
})
(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"
"(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
&& SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
&& (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
- "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
+ "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
[(set_attr "type" "sseicvt")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODEF:MODE>")
(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
&& (SSE_REG_P (operands[0])
|| (GET_CODE (operands[0]) == SUBREG
&& SSE_REG_P (operands[0])))"
- [(set (match_dup 0) (float:MODEF (match_dup 1)))]
- "")
+ [(set (match_dup 0) (float:MODEF (match_dup 1)))])
(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
[(set (match_operand:MODEF 0 "register_operand" "=x")
"(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
&& SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
&& !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
- "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
+ "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
[(set_attr "type" "sseicvt")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODEF:MODE>")
(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
|| (GET_CODE (operands[0]) == SUBREG
&& SSE_REG_P (operands[0])))"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (float:MODEF (match_dup 2)))]
- "")
+ (set (match_dup 0) (float:MODEF (match_dup 2)))])
(define_split
[(set (match_operand:MODEF 0 "register_operand" "")
&& (SSE_REG_P (operands[0])
|| (GET_CODE (operands[0]) == SUBREG
&& SSE_REG_P (operands[0])))"
- [(set (match_dup 0) (float:MODEF (match_dup 1)))]
- "")
+ [(set (match_dup 0) (float:MODEF (match_dup 1)))])
(define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
[(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
&& reload_completed
&& FP_REG_P (operands[0])"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
- "")
+ (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
(define_split
[(set (match_operand:X87MODEF 0 "register_operand" "")
&& X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
&& reload_completed
&& FP_REG_P (operands[0])"
- [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
- "")
+ [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
;; Avoid store forwarding (partial memory) stall penalty
;; by passing DImode value through XMM registers. */
&& !TARGET_64BIT && optimize_function_for_speed_p (cfun)
&& reload_completed
&& FP_REG_P (operands[0])"
- [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
- "")
+ [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
;; Avoid store forwarding (partial memory) stall penalty by extending
;; SImode value to DImode through XMM register instead of pushing two
(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)
(set_attr "mode" "QI")])
(define_insn "*lea_1"
- [(set (match_operand:DWIH 0 "register_operand" "=r")
- (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (match_operand:P 1 "no_seg_address_operand" "p"))]
""
"lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
[(set_attr "type" "lea")
switch (get_attr_type (insn))
{
case TYPE_LEA:
- operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
- return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
+ return "#";
case TYPE_INCDEC:
gcc_assert (rtx_equal_p (operands[0], operands[1]));
}
default:
- /* Use add as much as possible to replace lea for AGU optimization. */
- if (which_alternative == 2 && TARGET_OPT_AGU)
- return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
+ /* For most processors, ADD is faster than LEA. This alternative
+ was added to use ADD as much as possible. */
+ if (which_alternative == 2)
+ {
+ rtx tmp;
+ tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
+ }
gcc_assert (rtx_equal_p (operands[0], operands[1]));
if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
}
}
[(set (attr "type")
- (cond [(and (eq_attr "alternative" "2")
- (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
- (const_string "lea")
- (eq_attr "alternative" "3")
+ (cond [(eq_attr "alternative" "3")
(const_string "lea")
(match_operand:SWI48 2 "incdec_operand" "")
(const_string "incdec")
;; patterns constructed from addsi_1 to match.
(define_insn "*addsi_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r")
(zero_extend:DI
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
- (match_operand:SI 2 "general_operand" "g,li"))))
+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
+ (match_operand:SI 2 "general_operand" "g,0,li"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_LEA:
- operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
- return "lea{l}\t{%a2, %k0|%k0, %a2}";
+ return "#";
case TYPE_INCDEC:
if (operands[2] == const1_rtx)
}
default:
+ /* For most processors, ADD is faster than LEA. This alternative
+ was added to use ADD as much as possible. */
+ if (which_alternative == 1)
+ {
+ rtx tmp;
+ tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
+ }
+
if (x86_maybe_negate_const_int (&operands[2], SImode))
return "sub{l}\t{%2, %k0|%k0, %2}";
}
}
[(set (attr "type")
- (cond [(eq_attr "alternative" "1")
+ (cond [(eq_attr "alternative" "2")
(const_string "lea")
(match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "*")))
(set_attr "mode" "HI")])
-;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
-;; type optimizations enabled by define-splits. This is not important
-;; for PII, and in fact harmful because of partial register stalls.
-
(define_insn "*addhi_1_lea"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
- (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
- (match_operand:HI 2 "general_operand" "rn,rm,ln")))
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
+ (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_PARTIAL_REG_STALL
&& ix86_binary_operator_ok (PLUS, HImode, operands)"
}
default:
+ /* For most processors, ADD is faster than LEA. This alternative
+ was added to use ADD as much as possible. */
+ if (which_alternative == 2)
+ {
+ rtx tmp;
+ tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
+ }
+
gcc_assert (rtx_equal_p (operands[0], operands[1]));
if (x86_maybe_negate_const_int (&operands[2], HImode))
return "sub{w}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (eq_attr "alternative" "2")
- (const_string "lea")
- (if_then_else (match_operand:HI 2 "incdec_operand" "")
- (const_string "incdec")
- (const_string "alu"))))
+ (cond [(eq_attr "alternative" "3")
+ (const_string "lea")
+ (match_operand:HI 2 "incdec_operand" "")
+ (const_string "incdec")
+ ]
+ (const_string "alu")))
(set (attr "length_immediate")
(if_then_else
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "HI,HI,SI")])
+ (set_attr "mode" "HI,HI,HI,SI")])
+;; %%% Potential partial reg stall on alternative 2. What to do?
(define_insn "*addqi_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
(const_string "*")))
(set_attr "mode" "QI,QI,SI")])
-;; %%% Potential partial reg stall on alternative 2. What to do?
+;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
(define_insn "*addqi_1_lea"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
- (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
- (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
+ (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_PARTIAL_REG_STALL
&& ix86_binary_operator_ok (PLUS, QImode, operands)"
{
- int widen = (which_alternative == 2);
+ int widen = (which_alternative == 3 || which_alternative == 4);
+
switch (get_attr_type (insn))
{
case TYPE_LEA:
}
default:
+ /* For most processors, ADD is faster than LEA. These alternatives
+ were added to use ADD as much as possible. */
+ if (which_alternative == 2 || which_alternative == 4)
+ {
+ rtx tmp;
+ tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
+ }
+
gcc_assert (rtx_equal_p (operands[0], operands[1]));
if (x86_maybe_negate_const_int (&operands[2], QImode))
{
}
}
[(set (attr "type")
- (if_then_else (eq_attr "alternative" "3")
- (const_string "lea")
- (if_then_else (match_operand:QI 2 "incdec_operand" "")
- (const_string "incdec")
- (const_string "alu"))))
+ (cond [(eq_attr "alternative" "5")
+ (const_string "lea")
+ (match_operand:QI 2 "incdec_operand" "")
+ (const_string "incdec")
+ ]
+ (const_string "alu")))
(set (attr "length_immediate")
(if_then_else
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "QI,QI,SI,SI")])
+ (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
(define_insn "*addqi_1_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
(const_string "none")))
(set_attr "mode" "QI")])
+;; Convert lea to the lea pattern to avoid flags dependency.
+(define_split
+ [(set (match_operand 0 "register_operand" "")
+ (plus (match_operand 1 "register_operand" "")
+ (match_operand 2 "nonmemory_operand" "")))
+ (clobber (reg:CC FLAGS_REG))]
+ "reload_completed && ix86_lea_for_add_ok (insn, operands)"
+ [(const_int 0)]
+{
+ rtx pat;
+ enum machine_mode mode = GET_MODE (operands[0]);
+
+ /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
+ may confuse gen_lowpart. */
+ if (mode != Pmode)
+ {
+ operands[1] = gen_lowpart (Pmode, operands[1]);
+ operands[2] = gen_lowpart (Pmode, operands[2]);
+ }
+
+ pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
+
+ if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
+ operands[0] = gen_lowpart (SImode, operands[0]);
+
+ if (TARGET_64BIT && mode != Pmode)
+ pat = gen_rtx_SUBREG (SImode, pat, 0);
+
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
+ DONE;
+})
+
+;; Convert lea to the lea pattern to avoid flags dependency.
+;; ??? This pattern handles immediate operands that do not satisfy immediate
+;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "x86_64_immediate_operand" "")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT && reload_completed
+ && true_regnum (operands[0]) != true_regnum (operands[1])"
+ [(set (match_dup 0)
+ (plus:DI (match_dup 1) (match_dup 2)))])
+
+;; Convert lea to the lea pattern to avoid flags dependency.
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" ""))))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT && reload_completed
+ && ix86_lea_for_add_ok (insn, operands)"
+ [(set (match_dup 0)
+ (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
+{
+ operands[1] = gen_lowpart (DImode, operands[1]);
+ operands[2] = gen_lowpart (DImode, operands[2]);
+})
+
(define_insn "*add<mode>_2"
[(set (reg FLAGS_REG)
(compare
}
[(set_attr "type" "lea")
(set_attr "mode" "SI")])
-
-;; Convert lea to the lea pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && reload_completed
- && ix86_lea_for_add_ok (PLUS, insn, operands)"
- [(set (match_dup 0)
- (plus:DI (match_dup 1)
- (match_dup 2)))]
- "")
-
-;; Convert lea to the lea pattern to avoid flags dependency.
-(define_split
- [(set (match_operand 0 "register_operand" "")
- (plus (match_operand 1 "register_operand" "")
- (match_operand 2 "nonmemory_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
- [(const_int 0)]
-{
- rtx pat;
- /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
- may confuse gen_lowpart. */
- if (GET_MODE (operands[0]) != Pmode)
- {
- operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[2] = gen_lowpart (Pmode, operands[2]);
- }
- operands[0] = gen_lowpart (SImode, operands[0]);
- pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
- if (Pmode != SImode)
- pat = gen_rtx_SUBREG (SImode, pat, 0);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
- DONE;
-})
-
-;; Convert lea to the lea pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (zero_extend:DI
- (plus:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" ""))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])"
- [(set (match_dup 0)
- (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
-{
- operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[2] = gen_lowpart (Pmode, operands[2]);
-})
\f
;; Subtract instructions
(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>")
(const_int 0)])
(match_operand:SWI 2 "<general_operand>" ""))))
(clobber (reg:CC FLAGS_REG))])]
- "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
- "")
+ "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
(define_insn "*<plusminus_insn><mode>3_carry"
[(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
(compare:CCC
(plus:SWI
(match_operand:SWI 1 "nonimmediate_operand" "%0")
- (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
+ (match_operand:SWI 2 "<general_operand>" "<g>"))
(match_dup 1)))
(clobber (match_scratch:SWI 0 "=<r>"))]
- "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
+ "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
"add{<imodesuffix>}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
(set_attr "mode" "<MODE>")])
(plusminus:XF
(match_operand:XF 1 "register_operand" "")
(match_operand:XF 2 "register_operand" "")))]
- "TARGET_80387"
- "")
+ "TARGET_80387")
(define_expand "<plusminus_insn><mode>3"
[(set (match_operand:MODEF 0 "register_operand" "")
(match_operand:MODEF 1 "register_operand" "")
(match_operand:MODEF 2 "nonimmediate_operand" "")))]
"(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
- || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
- "")
+ || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
\f
;; Multiply instructions
(mult:SWIM248
(match_operand:SWIM248 1 "register_operand" "")
(match_operand:SWIM248 2 "<general_operand>" "")))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- "")
+ (clobber (reg:CC FLAGS_REG))])])
(define_expand "mulqi3"
[(parallel [(set (match_operand:QI 0 "register_operand" "")
(match_operand:QI 1 "register_operand" "")
(match_operand:QI 2 "nonimmediate_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
- "TARGET_QIMODE_MATH"
- "")
+ "TARGET_QIMODE_MATH")
;; On AMDFAM10
;; IMUL reg32/64, reg32/64, imm8 Direct
;; 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"
(match_operand:DWIH 1 "nonimmediate_operand" ""))
(any_extend:<DWI>
(match_operand:DWIH 2 "register_operand" ""))))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- "")
+ (clobber (reg:CC FLAGS_REG))])])
(define_expand "<u>mulqihi3"
[(parallel [(set (match_operand:HI 0 "register_operand" "")
(any_extend:HI
(match_operand:QI 2 "register_operand" ""))))
(clobber (reg:CC FLAGS_REG))])]
- "TARGET_QIMODE_MATH"
- "")
+ "TARGET_QIMODE_MATH")
(define_insn "*<u>mul<mode><dwi>3_1"
[(set (match_operand:<DWI> 0 "register_operand" "=A")
(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_operand:XF 0 "register_operand" "")
(mult:XF (match_operand:XF 1 "register_operand" "")
(match_operand:XF 2 "register_operand" "")))]
- "TARGET_80387"
- "")
+ "TARGET_80387")
(define_expand "mul<mode>3"
[(set (match_operand:MODEF 0 "register_operand" "")
(mult:MODEF (match_operand:MODEF 1 "register_operand" "")
(match_operand:MODEF 2 "nonimmediate_operand" "")))]
"(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
- || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
- "")
+ || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
\f
;; Divide instructions
[(set (match_operand:XF 0 "register_operand" "")
(div:XF (match_operand:XF 1 "register_operand" "")
(match_operand:XF 2 "register_operand" "")))]
- "TARGET_80387"
- "")
+ "TARGET_80387")
(define_expand "divdf3"
[(set (match_operand:DF 0 "register_operand" "")
(div:DF (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "nonimmediate_operand" "")))]
"(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
- || (TARGET_SSE2 && TARGET_SSE_MATH)"
- "")
+ || (TARGET_SSE2 && TARGET_SSE_MATH)")
(define_expand "divsf3"
[(set (match_operand:SF 0 "register_operand" "")
\f
;; Divmod instructions.
-(define_expand "<u>divmodqi4"
- [(parallel [(set (match_operand:QI 0 "register_operand" "")
- (any_div:QI
- (match_operand:QI 1 "register_operand" "")
- (match_operand:QI 2 "nonimmediate_operand" "")))
- (set (match_operand:QI 3 "register_operand" "")
- (mod:QI (match_dup 1) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_QIMODE_MATH"
-{
- rtx div, mod, insn;
- rtx tmp0, tmp1;
-
- tmp0 = gen_reg_rtx (HImode);
- tmp1 = gen_reg_rtx (HImode);
-
- /* Extend operands[1] to HImode. Generate 8bit divide. Result is
- in AX. */
- if (<extract_code> == SIGN_EXTRACT)
- {
- emit_insn (gen_extendqihi2 (tmp1, operands[1]));
- emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
-
- div = gen_rtx_DIV (QImode, operands[1], operands[2]);
- mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
-
- tmp1 = gen_rtx_<extract_code> (QImode, tmp0,
- GEN_INT (8), GEN_INT (8));
- }
- else
- {
- emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
- emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
-
- div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
- mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
-
- tmp1 = gen_rtx_<extract_code> (SImode, tmp0,
- GEN_INT (8), GEN_INT (8));
- tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
- }
-
- /* Extract remainder from AH. */
- insn = emit_move_insn (operands[3], tmp1);
- set_unique_reg_note (insn, REG_EQUAL, mod);
-
- /* Extract quotient from AL. */
- insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
- set_unique_reg_note (insn, REG_EQUAL, div);
-
- DONE;
-})
-
-;; Divide AX by r/m8, with result stored in
-;; AL <- Quotient
-;; AH <- Remainder
-(define_insn "divmodhiqi3"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (ior:HI
- (ashift:HI
- (zero_extend:HI
- (mod:QI (match_operand:HI 1 "register_operand" "0")
- (match_operand:QI 2 "nonimmediate_operand" "qm")))
- (const_int 8))
- (zero_extend:HI (div:QI (match_dup 1) (match_dup 2)))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_QIMODE_MATH"
- "idiv{b}\t%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "QI")])
-
-(define_insn "udivmodhiqi3"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (ior:HI
- (ashift:HI
- (zero_extend:HI
- (umod:QI (match_operand:HI 1 "register_operand" "0")
- (match_operand:QI 2 "nonimmediate_operand" "qm")))
- (const_int 8))
- (zero_extend:HI (udiv:QI (match_dup 1) (match_dup 2)))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_QIMODE_MATH"
- "div{b}\t%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "QI")])
-
(define_expand "divmod<mode>4"
[(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
(div:SWIM248
(match_operand:SWIM248 2 "nonimmediate_operand" "")))
(set (match_operand:SWIM248 3 "register_operand" "")
(mod:SWIM248 (match_dup 1) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
+ (clobber (reg:CC FLAGS_REG))])])
+
+;; Split with 8bit unsigned divide:
+;; if (dividend an divisor are in [0-255])
+;; use 8bit unsigned integer divide
+;; else
+;; use original integer divide
+(define_split
+ [(set (match_operand:SWI48 0 "register_operand" "")
+ (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
+ (match_operand:SWI48 3 "nonimmediate_operand" "")))
+ (set (match_operand:SWI48 1 "register_operand" "")
+ (mod:SWI48 (match_dup 2) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_USE_8BIT_IDIV
+ && TARGET_QIMODE_MATH
+ && can_create_pseudo_p ()
+ && !optimize_insn_for_size_p ()"
+ [(const_int 0)]
+ "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
+
+(define_insn_and_split "divmod<mode>4_1"
+ [(set (match_operand:SWI48 0 "register_operand" "=a")
+ (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
+ (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
+ (set (match_operand:SWI48 1 "register_operand" "=&d")
+ (mod:SWI48 (match_dup 2) (match_dup 3)))
+ (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
+ (clobber (reg:CC FLAGS_REG))]
""
- "")
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 1)
+ (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
+ (clobber (reg:CC FLAGS_REG))])
+ (parallel [(set (match_dup 0)
+ (div:SWI48 (match_dup 2) (match_dup 3)))
+ (set (match_dup 1)
+ (mod:SWI48 (match_dup 2) (match_dup 3)))
+ (use (match_dup 1))
+ (clobber (reg:CC FLAGS_REG))])]
+{
+ operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
+
+ if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
+ operands[4] = operands[2];
+ else
+ {
+ /* Avoid use of cltd in favor of a mov+shift. */
+ emit_move_insn (operands[1], operands[2]);
+ operands[4] = operands[1];
+ }
+}
+ [(set_attr "type" "multi")
+ (set_attr "mode" "<MODE>")])
(define_insn_and_split "*divmod<mode>4"
[(set (match_operand:SWIM248 0 "register_operand" "=a")
[(set_attr "type" "idiv")
(set_attr "mode" "<MODE>")])
+(define_expand "divmodqi4"
+ [(parallel [(set (match_operand:QI 0 "register_operand" "")
+ (div:QI
+ (match_operand:QI 1 "register_operand" "")
+ (match_operand:QI 2 "nonimmediate_operand" "")))
+ (set (match_operand:QI 3 "register_operand" "")
+ (mod:QI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC FLAGS_REG))])]
+ "TARGET_QIMODE_MATH"
+{
+ rtx div, mod, insn;
+ rtx tmp0, tmp1;
+
+ tmp0 = gen_reg_rtx (HImode);
+ tmp1 = gen_reg_rtx (HImode);
+
+ /* Extend operands[1] to HImode. Generate 8bit divide. Result is
+ in AX. */
+ emit_insn (gen_extendqihi2 (tmp1, operands[1]));
+ emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
+
+ /* Extract remainder from AH. */
+ tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
+ insn = emit_move_insn (operands[3], tmp1);
+
+ mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
+ set_unique_reg_note (insn, REG_EQUAL, mod);
+
+ /* Extract quotient from AL. */
+ insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
+
+ div = gen_rtx_DIV (QImode, operands[1], operands[2]);
+ set_unique_reg_note (insn, REG_EQUAL, div);
+
+ DONE;
+})
+
+;; Divide AX by r/m8, with result stored in
+;; AL <- Quotient
+;; AH <- Remainder
+;; Change div/mod to HImode and extend the second argument to HImode
+;; so that mode of div/mod matches with mode of arguments. Otherwise
+;; combine may fail.
+(define_insn "divmodhiqi3"
+ [(set (match_operand:HI 0 "register_operand" "=a")
+ (ior:HI
+ (ashift:HI
+ (zero_extend:HI
+ (truncate:QI
+ (mod:HI (match_operand:HI 1 "register_operand" "0")
+ (sign_extend:HI
+ (match_operand:QI 2 "nonimmediate_operand" "qm")))))
+ (const_int 8))
+ (zero_extend:HI
+ (truncate:QI
+ (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_QIMODE_MATH"
+ "idiv{b}\t%2"
+ [(set_attr "type" "idiv")
+ (set_attr "mode" "QI")])
+
(define_expand "udivmod<mode>4"
[(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
(udiv:SWIM248
(match_operand:SWIM248 2 "nonimmediate_operand" "")))
(set (match_operand:SWIM248 3 "register_operand" "")
(umod:SWIM248 (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC FLAGS_REG))])])
+
+;; Split with 8bit unsigned divide:
+;; if (dividend an divisor are in [0-255])
+;; use 8bit unsigned integer divide
+;; else
+;; use original integer divide
+(define_split
+ [(set (match_operand:SWI48 0 "register_operand" "")
+ (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
+ (match_operand:SWI48 3 "nonimmediate_operand" "")))
+ (set (match_operand:SWI48 1 "register_operand" "")
+ (umod:SWI48 (match_dup 2) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_USE_8BIT_IDIV
+ && TARGET_QIMODE_MATH
+ && can_create_pseudo_p ()
+ && !optimize_insn_for_size_p ()"
+ [(const_int 0)]
+ "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
+
+(define_insn_and_split "udivmod<mode>4_1"
+ [(set (match_operand:SWI48 0 "register_operand" "=a")
+ (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
+ (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
+ (set (match_operand:SWI48 1 "register_operand" "=&d")
+ (umod:SWI48 (match_dup 2) (match_dup 3)))
+ (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
+ (clobber (reg:CC FLAGS_REG))]
+ ""
+ "#"
+ "reload_completed"
+ [(set (match_dup 1) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (udiv:SWI48 (match_dup 2) (match_dup 3)))
+ (set (match_dup 1)
+ (umod:SWI48 (match_dup 2) (match_dup 3)))
+ (use (match_dup 1))
(clobber (reg:CC FLAGS_REG))])]
""
- "")
+ [(set_attr "type" "multi")
+ (set_attr "mode" "<MODE>")])
(define_insn_and_split "*udivmod<mode>4"
[(set (match_operand:SWIM248 0 "register_operand" "=a")
[(set_attr "type" "idiv")
(set_attr "mode" "<MODE>")])
+(define_expand "udivmodqi4"
+ [(parallel [(set (match_operand:QI 0 "register_operand" "")
+ (udiv:QI
+ (match_operand:QI 1 "register_operand" "")
+ (match_operand:QI 2 "nonimmediate_operand" "")))
+ (set (match_operand:QI 3 "register_operand" "")
+ (umod:QI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC FLAGS_REG))])]
+ "TARGET_QIMODE_MATH"
+{
+ rtx div, mod, insn;
+ rtx tmp0, tmp1;
+
+ tmp0 = gen_reg_rtx (HImode);
+ tmp1 = gen_reg_rtx (HImode);
+
+ /* Extend operands[1] to HImode. Generate 8bit divide. Result is
+ in AX. */
+ emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
+ emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
+
+ /* Extract remainder from AH. */
+ tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
+ tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
+ insn = emit_move_insn (operands[3], tmp1);
+
+ mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
+ set_unique_reg_note (insn, REG_EQUAL, mod);
+
+ /* Extract quotient from AL. */
+ insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
+
+ div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
+ set_unique_reg_note (insn, REG_EQUAL, div);
+
+ DONE;
+})
+
+(define_insn "udivmodhiqi3"
+ [(set (match_operand:HI 0 "register_operand" "=a")
+ (ior:HI
+ (ashift:HI
+ (zero_extend:HI
+ (truncate:QI
+ (mod:HI (match_operand:HI 1 "register_operand" "0")
+ (zero_extend:HI
+ (match_operand:QI 2 "nonimmediate_operand" "qm")))))
+ (const_int 8))
+ (zero_extend:HI
+ (truncate:QI
+ (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_QIMODE_MATH"
+ "div{b}\t%2"
+ [(set_attr "type" "idiv")
+ (set_attr "mode" "QI")])
+
;; We cannot use div/idiv for double division, because it causes
;; "division by zero" on the overflow and that's not what we expect
;; from truncate. Because true (non truncating) double division is
(compare:CCNO
(and:SI (match_operand:SI 0 "nonimmediate_operand" "")
(match_operand:SI 1 "nonmemory_operand" ""))
- (const_int 0)))]
- ""
- "")
+ (const_int 0)))])
(define_expand "testqi_ccz_1"
[(set (reg:CCZ FLAGS_REG)
(compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
(match_operand:QI 1 "nonmemory_operand" ""))
- (const_int 0)))]
- ""
- "")
+ (const_int 0)))])
+
+(define_expand "testdi_ccno_1"
+ [(set (reg:CCNO FLAGS_REG)
+ (compare:CCNO
+ (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
+ (match_operand:DI 1 "x86_64_szext_general_operand" ""))
+ (const_int 0)))]
+ "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
(define_insn "*testdi_1"
[(set (reg FLAGS_REG)
(const_int 8)
(const_int 8))
(match_operand 1 "const_int_operand" ""))
- (const_int 0)))]
- ""
- "")
+ (const_int 0)))])
(define_insn "*testqi_ext_0"
[(set (reg FLAGS_REG)
(if_then_else
(and (eq_attr "type" "imovx")
(and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
- (match_operand 1 "ext_QIreg_nomode_operand" "")))
+ (match_operand 1 "ext_QIreg_operand" "")))
(const_string "1")
(const_string "*")))
(set_attr "mode" "SI,DI,DI,SI")])
(if_then_else
(and (eq_attr "type" "imovx")
(and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
- (match_operand 1 "ext_QIreg_nomode_operand" "")))
+ (match_operand 1 "ext_QIreg_operand" "")))
(const_string "1")
(const_string "*")))
(set_attr "length_immediate" "*,*,0")
(set (attr "prefix_rex")
(if_then_else
(and (eq_attr "type" "imovx")
- (match_operand 1 "ext_QIreg_nomode_operand" ""))
+ (match_operand 1 "ext_QIreg_operand" ""))
(const_string "1")
(const_string "*")))
(set_attr "mode" "HI,HI,SI")])
(const_int 0)))
(clobber (match_scratch:SWI 0 "=<r>"))]
"ix86_match_ccmode (insn, CCNOmode)
- && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+ && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
"<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
(set_attr "mode" "<MODE>")])
(match_dup 1)
(const_int 8)
(const_int 8))
- (match_dup 2)))])]
- ""
- "")
+ (match_dup 2)))])])
(define_insn "*xorqi_cc_ext_1_rex64"
[(set (reg FLAGS_REG)
[(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")
(match_operand:CSGNMODE 2 "register_operand" "")]
"(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
|| (TARGET_SSE2 && (<MODE>mode == TFmode))"
-{
- ix86_expand_copysign (operands);
- DONE;
-})
+ "ix86_expand_copysign (operands); DONE;")
(define_insn_and_split "copysign<mode>3_const"
[(set (match_operand:CSGNMODE 0 "register_operand" "=x")
"#"
"&& reload_completed"
[(const_int 0)]
-{
- ix86_split_copysign_const (operands);
- DONE;
-})
+ "ix86_split_copysign_const (operands); DONE;")
(define_insn "copysign<mode>3_var"
[(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
|| (TARGET_SSE2 && (<MODE>mode == TFmode)))
&& reload_completed"
[(const_int 0)]
-{
- ix86_split_copysign_var (operands);
- DONE;
-})
+ "ix86_split_copysign_var (operands); DONE;")
\f
;; One complement instructions
(match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
(const_int 0)]))
(set (match_dup 1)
- (xor:SWI (match_dup 3) (const_int -1)))])]
- "")
+ (xor:SWI (match_dup 3) (const_int -1)))])])
;; ??? Currently never generated - xor is used instead.
(define_insn "*one_cmplsi2_2_zext"
(match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
(const_int 0)]))
(set (match_dup 1)
- (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
- "")
+ (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
\f
;; Shift instructions
(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")
(if_then_else
(ior (eq_attr "type" "alu")
(and (eq_attr "type" "ishift1")
- (and (match_operand 1 "const1_operand" "")
- (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
- (const_int 0)))))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "QI")])
-
-;; Convert lea to the lea pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ashift:DI (match_operand:DI 1 "index_register_operand" "")
- (match_operand:QI 2 "const_int_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])"
- [(set (match_dup 0)
- (mult:DI (match_dup 1)
- (match_dup 2)))]
- "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
+ (and (match_operand 1 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
+ (set_attr "mode" "QI")])
;; Convert lea to the lea pattern to avoid flags dependency.
(define_split
(match_operand:QI 2 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])
- && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
+ && true_regnum (operands[0]) != true_regnum (operands[1])"
[(const_int 0)]
{
rtx pat;
enum machine_mode mode = GET_MODE (operands[0]);
- if (GET_MODE_SIZE (mode) < 4)
- operands[0] = gen_lowpart (SImode, operands[0]);
if (mode != Pmode)
operands[1] = gen_lowpart (Pmode, operands[1]);
operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
- if (Pmode != SImode)
+
+ if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
+ operands[0] = gen_lowpart (SImode, operands[0]);
+
+ if (TARGET_64BIT && mode != Pmode)
pat = gen_rtx_SUBREG (SImode, pat, 0);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
- DONE;
-})
-;; Rare case of shifting RSP is handled by generating move and shift
-(define_split
- [(set (match_operand 0 "register_operand" "")
- (ashift (match_operand 1 "register_operand" "")
- (match_operand:QI 2 "const_int_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])"
- [(const_int 0)]
-{
- rtx pat, clob;
- emit_move_insn (operands[0], operands[1]);
- pat = gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_ASHIFT (GET_MODE (operands[0]),
- operands[0], operands[2]));
- clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
- emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
DONE;
})
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(zero_extend:DI
- (ashift:SI (match_operand:SI 1 "register_operand" "")
+ (ashift:SI (match_operand:SI 1 "index_register_operand" "")
(match_operand:QI 2 "const_int_operand" ""))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed
[(set (match_dup 0)
(zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
{
- operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
+ operands[1] = gen_lowpart (DImode, operands[1]);
+ operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
})
;; This pattern can't accept a variable shift count, since shifts by
(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"
&& (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
[(parallel [(set (strict_low_part (match_dup 0))
(bswap:HI (match_dup 0)))
- (clobber (reg:CC FLAGS_REG))])]
- "")
+ (clobber (reg:CC FLAGS_REG))])])
\f
;; Bit set / bit test instructions
})
(define_expand "insv"
- [(set (zero_extract (match_operand 0 "ext_register_operand" "")
- (match_operand 1 "const8_operand" "")
- (match_operand 2 "const8_operand" ""))
+ [(set (zero_extract (match_operand 0 "register_operand" "")
+ (match_operand 1 "const_int_operand" "")
+ (match_operand 2 "const_int_operand" ""))
(match_operand 3 "register_operand" ""))]
""
{
+ rtx (*gen_mov_insv_1) (rtx, rtx);
+
+ if (ix86_expand_pinsr (operands))
+ DONE;
+
/* Handle insertions to %ah et al. */
if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
FAIL;
if (! ext_register_operand (operands[0], VOIDmode))
FAIL;
- if (TARGET_64BIT)
- emit_insn (gen_movdi_insv_1 (operands[0], operands[3]));
- else
- emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
+ gen_mov_insv_1 = (TARGET_64BIT
+ ? gen_movdi_insv_1 : gen_movsi_insv_1);
+ emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
DONE;
})
(const_int 0)))]
""
[(set (match_dup 0) (match_dup 1))]
-{
- PUT_MODE (operands[1], QImode);
-})
+ "PUT_MODE (operands[1], QImode);")
(define_split
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
(const_int 0)))]
""
[(set (match_dup 0) (match_dup 1))]
-{
- PUT_MODE (operands[1], QImode);
-})
+ "PUT_MODE (operands[1], QImode);")
(define_split
[(set (match_operand:QI 0 "nonimmediate_operand" "")
;; 0xffffffff is NaN, but not in normalized form, so we can't represent
;; it directly.
-(define_insn "*avx_setcc<mode>"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (match_operator:MODEF 1 "avx_comparison_float_operator"
- [(match_operand:MODEF 2 "register_operand" "x")
- (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
- "TARGET_AVX"
- "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
- [(set_attr "type" "ssecmp")
- (set_attr "prefix" "vex")
- (set_attr "length_immediate" "1")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*sse_setcc<mode>"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (match_operator:MODEF 1 "sse_comparison_operator"
- [(match_operand:MODEF 2 "register_operand" "0")
- (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
+(define_insn "setcc_<mode>_sse"
+ [(set (match_operand:MODEF 0 "register_operand" "=x,x")
+ (match_operator:MODEF 3 "sse_comparison_operator"
+ [(match_operand:MODEF 1 "register_operand" "0,x")
+ (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
"SSE_FLOAT_MODE_P (<MODE>mode)"
- "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
- [(set_attr "type" "ssecmp")
+ "@
+ cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
+ vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "type" "ssecmp")
(set_attr "length_immediate" "1")
+ (set_attr "prefix" "orig,vex")
(set_attr "mode" "<MODE>")])
\f
;; Basic conditional jump instructions.
(if_then_else (match_dup 0)
(label_ref (match_dup 1))
(pc)))]
-{
- PUT_MODE (operands[0], VOIDmode);
-})
+ "PUT_MODE (operands[0], VOIDmode);")
(define_split
[(set (pc)
;; P6 processors will jump to the address after the decrement when %esp
;; is used as a call operand, so they will execute return address as a code.
;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
-
+
+;; Register constraint for call instruction.
+(define_mode_attr c [(SI "l") (DI "r")])
+
;; Call subroutine returning no value.
+(define_expand "call"
+ [(call (match_operand:QI 0 "" "")
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))]
+ ""
+{
+ ix86_expand_call (NULL, operands[0], operands[1],
+ operands[2], NULL, false);
+ DONE;
+})
+
+(define_expand "sibcall"
+ [(call (match_operand:QI 0 "" "")
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))]
+ ""
+{
+ ix86_expand_call (NULL, operands[0], operands[1],
+ operands[2], NULL, true);
+ DONE;
+})
+
+(define_insn_and_split "*call_vzeroupper"
+ [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
+ (match_operand 1 "" ""))
+ (unspec [(match_operand 2 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !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"
+ [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
+ (match_operand 1 "" ""))]
+ "!SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[0]);"
+ [(set_attr "type" "call")])
+
+(define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
+ [(parallel
+ [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
+ (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_rex64_ms_sysv"
+ [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
+ (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))]
+ "TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[0]);"
+ [(set_attr "type" "call")])
+
+(define_insn_and_split "*sibcall_vzeroupper"
+ [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
+ (match_operand 1 "" ""))
+ (unspec [(match_operand 2 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && 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"
+ [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
+ (match_operand 1 "" ""))]
+ "SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[0]);"
+ [(set_attr "type" "call")])
+
(define_expand "call_pop"
[(parallel [(call (match_operand:QI 0 "" "")
(match_operand:SI 1 "" ""))
"!TARGET_64BIT"
{
ix86_expand_call (NULL, operands[0], operands[1],
- operands[2], operands[3], 0);
+ operands[2], operands[3], false);
DONE;
})
-(define_insn "*call_pop_0"
- [(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" "")))]
- "!TARGET_64BIT"
-{
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P0";
- else
- return "call\t%P0";
-}
+(define_insn_and_split "*call_pop_vzeroupper"
+ [(parallel
+ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
+ (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 "" ""))
+(define_insn "*call_pop"
+ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
+ (match_operand 1 "" ""))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
(match_operand:SI 2 "immediate_operand" "i")))]
"!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]);"
+ [(set_attr "type" "call")])
+
+(define_insn_and_split "*sibcall_pop_vzeroupper"
+ [(parallel
+ [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
+ (match_operand 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 "*sibcall_pop_1"
- [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
- (match_operand:SI 1 "" ""))
+(define_insn "*sibcall_pop"
+ [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
+ (match_operand 1 "" ""))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
- (match_operand:SI 2 "immediate_operand" "i,i")))]
+ (match_operand:SI 2 "immediate_operand" "i")))]
"!TARGET_64BIT && SIBLING_CALL_P (insn)"
- "@
- jmp\t%P0
- jmp\t%A0"
+ "* return ix86_output_call_insn (insn, operands[0]);"
[(set_attr "type" "call")])
-(define_expand "call"
- [(call (match_operand:QI 0 "" "")
- (match_operand 1 "" ""))
- (use (match_operand 2 "" ""))]
+;; Call subroutine, returning value in operand 0
+
+(define_expand "call_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "" "")
+ (match_operand 2 "" "")))
+ (use (match_operand 3 "" ""))]
""
{
- ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
+ ix86_expand_call (operands[0], operands[1], operands[2],
+ operands[3], NULL, false);
DONE;
})
-(define_expand "sibcall"
- [(call (match_operand:QI 0 "" "")
- (match_operand 1 "" ""))
- (use (match_operand 2 "" ""))]
+(define_expand "sibcall_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "" "")
+ (match_operand 2 "" "")))
+ (use (match_operand 3 "" ""))]
""
{
- ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
+ ix86_expand_call (operands[0], operands[1], operands[2],
+ operands[3], NULL, true);
DONE;
})
-(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";
-}
- [(set_attr "type" "call")])
+(define_insn_and_split "*call_value_vzeroupper"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
+ (match_operand 2 "" "")))
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && !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_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";
-}
- [(set_attr "type" "call")])
+(define_insn "*call_value"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
+ (match_operand 2 "" "")))]
+ "!SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[1]);"
+ [(set_attr "type" "callv")])
-(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"
- [(set_attr "type" "call")])
+(define_insn_and_split "*sibcall_value_vzeroupper"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
+ (match_operand 2 "" "")))
+ (unspec [(match_operand 3 "const_int_operand" "")]
+ UNSPEC_CALL_NEEDS_VZEROUPPER)]
+ "TARGET_VZEROUPPER && 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_1_rex64"
- [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
- (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";
-}
- [(set_attr "type" "call")])
+(define_insn "*sibcall_value"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
+ (match_operand 2 "" "")))]
+ "SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[1]);"
+ [(set_attr "type" "callv")])
-(define_insn "*call_1_rex64_ms_sysv"
- [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
- (match_operand 1 "" ""))
+(define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
+ [(parallel
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
+ (match_operand 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_rex64_ms_sysv"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
+ (match_operand 2 "" "")))
(unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
(clobber (reg:TI XMM6_REG))
(clobber (reg:TI XMM7_REG))
(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";
-}
- [(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"
- [(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"
- [(set_attr "type" "call")])
+ "* return ix86_output_call_insn (insn, operands[1]);"
+ [(set_attr "type" "callv")])
-;; Call subroutine, returning value in operand 0
(define_expand "call_value_pop"
[(parallel [(set (match_operand 0 "" "")
(call (match_operand:QI 1 "" "")
"!TARGET_64BIT"
{
ix86_expand_call (operands[0], operands[1], operands[2],
- operands[3], operands[4], 0);
+ operands[3], operands[4], false);
DONE;
})
-(define_expand "call_value"
+(define_insn_and_split "*call_value_pop_vzeroupper"
+ [(parallel
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
+ (match_operand 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"
[(set (match_operand 0 "" "")
- (call (match_operand:QI 1 "" "")
- (match_operand:SI 2 "" "")))
- (use (match_operand:SI 3 "" ""))]
- ;; Operand 3 is not used on the i386.
- ""
-{
- ix86_expand_call (operands[0], operands[1], operands[2],
- operands[3], NULL, 0);
- DONE;
-})
+ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
+ (match_operand 2 "" "")))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 3 "immediate_operand" "i")))]
+ "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[1]);"
+ [(set_attr "type" "callv")])
-(define_expand "sibcall_value"
+(define_insn_and_split "*sibcall_value_pop_vzeroupper"
+ [(parallel
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
+ (match_operand 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 "*sibcall_value_pop"
[(set (match_operand 0 "" "")
- (call (match_operand:QI 1 "" "")
- (match_operand:SI 2 "" "")))
- (use (match_operand:SI 3 "" ""))]
- ;; Operand 3 is not used on the i386.
- ""
-{
- ix86_expand_call (operands[0], operands[1], operands[2],
- operands[3], NULL, 1);
- DONE;
-})
+ (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
+ (match_operand 2 "" "")))
+ (set (reg:SI SP_REG)
+ (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 3 "immediate_operand" "i")))]
+ "!TARGET_64BIT && SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[1]);"
+ [(set_attr "type" "callv")])
;; Call subroutine returning any type.
: X86_64_MS_SSE_REGPARM_MAX)
: X86_32_SSE_REGPARM_MAX)
- 1),
- NULL, 0);
+ NULL, false);
for (i = 0; i < XVECLEN (operands[2], 0); i++)
{
(set_attr "length_immediate" "0")
(set_attr "modrm" "0")])
-(define_insn "vswapmov"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "register_operand" "r"))
- (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
- ""
- "movl.s\t{%1, %0|%0, %1}"
- [(set_attr "length" "2")
+;; Generate nops. Operand 0 is the number of nops, up to 8.
+(define_insn "nops"
+ [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
+ UNSPECV_NOPS)]
+ "reload_completed"
+{
+ 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")
(set_attr "modrm" "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>")])
+;; 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_BMI"
+ "andn\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(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))]
+ "TARGET_BMI"
+ "bextr\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(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))]
+ "TARGET_BMI"
+ "blsi\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "<MODE>")])
+
+(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)
(define_insn "*tls_global_dynamic_32_gnu"
[(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI [(match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "tls_symbolic_operand" "")
- (match_operand:SI 3 "call_insn_operand" "")]
- UNSPEC_TLS_GD))
+ (unspec:SI
+ [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "tls_symbolic_operand" "")
+ (match_operand:SI 3 "constant_call_address_operand" "z")]
+ UNSPEC_TLS_GD))
(clobber (match_scratch:SI 4 "=d"))
(clobber (match_scratch:SI 5 "=c"))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && TARGET_GNU_TLS"
- "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
+{
+ output_asm_insn
+ ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
+ if (TARGET_SUN_TLS)
+#ifdef HAVE_AS_IX86_TLSGDPLT
+ return "call\t%a2@tlsgdplt";
+#else
+ return "call\t%p3@plt";
+#endif
+ return "call\t%P3";
+}
[(set_attr "type" "multi")
(set_attr "length" "12")])
(define_expand "tls_global_dynamic_32"
- [(parallel [(set (match_operand:SI 0 "register_operand" "")
- (unspec:SI
- [(match_dup 2)
- (match_operand:SI 1 "tls_symbolic_operand" "")
- (match_dup 3)]
- UNSPEC_TLS_GD))
- (clobber (match_scratch:SI 4 ""))
- (clobber (match_scratch:SI 5 ""))
- (clobber (reg:CC FLAGS_REG))])]
- ""
-{
- if (flag_pic)
- operands[2] = pic_offset_table_rtx;
- else
- {
- operands[2] = gen_reg_rtx (Pmode);
- emit_insn (gen_set_got (operands[2]));
- }
- if (TARGET_GNU2_TLS)
- {
- emit_insn (gen_tls_dynamic_gnu2_32
- (operands[0], operands[1], operands[2]));
- DONE;
- }
- operands[3] = ix86_tls_get_addr ();
-})
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (unspec:SI [(match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 1 "tls_symbolic_operand" "")
+ (match_operand:SI 3 "constant_call_address_operand" "")]
+ UNSPEC_TLS_GD))
+ (clobber (match_scratch:SI 4 ""))
+ (clobber (match_scratch:SI 5 ""))
+ (clobber (reg:CC FLAGS_REG))])])
(define_insn "*tls_global_dynamic_64"
[(set (match_operand:DI 0 "register_operand" "=a")
- (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
- (match_operand:DI 3 "" "")))
+ (call:DI
+ (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
+ (match_operand:DI 3 "" "")))
(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
UNSPEC_TLS_GD)]
"TARGET_64BIT"
- { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
+{
+ fputs (ASM_BYTE "0x66\n", asm_out_file);
+ output_asm_insn
+ ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
+ fputs (ASM_SHORT "0x6666\n", asm_out_file);
+ fputs ("\trex64\n", asm_out_file);
+ if (TARGET_SUN_TLS)
+ return "call\t%p2@plt";
+ return "call\t%P2";
+}
[(set_attr "type" "multi")
(set_attr "length" "16")])
(define_expand "tls_global_dynamic_64"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (call:DI (mem:QI (match_dup 2)) (const_int 0)))
- (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
- UNSPEC_TLS_GD)])]
- ""
-{
- if (TARGET_GNU2_TLS)
- {
- emit_insn (gen_tls_dynamic_gnu2_64
- (operands[0], operands[1]));
- DONE;
- }
- operands[2] = ix86_tls_get_addr ();
-})
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (call:DI
+ (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
+ (const_int 0)))
+ (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
+ UNSPEC_TLS_GD)])])
(define_insn "*tls_local_dynamic_base_32_gnu"
[(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI [(match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "call_insn_operand" "")]
- UNSPEC_TLS_LD_BASE))
+ (unspec:SI
+ [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "constant_call_address_operand" "z")]
+ UNSPEC_TLS_LD_BASE))
(clobber (match_scratch:SI 3 "=d"))
(clobber (match_scratch:SI 4 "=c"))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && TARGET_GNU_TLS"
- "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
+{
+ output_asm_insn
+ ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
+ if (TARGET_SUN_TLS)
+#ifdef HAVE_AS_IX86_TLSLDMPLT
+ return "call\t%&@tlsldmplt";
+#else
+ return "call\t%p2@plt";
+#endif
+ return "call\t%P2";
+}
[(set_attr "type" "multi")
(set_attr "length" "11")])
(define_expand "tls_local_dynamic_base_32"
- [(parallel [(set (match_operand:SI 0 "register_operand" "")
- (unspec:SI [(match_dup 1) (match_dup 2)]
- UNSPEC_TLS_LD_BASE))
- (clobber (match_scratch:SI 3 ""))
- (clobber (match_scratch:SI 4 ""))
- (clobber (reg:CC FLAGS_REG))])]
- ""
-{
- if (flag_pic)
- operands[1] = pic_offset_table_rtx;
- else
- {
- operands[1] = gen_reg_rtx (Pmode);
- emit_insn (gen_set_got (operands[1]));
- }
- if (TARGET_GNU2_TLS)
- {
- emit_insn (gen_tls_dynamic_gnu2_32
- (operands[0], ix86_tls_module_base (), operands[1]));
- DONE;
- }
- operands[2] = ix86_tls_get_addr ();
-})
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (unspec:SI
+ [(match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "constant_call_address_operand" "")]
+ UNSPEC_TLS_LD_BASE))
+ (clobber (match_scratch:SI 3 ""))
+ (clobber (match_scratch:SI 4 ""))
+ (clobber (reg:CC FLAGS_REG))])])
(define_insn "*tls_local_dynamic_base_64"
[(set (match_operand:DI 0 "register_operand" "=a")
- (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
- (match_operand:DI 2 "" "")))
+ (call:DI
+ (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
+ (match_operand:DI 2 "" "")))
(unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
"TARGET_64BIT"
- "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
+{
+ output_asm_insn
+ ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
+ if (TARGET_SUN_TLS)
+ return "call\t%p1@plt";
+ return "call\t%P1";
+}
[(set_attr "type" "multi")
(set_attr "length" "12")])
(define_expand "tls_local_dynamic_base_64"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (call:DI (mem:QI (match_dup 1)) (const_int 0)))
- (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
- ""
-{
- if (TARGET_GNU2_TLS)
- {
- emit_insn (gen_tls_dynamic_gnu2_64
- (operands[0], ix86_tls_module_base ()));
- DONE;
- }
- operands[1] = ix86_tls_get_addr ();
-})
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (call:DI
+ (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
+ (const_int 0)))
+ (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
;; Local dynamic of a single variable is a lose. Show combine how
;; to convert that back to global dynamic.
(define_insn_and_split "*tls_local_dynamic_32_once"
[(set (match_operand:SI 0 "register_operand" "=a")
- (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "call_insn_operand" "")]
- UNSPEC_TLS_LD_BASE)
- (const:SI (unspec:SI
- [(match_operand:SI 3 "tls_symbolic_operand" "")]
- UNSPEC_DTPOFF))))
+ (plus:SI
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "constant_call_address_operand" "z")]
+ UNSPEC_TLS_LD_BASE)
+ (const:SI (unspec:SI
+ [(match_operand:SI 3 "tls_symbolic_operand" "")]
+ UNSPEC_DTPOFF))))
(clobber (match_scratch:SI 4 "=d"))
(clobber (match_scratch:SI 5 "=c"))
(clobber (reg:CC FLAGS_REG))]
""
"#"
""
- [(parallel [(set (match_dup 0)
- (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
- UNSPEC_TLS_GD))
- (clobber (match_dup 4))
- (clobber (match_dup 5))
- (clobber (reg:CC FLAGS_REG))])]
- "")
+ [(parallel
+ [(set (match_dup 0)
+ (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
+ UNSPEC_TLS_GD))
+ (clobber (match_dup 4))
+ (clobber (match_dup 5))
+ (clobber (reg:CC FLAGS_REG))])])
-;; Load and add the thread base pointer from %gs:0.
+;; Segment register for the thread base ptr load
+(define_mode_attr tp_seg [(SI "gs") (DI "fs")])
-(define_insn "*load_tp_si"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (unspec:SI [(const_int 0)] UNSPEC_TP))]
- "!TARGET_64BIT"
- "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
+;; Load and add the thread base pointer from %<tp_seg>:0.
+(define_insn "*load_tp_<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(const_int 0)] UNSPEC_TP))]
+ ""
+ "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
[(set_attr "type" "imov")
(set_attr "modrm" "0")
(set_attr "length" "7")
(set_attr "memory" "load")
(set_attr "imm_disp" "false")])
-(define_insn "*add_tp_si"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
- (match_operand:SI 1 "register_operand" "0")))
+(define_insn "*add_tp_<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
+ (match_operand:P 1 "register_operand" "0")))
(clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT"
- "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
+ ""
+ "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
[(set_attr "type" "alu")
(set_attr "modrm" "0")
(set_attr "length" "7")
(set_attr "memory" "load")
(set_attr "imm_disp" "false")])
-(define_insn "*load_tp_di"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(const_int 0)] UNSPEC_TP))]
- "TARGET_64BIT"
- "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
- [(set_attr "type" "imov")
- (set_attr "modrm" "0")
- (set_attr "length" "7")
- (set_attr "memory" "load")
- (set_attr "imm_disp" "false")])
-
-(define_insn "*add_tp_di"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
- (match_operand:DI 1 "register_operand" "0")))
+;; 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"
- "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
- [(set_attr "type" "alu")
- (set_attr "modrm" "0")
- (set_attr "length" "7")
- (set_attr "memory" "load")
- (set_attr "imm_disp" "false")])
+ "TARGET_64BIT && TARGET_SUN_TLS"
+{
+ output_asm_insn
+ ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
+ return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
+}
+ [(set_attr "type" "multi")])
;; GNU2 TLS patterns can be split.
operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
})
-
-;;
\f
;; These patterns match the binary 387 instructions for addM3, subM3,
;; mulM3 and divM3. There are three patterns for each of DFmode and
;; Gcc is slightly more smart about handling normal two address instructions
;; so use special patterns for add and mull.
-(define_insn "*fop_<mode>_comm_mixed_avx"
- [(set (match_operand:MODEF 0 "register_operand" "=f,x")
- (match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
- (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
- "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
- && COMMUTATIVE_ARITH_P (operands[3])
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (if_then_else (eq_attr "alternative" "1")
- (if_then_else (match_operand:MODEF 3 "mult_operator" "")
- (const_string "ssemul")
- (const_string "sseadd"))
- (if_then_else (match_operand:MODEF 3 "mult_operator" "")
- (const_string "fmul")
- (const_string "fop"))))
- (set_attr "prefix" "orig,maybe_vex")
- (set_attr "mode" "<MODE>")])
-
(define_insn "*fop_<mode>_comm_mixed"
- [(set (match_operand:MODEF 0 "register_operand" "=f,x")
+ [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
(match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
- (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
+ [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
+ (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
&& COMMUTATIVE_ARITH_P (operands[3])
&& !(MEM_P (operands[1]) && MEM_P (operands[2]))"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
- (if_then_else (eq_attr "alternative" "1")
+ (if_then_else (eq_attr "alternative" "1,2")
(if_then_else (match_operand:MODEF 3 "mult_operator" "")
(const_string "ssemul")
(const_string "sseadd"))
(if_then_else (match_operand:MODEF 3 "mult_operator" "")
- (const_string "fmul")
- (const_string "fop"))))
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*fop_<mode>_comm_avx"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
- "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
- && COMMUTATIVE_ARITH_P (operands[3])
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (if_then_else (match_operand:MODEF 3 "mult_operator" "")
- (const_string "ssemul")
- (const_string "sseadd")))
- (set_attr "prefix" "vex")
+ (const_string "fmul")
+ (const_string "fop"))))
+ (set_attr "isa" "base,noavx,avx")
+ (set_attr "prefix" "orig,orig,vex")
(set_attr "mode" "<MODE>")])
(define_insn "*fop_<mode>_comm_sse"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
+ [(set (match_operand:MODEF 0 "register_operand" "=x,x")
(match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
+ [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
+ (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
&& COMMUTATIVE_ARITH_P (operands[3])
&& !(MEM_P (operands[1]) && MEM_P (operands[2]))"
(if_then_else (match_operand:MODEF 3 "mult_operator" "")
(const_string "ssemul")
(const_string "sseadd")))
+ (set_attr "isa" "noavx,avx")
+ (set_attr "prefix" "orig,vex")
(set_attr "mode" "<MODE>")])
(define_insn "*fop_<mode>_comm_i387"
(const_string "fop")))
(set_attr "mode" "<MODE>")])
-(define_insn "*fop_<mode>_1_mixed_avx"
- [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
- (match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
- (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
- "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
- && !COMMUTATIVE_ARITH_P (operands[3])
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(and (eq_attr "alternative" "2")
- (match_operand:MODEF 3 "mult_operator" ""))
- (const_string "ssemul")
- (and (eq_attr "alternative" "2")
- (match_operand:MODEF 3 "div_operator" ""))
- (const_string "ssediv")
- (eq_attr "alternative" "2")
- (const_string "sseadd")
- (match_operand:MODEF 3 "mult_operator" "")
- (const_string "fmul")
- (match_operand:MODEF 3 "div_operator" "")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "prefix" "orig,orig,maybe_vex")
- (set_attr "mode" "<MODE>")])
-
(define_insn "*fop_<mode>_1_mixed"
- [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
+ [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
(match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
- (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
+ [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
+ (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
&& !COMMUTATIVE_ARITH_P (operands[3])
&& !(MEM_P (operands[1]) && MEM_P (operands[2]))"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
- (cond [(and (eq_attr "alternative" "2")
+ (cond [(and (eq_attr "alternative" "2,3")
(match_operand:MODEF 3 "mult_operator" ""))
(const_string "ssemul")
- (and (eq_attr "alternative" "2")
+ (and (eq_attr "alternative" "2,3")
(match_operand:MODEF 3 "div_operator" ""))
(const_string "ssediv")
- (eq_attr "alternative" "2")
+ (eq_attr "alternative" "2,3")
(const_string "sseadd")
(match_operand:MODEF 3 "mult_operator" "")
(const_string "fmul")
(const_string "fdiv")
]
(const_string "fop")))
+ (set_attr "isa" "base,base,noavx,avx")
+ (set_attr "prefix" "orig,orig,orig,vex")
(set_attr "mode" "<MODE>")])
(define_insn "*rcpsf2_sse"
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "SF")])
-(define_insn "*fop_<mode>_1_avx"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "register_operand" "x")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
- "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
- && !COMMUTATIVE_ARITH_P (operands[3])"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:MODEF 3 "mult_operator" "")
- (const_string "ssemul")
- (match_operand:MODEF 3 "div_operator" "")
- (const_string "ssediv")
- ]
- (const_string "sseadd")))
- (set_attr "prefix" "vex")
- (set_attr "mode" "<MODE>")])
-
(define_insn "*fop_<mode>_1_sse"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
+ [(set (match_operand:MODEF 0 "register_operand" "=x,x")
(match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "register_operand" "0")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
+ [(match_operand:MODEF 1 "register_operand" "0,x")
+ (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
&& !COMMUTATIVE_ARITH_P (operands[3])"
"* return output_387_binary_op (insn, operands);"
(const_string "ssediv")
]
(const_string "sseadd")))
+ (set_attr "isa" "noavx,avx")
+ (set_attr "prefix" "orig,vex")
(set_attr "mode" "<MODE>")])
;; This pattern is not fully shadowed by the pattern above.
[(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")
(sqrt:MODEF
(match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
+ "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
[(set_attr "type" "sse")
(set_attr "atom_sse_attr" "sqrt")
(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" "")
(use (match_operand:MODEF 2 "general_operand" ""))]
"TARGET_USE_FANCY_MATH_387"
{
+ rtx (*gen_truncxf) (rtx, rtx);
+
rtx label = gen_label_rtx ();
rtx op1 = gen_reg_rtx (XFmode);
/* Truncate the result properly for strict SSE math. */
if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
&& !TARGET_MIX_SSE_I387)
- emit_insn (gen_truncxf<mode>2 (operands[0], op1));
+ gen_truncxf = gen_truncxf<mode>2;
else
- emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
+ gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
+ emit_insn (gen_truncxf (operands[0], op1));
DONE;
})
(use (match_operand:MODEF 2 "general_operand" ""))]
"TARGET_USE_FANCY_MATH_387"
{
+ rtx (*gen_truncxf) (rtx, rtx);
+
rtx label = gen_label_rtx ();
rtx op1 = gen_reg_rtx (XFmode);
/* Truncate the result properly for strict SSE math. */
if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
&& !TARGET_MIX_SSE_I387)
- emit_insn (gen_truncxf<mode>2 (operands[0], op1));
+ gen_truncxf = gen_truncxf<mode>2;
else
- emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
+ gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
+ emit_insn (gen_truncxf (operands[0], op1));
DONE;
})
(set (match_operand:XF 1 "register_operand" "")
(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
"find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
- && !(reload_completed || reload_in_progress)"
- [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
- "")
+ && can_create_pseudo_p ()"
+ [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
(define_split
[(set (match_operand:XF 0 "register_operand" "")
(set (match_operand:XF 1 "register_operand" "")
(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
"find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
- && !(reload_completed || reload_in_progress)"
- [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
- "")
+ && can_create_pseudo_p ()"
+ [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
(define_insn "sincos_extend<mode>xf3_i387"
[(set (match_operand:XF 0 "register_operand" "=f")
(set (match_operand:XF 1 "register_operand" "")
(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
"find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
- && !(reload_completed || reload_in_progress)"
- [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
- "")
+ && can_create_pseudo_p ()"
+ [(set (match_dup 1)
+ (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
(define_split
[(set (match_operand:XF 0 "register_operand" "")
(set (match_operand:XF 1 "register_operand" "")
(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
"find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
- && !(reload_completed || reload_in_progress)"
- [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
- "")
+ && can_create_pseudo_p ()"
+ [(set (match_dup 0)
+ (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
(define_expand "sincos<mode>3"
[(use (match_operand:MODEF 0 "register_operand" ""))
UNSPEC_FPATAN))
(clobber (match_scratch:XF 3 ""))])]
"TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "")
+ && flag_unsafe_math_optimizations")
(define_expand "atan2<mode>3"
[(use (match_operand:MODEF 0 "register_operand" ""))
(unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
-{
- operands[2] = gen_reg_rtx (XFmode);
-})
+ "operands[2] = gen_reg_rtx (XFmode);")
(define_expand "logb<mode>2"
[(use (match_operand:MODEF 0 "register_operand" ""))
(unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
-{
- operands[2] = gen_reg_rtx (XFmode);
-})
+ "operands[2] = gen_reg_rtx (XFmode);")
(define_expand "significand<mode>2"
[(use (match_operand:MODEF 0 "register_operand" ""))
(match_operand:SI 2 "const_0_to_15_operand" "n")]
UNSPEC_ROUND))]
"TARGET_ROUND"
- "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
+ "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
[(set_attr "type" "ssecvt")
(set_attr "prefix_extra" "1")
(set_attr "prefix" "maybe_vex")
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);
}
UNSPEC_FIST))
(clobber (match_scratch:XF 2 "=&1f"))]
"TARGET_USE_FANCY_MATH_387"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fpspc")
(set_attr "mode" "DI")])
"reload_completed"
[(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
(clobber (match_dup 3))])
- (set (match_dup 0) (match_dup 2))]
- "")
+ (set (match_dup 0) (match_dup 2))])
(define_split
[(set (match_operand:DI 0 "memory_operand" "")
(clobber (match_scratch 3 ""))]
"reload_completed"
[(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
- (clobber (match_dup 3))])]
- "")
+ (clobber (match_dup 3))])])
(define_insn_and_split "*fist<mode>2_1"
[(set (match_operand:X87MODEI12 0 "register_operand" "")
(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
UNSPEC_FIST))]
"TARGET_USE_FANCY_MATH_387"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fpspc")
(set_attr "mode" "<MODE>")])
(clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
"reload_completed"
[(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
- (set (match_dup 0) (match_dup 2))]
- "")
+ (set (match_dup 0) (match_dup 2))])
(define_split
[(set (match_operand:X87MODEI12 0 "memory_operand" "")
UNSPEC_FIST))
(clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
"reload_completed"
- [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
- "")
+ [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
(define_expand "lrintxf<mode>2"
[(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
UNSPEC_FIST))]
- "TARGET_USE_FANCY_MATH_387"
- "")
+ "TARGET_USE_FANCY_MATH_387")
(define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
[(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
(unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
UNSPEC_FIX_NOTRUNC))]
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
- && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
- "")
+ && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
(define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
[(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
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
(clobber (match_scratch:XF 4 "=&1f"))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "floor")
(set_attr "mode" "DI")])
(use (match_dup 2))
(use (match_dup 3))
(clobber (match_dup 5))])
- (set (match_dup 0) (match_dup 4))]
- "")
+ (set (match_dup 0) (match_dup 4))])
(define_split
[(set (match_operand:DI 0 "memory_operand" "")
[(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
(use (match_dup 2))
(use (match_dup 3))
- (clobber (match_dup 5))])]
- "")
+ (clobber (match_dup 5))])])
(define_insn "fist<mode>2_floor"
[(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
(use (match_operand:HI 3 "memory_operand" "m"))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "floor")
(set_attr "mode" "<MODE>")])
UNSPEC_FIST_FLOOR))
(use (match_dup 2))
(use (match_dup 3))])
- (set (match_dup 0) (match_dup 4))]
- "")
+ (set (match_dup 0) (match_dup 4))])
(define_split
[(set (match_operand:X87MODEI12 0 "memory_operand" "")
[(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
UNSPEC_FIST_FLOOR))
(use (match_dup 2))
- (use (match_dup 3))])]
- "")
+ (use (match_dup 3))])])
(define_expand "lfloorxf<mode>2"
[(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
(clobber (reg:CC FLAGS_REG))])]
"TARGET_USE_FANCY_MATH_387
&& (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
- "")
+ && flag_unsafe_math_optimizations")
(define_expand "lfloor<MODEF:mode><SWI48:mode>2"
[(match_operand:SWI48 0 "nonimmediate_operand" "")
{
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))
(clobber (match_scratch:XF 4 "=&1f"))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "ceil")
(set_attr "mode" "DI")])
(use (match_dup 2))
(use (match_dup 3))
(clobber (match_dup 5))])
- (set (match_dup 0) (match_dup 4))]
- "")
+ (set (match_dup 0) (match_dup 4))])
(define_split
[(set (match_operand:DI 0 "memory_operand" "")
[(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
(use (match_dup 2))
(use (match_dup 3))
- (clobber (match_dup 5))])]
- "")
+ (clobber (match_dup 5))])])
(define_insn "fist<mode>2_ceil"
[(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
(use (match_operand:HI 3 "memory_operand" "m"))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
- "* return output_fix_trunc (insn, operands, 0);"
+ "* return output_fix_trunc (insn, operands, false);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "ceil")
(set_attr "mode" "<MODE>")])
UNSPEC_FIST_CEIL))
(use (match_dup 2))
(use (match_dup 3))])
- (set (match_dup 0) (match_dup 4))]
- "")
+ (set (match_dup 0) (match_dup 4))])
(define_split
[(set (match_operand:X87MODEI12 0 "memory_operand" "")
[(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
UNSPEC_FIST_CEIL))
(use (match_dup 2))
- (use (match_dup 3))])]
- "")
+ (use (match_dup 3))])])
(define_expand "lceilxf<mode>2"
[(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
(clobber (reg:CC FLAGS_REG))])]
"TARGET_USE_FANCY_MATH_387
&& (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
- "")
+ && flag_unsafe_math_optimizations")
(define_expand "lceil<MODEF:mode><SWI48:mode>2"
[(match_operand:SWI48 0 "nonimmediate_operand" "")
{
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))
&& flag_unsafe_math_optimizations"
{
emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
-
DONE;
})
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 2 "const_int_operand" ""))
+ (use (match_operand:SWI48 1 "nonmemory_operand" ""))
+ (use (match_operand:QI 2 "nonmemory_operand" ""))
(use (match_operand 3 "const_int_operand" ""))
(use (match_operand:SI 4 "const_int_operand" ""))
(use (match_operand:SI 5 "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"))
- (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"))
+ [(set (mem:HI (match_operand:P 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"))
- (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"))
+ [(set (mem:QI (match_operand:P 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 (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 (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 "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"
}
else
{
- rtx (*cmp_insn)(rtx, rtx);
+ rtx (*gen_cmp) (rtx, rtx);
- if (TARGET_64BIT)
- cmp_insn = gen_cmpdi_1;
- else
- cmp_insn = gen_cmpsi_1;
- emit_insn (cmp_insn (countreg, countreg));
+ gen_cmp = (TARGET_64BIT
+ ? gen_cmpdi_1 : gen_cmpsi_1);
+
+ emit_insn (gen_cmp (countreg, countreg));
emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
operands[1], operands[2]));
}
(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"))
- (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"))
+ (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: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"))
- (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"))
+ [(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_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
(use (match_dup 3))
(clobber (match_dup 0))
(clobber (match_dup 1))
- (clobber (match_dup 2))])]
- "")
+ (clobber (match_dup 2))])])
;; ...and this one handles cmpstrn*_1.
(define_peephole2
(use (reg:CC FLAGS_REG))
(clobber (match_dup 0))
(clobber (match_dup 1))
- (clobber (match_dup 2))])]
- "")
-
-
+ (clobber (match_dup 2))])])
\f
;; Conditional move instructions.
(define_expand "mov<mode>cc"
[(set (match_operand:SWIM 0 "register_operand" "")
- (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
+ (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
(match_operand:SWIM 2 "general_operand" "")
(match_operand:SWIM 3 "general_operand" "")))]
""
(const_int 0)])
(const_int -1)
(const_int 0)))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- "")
+ (clobber (reg:CC FLAGS_REG))])])
(define_insn "*x86_mov<mode>cc_0_m1"
[(set (match_operand:SWI48 0 "register_operand" "=r")
|| (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.
;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
;; are undefined in this condition, we're certain this is correct.
-(define_insn "*avx_<code><mode>3"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (smaxmin:MODEF
- (match_operand:MODEF 1 "nonimmediate_operand" "%x")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
- "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "sseadd")
- (set_attr "prefix" "vex")
- (set_attr "mode" "<MODE>")])
-
(define_insn "<code><mode>3"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
+ [(set (match_operand:MODEF 0 "register_operand" "=x,x")
(smaxmin:MODEF
- (match_operand:MODEF 1 "nonimmediate_operand" "%0")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
+ (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
+ (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseadd")
+ "@
+ <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
+ v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "prefix" "orig,vex")
+ (set_attr "type" "sseadd")
(set_attr "mode" "<MODE>")])
;; These versions of the min/max patterns implement exactly the operations
;; Their operands are not commutative, and thus they may be used in the
;; presence of -0.0 and NaN.
-(define_insn "*avx_ieee_smin<mode>3"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (unspec:MODEF
- [(match_operand:MODEF 1 "register_operand" "x")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
- UNSPEC_IEEE_MIN))]
- "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "sseadd")
- (set_attr "prefix" "vex")
- (set_attr "mode" "<MODE>")])
-
(define_insn "*ieee_smin<mode>3"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
+ [(set (match_operand:MODEF 0 "register_operand" "=x,x")
(unspec:MODEF
- [(match_operand:MODEF 1 "register_operand" "0")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
+ [(match_operand:MODEF 1 "register_operand" "0,x")
+ (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
UNSPEC_IEEE_MIN))]
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseadd")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*avx_ieee_smax<mode>3"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (unspec:MODEF
- [(match_operand:MODEF 1 "register_operand" "0")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
- UNSPEC_IEEE_MAX))]
- "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "sseadd")
- (set_attr "prefix" "vex")
+ "@
+ min<ssemodesuffix>\t{%2, %0|%0, %2}
+ vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "prefix" "orig,vex")
+ (set_attr "type" "sseadd")
(set_attr "mode" "<MODE>")])
(define_insn "*ieee_smax<mode>3"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
+ [(set (match_operand:MODEF 0 "register_operand" "=x,x")
(unspec:MODEF
- [(match_operand:MODEF 1 "register_operand" "0")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
+ [(match_operand:MODEF 1 "register_operand" "0,x")
+ (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
UNSPEC_IEEE_MAX))]
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
- [(set_attr "type" "sseadd")
+ "@
+ max<ssemodesuffix>\t{%2, %0|%0, %2}
+ vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "prefix" "orig,vex")
+ (set_attr "type" "sseadd")
(set_attr "mode" "<MODE>")])
;; Make two stack loads independent:
;; The % modifier is not operational anymore in peephole2's, so we have to
;; swap the operands manually in the case of addition and multiplication.
"if (COMMUTATIVE_ARITH_P (operands[2]))
- operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
- operands[0], operands[1]);
+ operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
+ GET_MODE (operands[2]),
+ operands[0], operands[1]);
else
- operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
- operands[1], operands[0]);")
+ operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
+ GET_MODE (operands[2]),
+ operands[1], operands[0]);")
;; Conditional addition patterns
(define_expand "add<mode>cc"
[(match_operand:SWI 0 "register_operand" "")
- (match_operand 1 "comparison_operator" "")
+ (match_operand 1 "ordered_comparison_operator" "")
(match_operand:SWI 2 "register_operand" "")
(match_operand:SWI 3 "const_int_operand" "")]
""
"if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
-
\f
;; Misc patterns (?)
;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
;;
;; in proper program order.
-(define_insn "pro_epilogue_adjust_stack_1"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_operand:SI 1 "register_operand" "0,r")
- (match_operand:SI 2 "immediate_operand" "i,i")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))]
- "!TARGET_64BIT"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_IMOV:
- return "mov{l}\t{%1, %0|%0, %1}";
-
- case TYPE_ALU:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (x86_maybe_negate_const_int (&operands[2], SImode))
- return "sub{l}\t{%2, %0|%0, %2}";
-
- return "add{l}\t{%2, %0|%0, %2}";
-
- default:
- operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
- return "lea{l}\t{%a2, %0|%0, %a2}";
- }
-}
- [(set (attr "type")
- (cond [(and (eq_attr "alternative" "0")
- (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
- (const_string "alu")
- (match_operand:SI 2 "const0_operand" "")
- (const_string "imov")
- ]
- (const_string "lea")))
- (set (attr "length_immediate")
- (cond [(eq_attr "type" "imov")
- (const_string "0")
- (and (eq_attr "type" "alu")
- (match_operand 2 "const128_operand" ""))
- (const_string "1")
- ]
- (const_string "*")))
- (set_attr "mode" "SI")])
-(define_insn "pro_epilogue_adjust_stack_rex64"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (plus:DI (match_operand:DI 1 "register_operand" "0,r")
- (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
+(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 "<nonmemory_operand>" "r<i>,l<i>")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))]
- "TARGET_64BIT"
+ ""
{
switch (get_attr_type (insn))
{
case TYPE_IMOV:
- return "mov{q}\t{%1, %0|%0, %1}";
+ return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
case TYPE_ALU:
gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (x86_maybe_negate_const_int (&operands[2], DImode))
- return "sub{q}\t{%2, %0|%0, %2}";
+ if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
+ return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
- return "add{q}\t{%2, %0|%0, %2}";
+ return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
default:
operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
- return "lea{q}\t{%a2, %0|%0, %a2}";
+ return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
}
}
[(set (attr "type")
(cond [(and (eq_attr "alternative" "0")
- (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
+ (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
(const_string "alu")
- (match_operand:DI 2 "const0_operand" "")
+ (match_operand:<MODE> 2 "const0_operand" "")
(const_string "imov")
]
- (const_string "lea")))
- (set (attr "length_immediate")
- (cond [(eq_attr "type" "imov")
- (const_string "0")
- (and (eq_attr "type" "alu")
- (match_operand 2 "const128_operand" ""))
- (const_string "1")
- ]
- (const_string "*")))
- (set_attr "mode" "DI")])
-
-(define_insn "pro_epilogue_adjust_stack_rex64_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,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")])
+ (const_string "lea")))
+ (set (attr "length_immediate")
+ (cond [(eq_attr "type" "imov")
+ (const_string "0")
+ (and (eq_attr "type" "alu")
+ (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ ]
+ (const_string "*")))
+ (set_attr "mode" "<MODE>")])
-(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 && TARGET_STACK_PROBE"
- "call\t___chkstk"
- [(set_attr "type" "multi")
- (set_attr "length" "5")])
+(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)))]
+ ""
+ "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 && TARGET_STACK_PROBE"
- "call\t___chkstk"
+ "ix86_target_stack_probe ()"
+ "call\t___chkstk_ms"
[(set_attr "type" "multi")
(set_attr "length" "5")])
(define_expand "allocate_stack"
[(match_operand 0 "register_operand" "")
(match_operand 1 "general_operand" "")]
- "TARGET_STACK_PROBE"
+ "ix86_target_stack_probe ()"
{
rtx x;
{
x = copy_to_mode_reg (Pmode, operands[1]);
if (TARGET_64BIT)
- x = gen_allocate_stack_worker_64 (x, x);
+ emit_insn (gen_allocate_stack_worker_probe_di (x, x));
else
- x = gen_allocate_stack_worker_32 (x, x);
- emit_insn (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);
[(match_operand 0 "memory_operand" "")]
""
{
- if (GET_MODE (operands[0]) == DImode)
- emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
- else
- emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
+ rtx (*gen_ior3) (rtx, rtx, rtx);
+
+ gen_ior3 = (GET_MODE (operands[0]) == DImode
+ ? gen_iordi3 : gen_iorsi3);
+
+ emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
DONE;
})
+(define_insn "adjust_stack_and_probe<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
+ UNSPECV_PROBE_STACK_RANGE))
+ (set (reg:P SP_REG)
+ (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
+ (clobber (reg:CC FLAGS_REG))
+ (clobber (mem:BLK (scratch)))]
+ ""
+ "* return output_adjust_stack_and_probe (operands[0]);"
+ [(set_attr "type" "multi")])
+
+(define_insn "probe_stack_range<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
+ (match_operand:P 2 "const_int_operand" "n")]
+ UNSPECV_PROBE_STACK_RANGE))
+ (clobber (reg:CC FLAGS_REG))]
+ ""
+ "* return output_probe_stack_range (operands[0], operands[2]);"
+ [(set_attr "type" "multi")])
+
(define_expand "builtin_setjmp_receiver"
[(label_ref (match_operand 0 "" ""))]
"!TARGET_64BIT && flag_pic"
(define_split
[(set (match_operand 0 "register_operand" "")
- (if_then_else (match_operator 1 "comparison_operator"
+ (if_then_else (match_operator 1 "ordered_comparison_operator"
[(reg FLAGS_REG) (const_int 0)])
(match_operand 2 "register_operand" "")
(match_operand 3 "register_operand" "")))]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[2] = gen_lowpart (SImode, operands[2]);
operands[3] = gen_lowpart (SImode, operands[3]);")
-
\f
;; RTL Peephole optimizations, run before sched2. These primarily look to
;; transform a complex memory operation into two memory to register operations.
;; Don't push memory operands
(define_peephole2
- [(set (match_operand:SI 0 "push_operand" "")
- (match_operand:SI 1 "memory_operand" ""))
- (match_scratch:SI 2 "r")]
- "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
- && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))]
- "")
-
-(define_peephole2
- [(set (match_operand:DI 0 "push_operand" "")
- (match_operand:DI 1 "memory_operand" ""))
- (match_scratch:DI 2 "r")]
+ [(set (match_operand:SWI 0 "push_operand" "")
+ (match_operand:SWI 1 "memory_operand" ""))
+ (match_scratch:SWI 2 "<r>")]
"optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
&& !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))]
- "")
+ (set (match_dup 0) (match_dup 2))])
-;; We need to handle SFmode only, because DFmode and XFmode is split to
+;; We need to handle SFmode only, because DFmode and XFmode are split to
;; SImode pushes.
(define_peephole2
[(set (match_operand:SF 0 "push_operand" "")
"optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
&& !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))]
- "")
-
-(define_peephole2
- [(set (match_operand:HI 0 "push_operand" "")
- (match_operand:HI 1 "memory_operand" ""))
- (match_scratch:HI 2 "r")]
- "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
- && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))]
- "")
-
-(define_peephole2
- [(set (match_operand:QI 0 "push_operand" "")
- (match_operand:QI 1 "memory_operand" ""))
- (match_scratch:QI 2 "q")]
- "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
- && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))]
- "")
+ (set (match_dup 0) (match_dup 2))])
;; Don't move an immediate directly to memory when the instruction
;; gets too big.
(define_peephole2
- [(match_scratch:SI 1 "r")
- (set (match_operand:SI 0 "memory_operand" "")
- (const_int 0))]
- "optimize_insn_for_speed_p ()
- && ! TARGET_USE_MOV0
- && TARGET_SPLIT_LONG_MOVES
- && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 1) (const_int 0))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_dup 0) (match_dup 1))]
- "")
-
-(define_peephole2
- [(match_scratch:HI 1 "r")
- (set (match_operand:HI 0 "memory_operand" "")
- (const_int 0))]
- "optimize_insn_for_speed_p ()
- && ! TARGET_USE_MOV0
- && TARGET_SPLIT_LONG_MOVES
- && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 2) (const_int 0))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_dup 0) (match_dup 1))]
- "operands[2] = gen_lowpart (SImode, operands[1]);")
-
-(define_peephole2
- [(match_scratch:QI 1 "q")
- (set (match_operand:QI 0 "memory_operand" "")
+ [(match_scratch:SWI124 1 "<r>")
+ (set (match_operand:SWI124 0 "memory_operand" "")
(const_int 0))]
"optimize_insn_for_speed_p ()
- && ! TARGET_USE_MOV0
+ && !TARGET_USE_MOV0
&& TARGET_SPLIT_LONG_MOVES
&& get_attr_length (insn) >= ix86_cur_cost ()->large_insn
&& peep2_regno_dead_p (0, FLAGS_REG)"
"operands[2] = gen_lowpart (SImode, operands[1]);")
(define_peephole2
- [(match_scratch:SI 2 "r")
- (set (match_operand:SI 0 "memory_operand" "")
- (match_operand:SI 1 "immediate_operand" ""))]
- "optimize_insn_for_speed_p ()
- && TARGET_SPLIT_LONG_MOVES
- && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))]
- "")
-
-(define_peephole2
- [(match_scratch:HI 2 "r")
- (set (match_operand:HI 0 "memory_operand" "")
- (match_operand:HI 1 "immediate_operand" ""))]
- "optimize_insn_for_speed_p ()
- && TARGET_SPLIT_LONG_MOVES
- && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))]
- "")
-
-(define_peephole2
- [(match_scratch:QI 2 "q")
- (set (match_operand:QI 0 "memory_operand" "")
- (match_operand:QI 1 "immediate_operand" ""))]
+ [(match_scratch:SWI124 2 "<r>")
+ (set (match_operand:SWI124 0 "memory_operand" "")
+ (match_operand:SWI124 1 "immediate_operand" ""))]
"optimize_insn_for_speed_p ()
&& TARGET_SPLIT_LONG_MOVES
&& get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))]
- "")
+ (set (match_dup 0) (match_dup 2))])
;; Don't compare memory with zero, load and use a test instead.
(define_peephole2
(match_scratch:SI 3 "r")]
"optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
[(set (match_dup 3) (match_dup 2))
- (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
- "")
+ (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
;; Don't split NOTs with a displacement operand, because resulting XOR
;; lifetime information then.
(define_peephole2
- [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
- "optimize_insn_for_speed_p ()
- && ((TARGET_NOT_UNPAIRABLE
- && (!MEM_P (operands[0])
- || !memory_displacement_operand (operands[0], SImode)))
- || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0)
- (xor:SI (match_dup 1) (const_int -1)))
- (clobber (reg:CC FLAGS_REG))])]
- "")
-
-(define_peephole2
- [(set (match_operand:HI 0 "nonimmediate_operand" "")
- (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
- "optimize_insn_for_speed_p ()
- && ((TARGET_NOT_UNPAIRABLE
- && (!MEM_P (operands[0])
- || !memory_displacement_operand (operands[0], HImode)))
- || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0)
- (xor:HI (match_dup 1) (const_int -1)))
- (clobber (reg:CC FLAGS_REG))])]
- "")
-
-(define_peephole2
- [(set (match_operand:QI 0 "nonimmediate_operand" "")
- (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
+ (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
"optimize_insn_for_speed_p ()
&& ((TARGET_NOT_UNPAIRABLE
- && (!MEM_P (operands[0])
- || !memory_displacement_operand (operands[0], QImode)))
- || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
+ && (!MEM_P (operands[0])
+ || !memory_displacement_operand (operands[0], <MODE>mode)))
+ || (TARGET_NOT_VECTORMODE
+ && long_memory_operand (operands[0], <MODE>mode)))
&& peep2_regno_dead_p (0, FLAGS_REG)"
[(parallel [(set (match_dup 0)
- (xor:QI (match_dup 1) (const_int -1)))
- (clobber (reg:CC FLAGS_REG))])]
- "")
+ (xor:SWI124 (match_dup 1) (const_int -1)))
+ (clobber (reg:CC FLAGS_REG))])])
;; Non pairable "test imm, reg" instructions can be translated to
;; "and imm, reg" if reg dies. The "and" form is also shorter (one
(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
(const_int 0)]))
(set (match_dup 2)
- (and:SI (match_dup 2) (match_dup 3)))])]
- "")
+ (and:SI (match_dup 2) (match_dup 3)))])])
;; We don't need to handle HImode case, because it will be promoted to SImode
;; on ! TARGET_PARTIAL_REG_STALL
(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
(const_int 0)]))
(set (match_dup 2)
- (and:QI (match_dup 2) (match_dup 3)))])]
- "")
+ (and:QI (match_dup 2) (match_dup 3)))])])
(define_peephole2
[(set (match_operand 0 "flags_reg_operand" "")
(match_dup 2)
(const_int 8)
(const_int 8))
- (match_dup 3)))])]
- "")
+ (match_dup 3)))])])
;; Don't do logical operations with memory inputs.
(define_peephole2
[(set (match_dup 2) (match_dup 1))
(parallel [(set (match_dup 0)
(match_op_dup 3 [(match_dup 0) (match_dup 2)]))
- (clobber (reg:CC FLAGS_REG))])]
- "")
+ (clobber (reg:CC FLAGS_REG))])])
(define_peephole2
[(match_scratch:SI 2 "r")
[(set (match_dup 2) (match_dup 1))
(parallel [(set (match_dup 0)
(match_op_dup 3 [(match_dup 2) (match_dup 0)]))
- (clobber (reg:CC FLAGS_REG))])]
- "")
+ (clobber (reg:CC FLAGS_REG))])])
;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
;; refers to the destination of the load!
|| (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 0)
- (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
- "")
+ (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
; Don't do logical operations with memory outputs
;
(parallel [(set (match_dup 2)
(match_op_dup 3 [(match_dup 2) (match_dup 1)]))
(clobber (reg:CC FLAGS_REG))])
- (set (match_dup 0) (match_dup 2))]
- "")
+ (set (match_dup 0) (match_dup 2))])
(define_peephole2
[(match_scratch:SI 2 "r")
(parallel [(set (match_dup 2)
(match_op_dup 3 [(match_dup 1) (match_dup 2)]))
(clobber (reg:CC FLAGS_REG))])
- (set (match_dup 0) (match_dup 2))]
- "")
+ (set (match_dup 0) (match_dup 2))])
;; Attempt to always use XOR for zeroing registers.
(define_peephole2
&& peep2_regno_dead_p (0, FLAGS_REG)"
[(parallel [(set (match_dup 0) (const_int 0))
(clobber (reg:CC FLAGS_REG))])]
-{
- operands[0] = gen_lowpart (word_mode, operands[0]);
-})
+ "operands[0] = gen_lowpart (word_mode, operands[0]);")
(define_peephole2
[(set (strict_low_part (match_operand 0 "register_operand" ""))
[(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
(clobber (reg:CC FLAGS_REG))])])
-;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
+;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
(define_peephole2
- [(set (match_operand 0 "register_operand" "")
+ [(set (match_operand:SWI248 0 "register_operand" "")
(const_int -1))]
- "(GET_MODE (operands[0]) == HImode
- || GET_MODE (operands[0]) == SImode
- || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
- && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
+ "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
&& peep2_regno_dead_p (0, FLAGS_REG)"
[(parallel [(set (match_dup 0) (const_int -1))
(clobber (reg:CC FLAGS_REG))])]
- "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
- operands[0]);")
+{
+ if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
+ operands[0] = gen_lowpart (SImode, operands[0]);
+})
+
+;; Attempt to convert simple lea to add/shift.
+;; These can be created by move expanders.
-;; Attempt to convert simple leas to adds. These can be created by
-;; move expanders.
(define_peephole2
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (match_dup 0)
- (match_operand:SI 1 "nonmemory_operand" "")))]
+ [(set (match_operand:SWI48 0 "register_operand" "")
+ (plus:SWI48 (match_dup 0)
+ (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
"peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))])]
- "")
+ [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))])])
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "nonmemory_operand" "")) 0))]
- "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
+ "TARGET_64BIT
+ && peep2_regno_dead_p (0, FLAGS_REG)
+ && REGNO (operands[0]) == REGNO (operands[1])"
[(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
"operands[2] = gen_lowpart (SImode, operands[2]);")
(define_peephole2
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_dup 0)
- (match_operand:DI 1 "x86_64_general_operand" "")))]
- "peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))])]
- "")
-
-(define_peephole2
- [(set (match_operand:SI 0 "register_operand" "")
- (mult:SI (match_dup 0)
- (match_operand:SI 1 "const_int_operand" "")))]
- "exact_log2 (INTVAL (operands[1])) >= 0
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
- "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
-
-(define_peephole2
- [(set (match_operand:DI 0 "register_operand" "")
- (mult:DI (match_dup 0)
- (match_operand:DI 1 "const_int_operand" "")))]
+ [(set (match_operand:SWI48 0 "register_operand" "")
+ (mult:SWI48 (match_dup 0)
+ (match_operand:SWI48 1 "const_int_operand" "")))]
"exact_log2 (INTVAL (operands[1])) >= 0
&& peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
+ [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
"operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
[(set (match_operand:SI 0 "register_operand" "")
(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "const_int_operand" "")) 0))]
- "exact_log2 (INTVAL (operands[2])) >= 0
+ "TARGET_64BIT
+ && exact_log2 (INTVAL (operands[2])) >= 0
&& REGNO (operands[0]) == REGNO (operands[1])
&& peep2_regno_dead_p (0, FLAGS_REG)"
[(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
"operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
;; The ESP adjustments can be done by the push and pop instructions. Resulting
-;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
-;; many CPUs it is also faster, since special hardware to avoid esp
+;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
+;; On many CPUs it is also faster, since special hardware to avoid esp
;; dependencies is present.
-;; While some of these conversions may be done using splitters, we use peepholes
-;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
+;; While some of these conversions may be done using splitters, we use
+;; peepholes in order to allow combine_stack_adjustments pass to see
+;; nonobfuscated RTL.
;; Convert prologue esp subtractions to push.
;; We need register to push. In order to keep verify_flow_info happy we have
;; alternative when no register is available later.
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
- [(clobber (match_dup 0))
- (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
+ "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
+ && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
+ [(clobber (match_dup 1))
+ (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
(clobber (mem:BLK (scratch)))])])
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
- [(clobber (match_dup 0))
- (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
- (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
+ "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
+ && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
+ [(clobber (match_dup 1))
+ (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
+ (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
(clobber (mem:BLK (scratch)))])])
;; Convert esp subtractions to push.
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
- [(clobber (match_dup 0))
- (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
+ "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
+ && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
+ [(clobber (match_dup 1))
+ (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
- [(clobber (match_dup 0))
- (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
- (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
+ "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
+ && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
+ [(clobber (match_dup 1))
+ (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
+ (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
;; Convert epilogue deallocator to pop.
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
- [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
- (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
- (clobber (mem:BLK (scratch)))])]
- "")
+ "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
+ && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
+ [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
+ (clobber (mem:BLK (scratch)))])])
-;; Two pops case is tricky, since pop causes dependency on destination register.
-;; We use two registers if available.
+;; Two pops case is tricky, since pop causes dependency
+;; on destination register. We use two registers if available.
(define_peephole2
- [(match_scratch:SI 0 "r")
- (match_scratch:SI 1 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
+ [(match_scratch:P 1 "r")
+ (match_scratch:P 2 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
- [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
- (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
+ "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
+ && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
+ [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
(clobber (mem:BLK (scratch)))])
- (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
- (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
- "")
+ (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p ()"
- [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
- (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
+ "optimize_insn_for_size_p ()
+ && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
+ [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
(clobber (mem:BLK (scratch)))])
- (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
- (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
- "")
+ (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
;; Convert esp additions to pop.
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
- ""
- [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
- (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
- "")
+ "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
+ [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
-;; Two pops case is tricky, since pop causes dependency on destination register.
-;; We use two registers if available.
+;; Two pops case is tricky, since pop causes dependency
+;; on destination register. We use two registers if available.
(define_peephole2
- [(match_scratch:SI 0 "r")
- (match_scratch:SI 1 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
+ [(match_scratch:P 1 "r")
+ (match_scratch:P 2 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
- ""
- [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
- (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
- (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
- (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
- "")
+ "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
+ [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
+ (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p ()"
- [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
- (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
- (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
- (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
- "")
+ "optimize_insn_for_size_p ()
+ && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
+ [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
+ (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
\f
;; Convert compares with 1 to shorter inc/dec operations when CF is not
;; required and register dies. Similarly for 128 to -128.
&& peep2_reg_dead_p (1, operands[2])"
[(parallel [(set (match_dup 0)
(match_op_dup 1 [(match_dup 2) (match_dup 3)]))
- (clobber (match_dup 2))])]
- "")
-\f
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
- [(clobber (match_dup 0))
- (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
- (clobber (mem:BLK (scratch)))])])
-
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
- [(clobber (match_dup 0))
- (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
- (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
- (clobber (mem:BLK (scratch)))])])
-
-;; Convert esp subtractions to push.
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
- (clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
- [(clobber (match_dup 0))
- (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
-
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
- (clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
- [(clobber (match_dup 0))
- (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
- (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
-
-;; Convert epilogue deallocator to pop.
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
- [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
- (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
- (clobber (mem:BLK (scratch)))])]
- "")
-
-;; Two pops case is tricky, since pop causes dependency on destination register.
-;; We use two registers if available.
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (match_scratch:DI 1 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
- [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
- (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
- (clobber (mem:BLK (scratch)))])
- (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
- (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
- "")
-
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p ()"
- [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
- (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
- (clobber (mem:BLK (scratch)))])
- (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
- (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
- "")
-
-;; Convert esp additions to pop.
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
- (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
- "")
-
-;; Two pops case is tricky, since pop causes dependency on destination register.
-;; We use two registers if available.
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (match_scratch:DI 1 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
- (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
- (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
- (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
- "")
-
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
- (clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p ()"
- [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
- (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
- (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
- (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
- "")
+ (clobber (match_dup 2))])])
\f
;; Convert imul by three, five and nine into lea
(define_peephole2
[(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (mult:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))
+ [(set (match_operand:SWI48 0 "register_operand" "")
+ (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
+ (match_operand:SWI48 2 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
"INTVAL (operands[2]) == 3
|| INTVAL (operands[2]) == 5
|| INTVAL (operands[2]) == 9"
[(set (match_dup 0)
- (plus:SI (mult:SI (match_dup 1) (match_dup 2))
- (match_dup 1)))]
- { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
-
-(define_peephole2
- [(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))
- (clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_speed_p ()
- && (INTVAL (operands[2]) == 3
- || INTVAL (operands[2]) == 5
- || INTVAL (operands[2]) == 9)"
- [(set (match_dup 0) (match_dup 1))
- (set (match_dup 0)
- (plus:SI (mult:SI (match_dup 0) (match_dup 2))
- (match_dup 0)))]
- { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
-
-(define_peephole2
- [(parallel
- [(set (match_operand:DI 0 "register_operand" "")
- (mult:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "const_int_operand" "")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_64BIT
- && (INTVAL (operands[2]) == 3
- || INTVAL (operands[2]) == 5
- || INTVAL (operands[2]) == 9)"
- [(set (match_dup 0)
- (plus:DI (mult:DI (match_dup 1) (match_dup 2))
- (match_dup 1)))]
- { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
+ (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
+ (match_dup 1)))]
+ "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
(define_peephole2
[(parallel
- [(set (match_operand:DI 0 "register_operand" "")
- (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
- (match_operand:DI 2 "const_int_operand" "")))
+ [(set (match_operand:SWI48 0 "register_operand" "")
+ (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
+ (match_operand:SWI48 2 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
- "TARGET_64BIT
- && optimize_insn_for_speed_p ()
+ "optimize_insn_for_speed_p ()
&& (INTVAL (operands[2]) == 3
|| INTVAL (operands[2]) == 5
|| INTVAL (operands[2]) == 9)"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 0)
- (plus:DI (mult:DI (match_dup 0) (match_dup 2))
- (match_dup 0)))]
- { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
+ (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
+ (match_dup 0)))]
+ "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
-;; Imul $32bit_imm, mem, reg is vector decoded, while
+;; imul $32bit_imm, mem, reg is vector decoded, while
;; imul $32bit_imm, reg, reg is direct decoded.
(define_peephole2
- [(match_scratch:DI 3 "r")
- (parallel [(set (match_operand:DI 0 "register_operand" "")
- (mult:DI (match_operand:DI 1 "memory_operand" "")
- (match_operand:DI 2 "immediate_operand" "")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
- && !satisfies_constraint_K (operands[2])"
- [(set (match_dup 3) (match_dup 1))
- (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
-"")
-
-(define_peephole2
- [(match_scratch:SI 3 "r")
- (parallel [(set (match_operand:SI 0 "register_operand" "")
- (mult:SI (match_operand:SI 1 "memory_operand" "")
- (match_operand:SI 2 "immediate_operand" "")))
+ [(match_scratch:SWI48 3 "r")
+ (parallel [(set (match_operand:SWI48 0 "register_operand" "")
+ (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
+ (match_operand:SWI48 2 "immediate_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
&& !satisfies_constraint_K (operands[2])"
[(set (match_dup 3) (match_dup 1))
- (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
-"")
+ (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
+ (clobber (reg:CC FLAGS_REG))])])
(define_peephole2
[(match_scratch:SI 3 "r")
(mult:SI (match_operand:SI 1 "memory_operand" "")
(match_operand:SI 2 "immediate_operand" ""))))
(clobber (reg:CC FLAGS_REG))])]
- "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
+ "TARGET_64BIT
+ && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
&& !satisfies_constraint_K (operands[2])"
[(set (match_dup 3) (match_dup 1))
- (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
- (clobber (reg:CC FLAGS_REG))])]
-"")
+ (parallel [(set (match_dup 0)
+ (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
+ (clobber (reg:CC FLAGS_REG))])])
;; imul $8/16bit_imm, regmem, reg is vector decoded.
;; Convert it into imul reg, reg
;; It would be better to force assembler to encode instruction using long
;; immediate, but there is apparently no way to do so.
(define_peephole2
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
- (match_operand:DI 2 "const_int_operand" "")))
- (clobber (reg:CC FLAGS_REG))])
- (match_scratch:DI 3 "r")]
- "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
- && satisfies_constraint_K (operands[2])"
- [(set (match_dup 3) (match_dup 2))
- (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- if (!rtx_equal_p (operands[0], operands[1]))
- emit_move_insn (operands[0], operands[1]);
-})
-
-(define_peephole2
- [(parallel [(set (match_operand:SI 0 "register_operand" "")
- (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))
+ [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
+ (mult:SWI248
+ (match_operand:SWI248 1 "nonimmediate_operand" "")
+ (match_operand:SWI248 2 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])
- (match_scratch:SI 3 "r")]
+ (match_scratch:SWI248 3 "r")]
"TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
&& satisfies_constraint_K (operands[2])"
[(set (match_dup 3) (match_dup 2))
- (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- if (!rtx_equal_p (operands[0], operands[1]))
- emit_move_insn (operands[0], operands[1]);
-})
-
-(define_peephole2
- [(parallel [(set (match_operand:HI 0 "register_operand" "")
- (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
- (match_operand:HI 2 "immediate_operand" "")))
- (clobber (reg:CC FLAGS_REG))])
- (match_scratch:HI 3 "r")]
- "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
- [(set (match_dup 3) (match_dup 2))
- (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
+ (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
(clobber (reg:CC FLAGS_REG))])]
{
if (!rtx_equal_p (operands[0], operands[1]))
;; leal (%edx,%eax,4), %eax
(define_peephole2
- [(parallel [(set (match_operand 0 "register_operand" "")
+ [(match_scratch:P 5 "r")
+ (parallel [(set (match_operand 0 "register_operand" "")
(ashift (match_operand 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])
- (set (match_operand 3 "register_operand")
- (match_operand 4 "x86_64_general_operand" ""))
- (parallel [(set (match_operand 5 "register_operand" "")
- (plus (match_operand 6 "register_operand" "")
- (match_operand 7 "register_operand" "")))
+ (parallel [(set (match_operand 3 "register_operand" "")
+ (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
|| GET_MODE (operands[0]) == HImode))
|| GET_MODE (operands[0]) == SImode
|| (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
+ && (rtx_equal_p (operands[0], operands[3])
+ || peep2_reg_dead_p (2, operands[0]))
/* We reorder load and the shift. */
- && !rtx_equal_p (operands[1], operands[3])
- && !reg_overlap_mentioned_p (operands[0], operands[4])
- /* Last PLUS must consist of operand 0 and 3. */
- && !rtx_equal_p (operands[0], operands[3])
- && (rtx_equal_p (operands[3], operands[6])
- || rtx_equal_p (operands[3], operands[7]))
- && (rtx_equal_p (operands[0], operands[6])
- || rtx_equal_p (operands[0], operands[7]))
- /* The intermediate operand 0 must die or be same as output. */
- && (rtx_equal_p (operands[0], operands[5])
- || peep2_reg_dead_p (3, operands[0]))"
- [(set (match_dup 3) (match_dup 4))
+ && !reg_overlap_mentioned_p (operands[0], operands[4])"
+ [(set (match_dup 5) (match_dup 4))
(set (match_dup 0) (match_dup 1))]
{
- enum machine_mode mode = GET_MODE (operands[5]) == 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[3]);
- rtx dest = gen_lowpart (mode, operands[5]);
+ rtx base = gen_lowpart (Pmode, operands[5]);
+ rtx dest = gen_lowpart (mode, operands[3]);
operands[1] = gen_rtx_PLUS (Pmode, base,
gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
+ operands[5] = base;
if (mode != Pmode)
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 "*call_value_pop_0"
- [(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" "")))]
- "!TARGET_64BIT"
-{
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P1";
- else
- return "call\t%P1";
-}
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_pop_1"
- [(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")))]
- "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
-{
- if (constant_call_address_operand (operands[1], Pmode))
- return "call\t%P1";
- return "call\t%A1";
-}
- [(set_attr "type" "callv")])
-
-(define_insn "*sibcall_value_pop_1"
- [(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")))]
- "!TARGET_64BIT && SIBLING_CALL_P (insn)"
- "@
- jmp\t%P1
- jmp\t%A1"
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_0"
- [(set (match_operand 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";
-}
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_0_rex64"
- [(set (match_operand 0 "" "")
- (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";
-}
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_0_rex64_ms_sysv"
- [(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))]
- "TARGET_64BIT && !SIBLING_CALL_P (insn)"
-{
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P1";
- else
- return "call\t%P1";
-}
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_1"
- [(set (match_operand 0 "" "")
- (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";
-}
- [(set_attr "type" "callv")])
-
-(define_insn "*sibcall_value_1"
- [(set (match_operand 0 "" "")
- (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"
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_1_rex64"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
- (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";
-}
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_1_rex64_ms_sysv"
- [(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))]
- "TARGET_64BIT && !SIBLING_CALL_P (insn)"
-{
- if (constant_call_address_operand (operands[1], Pmode))
- return "call\t%P1";
- return "call\t%A1";
-}
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_1_rex64_large"
- [(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
- (match_operand:DI 2 "" "")))]
- "TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "call\t%A1"
- [(set_attr "type" "callv")])
-
-(define_insn "*sibcall_value_1_rex64"
- [(set (match_operand 0 "" "")
- (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"
- [(set_attr "type" "callv")])
-\f
;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
;; That, however, is usually mapped by the OS to SIGSEGV, which is often
;; caught for use by garbage collectors and the like. Using an insn that
{ return ASM_SHORT "0x0b0f"; }
[(set_attr "length" "2")])
-(define_expand "sse_prologue_save"
- [(parallel [(set (match_operand:BLK 0 "" "")
- (unspec:BLK [(reg:DI XMM0_REG)
- (reg:DI XMM1_REG)
- (reg:DI XMM2_REG)
- (reg:DI XMM3_REG)
- (reg:DI XMM4_REG)
- (reg:DI XMM5_REG)
- (reg:DI XMM6_REG)
- (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
- (clobber (reg:CC FLAGS_REG))
- (clobber (match_operand:DI 1 "register_operand" ""))
- (use (match_operand:DI 2 "immediate_operand" ""))
- (use (label_ref:DI (match_operand 3 "" "")))
- (clobber (match_operand:DI 4 "register_operand" ""))
- (use (match_dup 1))])]
- "TARGET_64BIT"
- "")
-
-;; Pre-reload version of prologue save. Until after prologue generation we don't know
-;; what the size of save instruction will be.
-;; Operand 0+operand 6 is the memory save area
-;; Operand 1 is number of registers to save (will get overwritten to operand 5)
-;; Operand 2 is number of non-vaargs SSE arguments
-;; Operand 3 is label starting the save block
-;; Operand 4 is used for temporary computation of jump address
-(define_insn "*sse_prologue_save_insn1"
- [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
- (match_operand:DI 6 "const_int_operand" "n")))
- (unspec:BLK [(reg:DI XMM0_REG)
- (reg:DI XMM1_REG)
- (reg:DI XMM2_REG)
- (reg:DI XMM3_REG)
- (reg:DI XMM4_REG)
- (reg:DI XMM5_REG)
- (reg:DI XMM6_REG)
- (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
- (clobber (reg:CC FLAGS_REG))
- (clobber (match_operand:DI 1 "register_operand" "=r"))
- (use (match_operand:DI 2 "const_int_operand" "i"))
- (use (label_ref:DI (match_operand 3 "" "X")))
- (clobber (match_operand:DI 4 "register_operand" "=&r"))
- (use (match_operand:DI 5 "register_operand" "1"))]
- "TARGET_64BIT
- && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
- && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
- "#"
- [(set_attr "type" "other")
- (set_attr "memory" "store")
- (set_attr "mode" "DI")])
-
-;; We know size of save instruction; expand the computation of jump address
-;; in the jumptable.
-(define_split
- [(parallel [(set (match_operand:BLK 0 "" "")
- (unspec:BLK [(reg:DI XMM0_REG)
- (reg:DI XMM1_REG)
- (reg:DI XMM2_REG)
- (reg:DI XMM3_REG)
- (reg:DI XMM4_REG)
- (reg:DI XMM5_REG)
- (reg:DI XMM6_REG)
- (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
- (clobber (reg:CC FLAGS_REG))
- (clobber (match_operand:DI 1 "register_operand" ""))
- (use (match_operand:DI 2 "const_int_operand" ""))
- (use (match_operand 3 "" ""))
- (clobber (match_operand:DI 4 "register_operand" ""))
- (use (match_operand:DI 5 "register_operand" ""))])]
- "reload_completed"
- [(parallel [(set (match_dup 0)
- (unspec:BLK [(reg:DI XMM0_REG)
- (reg:DI XMM1_REG)
- (reg:DI XMM2_REG)
- (reg:DI XMM3_REG)
- (reg:DI XMM4_REG)
- (reg:DI XMM5_REG)
- (reg:DI XMM6_REG)
- (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
- (use (match_dup 1))
- (use (match_dup 2))
- (use (match_dup 3))
- (use (match_dup 5))])]
-{
- /* Movaps is 4 bytes, AVX and movsd is 5 bytes. */
- int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
-
- /* Compute address to jump to:
- label - eax*size + nnamed_sse_arguments*size. */
- if (size == 5)
- emit_insn (gen_rtx_SET (VOIDmode, operands[4],
- gen_rtx_PLUS
- (Pmode,
- gen_rtx_MULT (Pmode, operands[1],
- GEN_INT (4)),
- operands[1])));
- else if (size == 4)
- emit_insn (gen_rtx_SET (VOIDmode, operands[4],
- gen_rtx_MULT (Pmode, operands[1],
- GEN_INT (4))));
- else
- gcc_unreachable ();
- if (INTVAL (operands[2]))
- emit_move_insn
- (operands[1],
- gen_rtx_CONST (DImode,
- gen_rtx_PLUS (DImode,
- operands[3],
- GEN_INT (INTVAL (operands[2])
- * size))));
- else
- emit_move_insn (operands[1], operands[3]);
- emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
- operands[5] = GEN_INT (size);
-})
-
-(define_insn "sse_prologue_save_insn"
- [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
- (match_operand:DI 4 "const_int_operand" "n")))
- (unspec:BLK [(reg:DI XMM0_REG)
- (reg:DI XMM1_REG)
- (reg:DI XMM2_REG)
- (reg:DI XMM3_REG)
- (reg:DI XMM4_REG)
- (reg:DI XMM5_REG)
- (reg:DI XMM6_REG)
- (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
- (use (match_operand:DI 1 "register_operand" "r"))
- (use (match_operand:DI 2 "const_int_operand" "i"))
- (use (label_ref:DI (match_operand 3 "" "X")))
- (use (match_operand:DI 5 "const_int_operand" "i"))]
- "TARGET_64BIT
- && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
- && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
-{
- int i;
- operands[0] = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode, operands[0], operands[4]));
- /* VEX instruction with a REX prefix will #UD. */
- if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
- gcc_unreachable ();
-
- output_asm_insn ("jmp\t%A1", operands);
- for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
- {
- operands[4] = adjust_address (operands[0], DImode, i*16);
- operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
- PUT_MODE (operands[4], TImode);
- if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
- output_asm_insn ("rex", operands);
- if (crtl->stack_alignment_needed < 128)
- output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
- else
- output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
- }
- (*targetm.asm_out.internal_label) (asm_out_file, "L",
- CODE_LABEL_NUMBER (operands[3]));
- return "";
-}
- [(set_attr "type" "other")
- (set_attr "length_immediate" "0")
- (set_attr "length_address" "0")
- ;; 2 bytes for jump and opernds[4] bytes for each save.
- (set (attr "length")
- (plus (const_int 2)
- (mult (symbol_ref ("INTVAL (operands[5])"))
- (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
- (set_attr "memory" "store")
- (set_attr "modrm" "0")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "DI")])
-
(define_expand "prefetch"
[(prefetch (match_operand 0 "address_operand" "")
(match_operand:SI 1 "const_int_operand" "")
(match_operand 1 "memory_operand" "")]
""
{
+ rtx (*insn)(rtx, rtx);
+
#ifdef TARGET_THREAD_SSP_OFFSET
- if (TARGET_64BIT)
- emit_insn (gen_stack_tls_protect_set_di (operands[0],
- GEN_INT (TARGET_THREAD_SSP_OFFSET)));
- else
- emit_insn (gen_stack_tls_protect_set_si (operands[0],
- GEN_INT (TARGET_THREAD_SSP_OFFSET)));
+ operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
+ insn = (TARGET_64BIT
+ ? gen_stack_tls_protect_set_di
+ : gen_stack_tls_protect_set_si);
#else
- if (TARGET_64BIT)
- emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
- else
- emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
+ insn = (TARGET_64BIT
+ ? gen_stack_protect_set_di
+ : gen_stack_protect_set_si);
#endif
+
+ emit_insn (insn (operands[0], operands[1]));
DONE;
})
-(define_insn "stack_protect_set_si"
- [(set (match_operand:SI 0 "memory_operand" "=m")
- (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
- (set (match_scratch:SI 2 "=&r") (const_int 0))
+(define_insn "stack_protect_set_<mode>"
+ [(set (match_operand:P 0 "memory_operand" "=m")
+ (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
+ (set (match_scratch:P 2 "=&r") (const_int 0))
(clobber (reg:CC FLAGS_REG))]
""
- "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
- [(set_attr "type" "multi")])
-
-(define_insn "stack_protect_set_di"
- [(set (match_operand:DI 0 "memory_operand" "=m")
- (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
- (set (match_scratch:DI 2 "=&r") (const_int 0))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
+ "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
[(set_attr "type" "multi")])
-(define_insn "stack_tls_protect_set_si"
- [(set (match_operand:SI 0 "memory_operand" "=m")
- (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
- UNSPEC_SP_TLS_SET))
- (set (match_scratch:SI 2 "=&r") (const_int 0))
+(define_insn "stack_tls_protect_set_<mode>"
+ [(set (match_operand:P 0 "memory_operand" "=m")
+ (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
+ UNSPEC_SP_TLS_SET))
+ (set (match_scratch:P 2 "=&r") (const_int 0))
(clobber (reg:CC FLAGS_REG))]
""
- "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
- [(set_attr "type" "multi")])
-
-(define_insn "stack_tls_protect_set_di"
- [(set (match_operand:DI 0 "memory_operand" "=m")
- (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
- UNSPEC_SP_TLS_SET))
- (set (match_scratch:DI 2 "=&r") (const_int 0))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- {
- /* The kernel uses a different segment register for performance reasons; a
- system call would not have to trash the userspace segment register,
- which would be expensive */
- if (ix86_cmodel != CM_KERNEL)
- return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
- else
- return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
- }
+ "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
[(set_attr "type" "multi")])
(define_expand "stack_protect_test"
{
rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
+ rtx (*insn)(rtx, rtx, rtx);
+
#ifdef TARGET_THREAD_SSP_OFFSET
- if (TARGET_64BIT)
- emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
- GEN_INT (TARGET_THREAD_SSP_OFFSET)));
- else
- emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
- GEN_INT (TARGET_THREAD_SSP_OFFSET)));
+ operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
+ insn = (TARGET_64BIT
+ ? gen_stack_tls_protect_test_di
+ : gen_stack_tls_protect_test_si);
#else
- if (TARGET_64BIT)
- emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
- else
- emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
+ insn = (TARGET_64BIT
+ ? gen_stack_protect_test_di
+ : gen_stack_protect_test_si);
#endif
+ emit_insn (insn (flags, operands[0], operands[1]));
+
emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
flags, const0_rtx, operands[2]));
DONE;
})
-(define_insn "stack_protect_test_si"
+(define_insn "stack_protect_test_<mode>"
[(set (match_operand:CCZ 0 "flags_reg_operand" "")
- (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
- (match_operand:SI 2 "memory_operand" "m")]
+ (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
+ (match_operand:P 2 "memory_operand" "m")]
UNSPEC_SP_TEST))
- (clobber (match_scratch:SI 3 "=&r"))]
+ (clobber (match_scratch:P 3 "=&r"))]
""
- "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
- [(set_attr "type" "multi")])
-
-(define_insn "stack_protect_test_di"
- [(set (match_operand:CCZ 0 "flags_reg_operand" "")
- (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
- (match_operand:DI 2 "memory_operand" "m")]
- UNSPEC_SP_TEST))
- (clobber (match_scratch:DI 3 "=&r"))]
- "TARGET_64BIT"
- "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
+ "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
[(set_attr "type" "multi")])
-(define_insn "stack_tls_protect_test_si"
+(define_insn "stack_tls_protect_test_<mode>"
[(set (match_operand:CCZ 0 "flags_reg_operand" "")
- (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
- (match_operand:SI 2 "const_int_operand" "i")]
+ (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
+ (match_operand:P 2 "const_int_operand" "i")]
UNSPEC_SP_TLS_TEST))
- (clobber (match_scratch:SI 3 "=r"))]
+ (clobber (match_scratch:P 3 "=r"))]
""
- "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
- [(set_attr "type" "multi")])
-
-(define_insn "stack_tls_protect_test_di"
- [(set (match_operand:CCZ 0 "flags_reg_operand" "")
- (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
- (match_operand:DI 2 "const_int_operand" "i")]
- UNSPEC_SP_TLS_TEST))
- (clobber (match_scratch:DI 3 "=r"))]
- "TARGET_64BIT"
- {
- /* The kernel uses a different segment register for performance reasons; a
- system call would not have to trash the userspace segment register,
- which would be expensive */
- if (ix86_cmodel != CM_KERNEL)
- return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
- else
- return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
- }
+ "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
[(set_attr "type" "multi")])
(define_insn "sse4_2_crc32<mode>"
(define_expand "lwp_llwpcb"
[(unspec_volatile [(match_operand 0 "register_operand" "r")]
UNSPECV_LLWP_INTRINSIC)]
- "TARGET_LWP"
- "")
+ "TARGET_LWP")
(define_insn "*lwp_llwpcb<mode>1"
[(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
[(set (match_operand 0 "register_operand" "=r")
(unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
"TARGET_LWP"
- {
- if (TARGET_64BIT)
- emit_insn (gen_lwp_slwpcbdi (operands[0]));
- else
- emit_insn (gen_lwp_slwpcbsi (operands[0]));
- DONE;
- })
+{
+ rtx (*insn)(rtx);
+
+ insn = (TARGET_64BIT
+ ? gen_lwp_slwpcbdi
+ : gen_lwp_slwpcbsi);
+
+ emit_insn (insn (operands[0]));
+ DONE;
+})
(define_insn "lwp_slwpcb<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
UNSPECV_LWPINS_INTRINSIC))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
- "TARGET_LWP"
- "")
+ "TARGET_LWP")
(define_insn "*lwp_lwpins<mode>3_1"
[(set (reg:CCC FLAGS_REG)
(set (attr "length")
(symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
+(define_insn "rdfsbase<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
+ "TARGET_64BIT && TARGET_FSGSBASE"
+ "rdfsbase %0"
+ [(set_attr "type" "other")
+ (set_attr "prefix_extra" "2")])
+
+(define_insn "rdgsbase<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
+ "TARGET_64BIT && TARGET_FSGSBASE"
+ "rdgsbase %0"
+ [(set_attr "type" "other")
+ (set_attr "prefix_extra" "2")])
+
+(define_insn "wrfsbase<mode>"
+ [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
+ UNSPECV_WRFSBASE)]
+ "TARGET_64BIT && TARGET_FSGSBASE"
+ "wrfsbase %0"
+ [(set_attr "type" "other")
+ (set_attr "prefix_extra" "2")])
+
+(define_insn "wrgsbase<mode>"
+ [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
+ UNSPECV_WRGSBASE)]
+ "TARGET_64BIT && TARGET_FSGSBASE"
+ "wrgsbase %0"
+ [(set_attr "type" "other")
+ (set_attr "prefix_extra" "2")])
+
+(define_insn "rdrand<mode>_1"
+ [(set (match_operand:SWI248 0 "register_operand" "=r")
+ (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
+ (set (reg:CCC FLAGS_REG)
+ (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
+ "TARGET_RDRND"
+ "rdrand\t%0"
+ [(set_attr "type" "other")
+ (set_attr "prefix_extra" "1")])
+
+(define_expand "pause"
+ [(set (match_dup 0)
+ (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
+ ""
+{
+ operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+ MEM_VOLATILE_P (operands[0]) = 1;
+})
+
+;; Use "rep; nop", instead of "pause", to support older assemblers.
+;; They have the same encoding.
+(define_insn "*pause"
+ [(set (match_operand:BLK 0 "" "")
+ (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
+ ""
+ "rep; nop"
+ [(set_attr "length" "2")
+ (set_attr "memory" "unknown")])
+
(include "mmx.md")
(include "sse.md")
(include "sync.md")