Commit 8fcaaa80 by Jan Hubicka Committed by Jan Hubicka

i386.h (enum reg_class): Add FLOAT_INT_REGS.

	* i386.h (enum reg_class): Add FLOAT_INT_REGS.
	(REG_CLASS_NAMES): Likewise.
	(REG_CLASS_CONTENTS): Define FLOAT_INT_REGS as union of FLOAT_REGS
	and GENERAL_REGS.
	* i386.md (pushsf): Do not preferre FLOAT_REGS over GENERAL_REGS.
	(movsf): Likewise; unify 4th and 5th alternative.
	(pushdf): Likewise.
	(movdf_1): Likewise; rename to movdf_integer.
	(pushxf): Likewise; rename to pushxf_integer; fix output template;
	remove redundant splitter.
	(movxf_1): Likewise; rename to movxf_integer; fix splitter's condition.
	(movdf_nointeger): New.
	(movxf_nointeger): New.
	(pushxf_nointeger): New.

From-SVN: r30594
parent f97d9ec3
Fri Nov 19 06:32:19 CET 1999 Jan Hubicka <hubicka@freesoft.cz>
* i386.h (enum reg_class): Add FLOAT_INT_REGS.
(REG_CLASS_NAMES): Likewise.
(REG_CLASS_CONTENTS): Define FLOAT_INT_REGS as union of FLOAT_REGS
and GENERAL_REGS.
* i386.md (pushsf): Do not preferre FLOAT_REGS over GENERAL_REGS.
(movsf): Likewise; unify 4th and 5th alternative.
(pushdf): Likewise.
(movdf_1): Likewise; rename to movdf_integer.
(pushxf): Likewise; rename to pushxf_integer; fix output template;
remove redundant splitter.
(movxf_1): Likewise; rename to movxf_integer; fix splitter's condition.
(movdf_nointeger): New.
(movxf_nointeger): New.
(pushxf_nointeger): New.
* i386.md (extend?f?f): Split to expander and pattern, refuse two
memory operands in patterns.
(fop*): Refuse two memory operands.
......
......@@ -835,6 +835,7 @@ enum reg_class
GENERAL_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp %esp */
FP_TOP_REG, FP_SECOND_REG, /* %st(0) %st(1) */
FLOAT_REGS,
FLOAT_INT_REGS, /* FLOAT_REGS and GENERAL_REGS. */
ALL_REGS, LIM_REG_CLASSES
};
......@@ -854,6 +855,7 @@ enum reg_class
"GENERAL_REGS", \
"FP_TOP_REG", "FP_SECOND_REG", \
"FLOAT_REGS", \
"FLOAT_INT_REGS", \
"ALL_REGS" }
/* Define which registers fit in which classes.
......@@ -871,6 +873,7 @@ enum reg_class
{0x100ff}, /* GENERAL_REGS */ \
{0x0100}, {0x0200}, /* FP_TOP_REG, FP_SECOND_REG */ \
{0xff00}, /* FLOAT_REGS */ \
{0x1ffff}, /* FLOAT_INT_REGS */ \
{0x7ffff} \
}
......
......@@ -1697,7 +1697,7 @@
(define_insn "*pushsf"
[(set (match_operand:SF 0 "push_operand" "=<,<")
(match_operand:SF 1 "general_operand" "f,Ffm*r"))]
(match_operand:SF 1 "general_operand" "f#r,rFm#f"))]
""
"*
{
......@@ -1731,9 +1731,9 @@
(set (mem:SF (reg:SI 7)) (match_dup 1))])
(define_insn "*movsf_1"
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,f,*r,m,*r")
(match_operand:SF 1 "general_operand" "fm,f,G,*rm,F*r,GF"))]
""
[(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,m")
(match_operand:SF 1 "general_operand" "fm#r,f#r,G,rmF#f,Fr#f"))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
"*
{
switch (which_alternative)
......@@ -1765,14 +1765,13 @@
case 3:
case 4:
case 5:
return \"mov{l}\\t{%1, %0|%0, %1}\";
default:
abort();
}
}"
[(set_attr "type" "fmov,fmov,fmov,imov,imov,imov")])
[(set_attr "type" "fmov,fmov,fmov,imov,imov")])
(define_insn "swapsf"
[(set (match_operand:SF 0 "register_operand" "+f")
......@@ -1795,9 +1794,14 @@
""
"ix86_expand_move (DFmode, operands); DONE;")
;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
;; Size of pushdf using integer insturctions 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"
[(set (match_operand:DF 0 "push_operand" "=<,<")
(match_operand:DF 1 "general_operand" "f,ofF*r"))]
(match_operand:DF 1 "general_operand" "f#r,rFo#f"))]
""
"*
{
......@@ -1838,10 +1842,59 @@
[(const_int 0)]
"if (!ix86_split_long_move (operands)) abort (); DONE;")
(define_insn "*movdf_1"
;; 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_nointeger"
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,*r,o")
(match_operand:DF 1 "general_operand" "fm,f,G,*roF,F*r"))]
""
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& optimize_size"
"*
{
switch (which_alternative)
{
case 0:
if (REG_P (operands[1])
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
return \"fstp\\t%y0\";
else if (STACK_TOP_P (operands[0]))
return \"fld%z1\\t%y1\";
else
return \"fst\\t%y0\";
case 1:
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
return \"fstp%z0\\t%y0\";
else
return \"fst%z0\\t%y0\";
case 2:
switch (standard_80387_constant_p (operands[1]))
{
case 1:
return \"fldz\";
case 2:
return \"fld1\";
}
abort();
case 3:
case 4:
return \"#\";
default:
abort();
}
}"
[(set_attr "type" "fmov,fmov,fmov,multi,multi")])
(define_insn "*movdf_integer"
[(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
(match_operand:DF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& !optimize_size"
"*
{
switch (which_alternative)
......@@ -1917,20 +1970,65 @@
""
"ix86_expand_move (XFmode, operands); DONE;")
(define_insn "*pushxf"
;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
;; Size of pushdf using integer insturctions 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" "=<,<,<")
(match_operand:XF 1 "general_operand" "f,Fo,*r"))]
"optimize_size"
"*
{
switch (which_alternative)
{
case 0:
/* %%% We loose REG_DEAD notes for controling pops if we split late. */
operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
operands[2] = stack_pointer_rtx;
operands[3] = GEN_INT (12);
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
else
return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
case 1:
case 2:
return \"#\";
default:
abort ();
}
}"
[(set_attr "type" "multi")])
(define_insn "*pushxf_integer"
[(set (match_operand:XF 0 "push_operand" "=<,<")
(match_operand:XF 1 "register_operand" "f,oF*r"))]
""
(match_operand:XF 1 "general_operand" "f#r,rFo#f"))]
"!optimize_size"
"*
{
/* %%% We loose REG_DEAD notes for controling pops if we split late. */
operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
operands[2] = stack_pointer_rtx;
operands[3] = GEN_INT (12);
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
else
return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
switch (which_alternative)
{
case 0:
/* %%% We loose REG_DEAD notes for controling pops if we split late. */
operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
operands[2] = stack_pointer_rtx;
operands[3] = GEN_INT (12);
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
else
return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
case 1:
return \"#\";
default:
abort ();
}
}"
[(set_attr "type" "multi")])
......@@ -1949,30 +2047,55 @@
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
(set (mem:XF (reg:SI 7)) (match_dup 1))])
(define_split
[(set (match_operand:DF 0 "push_operand" "")
(match_operand:DF 1 "memory_operand" ""))]
"reload_completed"
[(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 2))
(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))]
"
;; 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"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& optimize_size"
"*
{
operands[0] = change_address (operands[1], SImode, NULL_RTX);
operands[1] = adj_offsettable_operand (operands[0], 4);
operands[2] = adj_offsettable_operand (operands[0], 8);
/* Compensate for the fact that we're changing stack offsets in
the middle of this operation. */
if (reg_mentioned_p (stack_pointer_rtx, operands[1]))
operands[1] = adj_offsettable_operand (operands[1], 4);
if (reg_mentioned_p (stack_pointer_rtx, operands[0]))
operands[0] = adj_offsettable_operand (operands[0], 8);
}")
switch (which_alternative)
{
case 0:
if (REG_P (operands[1])
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
return \"fstp\\t%y0\";
else if (STACK_TOP_P (operands[0]))
return \"fld%z1\\t%y1\";
else
return \"fst\\t%y0\";
(define_insn "*movxf_1"
[(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
(match_operand:XF 1 "general_operand" "fm,f,G,*roF,*r"))]
""
case 1:
/* There is no non-popping store to memory for XFmode. So if
we need one, follow the store with a load. */
if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
else
return \"fstp%z0\\t%y0\";
case 2:
switch (standard_80387_constant_p (operands[1]))
{
case 1:
return \"fldz\";
case 2:
return \"fld1\";
}
break;
case 3: case 4:
return \"#\";
}
abort();
}"
[(set_attr "type" "fmov,fmov,fmov,multi,multi")])
(define_insn "*movxf_integer"
[(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& !optimize_size"
"*
{
switch (which_alternative)
......@@ -2009,14 +2132,19 @@
}
abort();
}"
[(set_attr "type" "fmov")])
[(set_attr "type" "fmov,fmov,fmov,multi,multi")])
(define_split
[(set (match_operand:XF 0 "nonimmediate_operand" "")
(match_operand:XF 1 "general_operand" ""))]
"reload_completed
&& ((REG_P (operands[0]) && ! FP_REGNO_P (REGNO (operands[0])))
|| (REG_P (operands[1]) && ! FP_REGNO_P (REGNO (operands[1]))))"
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& ! (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]))))"
[(set (match_dup 2) (match_dup 5))
(set (match_dup 3) (match_dup 6))
(set (match_dup 4) (match_dup 7))]
......
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