OSDN Git Service

* i386.md (pophi1, popqi1, pushqi1): Remove.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Mar 2001 09:41:11 +0000 (09:41 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Mar 2001 09:41:11 +0000 (09:41 +0000)
* expr.c (emit_single_push_insn): New function.
(move_by_pieces): Accept NULL as destination for push instructions.
(gen_push_operand): Kill.
(emit_push_insn): Pass NULL when pushing; avoid updating of
stack_pointer_delta.
* expr.h (gen_push_operand): Kill.

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

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/expr.c
gcc/expr.h

index 3bfd0a6..f2b8704 100644 (file)
@@ -1,3 +1,14 @@
+Wed Mar 21 10:25:13 CET 2001  Jan Hubicka  <jh@use.cz>
+
+       * i386.md (pophi1, popqi1, pushqi1): Remove.
+
+       * expr.c (emit_single_push_insn): New function.
+       (move_by_pieces): Accept NULL as destination for push instructions.
+       (gen_push_operand): Kill.
+       (emit_push_insn): Pass NULL when pushing; avoid updating of
+       stack_pointer_delta.
+       * expr.h (gen_push_operand): Kill.
+
 Tue Mar 20 20:15:06 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * rtl.texi (COMPARE): Clarify documentation and reference section
index c431e85..6eae78c 100644 (file)
   [(set_attr "type" "push")
    (set_attr "mode" "HI")])
 
-(define_insn "*pophi1"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=r*m")
-       (mem:HI (reg:SI 7)))
-   (set (reg:SI 7)
-       (plus:SI (reg:SI 7) (const_int 2)))]
-  "!TARGET_64BIT"
-  "pop{w}\\t%0"
-  [(set_attr "type" "pop")
-   (set_attr "mode" "HI")])
-
 (define_insn "*movhi_1"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
        (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
   ""
   "ix86_expand_move (QImode, operands); DONE;")
 
-;; emit_push_insn when it calls move_by_pieces requires an insn to
-;; "push a byte".  But actually we use pushw, which has the effect
-;; of rounding the amount pushed up to a halfword.
-
-(define_insn "*pushqi2"
-  [(set (match_operand:QI 0 "push_operand" "=<,<")
-       (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
-  "!TARGET_64BIT"
-  "@
-   push{w}\\t{|word ptr }%1
-   push{w}\\t%w1"
-  [(set_attr "type" "push")
-   (set_attr "mode" "HI")])
-
-(define_insn "*popqi1"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=r*m")
-       (mem:QI (reg:SI 7)))
-   (set (reg:SI 7)
-       (plus:SI (reg:SI 7) (const_int 2)))]
-  "!TARGET_64BIT"
-  "pop{w}\\t%0"
-  [(set_attr "type" "pop")
-   (set_attr "mode" "HI")])
-
 ;; Situation is quite tricky about when to choose full sized (SImode) move
 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
 ;; partial register dependency machines (such as AMD Athlon), where QImode
index d193242..f2523a4 100644 (file)
@@ -174,6 +174,7 @@ static void do_jump_by_parts_equality PARAMS ((tree, rtx, rtx));
 static void do_compare_and_jump        PARAMS ((tree, enum rtx_code, enum rtx_code,
                                         rtx, rtx));
 static rtx do_store_flag       PARAMS ((tree, rtx, enum machine_mode, int));
+static void emit_single_push_insn PARAMS ((enum machine_mode, rtx, tree));
 
 /* Record for each mode whether we can move a register directly to or
    from an object of that mode in memory.  If we can't, we won't try
@@ -1387,6 +1388,10 @@ convert_modes (mode, oldmode, x, unsignedp)
    from block FROM to block TO.  (These are MEM rtx's with BLKmode).
    The caller must pass FROM and TO
     through protect_from_queue before calling.
+
+   When TO is NULL, the emit_single_push_insn is used to push the
+   FROM to stack.
+
    ALIGN is maximum alignment we can assume.  */
 
 void
@@ -1396,19 +1401,36 @@ move_by_pieces (to, from, len, align)
      unsigned int align;
 {
   struct move_by_pieces data;
-  rtx to_addr = XEXP (to, 0), from_addr = XEXP (from, 0);
+  rtx to_addr, from_addr = XEXP (from, 0);
   unsigned int max_size = MOVE_MAX_PIECES + 1;
   enum machine_mode mode = VOIDmode, tmode;
   enum insn_code icode;
 
   data.offset = 0;
-  data.to_addr = to_addr;
   data.from_addr = from_addr;
-  data.to = to;
+  if (to)
+    {
+      to_addr = XEXP (to, 0);
+      data.to = to;
+      data.autinc_to
+       = (GET_CODE (to_addr) == PRE_INC || GET_CODE (to_addr) == PRE_DEC
+          || GET_CODE (to_addr) == POST_INC || GET_CODE (to_addr) == POST_DEC);
+      data.reverse
+       = (GET_CODE (to_addr) == PRE_DEC || GET_CODE (to_addr) == POST_DEC);
+    }
+  else
+    {
+      to_addr = NULL_RTX;
+      data.to = NULL_RTX;
+      data.autinc_to = 1;
+#ifdef STACK_GROWS_DOWNWARD
+      data.reverse = 1;
+#else
+      data.reverse = 0;
+#endif
+    }
+  data.to_addr = to_addr;
   data.from = from;
-  data.autinc_to
-    = (GET_CODE (to_addr) == PRE_INC || GET_CODE (to_addr) == PRE_DEC
-       || GET_CODE (to_addr) == POST_INC || GET_CODE (to_addr) == POST_DEC);
   data.autinc_from
     = (GET_CODE (from_addr) == PRE_INC || GET_CODE (from_addr) == PRE_DEC
        || GET_CODE (from_addr) == POST_INC
@@ -1416,8 +1438,6 @@ move_by_pieces (to, from, len, align)
 
   data.explicit_inc_from = 0;
   data.explicit_inc_to = 0;
-  data.reverse
-    = (GET_CODE (to_addr) == PRE_DEC || GET_CODE (to_addr) == POST_DEC);
   if (data.reverse) data.offset = len;
   data.len = len;
 
@@ -1550,14 +1570,17 @@ move_by_pieces_1 (genfun, mode, data)
       if (data->reverse)
        data->offset -= size;
 
-      if (data->autinc_to)
+      if (data->to)
        {
-         to1 = gen_rtx_MEM (mode, data->to_addr);
-         MEM_COPY_ATTRIBUTES (to1, data->to);
+         if (data->autinc_to)
+           {
+             to1 = gen_rtx_MEM (mode, data->to_addr);
+             MEM_COPY_ATTRIBUTES (to1, data->to);
+           }
+         else
+           to1 = change_address (data->to, mode,
+                                 plus_constant (data->to_addr, data->offset));
        }
-      else
-       to1 = change_address (data->to, mode,
-                             plus_constant (data->to_addr, data->offset));
 
       if (data->autinc_from)
        {
@@ -1573,7 +1596,10 @@ move_by_pieces_1 (genfun, mode, data)
       if (HAVE_PRE_DECREMENT && data->explicit_inc_from < 0)
        emit_insn (gen_add2_insn (data->from_addr, GEN_INT (-size)));
 
-      emit_insn ((*genfun) (to1, from1));
+      if (data->to)
+       emit_insn ((*genfun) (to1, from1));
+      else
+       emit_single_push_insn (mode, from1, NULL);
 
       if (HAVE_POST_INCREMENT && data->explicit_inc_to > 0)
        emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
@@ -3078,11 +3104,6 @@ push_block (size, extra, below)
   return memory_address (GET_CLASS_NARROWEST_MODE (MODE_INT), temp);
 }
 
-rtx
-gen_push_operand ()
-{
-  return gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
-}
 
 /* Return an rtx for the address of the beginning of a as-if-it-was-pushed
    block of SIZE bytes.  */
@@ -3103,6 +3124,51 @@ get_push_address (size)
   return copy_to_reg (temp);
 }
 
+/* Emit single push insn.  */
+static void
+emit_single_push_insn (mode, x, type)
+     rtx x;
+     enum machine_mode mode;
+     tree type;
+{
+#ifdef PUSH_ROUNDING
+  rtx dest_addr;
+  int rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
+  rtx dest;
+
+  if (GET_MODE_SIZE (mode) == rounded_size)
+    dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
+  else
+    {
+#ifdef STACK_GROWS_DOWNWARD
+      dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+                               GEN_INT (-rounded_size));
+#else
+      dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+                               GEN_INT (rounded_size));
+#endif
+      dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);
+    }
+
+  dest = gen_rtx_MEM (mode, dest_addr);
+
+  stack_pointer_delta += PUSH_ROUNDING (GET_MODE_SIZE (mode));
+
+  if (type != 0)
+    {
+      set_mem_attributes (dest, type, 1);
+      /* Function incoming arguments may overlap with sibling call
+         outgoing arguments and we cannot allow reordering of reads
+         from function arguments with stores to outgoing arguments
+         of sibling calls.  */
+      MEM_ALIAS_SET (dest) = 0;
+    }
+  emit_move_insn (dest, x);
+#else
+  abort();
+#endif
+}
+
 /* Generate code to push X onto the stack, assuming it has mode MODE and
    type TYPE.
    MODE is redundant except when X is a CONST_INT (since they don't
@@ -3223,9 +3289,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
              && where_pad != none && where_pad != stack_direction)
            anti_adjust_stack (GEN_INT (extra));
 
-         stack_pointer_delta += INTVAL (size) - used;
-         move_by_pieces (gen_rtx_MEM (BLKmode, gen_push_operand ()), xinner,
-                         INTVAL (size) - used, align);
+         move_by_pieces (NULL, xinner, INTVAL (size) - used, align);
 
          if (current_function_check_memory_usage && ! in_check_memory_usage)
            {
@@ -3477,10 +3541,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
 
 #ifdef PUSH_ROUNDING
       if (args_addr == 0 && PUSH_ARGS)
-       {
-         addr = gen_push_operand ();
-         stack_pointer_delta += PUSH_ROUNDING (GET_MODE_SIZE (mode));
-       }
+       emit_single_push_insn (mode, x, type);
       else
 #endif
        {
@@ -3493,20 +3554,20 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
            addr = memory_address (mode, gen_rtx_PLUS (Pmode, args_addr,
                                                       args_so_far));
          target = addr;
-       }
+         dest = gen_rtx_MEM (mode, addr);
+         if (type != 0)
+           {
+             set_mem_attributes (dest, type, 1);
+             /* Function incoming arguments may overlap with sibling call
+                outgoing arguments and we cannot allow reordering of reads
+                from function arguments with stores to outgoing arguments
+                of sibling calls.  */
+             MEM_ALIAS_SET (dest) = 0;
+           }
 
-      dest = gen_rtx_MEM (mode, addr);
-      if (type != 0)
-       {
-         set_mem_attributes (dest, type, 1);
-         /* Function incoming arguments may overlap with sibling call
-            outgoing arguments and we cannot allow reordering of reads
-            from function arguments with stores to outgoing arguments
-            of sibling calls.  */
-         MEM_ALIAS_SET (dest) = 0;
-       }
+         emit_move_insn (dest, x);
 
-      emit_move_insn (dest, x);
+       }
 
       if (current_function_check_memory_usage && ! in_check_memory_usage)
        {
index eea9b97..abfc38d 100644 (file)
@@ -1040,9 +1040,6 @@ extern rtx emit_move_insn_1 PARAMS ((rtx, rtx));
    and return an rtx to address the beginning of the block.  */
 extern rtx push_block PARAMS ((rtx, int, int));
 
-/* Make an operand to push something on the stack.  */
-extern rtx gen_push_operand PARAMS ((void));
-
 #ifdef TREE_CODE
 /* Generate code to push something onto the stack, given its mode and type.  */
 extern void emit_push_insn PARAMS ((rtx, enum machine_mode, tree, rtx,