OSDN Git Service

* config/m68k/coff.h (REGISTER_NAMES): Add fake register `argptr'
authorbernie <bernie@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Sep 2003 06:47:19 +0000 (06:47 +0000)
committerbernie <bernie@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Sep 2003 06:47:19 +0000 (06:47 +0000)
* config/m68k/hp320.h (REGISTER_NAMES): Likewise.
* config/m68k/linux.h (REGISTER_NAMES): Likewise.
* config/m68k/m68kelf.h (REGISTER_NAMES): Likewise.
* gcc/config/m68k/sgs.h (REGISTER_NAMES): Likewise.
* config/m68k/m68k-protos.h (m68k_initial_elimination_offset): Add prototype.
* config/m68k/m68k.c (m68k_frame): New struct, simular to ix86 back-end.
(m68k_compute_frame_layout): New function.
(m68k_initial_elimination_offset): New function.
(m68k_output_function_prologue): ColdFire-specific movem handling.
(m68k_output_function_epilogue): Likewise.
* config/m68k/m68k.h (FIRST_PSEOUDO_REGISTER): Make room for argptr reg.
(ARG_POINTER_REGNUM): Add new definition.
(INITIAL_FRAME_POINTER_OFFSET): Remove macro.
(ELIMINABLE_REGS): Define new macro, like in ix86 back-end.
(CAN_ELIMINATE): Likewise.
(INITIAL_ELIMINATION_OFFSET): Likewise.

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

gcc/ChangeLog
gcc/config/m68k/coff.h
gcc/config/m68k/hp320.h
gcc/config/m68k/linux.h
gcc/config/m68k/m68k-protos.h
gcc/config/m68k/m68k.c
gcc/config/m68k/m68k.h
gcc/config/m68k/m68kelf.h
gcc/config/m68k/sgs.h

index bd9c479..0a15e1d 100644 (file)
@@ -1,4 +1,25 @@
 2003-09-08  Bernardo Innocenti  <bernie@develer.com>
+            Peter Barada <peter@baradas.org>
+
+       * config/m68k/coff.h (REGISTER_NAMES): Add fake register `argptr'
+       * config/m68k/hp320.h (REGISTER_NAMES): Likewise.
+       * config/m68k/linux.h (REGISTER_NAMES): Likewise.
+       * config/m68k/m68kelf.h (REGISTER_NAMES): Likewise.
+       * gcc/config/m68k/sgs.h (REGISTER_NAMES): Likewise.
+       * config/m68k/m68k-protos.h (m68k_initial_elimination_offset): Add prototype.
+       * config/m68k/m68k.c (m68k_frame): New struct, simular to ix86 back-end.
+       (m68k_compute_frame_layout): New function.
+       (m68k_initial_elimination_offset): New function.
+       (m68k_output_function_prologue): ColdFire-specific movem handling.
+       (m68k_output_function_epilogue): Likewise.
+       * config/m68k/m68k.h (FIRST_PSEOUDO_REGISTER): Make room for argptr reg.
+       (ARG_POINTER_REGNUM): Add new definition.
+       (INITIAL_FRAME_POINTER_OFFSET): Remove macro.
+       (ELIMINABLE_REGS): Define new macro, like in ix86 back-end.
+       (CAN_ELIMINATE): Likewise.
+       (INITIAL_ELIMINATION_OFFSET): Likewise.
+
+2003-09-08  Bernardo Innocenti  <bernie@develer.com>
 
        * config/m68k/m68k.c (m68k_output_function_prologue): Simplify
        by removing redundant variable cfa_store_offset.
index 4806e9b..21699a6 100644 (file)
@@ -74,7 +74,7 @@ Boston, MA 02111-1307, USA.  */
 #define REGISTER_NAMES \
 {"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",       \
  "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%sp",       \
- "%fp0", "%fp1", "%fp2", "%fp3", "%fp4", "%fp5", "%fp6", "%fp7" }
+ "%fp0", "%fp1", "%fp2", "%fp3", "%fp4", "%fp5", "%fp6", "%fp7", "argptr" }
 
 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
 
index 3f09240..edfe3b9 100644 (file)
@@ -158,7 +158,7 @@ Boston, MA 02111-1307, USA.  */
 #define REGISTER_NAMES \
 {"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",       \
  "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",       \
- "%fp0", "%fp1", "%fp2", "%fp3", "%fp4", "%fp5", "%fp6", "%fp7"}
+ "%fp0", "%fp1", "%fp2", "%fp3", "%fp4", "%fp5", "%fp6", "%fp7", "argptr"}
 
 #define IMMEDIATE_PREFIX        "&"
 #define REGISTER_PREFIX         "%"
index ed9ba6b..8178d52 100644 (file)
@@ -68,7 +68,7 @@ Boston, MA 02111-1307, USA.  */
 #define REGISTER_NAMES \
 {"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7", \
  "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%sp", \
- "%fp0", "%fp1", "%fp2", "%fp3", "%fp4", "%fp5", "%fp6", "%fp7" }
+ "%fp0", "%fp1", "%fp2", "%fp3", "%fp4", "%fp5", "%fp6", "%fp7", "argptr" }
 
 #undef SIZE_TYPE
 #define SIZE_TYPE "unsigned int"
index 76083a7..955cbf5 100644 (file)
@@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA.  */
 /* Define functions defined in aux-output.c and used in templates.  */
 
 #ifdef RTX_CODE
+extern HOST_WIDE_INT m68k_initial_elimination_offset (int from, int to);
 extern const char *output_move_const_into_data_reg (rtx *);
 extern const char *output_move_simode_const (rtx *);
 extern const char *output_move_simode (rtx *);
index ccdedce..1c3d8cc 100644 (file)
@@ -215,6 +215,84 @@ override_options (void)
   real_format_for_mode[XFmode - QFmode] = &ieee_extended_motorola_format;
 }
 \f
+/* Structure describing stack frame layout. */
+struct m68k_frame {
+  HOST_WIDE_INT offset;
+  HOST_WIDE_INT size;
+  /* data and address register */
+  int reg_no;
+  unsigned int reg_mask;
+  unsigned int reg_rev_mask;
+  /* fpu registers */
+  int fpu_no;
+  unsigned int fpu_mask;
+  unsigned int fpu_rev_mask;
+  /* fpa registers */
+  int fpa_no;
+  /* offsets relative to ARG_POINTER.  */
+  HOST_WIDE_INT frame_pointer_offset;
+  HOST_WIDE_INT stack_pointer_offset;
+};
+
+static void
+m68k_compute_frame_layout (struct m68k_frame *frame)
+{
+  int regno, saved;
+  unsigned int mask, rmask;
+
+  frame->size = (get_frame_size () + 3) & -4;
+
+  mask = rmask = saved = 0;
+  for (regno = 0; regno < 16; regno++)
+    if (m68k_save_reg (regno))
+      {
+       mask |= 1 << regno;
+       rmask |= 1 << (15 - regno);
+       saved++;
+      }
+  frame->offset = saved * 4;
+  frame->reg_no = saved;
+  frame->reg_mask = mask;
+  frame->reg_rev_mask = rmask;
+
+  if (TARGET_68881 /* || TARGET_CFV4E */)
+    {
+      mask = rmask = saved = 0;
+      for (regno = 16; regno < 24; regno++)
+       if (regs_ever_live[regno] && ! call_used_regs[regno])
+         {
+           mask |= 1 << (23 - regno);
+           rmask |= 1 << (regno - 16);
+           saved++;
+         }
+      frame->offset += saved * 12 /* (TARGET_CFV4E ? 8 : 12) */;
+      frame->fpu_no = saved;
+      frame->fpu_mask = mask;
+      frame->fpu_rev_mask = rmask;
+    }
+}
+
+HOST_WIDE_INT
+m68k_initial_elimination_offset (int from, int to)
+{
+  struct m68k_frame frame;
+
+  /* FIXME: The correct offset to compute here would appear to be
+       (frame_pointer_needed ? -UNITS_PER_WORD * 2 : -UNITS_PER_WORD);
+     but for some obscure reason, this must be 0 to get correct code.  */
+  if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
+    return 0;
+
+  m68k_compute_frame_layout (&frame);
+
+  if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+    return frame.offset + frame.size + (frame_pointer_needed ? -UNITS_PER_WORD * 2 : -UNITS_PER_WORD);
+  else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+    return frame.offset + frame.size;
+
+  abort();
+}
+
 /* Return 1 if we need to save REGNO.  */
 static int
 m68k_save_reg (unsigned int regno)
@@ -261,6 +339,7 @@ m68k_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
   register int mask = 0;
   int num_saved_regs = 0;
   HOST_WIDE_INT fsize = (size + 3) & -4;
+  HOST_WIDE_INT fsize_with_regs;
   HOST_WIDE_INT cfa_offset = INCOMING_FRAME_SP_OFFSET;
   
   /* If the stack limit is a symbol, we can check it here,
@@ -277,6 +356,21 @@ m68k_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
 #endif
     }
 
+  if (TARGET_COLDFIRE)
+    {
+      /* on Coldfire add register save into initial stack frame setup, if possible */
+      for (regno = 0; regno < 16; regno++)
+        if (m68k_save_reg (regno))
+          num_saved_regs++;
+
+      if (num_saved_regs <= 2)
+        num_saved_regs = 0;
+    }
+  else
+      num_saved_regs = 0;
+
+  fsize_with_regs = fsize + num_saved_regs * 4;
+  
   if (frame_pointer_needed)
     {
       if (fsize == 0 && TARGET_68040)
@@ -294,35 +388,35 @@ m68k_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
                   reg_names[FRAME_POINTER_REGNUM]);
 #endif
        }
-      else if (fsize < 0x8000)
+      else if (fsize_with_regs < 0x8000)
        {
 #ifdef MOTOROLA
-         asm_fprintf (stream, "\tlink.w %s,%I%wd\n",
-                      reg_names[FRAME_POINTER_REGNUM], -fsize);
+             asm_fprintf (stream, "\tlink.w %s,%I%wd\n",
+               reg_names[FRAME_POINTER_REGNUM], -fsize_with_regs);
 #else
-         asm_fprintf (stream, "\tlink %s,%I%wd\n",
-                      reg_names[FRAME_POINTER_REGNUM], -fsize);
+             asm_fprintf (stream, "\tlink %s,%I%wd\n",
+               reg_names[FRAME_POINTER_REGNUM], -fsize_with_regs);
 #endif
        }
       else if (TARGET_68020)
        {
 #ifdef MOTOROLA
          asm_fprintf (stream, "\tlink.l %s,%I%wd\n",
-                      reg_names[FRAME_POINTER_REGNUM], -fsize);
+                      reg_names[FRAME_POINTER_REGNUM], -fsize_with_regs);
 #else
          asm_fprintf (stream, "\tlink %s,%I%wd\n",
-                      reg_names[FRAME_POINTER_REGNUM], -fsize);
+                      reg_names[FRAME_POINTER_REGNUM], -fsize_with_regs);
 #endif
        }
       else
        {
-      /* Adding negative number is faster on the 68040.  */
+          /* Adding negative number is faster on the 68040.  */
 #ifdef MOTOROLA
          asm_fprintf (stream, "\tlink.w %s,%I0\n\tadd.l %I%wd,%Rsp\n",
-                      reg_names[FRAME_POINTER_REGNUM], -fsize);
+                      reg_names[FRAME_POINTER_REGNUM], -fsize_with_regs);
 #else
          asm_fprintf (stream, "\tlink %s,%I0\n\taddl %I%wd,%Rsp\n",
-                      reg_names[FRAME_POINTER_REGNUM], -fsize);
+                      reg_names[FRAME_POINTER_REGNUM], -fsize_with_regs);
 #endif
        }
       if (dwarf2out_do_frame ())
@@ -335,32 +429,32 @@ m68k_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
          cfa_offset += fsize;
        }
     }
-  else if (fsize)
+  else if (fsize_with_regs) /* !frame_pointer_needed */
     {
-      if (fsize + 4 < 0x8000)
+      if (fsize_with_regs < 0x8000)
        {
-         if (fsize + 4 <= 8)
+         if (fsize_with_regs <= 8)
            {
              if (!TARGET_COLDFIRE)
                {
                  /* asm_fprintf() cannot handle %.  */
 #ifdef MOTOROLA
-                 asm_fprintf (stream, "\tsubq.w %I%wd,%Rsp\n", fsize + 4);
+                 asm_fprintf (stream, "\tsubq.w %I%wd,%Rsp\n", fsize_with_regs);
 #else
-                 asm_fprintf (stream, "\tsubqw %I%wd,%Rsp\n", fsize + 4);
+                 asm_fprintf (stream, "\tsubqw %I%wd,%Rsp\n", fsize_with_regs);
 #endif
                }
              else
                {
                  /* asm_fprintf() cannot handle %.  */
 #ifdef MOTOROLA
-                 asm_fprintf (stream, "\tsubq.l %I%wd,%Rsp\n", fsize + 4);
+                 asm_fprintf (stream, "\tsubq.l %I%wd,%Rsp\n", fsize_with_regs);
 #else
-                 asm_fprintf (stream, "\tsubql %I%wd,%Rsp\n", fsize + 4);
+                 asm_fprintf (stream, "\tsubql %I%wd,%Rsp\n", fsize_with_regs);
 #endif
                }
            }
-         else if (fsize + 4 <= 16 && TARGET_CPU32)
+         else if (fsize_with_regs <= 16 && TARGET_CPU32)
            {
              /* On the CPU32 it is faster to use two subqw instructions to
                 subtract a small integer (8 < N <= 16) to a register.  */
@@ -368,10 +462,10 @@ m68k_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
 #ifdef MOTOROLA
              asm_fprintf (stream,
                           "\tsubq.w %I8,%Rsp\n\tsubq.w %I%wd,%Rsp\n",
-                          fsize + 4 - 8);
+                          fsize_with_regs - 8);
 #else
              asm_fprintf (stream, "\tsubqw %I8,%Rsp\n\tsubqw %I%wd,%Rsp\n",
-                          fsize + 4 - 8);
+                          fsize_with_regs - 8);
 #endif
            }
          else if (TARGET_68040)
@@ -379,27 +473,26 @@ m68k_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
              /* Adding negative number is faster on the 68040.  */
              /* asm_fprintf() cannot handle %.  */
 #ifdef MOTOROLA
-             asm_fprintf (stream, "\tadd.w %I%wd,%Rsp\n", - (fsize + 4));
+             asm_fprintf (stream, "\tadd.w %I%wd,%Rsp\n", -fsize_with_regs);
 #else
-             asm_fprintf (stream, "\taddw %I%wd,%Rsp\n", - (fsize + 4));
+             asm_fprintf (stream, "\taddw %I%wd,%Rsp\n", -fsize_with_regs);
 #endif
            }
          else
            {
 #ifdef MOTOROLA
-             asm_fprintf (stream, "\tlea (%wd,%Rsp),%Rsp\n", - (fsize + 4));
+             asm_fprintf (stream, "\tlea (%wd,%Rsp),%Rsp\n", -fsize_with_regs);
 #else
-             asm_fprintf (stream, "\tlea %Rsp@(%wd),%Rsp\n", - (fsize + 4));
+             asm_fprintf (stream, "\tlea %Rsp@(%wd),%Rsp\n", -fsize_with_regs);
 #endif
            }
        }
-      else
+      else /* fsize_with_regs >= 0x8000 */
        {
-       /* asm_fprintf() cannot handle %.  */
 #ifdef MOTOROLA
-         asm_fprintf (stream, "\tadd.l %I%wd,%Rsp\n", - (fsize + 4));
+         asm_fprintf (stream, "\tadd.l %I%wd,%Rsp\n", -fsize_with_regs);
 #else
-         asm_fprintf (stream, "\taddl %I%wd,%Rsp\n", - (fsize + 4));
+         asm_fprintf (stream, "\taddl %I%wd,%Rsp\n", -fsize_with_regs);
 #endif
        }
       if (dwarf2out_do_frame ())
@@ -407,7 +500,10 @@ m68k_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
          cfa_offset += fsize + 4;
          dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, cfa_offset);
        }
-    }
+    } /* !frame_pointer_needed */
+
+  num_saved_regs = 0;
+
   if (TARGET_68881)
     {
       for (regno = 16; regno < 24; regno++)
@@ -505,10 +601,8 @@ m68k_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
             then use the plain address register indirect mode.  We also
             have to invert the register save mask to use the new mode.
 
-            FIXME: if num_saved_regs was calculated earlier, we could
-            combine the stack pointer adjustment with any adjustment
-            done when the initial stack frame is created.  This would
-            save an instruction */
+            The required register save space was combined earlier with
+            the fsize amount.  Don't add it again.  */
             
          int newmask = 0;
          int i;
@@ -518,10 +612,8 @@ m68k_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
                newmask |= (1 << (15-i));
 
 #ifdef MOTOROLA
-         asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs*4);
          asm_fprintf (stream, "\tmovm.l %I0x%x,(%Rsp)\n", newmask);
 #else
-         asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs*4);
          asm_fprintf (stream, "\tmoveml %I0x%x,%Rsp@\n", newmask);
 #endif
        }
@@ -595,6 +687,7 @@ m68k_output_function_epilogue (FILE *stream, HOST_WIDE_INT size)
   register int nregs;
   HOST_WIDE_INT offset, foffset;
   HOST_WIDE_INT fsize = (size + 3) & -4;
+  HOST_WIDE_INT fsize_with_regs;
   int big = 0;
   rtx insn = get_last_insn ();
   int restore_from_sp = 0;
@@ -637,18 +730,45 @@ m68k_output_function_epilogue (FILE *stream, HOST_WIDE_INT size)
      stack adjustment needed at that point.  */
   restore_from_sp = ! frame_pointer_needed
             || (! current_function_calls_alloca && leaf_function_p ());
+
+  /* fsize_with_regs is the size we need to adjust the sp when
+     popping the frame */
+  fsize_with_regs = fsize;
+
+  /* Because the ColdFire doesn't support moveml with
+     complex address modes, we must adjust the stack manually
+     after restoring registers. When the frame pointer isn't used,
+     we can merge movem adjustment into frame unlinking
+     made immediately after it. */
+  if (TARGET_COLDFIRE && restore_from_sp && (nregs > 2))
+    fsize_with_regs += nregs * 4;
+
   if (offset + fsize >= 0x8000
       && ! restore_from_sp
       && (mask || fmask))
     {
+      /* Because the ColdFire doesn't support moveml with
+         complex address modes we make an extra correction here */
+      if (TARGET_COLDFIRE)
+        {
 #ifdef MOTOROLA
-      asm_fprintf (stream, "\t%Omove.l %I%wd,%Ra1\n", -fsize);
+          asm_fprintf (stream, "\t%Omove.l %I%d,%Ra1\n", -fsize - offset);
 #else
-      asm_fprintf (stream, "\tmovel %I%wd,%Ra1\n", -fsize);
+          asm_fprintf (stream, "\tmovel %I%d,%Ra1\n", -fsize - offset);
 #endif
+        }
+      else
+        {
+#ifdef MOTOROLA
+          asm_fprintf (stream, "\t%Omove.l %I%wd,%Ra1\n", -fsize);
+#else
+          asm_fprintf (stream, "\tmovel %I%wd,%Ra1\n", -fsize);
+#endif
+        }
+
       fsize = 0, big = 1;
     }
-  if (TARGET_COLDFIRE || nregs <= 2)
+  if (nregs <= 2)
     {
       /* Restore each separately in the same order moveml does.
          Using two movel instructions instead of a single moveml
@@ -702,39 +822,77 @@ m68k_output_function_epilogue (FILE *stream, HOST_WIDE_INT size)
     }
   else if (mask)
     {
-      if (big)
-       {
+      /* The ColdFire requires special handling due to its limited moveml insn */
+      if (TARGET_COLDFIRE)
+        {
+          if (big)
+            {
 #ifdef MOTOROLA
-         asm_fprintf (stream, "\tmovm.l -%wd(%s,%Ra1.l),%I0x%x\n",
-                      offset + fsize,
-                      reg_names[FRAME_POINTER_REGNUM],
-                      mask);
+              asm_fprintf (stream, "\tadd.l %s,%Ra1\n", reg_names[FRAME_POINTER_REGNUM]);
+              asm_fprintf (stream, "\tmovm.l (%Ra1),%I0x%x\n", mask);
 #else
-         asm_fprintf (stream, "\tmoveml %s@(-%wd,%Ra1:l),%I0x%x\n",
-                      reg_names[FRAME_POINTER_REGNUM],
-                      offset + fsize, mask);
+              asm_fprintf (stream, "\taddl %s,%Ra1\n", reg_names[FRAME_POINTER_REGNUM]);
+              asm_fprintf (stream, "\tmoveml %Ra1@,%I0x%x\n", mask);
 #endif
-       }
-      else if (restore_from_sp)
-       {
+            }
+          else if (restore_from_sp)
+            {
 #ifdef MOTOROLA
-         asm_fprintf (stream, "\tmovm.l (%Rsp)+,%I0x%x\n", mask);
+              asm_fprintf (stream, "\tmovm.l (%Rsp),%I0x%x\n", mask);
 #else
-         asm_fprintf (stream, "\tmoveml %Rsp@+,%I0x%x\n", mask);
+              asm_fprintf (stream, "\tmoveml %Rsp@,%I0x%x\n", mask);
 #endif
-       }
-      else
+            }
+          else
+            {
+#ifdef MOTOROLA
+              asm_fprintf (stream, "\tmovm.l -%wd(%s),%I0x%x\n",
+                           offset + fsize,
+                           reg_names[FRAME_POINTER_REGNUM],
+                           mask);
+#else
+              asm_fprintf (stream, "\tmoveml %s@(-%wd),%I0x%x\n",
+                           reg_names[FRAME_POINTER_REGNUM],
+                           offset + fsize, mask);
+#endif
+           }
+        }
+      else /* !TARGET_COLDFIRE */
        {
+         if (big)
+           {
 #ifdef MOTOROLA
-         asm_fprintf (stream, "\tmovm.l -%wd(%s),%I0x%x\n",
-                      offset + fsize,
-                      reg_names[FRAME_POINTER_REGNUM],
-                      mask);
+             asm_fprintf (stream, "\tmovm.l -%wd(%s,%Ra1.l),%I0x%x\n",
+                          offset + fsize,
+                          reg_names[FRAME_POINTER_REGNUM],
+                          mask);
 #else
-         asm_fprintf (stream, "\tmoveml %s@(-%wd),%I0x%x\n",
-                      reg_names[FRAME_POINTER_REGNUM],
-                      offset + fsize, mask);
+             asm_fprintf (stream, "\tmoveml %s@(-%wd,%Ra1:l),%I0x%x\n",
+                          reg_names[FRAME_POINTER_REGNUM],
+                          offset + fsize, mask);
 #endif
+           }
+         else if (restore_from_sp)
+           {
+#ifdef MOTOROLA
+             asm_fprintf (stream, "\tmovm.l (%Rsp)+,%I0x%x\n", mask);
+#else
+             asm_fprintf (stream, "\tmoveml %Rsp@+,%I0x%x\n", mask);
+#endif
+           }
+         else
+           {
+#ifdef MOTOROLA
+             asm_fprintf (stream, "\tmovm.l -%wd(%s),%I0x%x\n",
+                          offset + fsize,
+                          reg_names[FRAME_POINTER_REGNUM],
+                          mask);
+#else
+             asm_fprintf (stream, "\tmoveml %s@(-%wd),%I0x%x\n",
+                          reg_names[FRAME_POINTER_REGNUM],
+                          offset + fsize, mask);
+#endif
+           }
        }
     }
   if (fmask)
@@ -777,57 +935,57 @@ m68k_output_function_epilogue (FILE *stream, HOST_WIDE_INT size)
   if (frame_pointer_needed)
     fprintf (stream, "\tunlk %s\n",
             reg_names[FRAME_POINTER_REGNUM]);
-  else if (fsize)
+  else if (fsize_with_regs)
     {
-      if (fsize + 4 <= 8) 
+      if (fsize_with_regs <= 8)
        {
          if (!TARGET_COLDFIRE)
            {
 #ifdef MOTOROLA
-             asm_fprintf (stream, "\taddq.w %I%wd,%Rsp\n", fsize + 4);
+             asm_fprintf (stream, "\taddq.w %I%wd,%Rsp\n", fsize_with_regs);
 #else
-             asm_fprintf (stream, "\taddqw %I%wd,%Rsp\n", fsize + 4);
+             asm_fprintf (stream, "\taddqw %I%wd,%Rsp\n", fsize_with_regs);
 #endif
            }
-         else
+         else /* TARGET_COLDFIRE */
            {
 #ifdef MOTOROLA
-             asm_fprintf (stream, "\taddq.l %I%wd,%Rsp\n", fsize + 4);
+             asm_fprintf (stream, "\taddq.l %I%wd,%Rsp\n", fsize_with_regs);
 #else
-             asm_fprintf (stream, "\taddql %I%wd,%Rsp\n", fsize + 4);
+             asm_fprintf (stream, "\taddql %I%wd,%Rsp\n", fsize_with_regs);
 #endif
            }
        }
-      else if (fsize + 4 <= 16 && TARGET_CPU32)
+      else if (fsize_with_regs <= 16 && TARGET_CPU32)
        {
          /* On the CPU32 it is faster to use two addqw instructions to
             add a small integer (8 < N <= 16) to a register.  */
          /* asm_fprintf() cannot handle %.  */
 #ifdef MOTOROLA
          asm_fprintf (stream, "\taddq.w %I8,%Rsp\n\taddq.w %I%wd,%Rsp\n",
-                      fsize + 4 - 8);
+                      fsize_with_regs - 8);
 #else
          asm_fprintf (stream, "\taddqw %I8,%Rsp\n\taddqw %I%wd,%Rsp\n",
-                      fsize + 4 - 8);
+                      fsize_with_regs - 8);
 #endif
        }
-      else if (fsize + 4 < 0x8000)
+      else if (fsize_with_regs < 0x8000)
        {
          if (TARGET_68040)
            { 
              /* asm_fprintf() cannot handle %.  */
 #ifdef MOTOROLA
-             asm_fprintf (stream, "\tadd.w %I%wd,%Rsp\n", fsize + 4);
+             asm_fprintf (stream, "\tadd.w %I%wd,%Rsp\n", fsize_with_regs);
 #else
-             asm_fprintf (stream, "\taddw %I%wd,%Rsp\n", fsize + 4);
+             asm_fprintf (stream, "\taddw %I%wd,%Rsp\n", fsize_with_regs);
 #endif
            }
          else
            {
 #ifdef MOTOROLA
-             asm_fprintf (stream, "\tlea (%wd,%Rsp),%Rsp\n", fsize + 4);
+             asm_fprintf (stream, "\tlea (%wd,%Rsp),%Rsp\n", fsize_with_regs);
 #else
-             asm_fprintf (stream, "\tlea %Rsp@(%wd),%Rsp\n", fsize + 4);
+             asm_fprintf (stream, "\tlea %Rsp@(%wd),%Rsp\n", fsize_with_regs);
 #endif
            }
        }
@@ -835,9 +993,9 @@ m68k_output_function_epilogue (FILE *stream, HOST_WIDE_INT size)
        {
        /* asm_fprintf() cannot handle %.  */
 #ifdef MOTOROLA
-         asm_fprintf (stream, "\tadd.l %I%wd,%Rsp\n", fsize + 4);
+         asm_fprintf (stream, "\tadd.l %I%wd,%Rsp\n", fsize_with_regs);
 #else
-         asm_fprintf (stream, "\taddl %I%wd,%Rsp\n", fsize + 4);
+         asm_fprintf (stream, "\taddl %I%wd,%Rsp\n", fsize_with_regs);
 #endif
        }
     }
index 808a93a..b82dbc7 100644 (file)
@@ -386,7 +386,7 @@ extern int target_flags;
    For the 68000, we give the data registers numbers 0-7,
    the address registers numbers 010-017,
    and the 68881 floating point registers numbers 020-027.  */
-#define FIRST_PSEUDO_REGISTER 24
+#define FIRST_PSEUDO_REGISTER 25
 
 /* This defines the register which is used to hold the offset table for PIC.  */
 #define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 13 : INVALID_REGNUM)
@@ -493,8 +493,11 @@ extern int target_flags;
    This is computed in `reload', in reload1.c.  */
 #define FRAME_POINTER_REQUIRED 0
 
-/* Base register for access to arguments of the function.  */
-#define ARG_POINTER_REGNUM 14
+/* Base register for access to arguments of the function.
+ * This isn't a hardware register. It will be eliminated to the
+ * stack pointer or frame pointer.
+ */
+#define ARG_POINTER_REGNUM 24
 
 /* Register in which static-chain is passed to a function.  */
 #define STATIC_CHAIN_REGNUM 8
@@ -879,32 +882,6 @@ enum reg_class {
    You should override this if you define FUNCTION_EXTRA_EPILOGUE.  */
 #define USE_RETURN_INSN use_return_insn ()
 
-/* Store in the variable DEPTH the initial difference between the
-   frame pointer reg contents and the stack pointer reg contents,
-   as of the start of the function body.  This depends on the layout
-   of the fixed parts of the stack frame and on how registers are saved.
-
-   On the 68k, if we have a frame, we must add one word to its length
-   to allow for the place that a6 is stored when we do have a frame pointer.
-   Otherwise, we would need to compute the offset from the frame pointer
-   of a local variable as a function of frame_pointer_needed, which
-   is hard.  */
-
-#define INITIAL_FRAME_POINTER_OFFSET(DEPTH)                    \
-{ int regno;                                                   \
-  int offset = -4;                                             \
-  for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++)     \
-    if (regs_ever_live[regno] && ! call_used_regs[regno])      \
-      offset += 12;                                            \
-  for (regno = 0; regno < 16; regno++)                         \
-    if (regs_ever_live[regno] && ! call_used_regs[regno])      \
-      offset += 4;                                             \
-  if (flag_pic && current_function_uses_pic_offset_table)      \
-    offset += 4;                                               \
-  (DEPTH) = (offset + ((get_frame_size () + 3) & -4)           \
-            + (get_frame_size () == 0 ? 0 : 4));               \
-}
-
 /* Output assembler code for a block containing the constant parts
    of a trampoline, leaving space for the variable parts.  */
 
@@ -982,6 +959,38 @@ __transfer_from_trampoline ()                                      \
   asm ("rts":);                                                        \
 }
 \f
+/* Definitions for register eliminations.
+
+   This is an array of structures.  Each structure initializes one pair
+   of eliminable registers.  The "from" register number is given first,
+   followed by "to".  Eliminations of the same "from" register are listed
+   in order of preference.
+
+   There are two registers that can always be eliminated on the m68k.
+   The frame pointer and the arg pointer can be replaced by either the
+   hard frame pointer or to the stack pointer, depending upon the
+   circumstances.  The hard frame pointer is not used before reload and
+   so it is not eligible for elimination.  */
+
+#define ELIMINABLE_REGS                                        \
+{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM },         \
+ { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }}
+
+/* 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) \
+  ((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.  */
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                   \
+  (OFFSET) = m68k_initial_elimination_offset(FROM, TO)
+\f
 /* Addressing modes, and classification of registers for them.  */
 
 #define HAVE_POST_INCREMENT 1
@@ -1381,7 +1390,7 @@ __transfer_from_trampoline ()                                     \
 #define REGISTER_NAMES \
 {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",       \
  "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp",       \
- "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7" }
+ "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", "argptr" }
 
 /* How to renumber registers for dbx and gdb.
    On the Sun-3, the floating point registers have numbers
index 419f86a..585b24f 100644 (file)
@@ -94,7 +94,7 @@ Boston, MA 02111-1307, USA.  */
 #define REGISTER_NAMES \
 {"%d0",   "%d1",   "%d2",   "%d3",   "%d4",   "%d5",   "%d6",   "%d7",      \
  "%a0",   "%a1",   "%a2",   "%a3",   "%a4",   "%a5",   "%a6",   "%sp",      \
- "%fp0",  "%fp1",  "%fp2",  "%fp3",  "%fp4",  "%fp5",  "%fp6",  "%fp7" }
+ "%fp0",  "%fp1",  "%fp2",  "%fp3",  "%fp4",  "%fp5",  "%fp6",  "%fp7", "argptr" }
 
 /* This is how to output an assembler line that says to advance the
    location counter to a multiple of 2**LOG bytes.  */
index b41908c..1dc44c7 100644 (file)
@@ -72,7 +72,7 @@ Boston, MA 02111-1307, USA.  */
 #define REGISTER_NAMES \
 {"%d0",   "%d1",   "%d2",   "%d3",   "%d4",   "%d5",   "%d6",   "%d7",      \
  "%a0",   "%a1",   "%a2",   "%a3",   "%a4",   "%a5",   "%fp",   "%sp",      \
- "%fp0",  "%fp1",  "%fp2",  "%fp3",  "%fp4",  "%fp5",  "%fp6",  "%fp7" }
+ "%fp0",  "%fp1",  "%fp2",  "%fp3",  "%fp4",  "%fp5",  "%fp6",  "%fp7", "argptr" }
 
 /* This is how to output an assembler line that says to advance the
    location counter to a multiple of 2**LOG bytes.  */