OSDN Git Service

* i386.c (general_no_elim_operand): New.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Feb 2000 07:50:21 +0000 (07:50 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Feb 2000 07:50:21 +0000 (07:50 +0000)
        (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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31755 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.md

index 480e69d..8af9597 100644 (file)
@@ -1,5 +1,15 @@
 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.
 
index 9d40768..21dc139 100644 (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));
index 2030daa..18fc2f3 100644 (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,
index 95532c9..1302b65 100644 (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}},    \
index fac96f5..ce2ac95 100644 (file)
 
 (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")])
 
 (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
 
 (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
 
 (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"))]
   ""
   "#")
 
 
 (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"))]
   ""
   "*
 {
 
 (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"))]
   ""
   "*
 {
 
 (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"
   "*
 {
 
 (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"
   "*
 {