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
This commit is contained in:
Richard Henderson 2000-02-01 23:50:21 -08:00 committed by Richard Henderson
parent ea2d416aac
commit 2c5a510cb8
5 changed files with 69 additions and 18 deletions

View File

@ -1,3 +1,13 @@
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

View File

@ -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));

View File

@ -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,

View File

@ -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}}, \

View File

@ -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"
"*
{