Commit bc051083 by Uros Bizjak Committed by Uros Bizjak

i386 (mov<mode>): Macroize expander from mov{sf,df,xf} using X87MODEF mode iterator.

	* config/i386/i386 (mov<mode>): Macroize expander from mov{sf,df,xf}
	using X87MODEF mode iterator.
	(pushsf splitter): Macroize splitter using P mode iterator.
	(*swap<mode>): Macroize insn from *swap{sf,df} using MODEF
	mode iterator.

	(*movxf_internal): Rename from *movxf_integer.
	(*movxf_internal_nointeger): Rename from *movxf_nointeger.
	(*movdf_internal_rex64): Rename from *movdf_integer_rex64.
	(*movdf_internal): Rename from *movdf_integer.
	(*movdf_internal_nointeger): Rename from *movdf_nointeger.
	(*movsf_internal): Rename from *movdf_1.

From-SVN: r161287
parent cde8534c
2010-06-23 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386 (mov<mode>): Macroize expander from mov{sf,df,xf}
using X87MODEF mode iterator.
(pushsf splitter): Macroize splitter using P mode iterator.
(*swap<mode>): Macroize insn from *swap{sf,df} using MODEF
mode iterator.
(*movxf_internal): Rename from *movxf_integer.
(*movxf_internal_nointeger): Rename from *movxf_nointeger.
(*movdf_internal_rex64): Rename from *movdf_integer_rex64.
(*movdf_internal): Rename from *movdf_integer.
(*movdf_internal_nointeger): Rename from *movdf_nointeger.
(*movsf_internal): Rename from *movdf_1.
2010-06-23 Basile Starynkevitch <basile@starynkevitch.net> 2010-06-23 Basile Starynkevitch <basile@starynkevitch.net>
* coretypes.h: (gimple_seq_node_d, gimple_seq_node) * coretypes.h: (gimple_seq_node_d, gimple_seq_node)
...@@ -104,7 +119,7 @@ ...@@ -104,7 +119,7 @@
(SWI48x): Ditto. (SWI48x): Ditto.
(SWI12): Ditto. (SWI12): Ditto.
(SWI24): Ditto. (SWI24): Ditto.
(mov<mode>): Macroize expander from mov{qi,hi,si,di} using (mov<mode>): Macroize expander from mov{qi,hi,si,di} using
SWI1248x mode iterator. SWI1248x mode iterator.
(*push<mode>2_rex64): Macroize insn from *push{qi,hi,si}_rex64 (*push<mode>2_rex64): Macroize insn from *push{qi,hi,si}_rex64
......
...@@ -2604,24 +2604,140 @@ ...@@ -2604,24 +2604,140 @@
;; Floating point move instructions. ;; Floating point move instructions.
(define_expand "movsf" (define_expand "movtf"
[(set (match_operand:SF 0 "nonimmediate_operand" "") [(set (match_operand:TF 0 "nonimmediate_operand" "")
(match_operand:SF 1 "general_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 (SFmode, operands); DONE;") "ix86_expand_move (<MODE>mode, operands); DONE;")
(define_insn "*pushsf" (define_insn "*pushtf"
[(set (match_operand:SF 0 "push_operand" "=<,<,<") [(set (match_operand:TF 0 "push_operand" "=<,<,<")
(match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))] (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
"!TARGET_64BIT" "TARGET_SSE2"
{ {
/* Anything else should be already split before reg-stack. */ /* This insn should be already split before reg-stack. */
gcc_assert (which_alternative == 1); gcc_unreachable ();
return "push{l}\t%1";
} }
[(set_attr "type" "multi,push,multi") [(set_attr "type" "multi")
(set_attr "unit" "sse,*,*")
(set_attr "mode" "TF,SI,SI")])
(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"))]
"optimize_function_for_speed_p (cfun)"
{
/* This insn should be already split before reg-stack. */
gcc_unreachable ();
}
[(set_attr "type" "multi")
(set_attr "unit" "i387,*")
(set_attr "mode" "XF,SI")])
;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
;; Size of pushxf using integer instructions is 3+3*memory operand size
;; Pushing using integer instructions is longer except for constants
;; and direct memory references (assuming that any given constant is pushed
;; only once, but this ought to be handled elsewhere).
(define_insn "*pushxf_nointeger"
[(set (match_operand:XF 0 "push_operand" "=X,X,X")
(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
"optimize_function_for_size_p (cfun)"
{
/* This insn should be already split before reg-stack. */
gcc_unreachable ();
}
[(set_attr "type" "multi")
(set_attr "unit" "i387,*,*") (set_attr "unit" "i387,*,*")
(set_attr "mode" "SF,SI,SF")]) (set_attr "mode" "XF,SI,SI")])
(define_split
[(set (match_operand:XF 0 "push_operand" "")
(match_operand:XF 1 "any_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))]
"operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
(define_split
[(set (match_operand:XF 0 "push_operand" "")
(match_operand:XF 1 "general_operand" ""))]
"reload_completed
&& !ANY_FP_REG_P (operands[1])"
[(const_int 0)]
"ix86_split_long_move (operands); DONE;")
(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"
{
/* This insn should be already split before reg-stack. */
gcc_unreachable ();
}
[(set_attr "type" "multi")
(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))]
"")
(define_split
[(set (match_operand:DF 0 "push_operand" "")
(match_operand:DF 1 "general_operand" ""))]
"reload_completed
&& !ANY_FP_REG_P (operands[1])"
[(const_int 0)]
"ix86_split_long_move (operands); DONE;")
(define_insn "*pushsf_rex64" (define_insn "*pushsf_rex64"
[(set (match_operand:SF 0 "push_operand" "=X,X,X") [(set (match_operand:SF 0 "push_operand" "=X,X,X")
...@@ -2636,6 +2752,19 @@ ...@@ -2636,6 +2752,19 @@
(set_attr "unit" "i387,*,*") (set_attr "unit" "i387,*,*")
(set_attr "mode" "SF,DI,SF")]) (set_attr "mode" "SF,DI,SF")])
(define_insn "*pushsf"
[(set (match_operand:SF 0 "push_operand" "=<,<,<")
(match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
"!TARGET_64BIT"
{
/* Anything else should be already split before reg-stack. */
gcc_assert (which_alternative == 1);
return "push{l}\t%1";
}
[(set_attr "type" "multi,push,multi")
(set_attr "unit" "i387,*,*")
(set_attr "mode" "SF,SI,SF")])
(define_split (define_split
[(set (match_operand:SF 0 "push_operand" "") [(set (match_operand:SF 0 "push_operand" "")
(match_operand:SF 1 "memory_operand" ""))] (match_operand:SF 1 "memory_operand" ""))]
...@@ -2649,202 +2778,148 @@ ...@@ -2649,202 +2778,148 @@
(define_split (define_split
[(set (match_operand:SF 0 "push_operand" "") [(set (match_operand:SF 0 "push_operand" "")
(match_operand:SF 1 "any_fp_register_operand" ""))] (match_operand:SF 1 "any_fp_register_operand" ""))]
"!TARGET_64BIT" "reload_completed"
[(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
(set (mem:SF (reg:SI SP_REG)) (match_dup 1))]) (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
"operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
(define_split
[(set (match_operand:SF 0 "push_operand" "")
(match_operand:SF 1 "any_fp_register_operand" ""))]
"TARGET_64BIT"
[(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
(set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
(define_insn "*movsf_1" (define_insn "*movtf_internal"
[(set (match_operand:SF 0 "nonimmediate_operand" [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
"=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r") (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
(match_operand:SF 1 "general_operand" "TARGET_SSE2
"fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))] && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"!(MEM_P (operands[0]) && MEM_P (operands[1]))
&& (reload_in_progress || reload_completed
|| (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
|| memory_operand (operands[0], SFmode))"
{ {
switch (which_alternative) switch (which_alternative)
{ {
case 0: case 0:
case 1: case 1:
return output_387_reg_move (insn, operands);
case 2:
return standard_80387_constant_opcode (operands[1]);
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";
case 6:
if (get_attr_mode (insn) == MODE_V4SF) if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovaps\t{%1, %0|%0, %1}"; return "%vmovaps\t{%1, %0|%0, %1}";
else else
return "%vmovss\t{%1, %d0|%d0, %1}"; return "%vmovdqa\t{%1, %0|%0, %1}";
case 7: case 2:
if (TARGET_AVX) if (get_attr_mode (insn) == MODE_V4SF)
return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}" return "%vxorps\t%0, %d0";
: "vmovss\t{%1, %0|%0, %1}";
else else
return "movss\t{%1, %0|%0, %1}"; return "%vpxor\t%0, %d0";
case 8: case 3:
return "%vmovss\t{%1, %0|%0, %1}"; case 4:
return "#";
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}";
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
} }
[(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov") [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
(set (attr "prefix") (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
(if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
(const_string "maybe_vex")
(const_string "orig")))
(set (attr "mode") (set (attr "mode")
(cond [(eq_attr "alternative" "3,4,9,10") (cond [(eq_attr "alternative" "0,2")
(const_string "SI")
(eq_attr "alternative" "5")
(if_then_else (if_then_else
(and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") (ne (symbol_ref "optimize_function_for_size_p (cfun)")
(const_int 0)) (const_int 0))
(ne (symbol_ref "TARGET_SSE2") (const_string "V4SF")
(const_int 0))) (const_string "TI"))
(eq (symbol_ref "optimize_function_for_size_p (cfun)") (eq_attr "alternative" "1")
(const_int 0)))
(const_string "TI")
(const_string "V4SF"))
/* For architectures resolving dependencies on
whole SSE registers use APS move to break dependency
chains, otherwise use short move to avoid extra work.
Do the same for architectures resolving dependencies on
the parts. While in DF mode it is better to always handle
just register parts, the SF mode is different due to lack
of instructions to load just part of the register. It is
better to maintain the whole registers in single format
to avoid problems on using packed logical operations. */
(eq_attr "alternative" "6")
(if_then_else (if_then_else
(ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
(const_int 0)) (const_int 0))
(ne (symbol_ref "TARGET_SSE_SPLIT_REGS") (ne (symbol_ref "optimize_function_for_size_p (cfun)")
(const_int 0))) (const_int 0)))
(const_string "V4SF") (const_string "V4SF")
(const_string "SF")) (const_string "TI"))]
(eq_attr "alternative" "11") (const_string "DI")))])
(const_string "DI")]
(const_string "SF")))])
(define_insn "*swapsf" (define_split
[(set (match_operand:SF 0 "fp_register_operand" "+f") [(set (match_operand:TF 0 "nonimmediate_operand" "")
(match_operand:SF 1 "fp_register_operand" "+f")) (match_operand:TF 1 "general_operand" ""))]
(set (match_dup 1) "reload_completed
(match_dup 0))] && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
"reload_completed || TARGET_80387" [(const_int 0)]
"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
|| GET_CODE (operands[1]) != CONST_DOUBLE
|| memory_operand (operands[0], XFmode))"
{ {
if (STACK_TOP_P (operands[0])) switch (which_alternative)
return "fxch\t%1"; {
else case 0:
return "fxch\t%0"; case 1:
} return output_387_reg_move (insn, operands);
[(set_attr "type" "fxch")
(set_attr "mode" "SF")])
(define_expand "movdf" case 2:
[(set (match_operand:DF 0 "nonimmediate_operand" "") return standard_80387_constant_opcode (operands[1]);
(match_operand:DF 1 "general_operand" ""))]
""
"ix86_expand_move (DFmode, operands); DONE;")
;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. case 3: case 4:
;; Size of pushdf using integer instructions is 2+2*memory operand size return "#";
;; On the average, pushdf using integers can be still shorter. Allow this
;; pattern for optimize_size too.
(define_insn "*pushdf_nointeger" default:
[(set (match_operand:DF 0 "push_operand" "=<,<,<,<") gcc_unreachable ();
(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 "type" "fmov,fmov,fmov,multi,multi")
(set_attr "unit" "i387,*,*,*") (set_attr "mode" "XF,XF,XF,SI,SI")])
(set_attr "mode" "DF,SI,SI,DF")])
(define_insn "*pushdf_integer" ;; Do not use integer registers when optimizing for size
[(set (match_operand:DF 0 "push_operand" "=<,<,<") (define_insn "*movxf_internal_nointeger"
(match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))] [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
"TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES" (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
"optimize_function_for_size_p (cfun)
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))
&& (reload_in_progress || reload_completed
|| standard_80387_constant_p (operands[1])
|| GET_CODE (operands[1]) != CONST_DOUBLE
|| memory_operand (operands[0], XFmode))"
{ {
/* This insn should be already split before reg-stack. */ switch (which_alternative)
gcc_unreachable (); {
} case 0:
[(set_attr "type" "multi") case 1:
(set_attr "unit" "i387,*,*") return output_387_reg_move (insn, operands);
(set_attr "mode" "DF,SI,DF")])
;; %%% Kill this when call knows how to work this out. case 2:
(define_split return standard_80387_constant_opcode (operands[1]);
[(set (match_operand:DF 0 "push_operand" "")
(match_operand:DF 1 "any_fp_register_operand" ""))] case 3: case 4:
"reload_completed" return "#";
[(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) default:
(set (mem:DF (reg:P SP_REG)) (match_dup 1))] gcc_unreachable ();
"") }
}
[(set_attr "type" "fmov,fmov,fmov,multi,multi")
(set_attr "mode" "XF,XF,XF,SI,SI")])
(define_split (define_split
[(set (match_operand:DF 0 "push_operand" "") [(set (match_operand:XF 0 "nonimmediate_operand" "")
(match_operand:DF 1 "general_operand" ""))] (match_operand:XF 1 "general_operand" ""))]
"reload_completed" "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)] [(const_int 0)]
"ix86_split_long_move (operands); DONE;") "ix86_split_long_move (operands); DONE;")
;; Moving is usually shorter when only FP registers are used. This separate (define_insn "*movdf_internal_rex64"
;; movdf pattern avoids the use of integer registers for FP operations
;; when optimizing for size.
(define_insn "*movdf_nointeger"
[(set (match_operand:DF 0 "nonimmediate_operand" [(set (match_operand:DF 0 "nonimmediate_operand"
"=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ") "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
(match_operand:DF 1 "general_operand" (match_operand:DF 1 "general_operand"
"fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))] "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1])) "TARGET_64BIT && !(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 && (reload_in_progress || reload_completed
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| (!(TARGET_SSE2 && TARGET_SSE_MATH) || (!(TARGET_SSE2 && TARGET_SSE_MATH)
&& optimize_function_for_size_p (cfun) && optimize_function_for_size_p (cfun)
&& !memory_operand (operands[0], DFmode)
&& standard_80387_constant_p (operands[1])) && standard_80387_constant_p (operands[1]))
|| GET_CODE (operands[1]) != CONST_DOUBLE || GET_CODE (operands[1]) != CONST_DOUBLE
|| ((optimize_function_for_size_p (cfun) || memory_operand (operands[0], DFmode))"
|| !TARGET_MEMORY_MISMATCH_STALL
|| reload_in_progress || reload_completed)
&& memory_operand (operands[0], DFmode)))"
{ {
switch (which_alternative) switch (which_alternative)
{ {
...@@ -2858,6 +2933,7 @@ ...@@ -2858,6 +2933,7 @@
case 3: case 3:
case 4: case 4:
return "#"; return "#";
case 5: case 5:
switch (get_attr_mode (insn)) switch (get_attr_mode (insn))
{ {
...@@ -2906,34 +2982,22 @@ ...@@ -2906,34 +2982,22 @@
else else
return "movsd\t{%1, %0|%0, %1}"; return "movsd\t{%1, %0|%0, %1}";
case MODE_V1DF: case MODE_V1DF:
if (TARGET_AVX) return "%vmovlpd\t{%1, %d0|%d0, %1}";
{
if (REG_P (operands[0]))
return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
else
return "vmovlpd\t{%1, %0|%0, %1}";
}
else
return "movlpd\t{%1, %0|%0, %1}";
case MODE_V2SF: case MODE_V2SF:
if (TARGET_AVX) return "%vmovlps\t{%1, %d0|%d0, %1}";
{
if (REG_P (operands[0]))
return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
else
return "vmovlps\t{%1, %0|%0, %1}";
}
else
return "movlps\t{%1, %0|%0, %1}";
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
case 9:
case 10:
return "%vmovd\t{%1, %0|%0, %1}";
default: default:
gcc_unreachable (); gcc_unreachable();
} }
} }
[(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov") [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
(set (attr "prefix") (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")
(const_string "orig") (const_string "orig")
...@@ -2945,8 +3009,8 @@ ...@@ -2945,8 +3009,8 @@
(set (attr "mode") (set (attr "mode")
(cond [(eq_attr "alternative" "0,1,2") (cond [(eq_attr "alternative" "0,1,2")
(const_string "DF") (const_string "DF")
(eq_attr "alternative" "3,4") (eq_attr "alternative" "3,4,9,10")
(const_string "SI") (const_string "DI")
/* For SSE1, we have many fewer alternatives. */ /* For SSE1, we have many fewer alternatives. */
(eq (symbol_ref "TARGET_SSE2") (const_int 0)) (eq (symbol_ref "TARGET_SSE2") (const_int 0))
...@@ -2993,12 +3057,14 @@ ...@@ -2993,12 +3057,14 @@
] ]
(const_string "DF")))]) (const_string "DF")))])
(define_insn "*movdf_integer_rex64" (define_insn "*movdf_internal"
[(set (match_operand:DF 0 "nonimmediate_operand" [(set (match_operand:DF 0 "nonimmediate_operand"
"=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ") "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
(match_operand:DF 1 "general_operand" (match_operand:DF 1 "general_operand"
"fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))] "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
"TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) "!(MEM_P (operands[0]) && MEM_P (operands[1]))
&& optimize_function_for_speed_p (cfun)
&& TARGET_INTEGER_DFMODE_MOVES
&& (reload_in_progress || reload_completed && (reload_in_progress || reload_completed
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| (!(TARGET_SSE2 && TARGET_SSE_MATH) || (!(TARGET_SSE2 && TARGET_SSE_MATH)
...@@ -3024,17 +3090,17 @@ ...@@ -3024,17 +3090,17 @@
switch (get_attr_mode (insn)) switch (get_attr_mode (insn))
{ {
case MODE_V4SF: case MODE_V4SF:
return "%vxorps\t%0, %d0"; return "xorps\t%0, %0";
case MODE_V2DF: case MODE_V2DF:
if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
return "%vxorps\t%0, %d0"; return "xorps\t%0, %0";
else else
return "%vxorpd\t%0, %d0"; return "xorpd\t%0, %0";
case MODE_TI: case MODE_TI:
if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
return "%vxorps\t%0, %d0"; return "xorps\t%0, %0";
else else
return "%vpxor\t%0, %d0"; return "pxor\t%0, %0";
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
...@@ -3044,50 +3110,34 @@ ...@@ -3044,50 +3110,34 @@
switch (get_attr_mode (insn)) switch (get_attr_mode (insn))
{ {
case MODE_V4SF: case MODE_V4SF:
return "%vmovaps\t{%1, %0|%0, %1}"; return "movaps\t{%1, %0|%0, %1}";
case MODE_V2DF: case MODE_V2DF:
if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
return "%vmovaps\t{%1, %0|%0, %1}"; return "movaps\t{%1, %0|%0, %1}";
else else
return "%vmovapd\t{%1, %0|%0, %1}"; return "movapd\t{%1, %0|%0, %1}";
case MODE_TI: case MODE_TI:
if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
return "%vmovaps\t{%1, %0|%0, %1}"; return "movaps\t{%1, %0|%0, %1}";
else else
return "%vmovdqa\t{%1, %0|%0, %1}"; return "movdqa\t{%1, %0|%0, %1}";
case MODE_DI: case MODE_DI:
return "%vmovq\t{%1, %0|%0, %1}"; return "movq\t{%1, %0|%0, %1}";
case MODE_DF: case MODE_DF:
if (TARGET_AVX) return "movsd\t{%1, %0|%0, %1}";
{
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}";
}
else
return "movsd\t{%1, %0|%0, %1}";
case MODE_V1DF: case MODE_V1DF:
return "%vmovlpd\t{%1, %d0|%d0, %1}"; return "movlpd\t{%1, %0|%0, %1}";
case MODE_V2SF: case MODE_V2SF:
return "%vmovlps\t{%1, %d0|%d0, %1}"; return "movlps\t{%1, %0|%0, %1}";
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
case 9:
case 10:
return "%vmovd\t{%1, %0|%0, %1}";
default: default:
gcc_unreachable(); gcc_unreachable();
} }
} }
[(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov") [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
(set (attr "prefix")
(if_then_else (eq_attr "alternative" "0,1,2,3,4")
(const_string "orig")
(const_string "maybe_vex")))
(set (attr "prefix_data16") (set (attr "prefix_data16")
(if_then_else (eq_attr "mode" "V1DF") (if_then_else (eq_attr "mode" "V1DF")
(const_string "1") (const_string "1")
...@@ -3095,8 +3145,8 @@ ...@@ -3095,8 +3145,8 @@
(set (attr "mode") (set (attr "mode")
(cond [(eq_attr "alternative" "0,1,2") (cond [(eq_attr "alternative" "0,1,2")
(const_string "DF") (const_string "DF")
(eq_attr "alternative" "3,4,9,10") (eq_attr "alternative" "3,4")
(const_string "DI") (const_string "SI")
/* For SSE1, we have many fewer alternatives. */ /* For SSE1, we have many fewer alternatives. */
(eq (symbol_ref "TARGET_SSE2") (const_int 0)) (eq (symbol_ref "TARGET_SSE2") (const_int 0))
...@@ -3143,21 +3193,29 @@ ...@@ -3143,21 +3193,29 @@
] ]
(const_string "DF")))]) (const_string "DF")))])
(define_insn "*movdf_integer" ;; 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" [(set (match_operand:DF 0 "nonimmediate_operand"
"=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ") "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
(match_operand:DF 1 "general_operand" (match_operand:DF 1 "general_operand"
"fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))] "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1])) "!(MEM_P (operands[0]) && MEM_P (operands[1]))
&& optimize_function_for_speed_p (cfun) && ((optimize_function_for_size_p (cfun)
&& TARGET_INTEGER_DFMODE_MOVES || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
&& (reload_in_progress || reload_completed && (reload_in_progress || reload_completed
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| (!(TARGET_SSE2 && TARGET_SSE_MATH) || (!(TARGET_SSE2 && TARGET_SSE_MATH)
&& optimize_function_for_size_p (cfun) && optimize_function_for_size_p (cfun)
&& !memory_operand (operands[0], DFmode)
&& standard_80387_constant_p (operands[1])) && standard_80387_constant_p (operands[1]))
|| GET_CODE (operands[1]) != CONST_DOUBLE || GET_CODE (operands[1]) != CONST_DOUBLE
|| memory_operand (operands[0], DFmode))" || ((optimize_function_for_size_p (cfun)
|| !TARGET_MEMORY_MISMATCH_STALL
|| reload_in_progress || reload_completed)
&& memory_operand (operands[0], DFmode)))"
{ {
switch (which_alternative) switch (which_alternative)
{ {
...@@ -3171,22 +3229,21 @@ ...@@ -3171,22 +3229,21 @@
case 3: case 3:
case 4: case 4:
return "#"; return "#";
case 5: case 5:
switch (get_attr_mode (insn)) switch (get_attr_mode (insn))
{ {
case MODE_V4SF: case MODE_V4SF:
return "xorps\t%0, %0"; return "%vxorps\t%0, %d0";
case MODE_V2DF: case MODE_V2DF:
if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
return "xorps\t%0, %0"; return "%vxorps\t%0, %d0";
else else
return "xorpd\t%0, %0"; return "%vxorpd\t%0, %d0";
case MODE_TI: case MODE_TI:
if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
return "xorps\t%0, %0"; return "%vxorps\t%0, %d0";
else else
return "pxor\t%0, %0"; return "%vpxor\t%0, %d0";
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
...@@ -3196,34 +3253,62 @@ ...@@ -3196,34 +3253,62 @@
switch (get_attr_mode (insn)) switch (get_attr_mode (insn))
{ {
case MODE_V4SF: case MODE_V4SF:
return "movaps\t{%1, %0|%0, %1}"; return "%vmovaps\t{%1, %0|%0, %1}";
case MODE_V2DF: case MODE_V2DF:
if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
return "movaps\t{%1, %0|%0, %1}"; return "%vmovaps\t{%1, %0|%0, %1}";
else else
return "movapd\t{%1, %0|%0, %1}"; return "%vmovapd\t{%1, %0|%0, %1}";
case MODE_TI: case MODE_TI:
if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
return "movaps\t{%1, %0|%0, %1}"; return "%vmovaps\t{%1, %0|%0, %1}";
else else
return "movdqa\t{%1, %0|%0, %1}"; return "%vmovdqa\t{%1, %0|%0, %1}";
case MODE_DI: case MODE_DI:
return "movq\t{%1, %0|%0, %1}"; return "%vmovq\t{%1, %0|%0, %1}";
case MODE_DF: case MODE_DF:
return "movsd\t{%1, %0|%0, %1}"; 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}";
}
else
return "movsd\t{%1, %0|%0, %1}";
case MODE_V1DF: case MODE_V1DF:
return "movlpd\t{%1, %0|%0, %1}"; 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}";
}
else
return "movlpd\t{%1, %0|%0, %1}";
case MODE_V2SF: case MODE_V2SF:
return "movlps\t{%1, %0|%0, %1}"; 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}";
}
else
return "movlps\t{%1, %0|%0, %1}";
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
default: default:
gcc_unreachable(); gcc_unreachable ();
} }
} }
[(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov") [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
(set (attr "prefix")
(if_then_else (eq_attr "alternative" "0,1,2,3,4")
(const_string "orig")
(const_string "maybe_vex")))
(set (attr "prefix_data16") (set (attr "prefix_data16")
(if_then_else (eq_attr "mode" "V1DF") (if_then_else (eq_attr "mode" "V1DF")
(const_string "1") (const_string "1")
...@@ -3277,129 +3362,34 @@ ...@@ -3277,129 +3362,34 @@
(const_string "V1DF") (const_string "V1DF")
(const_string "DF")) (const_string "DF"))
] ]
(const_string "DF")))]) (const_string "DF")))])
(define_split
[(set (match_operand:DF 0 "nonimmediate_operand" "")
(match_operand:DF 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 "*swapdf"
[(set (match_operand:DF 0 "fp_register_operand" "+f")
(match_operand:DF 1 "fp_register_operand" "+f"))
(set (match_dup 1)
(match_dup 0))]
"reload_completed || TARGET_80387"
{
if (STACK_TOP_P (operands[0]))
return "fxch\t%1";
else
return "fxch\t%0";
}
[(set_attr "type" "fxch")
(set_attr "mode" "DF")])
(define_expand "movxf"
[(set (match_operand:XF 0 "nonimmediate_operand" "")
(match_operand:XF 1 "general_operand" ""))]
""
"ix86_expand_move (XFmode, operands); DONE;")
;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
;; Size of pushdf using integer instructions is 3+3*memory operand size
;; Pushing using integer instructions is longer except for constants
;; and direct memory references.
;; (assuming that any given constant is pushed only once, but this ought to be
;; handled elsewhere).
(define_insn "*pushxf_nointeger"
[(set (match_operand:XF 0 "push_operand" "=X,X,X")
(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
"optimize_function_for_size_p (cfun)"
{
/* This insn should be already split before reg-stack. */
gcc_unreachable ();
}
[(set_attr "type" "multi")
(set_attr "unit" "i387,*,*")
(set_attr "mode" "XF,SI,SI")])
(define_insn "*pushxf_integer"
[(set (match_operand:XF 0 "push_operand" "=<,<")
(match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
"optimize_function_for_speed_p (cfun)"
{
/* This insn should be already split before reg-stack. */
gcc_unreachable ();
}
[(set_attr "type" "multi")
(set_attr "unit" "i387,*")
(set_attr "mode" "XF,SI")])
(define_split (define_split
[(set (match_operand 0 "push_operand" "") [(set (match_operand:DF 0 "nonimmediate_operand" "")
(match_operand 1 "general_operand" ""))] (match_operand:DF 1 "general_operand" ""))]
"reload_completed "reload_completed
&& (GET_MODE (operands[0]) == XFmode && !(MEM_P (operands[0]) && MEM_P (operands[1]))
|| GET_MODE (operands[0]) == DFmode) && ! (ANY_FP_REG_P (operands[0]) ||
&& !ANY_FP_REG_P (operands[1])" (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)] [(const_int 0)]
"ix86_split_long_move (operands); DONE;") "ix86_split_long_move (operands); DONE;")
(define_split (define_insn "*movsf_internal"
[(set (match_operand:XF 0 "push_operand" "") [(set (match_operand:SF 0 "nonimmediate_operand"
(match_operand:XF 1 "any_fp_register_operand" ""))] "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
"" (match_operand:SF 1 "general_operand"
[(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
(set (mem:XF (reg:P SP_REG)) (match_dup 1))] "!(MEM_P (operands[0]) && MEM_P (operands[1]))
"operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
;; Do not use integer registers when optimizing for size
(define_insn "*movxf_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)
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))
&& (reload_in_progress || reload_completed
|| standard_80387_constant_p (operands[1])
|| 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_insn "*movxf_integer"
[(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 && (reload_in_progress || reload_completed
|| (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 || GET_CODE (operands[1]) != CONST_DOUBLE
|| memory_operand (operands[0], XFmode))" || memory_operand (operands[0], SFmode))"
{ {
switch (which_alternative) switch (which_alternative)
{ {
...@@ -3410,112 +3400,79 @@ ...@@ -3410,112 +3400,79 @@
case 2: case 2:
return standard_80387_constant_opcode (operands[1]); return standard_80387_constant_opcode (operands[1]);
case 3: case 4: case 3:
return "#"; case 4:
return "mov{l}\t{%1, %0|%0, %1}";
default: case 5:
gcc_unreachable (); if (get_attr_mode (insn) == MODE_TI)
} return "%vpxor\t%0, %d0";
} else
[(set_attr "type" "fmov,fmov,fmov,multi,multi") return "%vxorps\t%0, %d0";
(set_attr "mode" "XF,XF,XF,SI,SI")]) case 6:
(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_insn "*movtf_internal"
[(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
(match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
"TARGET_SSE2
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
switch (which_alternative)
{
case 0:
case 1:
if (get_attr_mode (insn) == MODE_V4SF) if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovaps\t{%1, %0|%0, %1}"; return "%vmovaps\t{%1, %0|%0, %1}";
else else
return "%vmovdqa\t{%1, %0|%0, %1}"; return "%vmovss\t{%1, %d0|%d0, %1}";
case 2: case 7:
if (get_attr_mode (insn) == MODE_V4SF) if (TARGET_AVX)
return "%vxorps\t%0, %d0"; return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
: "vmovss\t{%1, %0|%0, %1}";
else else
return "%vpxor\t%0, %d0"; return "movss\t{%1, %0|%0, %1}";
case 3: case 8:
case 4: return "%vmovss\t{%1, %0|%0, %1}";
return "#";
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}";
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
} }
[(set_attr "type" "ssemov,ssemov,sselog1,*,*") [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
(set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*") (set (attr "prefix")
(if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
(const_string "maybe_vex")
(const_string "orig")))
(set (attr "mode") (set (attr "mode")
(cond [(eq_attr "alternative" "0,2") (cond [(eq_attr "alternative" "3,4,9,10")
(const_string "SI")
(eq_attr "alternative" "5")
(if_then_else (if_then_else
(ne (symbol_ref "optimize_function_for_size_p (cfun)") (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
(const_int 0)) (const_int 0))
(const_string "V4SF") (ne (symbol_ref "TARGET_SSE2")
(const_string "TI")) (const_int 0)))
(eq_attr "alternative" "1") (eq (symbol_ref "optimize_function_for_size_p (cfun)")
(const_int 0)))
(const_string "TI")
(const_string "V4SF"))
/* For architectures resolving dependencies on
whole SSE registers use APS move to break dependency
chains, otherwise use short move to avoid extra work.
Do the same for architectures resolving dependencies on
the parts. While in DF mode it is better to always handle
just register parts, the SF mode is different due to lack
of instructions to load just part of the register. It is
better to maintain the whole registers in single format
to avoid problems on using packed logical operations. */
(eq_attr "alternative" "6")
(if_then_else (if_then_else
(ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
(const_int 0)) (const_int 0))
(ne (symbol_ref "optimize_function_for_size_p (cfun)") (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
(const_int 0))) (const_int 0)))
(const_string "V4SF") (const_string "V4SF")
(const_string "TI"))] (const_string "SF"))
(const_string "DI")))]) (eq_attr "alternative" "11")
(const_string "DI")]
(define_insn "*pushtf_sse" (const_string "SF")))])
[(set (match_operand:TF 0 "push_operand" "=<,<,<")
(match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
"TARGET_SSE2"
{
/* This insn should be already split before reg-stack. */
gcc_unreachable ();
}
[(set_attr "type" "multi")
(set_attr "unit" "sse,*,*")
(set_attr "mode" "TF,SI,SI")])
(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_split
[(set (match_operand 0 "nonimmediate_operand" "")
(match_operand 1 "general_operand" ""))]
"reload_completed
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))
&& GET_MODE (operands[0]) == XFmode
&& ! (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_split (define_split
[(set (match_operand 0 "register_operand" "") [(set (match_operand 0 "register_operand" "")
...@@ -3524,8 +3481,8 @@ ...@@ -3524,8 +3481,8 @@
&& MEM_P (operands[1]) && MEM_P (operands[1])
&& (GET_MODE (operands[0]) == TFmode && (GET_MODE (operands[0]) == TFmode
|| GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == XFmode
|| GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode
|| GET_MODE (operands[0]) == DFmode) || GET_MODE (operands[0]) == SFmode)
&& (operands[2] = find_constant_src (insn))" && (operands[2] = find_constant_src (insn))"
[(set (match_dup 0) (match_dup 2))] [(set (match_dup 0) (match_dup 2))]
{ {
...@@ -3556,8 +3513,8 @@ ...@@ -3556,8 +3513,8 @@
&& MEM_P (operands[1]) && MEM_P (operands[1])
&& (GET_MODE (operands[0]) == TFmode && (GET_MODE (operands[0]) == TFmode
|| GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == XFmode
|| GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode
|| GET_MODE (operands[0]) == DFmode) || GET_MODE (operands[0]) == SFmode)
&& (operands[2] = find_constant_src (insn))" && (operands[2] = find_constant_src (insn))"
[(set (match_dup 0) (match_dup 2))] [(set (match_dup 0) (match_dup 2))]
{ {
...@@ -3581,21 +3538,6 @@ ...@@ -3581,21 +3538,6 @@
FAIL; FAIL;
}) })
(define_insn "swapxf"
[(set (match_operand:XF 0 "register_operand" "+f")
(match_operand:XF 1 "register_operand" "+f"))
(set (match_dup 1)
(match_dup 0))]
"TARGET_80387"
{
if (STACK_TOP_P (operands[0]))
return "fxch\t%1";
else
return "fxch\t%0";
}
[(set_attr "type" "fxch")
(set_attr "mode" "XF")])
;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
(define_split (define_split
[(set (match_operand:X87MODEF 0 "register_operand" "") [(set (match_operand:X87MODEF 0 "register_operand" "")
...@@ -3616,13 +3558,35 @@ ...@@ -3616,13 +3558,35 @@
operands[1] = CONST1_RTX (<MODE>mode); operands[1] = CONST1_RTX (<MODE>mode);
}) })
(define_split (define_insn "swapxf"
[(set (match_operand:TF 0 "nonimmediate_operand" "") [(set (match_operand:XF 0 "register_operand" "+f")
(match_operand:TF 1 "general_operand" ""))] (match_operand:XF 1 "register_operand" "+f"))
"reload_completed (set (match_dup 1)
&& !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))" (match_dup 0))]
[(const_int 0)] "TARGET_80387"
"ix86_split_long_move (operands); DONE;") {
if (STACK_TOP_P (operands[0]))
return "fxch\t%1";
else
return "fxch\t%0";
}
[(set_attr "type" "fxch")
(set_attr "mode" "XF")])
(define_insn "*swap<mode>"
[(set (match_operand:MODEF 0 "fp_register_operand" "+f")
(match_operand:MODEF 1 "fp_register_operand" "+f"))
(set (match_dup 1)
(match_dup 0))]
"TARGET_80387 || reload_completed"
{
if (STACK_TOP_P (operands[0]))
return "fxch\t%1";
else
return "fxch\t%0";
}
[(set_attr "type" "fxch")
(set_attr "mode" "<MODE>")])
;; Zero extension instructions ;; Zero extension instructions
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment