Commit 2c5a510c by Richard Henderson Committed by Richard Henderson

i386.c (general_no_elim_operand): New.

        * i386.c (general_no_elim_operand): New.
        (nonmemory_no_elim_operand): New.
        (ix86_expand_move): Copy eliminable operands before a push.
        * i386-protos.h: Declare new functions.
        * i386.h (CAN_ELIMINATE): Simplify.
        (PREDICATE_CODES): Update.
        * i386.md (push insns): Don't allow eliminable register operands.

From-SVN: r31755
parent ea2d416a
2000-02-01 Richard Henderson <rth@cygnus.com>
* i386.c (general_no_elim_operand): New.
(nonmemory_no_elim_operand): New.
(ix86_expand_move): Copy eliminable operands before a push.
* i386-protos.h: Declare new functions.
* i386.h (CAN_ELIMINATE): Simplify.
(PREDICATE_CODES): Update.
* i386.md (push insns): Don't allow eliminable register operands.
2000-02-01 Richard Henderson <rth@cygnus.com>
* flow.c (mark_regs_live_at_end): Follow expand_function_end and
replace BLKmode with DECL_RTL's mode.
......
......@@ -50,6 +50,8 @@ extern int const1_operand PARAMS ((rtx, enum machine_mode));
extern int const248_operand PARAMS ((rtx, enum machine_mode));
extern int incdec_operand PARAMS ((rtx, enum machine_mode));
extern int reg_no_sp_operand PARAMS ((rtx, enum machine_mode));
extern int general_no_elim_operand PARAMS ((rtx, enum machine_mode));
extern int nonmemory_no_elim_operand PARAMS ((rtx, enum machine_mode));
extern int q_regs_operand PARAMS ((rtx, enum machine_mode));
extern int non_q_regs_operand PARAMS ((rtx, enum machine_mode));
extern int no_comparison_operator PARAMS ((rtx, enum machine_mode));
......
......@@ -1168,6 +1168,44 @@ reg_no_sp_operand (op, mode)
return register_operand (op, mode);
}
/* Return false if this is any eliminable register. Otherwise
general_operand. */
int
general_no_elim_operand (op, mode)
register rtx op;
enum machine_mode mode;
{
rtx t = op;
if (GET_CODE (t) == SUBREG)
t = SUBREG_REG (t);
if (t == arg_pointer_rtx || t == frame_pointer_rtx
|| t == virtual_incoming_args_rtx || t == virtual_stack_vars_rtx
|| t == virtual_stack_dynamic_rtx)
return 0;
return general_operand (op, mode);
}
/* Return false if this is any eliminable register. Otherwise
register_operand or const_int. */
int
nonmemory_no_elim_operand (op, mode)
register rtx op;
enum machine_mode mode;
{
rtx t = op;
if (GET_CODE (t) == SUBREG)
t = SUBREG_REG (t);
if (t == arg_pointer_rtx || t == frame_pointer_rtx
|| t == virtual_incoming_args_rtx || t == virtual_stack_vars_rtx
|| t == virtual_stack_dynamic_rtx)
return 0;
return GET_CODE (op) == CONST_INT || register_operand (op, mode);
}
/* Return true if op is a Q_REGS class register. */
int
......@@ -3987,6 +4025,10 @@ ix86_expand_move (mode, operands)
&& GET_CODE (operands[1]) == MEM)
operands[1] = force_reg (mode, operands[1]);
if (push_operand (operands[0], mode)
&& ! general_no_elim_operand (operands[1], mode))
operands[1] = copy_to_mode_reg (mode, operands[1]);
if (FLOAT_MODE_P (mode))
{
/* If we are loading a floating point constant to a register,
......
......@@ -1411,19 +1411,13 @@ pop{l} %0" \
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} \
/* Given FROM and TO register numbers, say whether this elimination is allowed.
Frame pointer elimination is automatically handled.
For the i386, if frame pointer elimination is being done, we would like to
convert ap into sp, not fp.
/* Given FROM and TO register numbers, say whether this elimination is
allowed. Frame pointer elimination is automatically handled.
All other eliminations are valid. */
#define CAN_ELIMINATE(FROM, TO) \
((((FROM) == ARG_POINTER_REGNUM || (FROM) == FRAME_POINTER_REGNUM) \
&& (TO) == STACK_POINTER_REGNUM) \
? ! frame_pointer_needed \
: 1)
#define CAN_ELIMINATE(FROM, TO) \
((TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1)
/* Define the offset between two registers, one to be eliminated, and the other
its replacement, at the start of a routine. */
......@@ -2436,6 +2430,9 @@ do { long l; \
{"const248_operand", {CONST_INT}}, \
{"incdec_operand", {CONST_INT}}, \
{"reg_no_sp_operand", {SUBREG, REG}}, \
{"general_no_elim_operand", {CONST_INT, CONST_DOUBLE, CONST, \
SYMBOL_REF, LABEL_REF, SUBREG, REG, MEM}}, \
{"nonmemory_no_elim_operand", {CONST_INT, REG, SUBREG}}, \
{"q_regs_operand", {SUBREG, REG}}, \
{"non_q_regs_operand", {SUBREG, REG}}, \
{"no_comparison_operator", {EQ, NE, LT, GE, LTU, GTU, LEU, GEU}}, \
......
......@@ -1281,7 +1281,7 @@
(define_insn "pushsi2"
[(set (match_operand:SI 0 "push_operand" "=<")
(match_operand:SI 1 "general_operand" "ri*m"))]
(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
""
"push{l}\\t%1"
[(set_attr "type" "push")])
......@@ -1361,7 +1361,7 @@
(define_insn "pushhi2"
[(set (match_operand:HI 0 "push_operand" "=<,<")
(match_operand:HI 1 "general_operand" "n,r*m"))]
(match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
""
"@
push{w}\\t{|WORD PTR }%1
......@@ -1479,7 +1479,7 @@
(define_insn "pushqi2"
[(set (match_operand:QI 0 "push_operand" "=<,<")
(match_operand:QI 1 "nonmemory_operand" "n,r"))]
(match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
""
"@
push{w}\\t{|word ptr }%1
......@@ -1693,7 +1693,7 @@
(define_insn "*pushdi"
[(set (match_operand:DI 0 "push_operand" "=<")
(match_operand:DI 1 "general_operand" "riF*m"))]
(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
""
"#")
......@@ -1727,7 +1727,7 @@
(define_insn "*pushsf"
[(set (match_operand:SF 0 "push_operand" "=<,<")
(match_operand:SF 1 "general_operand" "f#r,rFm#f"))]
(match_operand:SF 1 "general_no_elim_operand" "f#r,rFm#f"))]
""
"*
{
......@@ -1861,7 +1861,7 @@
(define_insn "*pushdf"
[(set (match_operand:DF 0 "push_operand" "=<,<")
(match_operand:DF 1 "general_operand" "f#r,rFo#f"))]
(match_operand:DF 1 "general_no_elim_operand" "f#r,rFo#f"))]
""
"*
{
......@@ -2057,7 +2057,7 @@
(define_insn "*pushxf_nointeger"
[(set (match_operand:XF 0 "push_operand" "=<,<,<")
(match_operand:XF 1 "general_operand" "f,Fo,*r"))]
(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
"optimize_size"
"*
{
......@@ -2085,7 +2085,7 @@
(define_insn "*pushxf_integer"
[(set (match_operand:XF 0 "push_operand" "=<,<")
(match_operand:XF 1 "general_operand" "f#r,rFo#f"))]
(match_operand:XF 1 "general_no_elim_operand" "f#r,rFo#f"))]
"!optimize_size"
"*
{
......
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