re PR target/60525 (ICE: in final_scan_insn, at final.c:2952)
PR target/60525 * config/i386/i386.md (floathi<X87MODEF>2): Delete expander; rename define_insn from *floathi<X87MODEF>2_i387; allow nonimmediate_operand. (*floathi<X87MODEF>2_i387_with_temp): Remove. (floathi splitters): Remove. (float<SWI48x>xf2): New pattern. (float<SWI48><MODEF>2): Rename from float<SWI48x><X87MODEF>2. Drop code that tried to handle DImode for 32-bit, but which was excluded by the pattern's condition. Drop allocation of stack temporary. (*floatsi<MODEF>2_vector_mixed_with_temp): Remove. (*float<SWI48><MODEF>2_mixed_with_temp): Remove. (*float<SWI48><MODEF>2_mixed_interunit): Remove. (*float<SWI48><MODEF>2_mixed_nointerunit): Remove. (*floatsi<MODEF>2_vector_sse_with_temp): Remove. (*float<SWI48><MODEF>2_sse_with_temp): Remove. (*float<SWI48><MODEF>2_sse_interunit): Remove. (*float<SWI48><MODEF>2_sse_nointerunit): Remove. (*float<SWI48x><X87MODEF>2_i387_with_temp): Remove. (*float<SWI48x><X87MODEF>2_i387): Remove. (all float _with_temp splitters): Remove. (*float<SWI48x><MODEF>2_i387): New pattern. (*float<SWI48><MODEF>2_sse): New pattern. (float TARGET_USE_VECTOR_CONVERTS splitters): Merge them. (float TARGET_SSE_PARTIAL_REG_DEPENDENCY splitters): Merge them. From-SVN: r208587
This commit is contained in:
parent
47b5d284dd
commit
cfce90ac4a
2 changed files with 99 additions and 401 deletions
|
@ -1,3 +1,30 @@
|
|||
2014-03-14 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR target/60525
|
||||
* config/i386/i386.md (floathi<X87MODEF>2): Delete expander; rename
|
||||
define_insn from *floathi<X87MODEF>2_i387; allow nonimmediate_operand.
|
||||
(*floathi<X87MODEF>2_i387_with_temp): Remove.
|
||||
(floathi splitters): Remove.
|
||||
(float<SWI48x>xf2): New pattern.
|
||||
(float<SWI48><MODEF>2): Rename from float<SWI48x><X87MODEF>2. Drop
|
||||
code that tried to handle DImode for 32-bit, but which was excluded
|
||||
by the pattern's condition. Drop allocation of stack temporary.
|
||||
(*floatsi<MODEF>2_vector_mixed_with_temp): Remove.
|
||||
(*float<SWI48><MODEF>2_mixed_with_temp): Remove.
|
||||
(*float<SWI48><MODEF>2_mixed_interunit): Remove.
|
||||
(*float<SWI48><MODEF>2_mixed_nointerunit): Remove.
|
||||
(*floatsi<MODEF>2_vector_sse_with_temp): Remove.
|
||||
(*float<SWI48><MODEF>2_sse_with_temp): Remove.
|
||||
(*float<SWI48><MODEF>2_sse_interunit): Remove.
|
||||
(*float<SWI48><MODEF>2_sse_nointerunit): Remove.
|
||||
(*float<SWI48x><X87MODEF>2_i387_with_temp): Remove.
|
||||
(*float<SWI48x><X87MODEF>2_i387): Remove.
|
||||
(all float _with_temp splitters): Remove.
|
||||
(*float<SWI48x><MODEF>2_i387): New pattern.
|
||||
(*float<SWI48><MODEF>2_sse): New pattern.
|
||||
(float TARGET_USE_VECTOR_CONVERTS splitters): Merge them.
|
||||
(float TARGET_SSE_PARTIAL_REG_DEPENDENCY splitters): Merge them.
|
||||
|
||||
2014-03-14 Jakub Jelinek <jakub@redhat.com>
|
||||
Marek Polacek <polacek@redhat.com>
|
||||
|
||||
|
|
|
@ -4653,36 +4653,12 @@
|
|||
;; Conversion between fixed point and floating point.
|
||||
|
||||
;; Even though we only accept memory inputs, the backend _really_
|
||||
;; wants to be able to do this between registers.
|
||||
;; wants to be able to do this between registers. Thankfully, LRA
|
||||
;; will fix this up for us during register allocation.
|
||||
|
||||
(define_expand "floathi<mode>2"
|
||||
[(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)"
|
||||
{
|
||||
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")
|
||||
(float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
|
||||
(clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
|
||||
"TARGET_80387
|
||||
&& (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
|
||||
|| TARGET_MIX_SSE_I387)"
|
||||
"#"
|
||||
[(set_attr "type" "fmov,multi")
|
||||
(set_attr "mode" "<MODE>")
|
||||
(set_attr "unit" "*,i387")
|
||||
(set_attr "fp_int_src" "true")])
|
||||
|
||||
(define_insn "*floathi<mode>2_i387"
|
||||
(define_insn "floathi<mode>2"
|
||||
[(set (match_operand:X87MODEF 0 "register_operand" "=f")
|
||||
(float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
|
||||
(float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
|
||||
"TARGET_80387
|
||||
&& (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
|
||||
|| TARGET_MIX_SSE_I387)"
|
||||
|
@ -4691,50 +4667,31 @@
|
|||
(set_attr "mode" "<MODE>")
|
||||
(set_attr "fp_int_src" "true")])
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:X87MODEF 0 "register_operand")
|
||||
(float:X87MODEF (match_operand:HI 1 "register_operand")))
|
||||
(clobber (match_operand:HI 2 "memory_operand"))]
|
||||
"TARGET_80387
|
||||
&& (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
|
||||
|| TARGET_MIX_SSE_I387)
|
||||
&& reload_completed"
|
||||
[(set (match_dup 2) (match_dup 1))
|
||||
(set (match_dup 0) (float:X87MODEF (match_dup 2)))])
|
||||
(define_insn "float<SWI48x:mode>xf2"
|
||||
[(set (match_operand:XF 0 "register_operand" "=f")
|
||||
(float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
|
||||
"TARGET_80387"
|
||||
"fild%Z1\t%1"
|
||||
[(set_attr "type" "fmov")
|
||||
(set_attr "mode" "XF")
|
||||
(set_attr "fp_int_src" "true")])
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:X87MODEF 0 "register_operand")
|
||||
(float:X87MODEF (match_operand:HI 1 "memory_operand")))
|
||||
(clobber (match_operand:HI 2 "memory_operand"))]
|
||||
"TARGET_80387
|
||||
&& (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
|
||||
|| TARGET_MIX_SSE_I387)
|
||||
&& reload_completed"
|
||||
[(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
|
||||
|
||||
(define_expand "float<SWI48x:mode><X87MODEF:mode>2"
|
||||
[(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)"
|
||||
(define_expand "float<SWI48:mode><MODEF:mode>2"
|
||||
[(set (match_operand:MODEF 0 "register_operand")
|
||||
(float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
|
||||
"TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
|
||||
{
|
||||
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))
|
||||
if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
|
||||
&& !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
|
||||
{
|
||||
rtx reg = gen_reg_rtx (XFmode);
|
||||
rtx (*insn)(rtx, rtx);
|
||||
|
||||
emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
|
||||
emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
|
||||
|
||||
if (<X87MODEF:MODE>mode == SFmode)
|
||||
if (<MODEF:MODE>mode == SFmode)
|
||||
insn = gen_truncxfsf2;
|
||||
else if (<X87MODEF:MODE>mode == DFmode)
|
||||
else if (<MODEF:MODE>mode == DFmode)
|
||||
insn = gen_truncxfdf2;
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
@ -4742,83 +4699,22 @@
|
|||
emit_insn (insn (operands[0], reg));
|
||||
DONE;
|
||||
}
|
||||
|
||||
/* Avoid store forwarding (partial memory) stall penalty
|
||||
by passing DImode value through XMM registers. */
|
||||
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 (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
|
||||
(float:MODEF
|
||||
(match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
|
||||
(clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
|
||||
"TARGET_SSE2 && TARGET_MIX_SSE_I387
|
||||
&& TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
|
||||
"#"
|
||||
[(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
|
||||
(set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
|
||||
(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 "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
|
||||
[(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
|
||||
(float:MODEF
|
||||
(match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
|
||||
(clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
|
||||
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
|
||||
"#"
|
||||
[(set_attr "type" "fmov,multi,sseicvt,sseicvt")
|
||||
(define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
|
||||
[(set (match_operand:MODEF 0 "register_operand" "=f")
|
||||
(float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
|
||||
"TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
|
||||
"fild%Z1\t%1"
|
||||
[(set_attr "type" "fmov")
|
||||
(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_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 || optimize_function_for_size_p (cfun))
|
||||
&& reload_completed && SSE_REG_P (operands[0])"
|
||||
[(set (match_dup 2) (match_dup 1))
|
||||
(set (match_dup 0) (float:MODEF (match_dup 2)))])
|
||||
|
||||
(define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
|
||||
(define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
|
||||
[(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
|
||||
(float:MODEF
|
||||
(match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
|
||||
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
|
||||
&& (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
|
||||
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
|
||||
"@
|
||||
fild%Z1\t%1
|
||||
%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
|
||||
|
@ -4836,289 +4732,64 @@
|
|||
(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<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
|
||||
[(set (match_operand:MODEF 0 "register_operand" "=f,x")
|
||||
(float:MODEF
|
||||
(match_operand:SWI48 1 "memory_operand" "m,m")))]
|
||||
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
|
||||
&& !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
|
||||
"@
|
||||
fild%Z1\t%1
|
||||
%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
|
||||
[(set_attr "type" "fmov,sseicvt")
|
||||
(set_attr "prefix" "orig,maybe_vex")
|
||||
(set_attr "mode" "<MODEF:MODE>")
|
||||
(set (attr "prefix_rex")
|
||||
(if_then_else
|
||||
(and (eq_attr "prefix" "maybe_vex")
|
||||
(match_test "<SWI48:MODE>mode == DImode"))
|
||||
(const_string "1")
|
||||
(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 (match_operand:MODEF 0 "register_operand" "=x,x,x")
|
||||
(float:MODEF
|
||||
(match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
|
||||
(clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
|
||||
"TARGET_SSE2 && TARGET_SSE_MATH
|
||||
&& TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
|
||||
"#"
|
||||
[(set_attr "type" "sseicvt")
|
||||
(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_split
|
||||
[(set (match_operand:MODEF 0 "register_operand")
|
||||
(float:MODEF (match_operand:SI 1 "register_operand")))
|
||||
(clobber (match_operand:SI 2 "memory_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) && TARGET_INTER_UNIT_MOVES_TO_VEC)
|
||||
{
|
||||
operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
|
||||
emit_insn (gen_sse2_loadld (operands[4],
|
||||
CONST0_RTX (V4SImode), 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
|
||||
{
|
||||
operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
|
||||
emit_move_insn (operands[2], operands[1]);
|
||||
emit_insn (gen_sse2_loadld (operands[4],
|
||||
CONST0_RTX (V4SImode), operands[2]));
|
||||
}
|
||||
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")))
|
||||
(clobber (match_operand:SI 2 "memory_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)]
|
||||
{
|
||||
operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
|
||||
<MODE>mode, 0);
|
||||
operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
|
||||
|
||||
emit_insn (gen_sse2_loadld (operands[4],
|
||||
CONST0_RTX (V4SImode), operands[1]));
|
||||
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")))]
|
||||
"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)]
|
||||
{
|
||||
operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
|
||||
<MODE>mode, 0);
|
||||
operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
|
||||
|
||||
emit_insn (gen_sse2_loadld (operands[4],
|
||||
CONST0_RTX (V4SImode), operands[1]));
|
||||
if (<ssevecmode>mode == V4SFmode)
|
||||
emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
|
||||
else
|
||||
emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
|
||||
[(set (match_operand:MODEF 0 "register_operand" "=x,x")
|
||||
(float:MODEF
|
||||
(match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
|
||||
(clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
|
||||
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
|
||||
"#"
|
||||
[(set_attr "type" "sseicvt")
|
||||
(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 "btver2_decode" "double,double")
|
||||
(set_attr "fp_int_src" "true")])
|
||||
|
||||
(define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
|
||||
[(set (match_operand:MODEF 0 "register_operand" "=x,x")
|
||||
(float:MODEF
|
||||
(match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
|
||||
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
|
||||
&& (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
|
||||
"%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
|
||||
[(set_attr "type" "sseicvt")
|
||||
(set_attr "prefix" "maybe_vex")
|
||||
(set_attr "mode" "<MODEF:MODE>")
|
||||
(set (attr "prefix_rex")
|
||||
(if_then_else
|
||||
(and (eq_attr "prefix" "maybe_vex")
|
||||
(match_test "<SWI48:MODE>mode == DImode"))
|
||||
(const_string "1")
|
||||
(const_string "*")))
|
||||
(set_attr "athlon_decode" "double,direct")
|
||||
(set_attr "amdfam10_decode" "vector,double")
|
||||
(set_attr "bdver1_decode" "double,direct")
|
||||
(set_attr "btver2_decode" "double,double")
|
||||
(set_attr "fp_int_src" "true")])
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:MODEF 0 "register_operand")
|
||||
(float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
|
||||
(clobber (match_operand:SWI48 2 "memory_operand"))]
|
||||
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
|
||||
&& (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
|
||||
&& reload_completed && SSE_REG_P (operands[0])"
|
||||
[(set (match_dup 0) (float:MODEF (match_dup 1)))])
|
||||
|
||||
(define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
|
||||
[(set (match_operand:MODEF 0 "register_operand" "=x")
|
||||
(float:MODEF
|
||||
(match_operand:SWI48 1 "memory_operand" "m")))]
|
||||
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
|
||||
&& !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
|
||||
"%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
|
||||
[(set_attr "type" "sseicvt")
|
||||
(set_attr "prefix" "maybe_vex")
|
||||
(set_attr "mode" "<MODEF:MODE>")
|
||||
(set (attr "prefix_rex")
|
||||
(if_then_else
|
||||
(and (eq_attr "prefix" "maybe_vex")
|
||||
(match_test "<SWI48:MODE>mode == DImode"))
|
||||
(const_string "1")
|
||||
(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
|
||||
[(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_SSE_MATH
|
||||
&& !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
|
||||
&& reload_completed && SSE_REG_P (operands[0])"
|
||||
[(set (match_dup 2) (match_dup 1))
|
||||
(set (match_dup 0) (float:MODEF (match_dup 2)))])
|
||||
|
||||
(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
|
||||
[(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
|
||||
(float:X87MODEF
|
||||
(match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
|
||||
(clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
|
||||
"TARGET_80387
|
||||
&& X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
|
||||
"@
|
||||
fild%Z1\t%1
|
||||
#"
|
||||
[(set_attr "type" "fmov,multi")
|
||||
(set_attr "mode" "<X87MODEF:MODE>")
|
||||
(set_attr "unit" "*,i387")
|
||||
(set_attr "fp_int_src" "true")])
|
||||
|
||||
(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
|
||||
[(set (match_operand:X87MODEF 0 "register_operand" "=f")
|
||||
(float:X87MODEF
|
||||
(match_operand:SWI48x 1 "memory_operand" "m")))]
|
||||
"TARGET_80387
|
||||
&& X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
|
||||
"fild%Z1\t%1"
|
||||
[(set_attr "type" "fmov")
|
||||
(set_attr "mode" "<X87MODEF:MODE>")
|
||||
(set_attr "fp_int_src" "true")])
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:X87MODEF 0 "fp_register_operand")
|
||||
(float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
|
||||
(clobber (match_operand:SWI48x 2 "memory_operand"))]
|
||||
"TARGET_80387
|
||||
&& X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
|
||||
&& reload_completed"
|
||||
[(set (match_dup 2) (match_dup 1))
|
||||
(set (match_dup 0) (float:X87MODEF (match_dup 2)))])
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:X87MODEF 0 "fp_register_operand")
|
||||
(float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
|
||||
(clobber (match_operand:SWI48x 2 "memory_operand"))]
|
||||
"TARGET_80387
|
||||
&& X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
|
||||
&& reload_completed"
|
||||
[(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
|
||||
|
||||
;; Avoid partial SSE register dependency stalls
|
||||
(set_attr "fp_int_src" "true")
|
||||
(set (attr "enabled")
|
||||
(cond [(eq_attr "alternative" "0")
|
||||
(symbol_ref "TARGET_MIX_SSE_I387")
|
||||
(eq_attr "alternative" "1")
|
||||
(symbol_ref "TARGET_INTER_UNIT_CONVERSIONS
|
||||
|| optimize_function_for_size_p (cfun)")
|
||||
]
|
||||
(symbol_ref "true")))
|
||||
])
|
||||
|
||||
;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
|
||||
;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
|
||||
;; alternative in sse2_loadld.
|
||||
(define_split
|
||||
[(set (match_operand:MODEF 0 "register_operand")
|
||||
(float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
|
||||
"TARGET_SSE2 && TARGET_SSE_MATH
|
||||
&& TARGET_SSE_PARTIAL_REG_DEPENDENCY
|
||||
&& optimize_function_for_speed_p (cfun)
|
||||
&& reload_completed && SSE_REG_P (operands[0])"
|
||||
[(set (match_dup 0)
|
||||
(vec_merge:<ssevecmode>
|
||||
(vec_duplicate:<ssevecmode>
|
||||
(float:MODEF (match_dup 1)))
|
||||
(match_dup 0)
|
||||
(const_int 1)))]
|
||||
&& TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
|
||||
&& reload_completed && SSE_REG_P (operands[0])
|
||||
&& (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
|
||||
[(const_int 0)]
|
||||
{
|
||||
operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
|
||||
operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
|
||||
<MODE>mode, 0);
|
||||
emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
|
||||
operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
|
||||
|
||||
emit_insn (gen_sse2_loadld (operands[4],
|
||||
CONST0_RTX (V4SImode), operands[1]));
|
||||
|
||||
if (<ssevecmode>mode == V4SFmode)
|
||||
emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
|
||||
else
|
||||
emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Avoid partial SSE register dependency stalls
|
||||
(define_split
|
||||
[(set (match_operand:MODEF 0 "register_operand")
|
||||
(float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
|
||||
"TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
|
||||
(float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
|
||||
"TARGET_SSE2 && TARGET_SSE_MATH
|
||||
&& TARGET_SSE_PARTIAL_REG_DEPENDENCY
|
||||
&& optimize_function_for_speed_p (cfun)
|
||||
&& reload_completed && SSE_REG_P (operands[0])"
|
||||
[(set (match_dup 0)
|
||||
(vec_merge:<ssevecmode>
|
||||
(vec_duplicate:<ssevecmode>
|
||||
(float:MODEF (match_dup 1)))
|
||||
(match_dup 0)
|
||||
(const_int 1)))]
|
||||
[(const_int 0)]
|
||||
{
|
||||
operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
|
||||
<MODE>mode, 0);
|
||||
emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
|
||||
const enum machine_mode vmode = <MODEF:ssevecmode>mode;
|
||||
const enum machine_mode mode = <MODEF:MODE>mode;
|
||||
rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
|
||||
|
||||
emit_move_insn (op0, CONST0_RTX (vmode));
|
||||
|
||||
t = gen_rtx_FLOAT (mode, operands[1]);
|
||||
t = gen_rtx_VEC_DUPLICATE (vmode, t);
|
||||
t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, op0, t));
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Break partial reg stall for cvtsd2ss.
|
||||
|
|
Loading…
Add table
Reference in a new issue