Change MIPS fp to be at top of stack, instead of bottom; Fix calling mips-tfile with...
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 25 Aug 1992 17:39:37 +0000 (17:39 +0000)
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 25 Aug 1992 17:39:37 +0000 (17:39 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@1941 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/osfrose.h

index 4aed597..5cae65b 100644 (file)
@@ -107,10 +107,6 @@ int mips_section_threshold = -1;
 /* Count the number of .file directives, so that .loc is up to date.  */
 int num_source_filenames = 0;
 
-/* Count of the number of functions created so far, in order to make
-   unique labels for omitting the frame pointer.  */
-int number_functions_processed = 0;
-
 /* Count the number of sdb related labels are generated (to find block
    start and end boundaries).  */
 int sdb_label_count = 0;
@@ -3085,11 +3081,14 @@ override_options ()
 
 \f
 /*
- * If the frame pointer has been eliminated, the offset for an auto
- * or argument will be based on the stack pointer.  But this is not
- * what the debugger expects--it needs to find an offset off of the
- * frame pointer (whether it exists or not).  So here we turn all
- * offsets into those based on the (possibly virtual) frame pointer.
+ * The MIPS debug format wants all automatic variables and arguments
+ * to be in terms of the virtual frame pointer (stack pointer before
+ * any adjustment in the function), while the MIPS 3.0 linker wants
+ * the frame pointer to be the stack pointer after the initial
+ * adjustment.  So, we do the adjustment here.  The arg pointer (which
+ * is eliminated) points to the virtual frame pointer, while the frame
+ * pointer (which may be eliminated) points to the stack pointer after
+ * the initial adjustments.
  */
 
 int
@@ -3103,7 +3102,7 @@ mips_debugger_offset (addr, offset)
   if (!offset)
     offset = INTVAL (offset2);
 
-  if (reg == stack_pointer_rtx)
+  if (reg == stack_pointer_rtx || reg == frame_pointer_rtx)
     {
       int frame_size = (!current_frame_info.initialized)
                                ? compute_frame_size (get_frame_size ())
@@ -3111,13 +3110,8 @@ mips_debugger_offset (addr, offset)
 
       offset = offset - frame_size;
     }
-
-  /* Any other register is, we hope, either the frame pointer,
-     or a pseudo equivalent to the frame pointer.  (Assign_parms
-     copies the arg pointer to a pseudo if ARG_POINTER_REGNUM is
-     equal to FRAME_POINTER_REGNUM, so references off of the
-     arg pointer are all off a pseudo.)  Seems like all we can
-     do is to just return OFFSET and hope for the best.  */
+  else if (reg != arg_pointer_rtx)
+    abort_with_insn (addr, "mips_debugger_offset called with non stack/frame/arg pointer.");
 
   return offset;
 }
@@ -3415,6 +3409,9 @@ print_operand_address (file, addr)
        break;
 
       case REG:
+       if (REGNO (addr) == ARG_POINTER_REGNUM)
+         abort_with_insn (addr, "Arg pointer not eliminated.");
+
        fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
        break;
 
@@ -3448,6 +3445,9 @@ print_operand_address (file, addr)
          if (!CONSTANT_P (offset))
            abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, illegal insn #2");
 
+       if (REGNO (reg) == ARG_POINTER_REGNUM)
+         abort_with_insn (addr, "Arg pointer not eliminated.");
+
          output_addr_const (file, offset);
          fprintf (file, "(%s)", reg_names [REGNO (reg)]);
        }
@@ -3861,10 +3861,6 @@ mips_output_float (stream, value)
                                        |  GP save for V.4 abi  |
                                        |                       |
                                        +-----------------------+
-                                       |                       |
-                                       |  local variables      |
-                                       |                       |
-                                       +-----------------------+
                                        |                       |
                                         |  fp register save     |
                                        |                       |
@@ -3874,6 +3870,10 @@ mips_output_float (stream, value)
                                         |                      |
                                        +-----------------------+
                                        |                       |
+                                       |  local variables      |
+                                       |                       |
+                                       +-----------------------+
+                                       |                       |
                                         |  alloca allocations   |
                                        |                       |
                                        +-----------------------+
@@ -3906,16 +3906,23 @@ compute_frame_size (size)
   int fp_inc;                  /* 1 or 2 depending on the size of fp regs */
   int fp_bits;                 /* bitmask to use for each fp register */
 
-  extra_size    = MIPS_STACK_ALIGN (((TARGET_ABICALLS) ? UNITS_PER_WORD : 0)
-                                    -STARTING_FRAME_OFFSET);
-
-  var_size      = MIPS_STACK_ALIGN (size);
-  args_size     = MIPS_STACK_ALIGN (current_function_outgoing_args_size);
-  total_size    = var_size + args_size + extra_size;
   gp_reg_size   = 0;
   fp_reg_size   = 0;
   mask          = 0;
   fmask                 = 0;
+  extra_size    = MIPS_STACK_ALIGN (((TARGET_ABICALLS) ? UNITS_PER_WORD : 0));
+  var_size      = MIPS_STACK_ALIGN (size);
+  args_size     = MIPS_STACK_ALIGN (current_function_outgoing_args_size);
+
+  /* The MIPS 3.0 linker does not like functions that dynamically
+     allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
+     looks like we are trying to create a second frame pointer to the
+     function, so allocate some stack space to make it happy.  */
+
+  if (args_size == 0 && current_function_calls_alloca)
+       args_size = 4*UNITS_PER_WORD;
+
+  total_size = var_size + args_size + extra_size;
 
   /* Calculate space needed for gp registers.  */
   for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
@@ -3969,14 +3976,14 @@ compute_frame_size (size)
 
   if (mask)
     {
-      unsigned long offset = args_size + gp_reg_size - UNITS_PER_WORD;
+      unsigned long offset = args_size + var_size + gp_reg_size - UNITS_PER_WORD;
       current_frame_info.gp_sp_offset = offset;
       current_frame_info.gp_save_offset = offset - total_size;
     }
 
   if (fmask)
     {
-      unsigned long offset = args_size + gp_reg_rounded + fp_reg_size - 2*UNITS_PER_WORD;
+      unsigned long offset = args_size + var_size + gp_reg_rounded + fp_reg_size - 2*UNITS_PER_WORD;
       current_frame_info.fp_sp_offset = offset;
       current_frame_info.fp_save_offset = offset - total_size + UNITS_PER_WORD;
     }
@@ -4152,8 +4159,6 @@ function_prologue (file, size)
      int size;
 {
   int tsize = current_frame_info.total_size;
-  int vframe;
-  int vreg;
 
   ASM_OUTPUT_SOURCE_FILENAME (file, DECL_SOURCE_FILE (current_function_decl));
   ASM_OUTPUT_SOURCE_LINE (file, DECL_SOURCE_LINE (current_function_decl));
@@ -4174,20 +4179,9 @@ function_prologue (file, size)
   if (tsize > 0 && TARGET_ABICALLS)
     fprintf (file, "\t.cprestore %d\n", tsize + STARTING_FRAME_OFFSET);
 
-  if (frame_pointer_needed)
-    {
-      vframe = 0;
-      vreg   = FRAME_POINTER_REGNUM;
-    }
-  else
-    {
-      vframe = tsize;
-      vreg   = STACK_POINTER_REGNUM;
-    }
-
   fprintf (file, "\t.frame\t%s,%d,%s\t\t# vars= %d, regs= %d/%d, args = %d, extra= %d\n",
-          reg_names[ vreg ],
-          vframe,
+          reg_names[ (frame_pointer_needed) ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM ],
+          tsize,
           reg_names[31 + GP_REG_FIRST],
           current_frame_info.var_size,
           current_frame_info.num_gp,
@@ -4209,7 +4203,6 @@ void
 mips_expand_prologue ()
 {
   int regno;
-  int size;
   int tsize;
   tree fndecl = current_function_decl; /* current... is tooo long */
   tree fntype = TREE_TYPE (fndecl);
@@ -4291,9 +4284,7 @@ mips_expand_prologue ()
        }
     }
 
-  size  = MIPS_STACK_ALIGN (get_frame_size ());
-  tsize = compute_frame_size (size);
-
+  tsize = compute_frame_size (get_frame_size ());
   if (tsize > 0)
     {
       rtx tsize_rtx = GEN_INT (tsize);
@@ -4310,7 +4301,7 @@ mips_expand_prologue ()
       save_restore_insns (TRUE);
 
       if (frame_pointer_needed)
-       emit_insn (gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx, tsize_rtx));
+       emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
     }
 }
 
@@ -4413,15 +4404,8 @@ function_epilogue (file, size)
        fprintf (file, "\tli\t%s,%d\n", t1_str, tsize);
 
       if (frame_pointer_needed)
-       {
-         char *fp_str = reg_names[FRAME_POINTER_REGNUM];
-         if (tsize > 32767)
-           fprintf (file,"\tsubu\t%s,%s,%s\t\t# sp not trusted  here\n",
-                    sp_str, fp_str, t1_str);
-         else
-           fprintf (file,"\tsubu\t%s,%s,%d\t\t# sp not trusted  here\n",
-                    sp_str, fp_str, tsize);
-       }
+       fprintf (file, "\tmove\t%s,%s\t\t\t# sp not trusted here\n",
+                sp_str, reg_names[FRAME_POINTER_REGNUM]);
 
       save_restore (file, "lw", "ld", "l.d");
 
@@ -4489,6 +4473,10 @@ function_epilogue (file, size)
       int num_gp_regs = current_frame_info.gp_reg_size / 4;
       int num_fp_regs = current_frame_info.fp_reg_size / 8;
       int num_regs    = num_gp_regs + num_fp_regs;
+      char *name      = current_function_name;
+
+      if (name[0] == '*')
+       name++;
 
       dslots_load_total += num_regs;
 
@@ -4511,7 +4499,7 @@ function_epilogue (file, size)
 
       fprintf (stderr,
               "%-20s fp=%c leaf=%c alloca=%c setjmp=%c stack=%4ld arg=%3ld reg=%2d/%d delay=%3d/%3dL %3d/%3dJ refs=%3d/%3d/%3d",
-              current_function_name,
+              name,
               (frame_pointer_needed) ? 'y' : 'n',
               ((current_frame_info.mask & (1 << 31)) != 0) ? 'n' : 'y',
               (current_function_calls_alloca) ? 'y' : 'n',
@@ -4545,7 +4533,6 @@ function_epilogue (file, size)
   mips_load_reg      = (rtx)0;
   mips_load_reg2     = (rtx)0;
   current_frame_info = zero_frame_info;
-  number_functions_processed++;
 
   /* Restore the output file if optimizing the GP (optimizing the GP causes
      the text to be diverted to a tempfile, so that data decls come before
@@ -4574,7 +4561,7 @@ mips_expand_epilogue ()
   if (tsize > 0)
     {
       if (frame_pointer_needed)
-       emit_insn (gen_subsi3 (stack_pointer_rtx, frame_pointer_rtx, tsize_rtx));
+       emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx));
 
       save_restore_insns (FALSE);
 
index f51fe2b..fd748b4 100644 (file)
@@ -402,7 +402,7 @@ while (0)
        \n mips-tfile %{v*: -v} \
                %{K: -I %b.o~} \
                %{!K: %{save-temps: -I %b.o~}} \
-               %{c:%W{o*}%{!o*:-o %b.o}}%{!c:-o %u.o} \
+               %{c:%W{o*}%{!o*:-o %b.o}}%{!c:-o %U.o} \
                %{.s:%i} %{!.s:%g.s}}}"
 #endif
 
@@ -473,7 +473,7 @@ while (0)
 \f
 /* Print subsidiary information on the compiler version in use.  */
 
-#define MIPS_VERSION "[AL 1.1, MM 23]"
+#define MIPS_VERSION "[AL 1.1, MM 24]"
 
 #ifndef MACHINE_TYPE
 #define MACHINE_TYPE "BSD Mips"
@@ -651,8 +651,12 @@ do {                                                       \
 #define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
   sprintf ((BUFFER), ".%dfake", (NUMBER));
 
-/* Correct the offset of automatic variables and arguments
-   if the frame pointer has been eliminated.  */
+/* Correct the offset of automatic variables and arguments.  Note that
+   the MIPS debug format wants all automatic variables and arguments
+   to be in terms of the virtual frame pointer (stack pointer before
+   any adjustment in the function), while the MIPS 3.0 linker wants
+   the frame pointer to be the stack pointer after the initial
+   adjustment.  */
 
 #define DEBUGGER_AUTO_OFFSET(X)                mips_debugger_offset (X, 0)
 #define DEBUGGER_ARG_OFFSET(OFFSET, X) mips_debugger_offset (X, OFFSET)
@@ -1196,7 +1200,7 @@ extern char mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
 #define FRAME_POINTER_REQUIRED (current_function_calls_alloca)
 
 /* Base register for access to arguments of the function.  */
-#define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
+#define ARG_POINTER_REGNUM GP_REG_FIRST
 
 /* Register in which static-chain is passed to a function.  */
 #define STATIC_CHAIN_REGNUM (GP_REG_FIRST + 2)
@@ -1485,13 +1489,30 @@ extern enum reg_class mips_char_to_class[];
    is at the high-address end of the local variables;
    that is, each additional local variable allocated
    goes at a more negative offset in the frame.  */
-#define FRAME_GROWS_DOWNWARD
+/* #define FRAME_GROWS_DOWNWARD */
 
 /* Offset within stack frame to start allocating local variables at.
    If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
    first local allocated.  Otherwise, it is the offset to the BEGINNING
    of the first local allocated.  */
-#define STARTING_FRAME_OFFSET (-8)
+#define STARTING_FRAME_OFFSET current_function_outgoing_args_size
+
+/* Offset from the stack pointer register to an item dynamically
+   allocated on the stack, e.g., by `alloca'.
+
+   The default value for this macro is `STACK_POINTER_OFFSET' plus the
+   length of the outgoing arguments.  The default is correct for most
+   machines.  See `function.c' for details.
+
+   The MIPS 3.0 linker does not like functions that dynamically
+   allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
+   looks like we are trying to create a second frame pointer to the
+   function, so allocate some stack space to make it happy.  */
+
+#define STACK_DYNAMIC_OFFSET(FUNDECL)                                  \
+  ((current_function_outgoing_args_size == 0 && current_function_calls_alloca) \
+       ? 4*UNITS_PER_WORD                                              \
+       : current_function_outgoing_args_size)
 
 /* Structure to be filled in by compute_frame_size with register
    save masks, and offsets for the current function.  */
@@ -1522,8 +1543,69 @@ extern struct mips_frame_info current_frame_info;
    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.  */
 
-#define INITIAL_FRAME_POINTER_OFFSET(VAR)                              \
- ((VAR) = compute_frame_size (get_frame_size ()))
+/* #define INITIAL_FRAME_POINTER_OFFSET(VAR)                           \
+    ((VAR) = compute_frame_size (get_frame_size ())) */
+
+/* If defined, this macro specifies a table of register pairs used to
+   eliminate unneeded registers that point into the stack frame.  If
+   it is not defined, the only elimination attempted by the compiler
+   is to replace references to the frame pointer with references to
+   the stack pointer.
+
+   The definition of this macro is a list of structure
+   initializations, each of which specifies an original and
+   replacement register.
+
+   On some machines, the position of the argument pointer is not
+   known until the compilation is completed.  In such a case, a
+   separate hard register must be used for the argument pointer. 
+   This register can be eliminated by replacing it with either the
+   frame pointer or the argument pointer, depending on whether or not
+   the frame pointer has been eliminated.
+
+   In this case, you might specify:
+        #define ELIMINABLE_REGS  \
+        {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+         {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
+         {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
+
+   Note that the elimination of the argument pointer with the stack
+   pointer is specified first since that is the preferred elimination.  */
+
+#define ELIMINABLE_REGS                                                        \
+{{ ARG_POINTER_REGNUM,   STACK_POINTER_REGNUM},                                \
+ { ARG_POINTER_REGNUM,   FRAME_POINTER_REGNUM},                                \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
+
+
+/* A C expression that returns non-zero if the compiler is allowed to
+   try to replace register number FROM-REG with register number
+   TO-REG.  This macro need only be defined if `ELIMINABLE_REGS' is
+   defined, and will usually be the constant 1, since most of the
+   cases preventing register elimination are things that the compiler
+   already knows about.  */
+
+#define CAN_ELIMINATE(FROM, TO)                                                \
+  (!frame_pointer_needed                                               \
+   || ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM))
+
+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'.  It
+   specifies the initial difference between the specified pair of
+   registers.  This macro must be defined if `ELIMINABLE_REGS' is
+   defined.  */
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                    \
+{  compute_frame_size (get_frame_size ());                              \
+  if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM)   \
+    (OFFSET) = 0;                                                       \
+  else if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \
+    (OFFSET) = current_frame_info.total_size;                           \
+  else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
+    (OFFSET) = current_frame_info.total_size;                           \
+  else                                                                  \
+    abort ();                                                           \
+}
+
 
 /* If we generate an insn to push BYTES bytes,
    this says how many the stack pointer really advances by.
@@ -1780,18 +1862,19 @@ typedef struct mips_args {
   (get_attr_dslot (INSN) == DSLOT_NO                                   \
    && get_attr_length (INSN) == 1                                      \
    && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (INSN))            \
-   && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (INSN)))
+   && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (INSN))            \
+   && ! reg_mentioned_p (arg_pointer_rtx, PATTERN (INSN)))
 
 /* Tell prologue and epilogue if register REGNO should be saved / restored.  */
 
 #define MUST_SAVE_REGISTER(regno) \
  ((regs_ever_live[regno] && !call_used_regs[regno])            \
   || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)   \
-  || (regno == 31 && regs_ever_live[31]))
+  || (regno == (GP_REG_FIRST + 31) && regs_ever_live[GP_REG_FIRST + 31]))
 
 /* ALIGN FRAMES on double word boundaries */
 
-#define MIPS_STACK_ALIGN(LOC) (((LOC)+7) & 0xfffffff8)
+#define MIPS_STACK_ALIGN(LOC) (((LOC)+7) & ~7)
 
 \f
 /* Output assembler code to FILE to increment profiler label # LABELNO
@@ -2918,8 +3001,7 @@ while (0)
        $Lb[0-9]+       Begin blocks for MIPS debug support
        $Lc[0-9]+       Label for use in s<xx> operation.
        $Le[0-9]+       End blocks for MIPS debug support
-       $Lp\..+         Half-pic labels.
-       $Ls[0-9]+       FP-SP difference if -fomit-frame-pointer  */
+       $Lp\..+         Half-pic labels. */
 
 /* This is how to output the definition of a user-level label named NAME,
    such as the label on a static function or variable NAME.
index e8e15d6..dd3f9f7 100644 (file)
@@ -45,7 +45,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        \n mips-tfile %{v*: -v} %{d*} \
                        %{K: -I %b.o~} \
                        %{!K: %{save-temps: -I %b.o~}} \
-                       %{c:%W{o*}%{!o*:-o %b.o}}%{!c:-o %u.o} \
+                       %{c:%W{o*}%{!o*:-o %b.o}}%{!c:-o %U.o} \
                        %{.s:%i} %{!.s:%g.s}}}"
 
 #define CPP_SPEC "\