;; wants to be able to do this between registers.
(define_expand "floathi<mode>2"
- [(set (match_operand:X87MODEF 0 "register_operand")
- (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
- "TARGET_80387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)")
-
-;; Pre-reload splitter to add memory clobber to the pattern.
-(define_insn_and_split "*floathi<mode>2_1"
- [(set (match_operand:X87MODEF 0 "register_operand")
- (float:X87MODEF (match_operand:HI 1 "register_operand")))]
+ [(parallel [(set (match_operand:X87MODEF 0 "register_operand")
+ (float:X87MODEF
+ (match_operand:HI 1 "nonimmediate_operand")))
+ (clobber (match_dup 2))])]
"TARGET_80387
&& (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(parallel [(set (match_dup 0)
- (float:X87MODEF (match_dup 1)))
- (clobber (match_dup 2))])]
- "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
+ || TARGET_MIX_SSE_I387)"
+{
+ operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);
+})
(define_insn "*floathi<mode>2_i387_with_temp"
[(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
[(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
(define_expand "float<SWI48x:mode><X87MODEF:mode>2"
- [(set (match_operand:X87MODEF 0 "register_operand")
- (float:X87MODEF
- (match_operand:SWI48x 1 "nonimmediate_operand")))]
+ [(parallel [(set (match_operand:X87MODEF 0 "register_operand")
+ (float:X87MODEF
+ (match_operand:SWI48x 1 "nonimmediate_operand")))
+ (clobber (match_dup 2))])]
"TARGET_80387
|| ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
&& SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
{
- if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
+ bool native_int = TARGET_64BIT || <SWI48x:MODE>mode != DImode;
+
+ if (!(native_int
&& SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
&& !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
{
emit_insn (insn (operands[0], reg));
DONE;
}
-})
-
-;; Pre-reload splitter to add memory clobber to the pattern.
-(define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
- [(set (match_operand:X87MODEF 0 "register_operand")
- (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
- "((TARGET_80387
- && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
- && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
- && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387))
- || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
- && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
- && ((<SWI48x:MODE>mode == SImode
- && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
- && optimize_function_for_speed_p (cfun)
- && flag_trapping_math)
- || !(TARGET_INTER_UNIT_CONVERSIONS
- || optimize_function_for_size_p (cfun)))))
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
- (clobber (match_dup 2))])]
-{
- operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
/* Avoid store forwarding (partial memory) stall penalty
by passing DImode value through XMM registers. */
- if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
+ if (!native_int
&& TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
&& optimize_function_for_speed_p (cfun))
{
+ operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
operands[1],
operands[2]));
DONE;
}
+
+ /* Notice when we'd convert directly from general registers. */
+ if (native_int
+ && (TARGET_MIX_SSE_I387 || TARGET_SSE_MATH)
+ && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode)
+ && (TARGET_INTER_UNIT_CONVERSIONS
+ || optimize_function_for_size_p (cfun)))
+ {
+ emit_insn (gen_rtx_SET
+ (VOIDmode, operands[0],
+ gen_rtx_FLOAT (<X87MODEF:MODE>mode, operands[1])));
+ DONE;
+ }
+
+ operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
})
(define_insn "*floatsi<mode>2_vector_mixed_with_temp"
(set_attr "bdver1_decode" "*,*,double,direct,double")
(set_attr "fp_int_src" "true")])
-(define_insn "*floatsi<mode>2_vector_mixed"
- [(set (match_operand:MODEF 0 "register_operand" "=f,x")
- (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
- "TARGET_SSE2 && TARGET_MIX_SSE_I387
- && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
- "@
- fild%Z1\t%1
- #"
- [(set_attr "type" "fmov,sseicvt")
- (set_attr "mode" "<MODE>,<ssevecmode>")
- (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<SWI48:mode><MODEF:mode>2_mixed_with_temp"
[(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
(float:MODEF
(set_attr "bdver1_decode" "*,*,double,direct")
(set_attr "fp_int_src" "true")])
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float:MODEF (match_operand:SWI48 1 "register_operand")))
- (clobber (match_operand:SWI48 2 "memory_operand"))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
- && TARGET_INTER_UNIT_CONVERSIONS
- && reload_completed && SSE_REG_P (operands[0])"
- [(set (match_dup 0) (float:MODEF (match_dup 1)))])
-
(define_split
[(set (match_operand:MODEF 0 "register_operand")
(float:MODEF (match_operand:SWI48 1 "register_operand")))
(set_attr "bdver1_decode" "double,direct,double")
(set_attr "fp_int_src" "true")])
-(define_insn "*floatsi<mode>2_vector_sse"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
- "TARGET_SSE2 && TARGET_SSE_MATH
- && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
- "#"
- [(set_attr "type" "sseicvt")
- (set_attr "mode" "<MODE>")
- (set_attr "athlon_decode" "direct")
- (set_attr "amdfam10_decode" "double")
- (set_attr "bdver1_decode" "direct")
- (set_attr "fp_int_src" "true")])
-
(define_split
[(set (match_operand:MODEF 0 "register_operand")
(float:MODEF (match_operand:SI 1 "register_operand")))
DONE;
})
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float:MODEF (match_operand:SI 1 "register_operand")))]
- "TARGET_SSE2 && TARGET_SSE_MATH
- && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
- && reload_completed && SSE_REG_P (operands[0])"
- [(const_int 0)]
-{
- rtx op1 = operands[1];
-
- operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
- <MODE>mode, 0);
- if (GET_CODE (op1) == SUBREG)
- op1 = SUBREG_REG (op1);
-
- if (GENERAL_REG_P (op1))
- {
- operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
- if (TARGET_INTER_UNIT_MOVES_TO_VEC)
- emit_insn (gen_sse2_loadld (operands[4],
- CONST0_RTX (V4SImode), operands[1]));
- else
- {
- operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
- operands[1]);
- emit_insn (gen_sse2_loadld (operands[4],
- CONST0_RTX (V4SImode), operands[5]));
- ix86_free_from_memory (GET_MODE (operands[1]));
- }
- }
- /* We can ignore possible trapping value in the
- high part of SSE register for non-trapping math. */
- else if (SSE_REG_P (op1) && !flag_trapping_math)
- operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
- else
- gcc_unreachable ();
- if (<ssevecmode>mode == V4SFmode)
- emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
- else
- emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
- DONE;
-})
-
(define_split
[(set (match_operand:MODEF 0 "register_operand")
(float:MODEF (match_operand:SI 1 "memory_operand")))]
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (float:MODEF (match_dup 2)))])
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float:MODEF (match_operand:SWI48 1 "memory_operand")))
- (clobber (match_operand:SWI48 2 "memory_operand"))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
- && reload_completed && SSE_REG_P (operands[0])"
- [(set (match_dup 0) (float:MODEF (match_dup 1)))])
-
(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
[(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
(float:X87MODEF
[(const_int 0)]
{
ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
- operands[3], operands[4], NULL_RTX, NULL_RTX);
+ operands[3], operands[4], NULL_RTX);
DONE;
})
[(const_int 0)]
{
ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
- operands[3], operands[4], operands[5], NULL_RTX);
+ operands[3], operands[4], operands[5]);
DONE;
})
(if_then_else
(match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
[(match_operator:X87MODEF 1 "float_operator"
- [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
- (match_operand:X87MODEF 3 "register_operand" "f,f")])
+ [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
+ (match_operand:X87MODEF 3 "register_operand" "f")])
(label_ref (match_operand 4))
(pc)))
(clobber (reg:CCFP FPSR_REG))
(clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 5 "=a,a"))]
+ (clobber (match_scratch:HI 5 "=a"))]
"TARGET_80387 && !TARGET_CMOVE
&& (TARGET_USE_<SWI24:MODE>MODE_FIOP
|| optimize_function_for_size_p (cfun))"
(if_then_else
(match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
[(match_operator:X87MODEF 1 "float_operator"
- [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
- (match_operand:X87MODEF 3 "register_operand" "f,f")])
+ [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
+ (match_operand:X87MODEF 3 "register_operand" "f")])
(pc)
(label_ref (match_operand 4))))
(clobber (reg:CCFP FPSR_REG))
(clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 5 "=a,a"))]
+ (clobber (match_scratch:HI 5 "=a"))]
"TARGET_80387 && !TARGET_CMOVE
&& (TARGET_USE_<SWI24:MODE>MODE_FIOP
|| optimize_function_for_size_p (cfun))"
{
ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
- operands[4], operands[5], operands[6], NULL_RTX);
- DONE;
-})
-
-;; %%% Kill this when reload knows how to do it.
-(define_split
- [(set (pc)
- (if_then_else
- (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
- [(match_operator:X87MODEF 1 "float_operator"
- [(match_operand:SWI24 2 "register_operand")])
- (match_operand:X87MODEF 3 "register_operand")])
- (match_operand 4)
- (match_operand 5)))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 6))]
- "TARGET_80387 && !TARGET_CMOVE
- && reload_completed"
- [(const_int 0)]
-{
- operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
-
- ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
- gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
- operands[4], operands[5], operands[6], operands[2]);
+ operands[4], operands[5], operands[6]);
DONE;
})
\f
;; ??? Add SSE splitters for these!
(define_insn "*fop_<MODEF:mode>_2_i387"
- [(set (match_operand:MODEF 0 "register_operand" "=f,f")
+ [(set (match_operand:MODEF 0 "register_operand" "=f")
(match_operator:MODEF 3 "binary_fp_operator"
[(float:MODEF
- (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
- (match_operand:MODEF 2 "register_operand" "0,0")]))]
+ (match_operand:SWI24 1 "nonimmediate_operand" "m"))
+ (match_operand:MODEF 2 "register_operand" "0")]))]
"TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
&& !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
- && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
- "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
+ && (TARGET_USE_<SWI24:MODE>MODE_FIOP
+ || optimize_function_for_size_p (cfun))"
+ { return output_387_binary_op (insn, operands); }
[(set (attr "type")
(cond [(match_operand:MODEF 3 "mult_operator")
(const_string "fmul")
(set_attr "mode" "<SWI24:MODE>")])
(define_insn "*fop_<MODEF:mode>_3_i387"
- [(set (match_operand:MODEF 0 "register_operand" "=f,f")
+ [(set (match_operand:MODEF 0 "register_operand" "=f")
(match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "register_operand" "0,0")
+ [(match_operand:MODEF 1 "register_operand" "0")
(float:MODEF
- (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
+ (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
"TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
&& !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
- && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
- "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
+ && (TARGET_USE_<SWI24:MODE>MODE_FIOP
+ || optimize_function_for_size_p (cfun))"
+ { return output_387_binary_op (insn, operands); }
[(set (attr "type")
(cond [(match_operand:MODEF 3 "mult_operator")
(const_string "fmul")
(set_attr "mode" "XF")])
(define_insn "*fop_xf_2_i387"
- [(set (match_operand:XF 0 "register_operand" "=f,f")
+ [(set (match_operand:XF 0 "register_operand" "=f")
(match_operator:XF 3 "binary_fp_operator"
[(float:XF
- (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
- (match_operand:XF 2 "register_operand" "0,0")]))]
- "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
- "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
+ (match_operand:SWI24 1 "nonimmediate_operand" "m"))
+ (match_operand:XF 2 "register_operand" "0")]))]
+ "TARGET_80387
+ && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
+ { return output_387_binary_op (insn, operands); }
[(set (attr "type")
(cond [(match_operand:XF 3 "mult_operator")
(const_string "fmul")
(set_attr "mode" "<MODE>")])
(define_insn "*fop_xf_3_i387"
- [(set (match_operand:XF 0 "register_operand" "=f,f")
+ [(set (match_operand:XF 0 "register_operand" "=f")
(match_operator:XF 3 "binary_fp_operator"
- [(match_operand:XF 1 "register_operand" "0,0")
+ [(match_operand:XF 1 "register_operand" "0")
(float:XF
- (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
- "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
- "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
+ (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
+ "TARGET_80387
+ && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
+ { return output_387_binary_op (insn, operands); }
[(set (attr "type")
(cond [(match_operand:XF 3 "mult_operator")
(const_string "fmul")
]
(const_string "fop")))
(set_attr "mode" "<MODE>")])
-
-(define_split
- [(set (match_operand 0 "register_operand")
- (match_operator 3 "binary_fp_operator"
- [(float (match_operand:SWI24 1 "register_operand"))
- (match_operand 2 "register_operand")]))]
- "reload_completed
- && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
- && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
- [(const_int 0)]
-{
- operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
- operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_fmt_ee (GET_CODE (operands[3]),
- GET_MODE (operands[3]),
- operands[4],
- operands[2])));
- ix86_free_from_memory (GET_MODE (operands[1]));
- DONE;
-})
-
-(define_split
- [(set (match_operand 0 "register_operand")
- (match_operator 3 "binary_fp_operator"
- [(match_operand 1 "register_operand")
- (float (match_operand:SWI24 2 "register_operand"))]))]
- "reload_completed
- && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
- && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
- [(const_int 0)]
-{
- operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
- operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_fmt_ee (GET_CODE (operands[3]),
- GET_MODE (operands[3]),
- operands[1],
- operands[4])));
- ix86_free_from_memory (GET_MODE (operands[2]));
- DONE;
-})
\f
;; FPU special functions.
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")])
-(define_insn "*fscalexf4_i387"
+(define_insn "fscalexf4_i387"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 2 "register_operand" "0")
(match_operand:XF 3 "register_operand" "1")]
})
(define_expand "ldexpxf3"
- [(set (match_dup 3)
- (float:XF (match_operand:SI 2 "register_operand")))
- (parallel [(set (match_operand:XF 0 " register_operand")
- (unspec:XF [(match_operand:XF 1 "register_operand")
- (match_dup 3)]
- UNSPEC_FSCALE_FRACT))
- (set (match_dup 4)
- (unspec:XF [(match_dup 1) (match_dup 3)]
- UNSPEC_FSCALE_EXP))])]
+ [(match_operand:XF 0 "register_operand")
+ (match_operand:XF 1 "register_operand")
+ (match_operand:SI 2 "register_operand")]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
{
operands[3] = gen_reg_rtx (XFmode);
operands[4] = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_floatsixf2 (operands[3], operands[2]));
+ emit_insn (gen_fscalexf4_i387 (operands[0], operands[4],
+ operands[1], operands[3]));
+ DONE;
})
(define_expand "ldexp<mode>3"