mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-05 13:20:12 +08:00
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:
parent
ea2d416aac
commit
2c5a510cb8
@ -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
|
||||
|
@ -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"
|
||||
"*
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user