combine.c (force_to_mode): Remove STACK_BIAS code.
authorRichard Henderson <rth@redhat.com>
Mon, 4 Feb 2002 18:16:07 +0000 (10:16 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 4 Feb 2002 18:16:07 +0000 (10:16 -0800)
        * combine.c (force_to_mode): Remove STACK_BIAS code.
        (nonzero_bits): Likewise.  Replace sp/fp special case with
        REGNO_POINTER_ALIGN.

        * config/sparc/sparc.h (FRAME_POINTER_REGNUM): Change to SFP.
        (HARD_FRAME_POINTER_REGNUM): New.
        (FIRST_PSEUDO_REGISTER, REG_CLASS_CONTENTS): Update.
        (FIXED_REGS, CALL_USED_REGS): Update.
        (REG_ALLOC_ORDER, REGISTER_NAMES): Update.
        (CONDITIONAL_REGISTER_USAGE): Update for HFP.
        (HARD_REGNO_NREGS): Update for SFP.
        (STACK_POINTER_OFFSET): Include bias here ...
        (FIRST_PARM_OFFSET): ... not here.
        (STACK_BIAS): Remove.
        (INIT_EXPANDERS): New.
        (STARTING_FRAME_OFFSET): Do not include bias.
        (ELIMINABLE_REGS, CAN_ELIMINATE, INITIAL_ELIMINATION_OFFSET): New.
        (REGNO_OK_FOR_INDEX_P, REGNO_OK_FOR_BASE_P): Update for SFP.
        (REG_OK_FOR_INDEX_P, REG_OK_FOR_BASE_P): Likewise.
        * config/sparc/aout.h (DBX_REGISTER_NUMBER): Update for HFP.
        * config/sparc/litecoff.h, config/sparc/sol2.h: Likewise.
        * config/sparc/sparc.c (mem_min_alignment): Update for HFP.
        (sparc_nonflat_function_prologue, epilogue_renumber): Likewise.
        (MUST_SAVE_REGISTER): Likewise.
        (sparc_flat_function_prologue): Likewise.
        (sparc_flat_function_epilogue): Likewise.
        (HARD_FRAME_POINTER_MASK): Rename from FRAME_POINTER_MASK.
        (sparc_init_modes): SFP is GENERAL_REGS.
        (sparc_builtin_saveregs): SFP does not have bias applied.

From-SVN: r49486

gcc/ChangeLog
gcc/combine.c
gcc/config/sparc/aout.h
gcc/config/sparc/litecoff.h
gcc/config/sparc/sol2.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h

index 919a4081be80d5af355977f881fad046ebdc43bb..e55ca94e7e8b0706eefa389d06d64259a4e8eb98 100644 (file)
@@ -1,3 +1,35 @@
+2002-02-04  Richard Henderson  <rth@redhat.com>
+
+       * combine.c (force_to_mode): Remove STACK_BIAS code.
+       (nonzero_bits): Likewise.  Replace sp/fp special case with
+       REGNO_POINTER_ALIGN.
+
+       * config/sparc/sparc.h (FRAME_POINTER_REGNUM): Change to SFP.
+       (HARD_FRAME_POINTER_REGNUM): New.
+       (FIRST_PSEUDO_REGISTER, REG_CLASS_CONTENTS): Update.
+       (FIXED_REGS, CALL_USED_REGS): Update.
+       (REG_ALLOC_ORDER, REGISTER_NAMES): Update.
+       (CONDITIONAL_REGISTER_USAGE): Update for HFP.
+       (HARD_REGNO_NREGS): Update for SFP.
+       (STACK_POINTER_OFFSET): Include bias here ...
+       (FIRST_PARM_OFFSET): ... not here.
+       (STACK_BIAS): Remove.
+       (INIT_EXPANDERS): New.
+       (STARTING_FRAME_OFFSET): Do not include bias.
+       (ELIMINABLE_REGS, CAN_ELIMINATE, INITIAL_ELIMINATION_OFFSET): New.
+       (REGNO_OK_FOR_INDEX_P, REGNO_OK_FOR_BASE_P): Update for SFP.
+       (REG_OK_FOR_INDEX_P, REG_OK_FOR_BASE_P): Likewise.
+       * config/sparc/aout.h (DBX_REGISTER_NUMBER): Update for HFP.
+       * config/sparc/litecoff.h, config/sparc/sol2.h: Likewise.
+       * config/sparc/sparc.c (mem_min_alignment): Update for HFP.
+       (sparc_nonflat_function_prologue, epilogue_renumber): Likewise.
+       (MUST_SAVE_REGISTER): Likewise.
+       (sparc_flat_function_prologue): Likewise.
+       (sparc_flat_function_epilogue): Likewise.
+       (HARD_FRAME_POINTER_MASK): Rename from FRAME_POINTER_MASK.
+       (sparc_init_modes): SFP is GENERAL_REGS.
+       (sparc_builtin_saveregs): SFP does not have bias applied.
+
 2002-02-04  Richard Henderson  <rth@redhat.com>
 
        * config/alpha/alpha.c (current_function_is_thunk): Don't check
index 25b4d63d0f0ef4120b9d2853dbcdb43bbc3f43e8..7662b9b69087028db46d5f11be593332a09cd813 100644 (file)
@@ -6753,33 +6753,12 @@ force_to_mode (x, mode, mask, reg, just_select)
          smask |= (HOST_WIDE_INT) -1 << width;
 
        if (GET_CODE (XEXP (x, 1)) == CONST_INT
-           && exact_log2 (- smask) >= 0)
-         {
-#ifdef STACK_BIAS
-           if (STACK_BIAS
-               && (XEXP (x, 0) == stack_pointer_rtx
-                   || XEXP (x, 0) == frame_pointer_rtx))
-             {
-               int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
-               unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK (mode);
-
-               sp_mask &= ~(sp_alignment - 1);
-               if ((sp_mask & ~smask) == 0
-                   && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~smask) != 0)
-                 return force_to_mode (plus_constant (XEXP (x, 0),
-                                                      ((INTVAL (XEXP (x, 1)) -
-                                                        STACK_BIAS) & smask)
-                                                      + STACK_BIAS),
-                                       mode, smask, reg, next_select);
-             }
-#endif
-           if ((nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
-               && (INTVAL (XEXP (x, 1)) & ~smask) != 0)
-             return force_to_mode (plus_constant (XEXP (x, 0),
-                                                  (INTVAL (XEXP (x, 1))
-                                                   & smask)),
-                                   mode, smask, reg, next_select);
-         }
+           && exact_log2 (- smask) >= 0
+           && (nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
+           && (INTVAL (XEXP (x, 1)) & ~smask) != 0)
+         return force_to_mode (plus_constant (XEXP (x, 0),
+                                              (INTVAL (XEXP (x, 1)) & smask)),
+                               mode, smask, reg, next_select);
       }
 
       /* ... fall through ...  */
@@ -7916,40 +7895,23 @@ nonzero_bits (x, mode)
        nonzero &= GET_MODE_MASK (ptr_mode);
 #endif
 
-#ifdef STACK_BOUNDARY
-      /* If this is the stack pointer, we may know something about its
-        alignment.  If PUSH_ROUNDING is defined, it is possible for the
-        stack to be momentarily aligned only to that amount, so we pick
-        the least alignment.  */
-
-      /* We can't check for arg_pointer_rtx here, because it is not
-        guaranteed to have as much alignment as the stack pointer.
-        In particular, in the Irix6 n64 ABI, the stack has 128 bit
-        alignment but the argument pointer has only 64 bit alignment.  */
-
-      if ((x == frame_pointer_rtx
-          || x == stack_pointer_rtx
-          || x == hard_frame_pointer_rtx
-          || (REGNO (x) >= FIRST_VIRTUAL_REGISTER
-              && REGNO (x) <= LAST_VIRTUAL_REGISTER))
-#ifdef STACK_BIAS
-         && !STACK_BIAS
-#endif
-             )
+      /* Include declared information about alignment of pointers.  */
+
+      if (REG_POINTER (x) && REGNO_POINTER_ALIGN (REGNO (x)))
        {
-         int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
+         unsigned HOST_WIDE_INT alignment
+           = REGNO_POINTER_ALIGN (REGNO (x)) / BITS_PER_UNIT;
 
 #ifdef PUSH_ROUNDING
-         if (REGNO (x) == STACK_POINTER_REGNUM && PUSH_ARGS)
-           sp_alignment = MIN (PUSH_ROUNDING (1), sp_alignment);
+         /* If PUSH_ROUNDING is defined, it is possible for the
+            stack to be momentarily aligned only to that amount,
+            so we pick the least alignment.  */
+         if (x == stack_pointer_rtx && PUSH_ARGS)
+           alignment = MIN (PUSH_ROUNDING (1), alignment);
 #endif
 
-         /* We must return here, otherwise we may get a worse result from
-            one of the choices below.  There is nothing useful below as
-            far as the stack pointer is concerned.  */
-         return nonzero &= ~(sp_alignment - 1);
+         nonzero &= ~(alignment - 1);
        }
-#endif
 
       /* If X is a register whose nonzero bits value is current, use it.
         Otherwise, if X is a register whose value we can find, use that
@@ -7964,7 +7926,7 @@ nonzero_bits (x, mode)
                  && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
                                        REGNO (x))))
          && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
-       return reg_last_set_nonzero_bits[REGNO (x)];
+       return reg_last_set_nonzero_bits[REGNO (x)] & nonzero;
 
       tem = get_last_value (x);
 
@@ -7990,7 +7952,7 @@ nonzero_bits (x, mode)
                           | ((HOST_WIDE_INT) (-1)
                              << GET_MODE_BITSIZE (GET_MODE (x))));
 #endif
-         return nonzero_bits (tem, mode);
+         return nonzero_bits (tem, mode) & nonzero;
        }
       else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)])
        {
@@ -8128,22 +8090,6 @@ nonzero_bits (x, mode)
        switch (code)
          {
          case PLUS:
-#ifdef STACK_BIAS
-           if (STACK_BIAS
-               && (XEXP (x, 0) == stack_pointer_rtx
-                   || XEXP (x, 0) == frame_pointer_rtx)
-               && GET_CODE (XEXP (x, 1)) == CONST_INT)
-             {
-               int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
-
-               nz0 = (GET_MODE_MASK (mode) & ~(sp_alignment - 1));
-               nz1 = INTVAL (XEXP (x, 1)) - STACK_BIAS;
-               width0 = floor_log2 (nz0) + 1;
-               width1 = floor_log2 (nz1) + 1;
-               low0 = floor_log2 (nz0 & -nz0);
-               low1 = floor_log2 (nz1 & -nz1);
-             }
-#endif
            result_width = MAX (width0, width1) + 1;
            result_low = MIN (low0, low1);
            break;
index fd84d75244b0d108c28a0ef8ad49dcc12f21f8fd..3a2273f488bfa4fac90df0e4dc5a9ddae6bd9e02 100644 (file)
@@ -88,7 +88,7 @@ do {                                                                  \
    pointer is really %i7.  */
 
 #define DBX_REGISTER_NUMBER(REGNO) \
-  (TARGET_FLAT && REGNO == FRAME_POINTER_REGNUM ? 31 : REGNO)
+  (TARGET_FLAT && (REGNO) == HARD_FRAME_POINTER_REGNUM ? 31 : REGNO)
 
 /* This is how to output a note to DBX telling it the line number
    to which the following sequence of instructions corresponds.
index dede792e69bb068e00de7e49499210075f37a841..ad0e1225db41fd3004476650ee3b7989740cf6a1 100644 (file)
@@ -73,4 +73,4 @@ do {                                                                  \
    pointer is really %i7.  */
 
 #define DBX_REGISTER_NUMBER(REGNO) \
-  (TARGET_FLAT && REGNO == FRAME_POINTER_REGNUM ? 31 : REGNO)
+  (TARGET_FLAT && (REGNO) == HARD_FRAME_POINTER_REGNUM ? 31 : REGNO)
index 46e80c121cb7bb66a007e85f6d2989ce7d9447b5..a387dc24a1885a09f7fa20367c4e1465814ed902 100644 (file)
@@ -83,7 +83,7 @@ Boston, MA 02111-1307, USA.  */
 #undef DBX_REGISTER_NUMBER
 /* Same as sparc.h */
 #define DBX_REGISTER_NUMBER(REGNO) \
-  (TARGET_FLAT && REGNO == FRAME_POINTER_REGNUM ? 31 : REGNO)
+  (TARGET_FLAT && (REGNO) == HARD_FRAME_POINTER_REGNUM ? 31 : REGNO)
 
 /* We use stabs-in-elf for debugging, because that is what the native
    toolchain uses.  */
index c5b64a7b71dc14c2cfcbacd9de43ec2c4c131cad..4017ae7af8df0d92aa6da3c4620643e88b625f1d 100644 (file)
@@ -83,10 +83,9 @@ static rtx leaf_label;
 
 #ifdef LEAF_REGISTERS
 
-/* Vector to say how input registers are mapped to output
-   registers.  FRAME_POINTER_REGNUM cannot be remapped by
-   this function to eliminate it.  You must use -fomit-frame-pointer
-   to get that.  */
+/* Vector to say how input registers are mapped to output registers.
+   HARD_FRAME_POINTER_REGNUM cannot be remapped by this function to
+   eliminate it.  You must use -fomit-frame-pointer to get that.  */
 const char leaf_reg_remap[] =
 { 0, 1, 2, 3, 4, 5, 6, 7,
   -1, -1, -1, -1, -1, -1, 14, -1,
@@ -2988,8 +2987,7 @@ mem_min_alignment (mem, desired)
     {
       int regno = REGNO (base);
 
-      if (regno != FRAME_POINTER_REGNUM
-         && regno != STACK_POINTER_REGNUM)
+      if (regno != HARD_FRAME_POINTER_REGNUM && regno != STACK_POINTER_REGNUM)
        {
          /* Check if the compiler has recorded some information
             about the alignment of the base REG.  If reload has
@@ -3206,7 +3204,7 @@ sparc_init_modes ()
     {
       if (i < 16 && TARGET_V8PLUS)
        sparc_regno_reg_class[i] = I64_REGS;
-      else if (i < 32)
+      else if (i < 32 || i == FRAME_POINTER_REGNUM)
        sparc_regno_reg_class[i] = GENERAL_REGS;
       else if (i < 64)
        sparc_regno_reg_class[i] = FP_REGS;
@@ -3554,7 +3552,7 @@ sparc_nonflat_function_prologue (file, size, leaf_function)
 
       /* The canonical frame address refers to the top of the frame.  */
       dwarf2out_def_cfa (label, (leaf_function ? STACK_POINTER_REGNUM
-                                : FRAME_POINTER_REGNUM),
+                                : HARD_FRAME_POINTER_REGNUM),
                         frame_base_offset);
 
       if (! leaf_function)
@@ -4862,7 +4860,7 @@ sparc_builtin_saveregs ()
     emit_move_insn (gen_rtx_MEM (word_mode,
                                 gen_rtx_PLUS (Pmode,
                                               frame_pointer_rtx,
-                                              GEN_INT (STACK_POINTER_OFFSET
+                                              GEN_INT (FIRST_PARM_OFFSET (0)
                                                        + (UNITS_PER_WORD
                                                           * regno)))),
                    gen_rtx_REG (word_mode,
@@ -4870,7 +4868,7 @@ sparc_builtin_saveregs ()
 
   address = gen_rtx_PLUS (Pmode,
                          frame_pointer_rtx,
-                         GEN_INT (STACK_POINTER_OFFSET
+                         GEN_INT (FIRST_PARM_OFFSET (0)
                                   + UNITS_PER_WORD * first_reg));
 
   return address;
@@ -5483,7 +5481,7 @@ epilogue_renumber (where, test)
         are in the return delayed slot.  */
     case PLUS:
       if (GET_CODE (XEXP (*where, 0)) == REG
-         && REGNO (XEXP (*where, 0)) == FRAME_POINTER_REGNUM
+         && REGNO (XEXP (*where, 0)) == HARD_FRAME_POINTER_REGNUM
          && (GET_CODE (XEXP (*where, 1)) != CONST_INT
              || INTVAL (XEXP (*where, 1)) < SPARC_STACK_BIAS))
        return 1;
@@ -5492,7 +5490,7 @@ epilogue_renumber (where, test)
     case MEM:
       if (SPARC_STACK_BIAS
          && GET_CODE (XEXP (*where, 0)) == REG
-         && REGNO (XEXP (*where, 0)) == FRAME_POINTER_REGNUM)
+         && REGNO (XEXP (*where, 0)) == HARD_FRAME_POINTER_REGNUM)
        return 1;
       break;
 
@@ -6437,12 +6435,12 @@ struct sparc_frame_info zero_frame_info;
 /* Tell prologue and epilogue if register REGNO should be saved / restored.  */
 
 #define RETURN_ADDR_REGNUM 15
-#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
+#define HARD_FRAME_POINTER_MASK (1 << (HARD_FRAME_POINTER_REGNUM))
 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
 
 #define MUST_SAVE_REGISTER(regno) \
- ((regs_ever_live[regno] && !call_used_regs[regno])            \
-  || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)   \
+ ((regs_ever_live[regno] && !call_used_regs[regno])                    \
+  || (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)      \
   || (regno == RETURN_ADDR_REGNUM && regs_ever_live[RETURN_ADDR_REGNUM]))
 
 /* Return the bytes needed to compute the frame pointer from the current
@@ -6715,7 +6713,7 @@ sparc_flat_function_prologue (file, size)
   if (size > 0)
     {
       unsigned int reg_offset = current_frame_info.reg_offset;
-      const char *const fp_str = reg_names[FRAME_POINTER_REGNUM];
+      const char *const fp_str = reg_names[HARD_FRAME_POINTER_REGNUM];
       static const char *const t1_str = "%g1";
 
       /* Things get a little tricky if local variables take up more than ~4096
@@ -6736,7 +6734,7 @@ sparc_flat_function_prologue (file, size)
            {
              fprintf (file, "\tadd\t%s, %d, %s\n",
                       sp_str, (int) -size, sp_str);
-             if (gmask & FRAME_POINTER_MASK)
+             if (gmask & HARD_FRAME_POINTER_MASK)
                {
                  fprintf (file, "\tst\t%s, [%s+%d]\n",
                           fp_str, sp_str, reg_offset);
@@ -6751,7 +6749,7 @@ sparc_flat_function_prologue (file, size)
              fprintf (file, HOST_WIDE_INT_PRINT_DEC, size);
              fprintf (file, ", %s\n\tsub\t%s, %s, %s\n",
                       t1_str, sp_str, t1_str, sp_str);
-             if (gmask & FRAME_POINTER_MASK)
+             if (gmask & HARD_FRAME_POINTER_MASK)
                {
                  fprintf (file, "\tst\t%s, [%s+%d]\n",
                           fp_str, sp_str, reg_offset);
@@ -6763,11 +6761,11 @@ sparc_flat_function_prologue (file, size)
          if (dwarf2out_do_frame ())
            {
              char *l = dwarf2out_cfi_label ();
-             if (gmask & FRAME_POINTER_MASK)
+             if (gmask & HARD_FRAME_POINTER_MASK)
                {
-                 dwarf2out_reg_save (l, FRAME_POINTER_REGNUM,
+                 dwarf2out_reg_save (l, HARD_FRAME_POINTER_REGNUM,
                                      reg_offset - 4 - size);
-                 dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, 0);
+                 dwarf2out_def_cfa (l, HARD_FRAME_POINTER_REGNUM, 0);
                }
              else
                dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, size);
@@ -6781,7 +6779,7 @@ sparc_flat_function_prologue (file, size)
              reg_offset += 4;
            }
          sparc_flat_save_restore (file, sp_str, reg_offset,
-                                  gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
+                                  gmask & ~(HARD_FRAME_POINTER_MASK | RETURN_ADDR_MASK),
                                   current_frame_info.fmask,
                                   "st", "std", -size);
        }
@@ -6798,7 +6796,7 @@ sparc_flat_function_prologue (file, size)
            {
              fprintf (file, "\tadd\t%s, %d, %s\n",
                       sp_str, (int) -size1, sp_str);
-             if (gmask & FRAME_POINTER_MASK)
+             if (gmask & HARD_FRAME_POINTER_MASK)
                {
                  fprintf (file, "\tst\t%s, [%s+%d]\n\tsub\t%s, %d, %s\t%s# set up frame pointer\n",
                           fp_str, sp_str, (int) offset, sp_str, (int) -size1,
@@ -6812,7 +6810,7 @@ sparc_flat_function_prologue (file, size)
              fprintf (file, HOST_WIDE_INT_PRINT_DEC, size1);
              fprintf (file, ", %s\n\tsub\t%s, %s, %s\n",
                       t1_str, sp_str, t1_str, sp_str);
-             if (gmask & FRAME_POINTER_MASK)
+             if (gmask & HARD_FRAME_POINTER_MASK)
                {
                  fprintf (file, "\tst\t%s, [%s+%d]\n\tadd\t%s, %s, %s\t%s# set up frame pointer\n",
                           fp_str, sp_str, (int) offset, sp_str, t1_str,
@@ -6823,11 +6821,11 @@ sparc_flat_function_prologue (file, size)
          if (dwarf2out_do_frame ())
            {
              char *l = dwarf2out_cfi_label ();
-             if (gmask & FRAME_POINTER_MASK)
+             if (gmask & HARD_FRAME_POINTER_MASK)
                {
-                 dwarf2out_reg_save (l, FRAME_POINTER_REGNUM,
+                 dwarf2out_reg_save (l, HARD_FRAME_POINTER_REGNUM,
                                      offset - 4 - size1);
-                 dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, 0);
+                 dwarf2out_def_cfa (l, HARD_FRAME_POINTER_REGNUM, 0);
                }
              else
                dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, size1);
@@ -6843,7 +6841,7 @@ sparc_flat_function_prologue (file, size)
              offset += 4;
            }
          sparc_flat_save_restore (file, sp_str, offset,
-                                  gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
+                                  gmask & ~(HARD_FRAME_POINTER_MASK | RETURN_ADDR_MASK),
                                   current_frame_info.fmask,
                                   "st", "std", -size1);
          fprintf (file, "\tset\t");
@@ -6851,7 +6849,7 @@ sparc_flat_function_prologue (file, size)
          fprintf (file, ", %s\n\tsub\t%s, %s, %s\n",
                   t1_str, sp_str, t1_str, sp_str);
          if (dwarf2out_do_frame ())
-           if (! (gmask & FRAME_POINTER_MASK))
+           if (! (gmask & HARD_FRAME_POINTER_MASK))
              dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, size);
        }
     }
@@ -6900,7 +6898,7 @@ sparc_flat_function_epilogue (file, size)
       unsigned HOST_WIDE_INT reg_offset = current_frame_info.reg_offset;
       unsigned HOST_WIDE_INT size1;
       const char *const sp_str = reg_names[STACK_POINTER_REGNUM];
-      const char *const fp_str = reg_names[FRAME_POINTER_REGNUM];
+      const char *const fp_str = reg_names[HARD_FRAME_POINTER_REGNUM];
       static const char *const t1_str = "%g1";
 
       /* In the reload sequence, we don't need to fill the load delay
@@ -6946,7 +6944,7 @@ sparc_flat_function_epilogue (file, size)
 
       /* We must restore the frame pointer and return address reg first
         because they are treated specially by the prologue output code.  */
-      if (current_frame_info.gmask & FRAME_POINTER_MASK)
+      if (current_frame_info.gmask & HARD_FRAME_POINTER_MASK)
        {
          fprintf (file, "\tld\t[%s+%d], %s\n",
                   sp_str, (int) reg_offset, fp_str);
@@ -6961,7 +6959,7 @@ sparc_flat_function_epilogue (file, size)
 
       /* Restore any remaining saved registers.  */
       sparc_flat_save_restore (file, sp_str, reg_offset,
-                              current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
+                              current_frame_info.gmask & ~(HARD_FRAME_POINTER_MASK | RETURN_ADDR_MASK),
                               current_frame_info.fmask,
                               "ld", "ldd", 0);
 
index 608b3938d72dd616d8837abc54b46913818e332f..7b793234b1ddbb63126499b7b0f0694c39e9561a 100644 (file)
@@ -894,9 +894,10 @@ if (TARGET_ARCH64                          \
    accessible.  We still account for them to simplify register computations
    (eg: in CLASS_MAX_NREGS).  There are also 4 fp condition code registers, so
    32+32+32+4 == 100.
-   Register 100 is used as the integer condition code register.  */
+   Register 100 is used as the integer condition code register.
+   Register 101 is used as the soft frame pointer register.  */
 
-#define FIRST_PSEUDO_REGISTER 101
+#define FIRST_PSEUDO_REGISTER 102
 
 #define SPARC_FIRST_FP_REG     32
 /* Additional V9 fp regs.  */
@@ -962,7 +963,7 @@ if (TARGET_ARCH64                           \
   0, 0, 0, 0, 0, 0, 0, 0,      \
   0, 0, 0, 0, 0, 0, 0, 0,      \
                                \
-  0, 0, 0, 0, 0}
+  0, 0, 0, 0, 0, 1}
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -987,7 +988,7 @@ if (TARGET_ARCH64                           \
   1, 1, 1, 1, 1, 1, 1, 1,      \
   1, 1, 1, 1, 1, 1, 1, 1,      \
                                \
-  1, 1, 1, 1, 1}
+  1, 1, 1, 1, 1, 1}
 
 /* If !TARGET_FPU, then make the fp registers and fp cc regs fixed so that
    they won't be allocated.  */
@@ -1042,7 +1043,7 @@ do                                                                \
        /* Let the compiler believe the frame pointer is still  \
           %fp, but output it as %i7.  */                       \
        fixed_regs[31] = 1;                                     \
-       reg_names[FRAME_POINTER_REGNUM] = "%i7";                \
+       reg_names[HARD_FRAME_POINTER_REGNUM] = "%i7";           \
        /* Disable leaf functions */                            \
        memset (sparc_leaf_regs, 0, FIRST_PSEUDO_REGISTER);     \
       }                                                                \
@@ -1062,9 +1063,9 @@ while (0)
 
 #define HARD_REGNO_NREGS(REGNO, MODE) \
   (TARGET_ARCH64                                                       \
-   ?  ((REGNO) < 32                                                    \
-       ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD  \
-       : (GET_MODE_SIZE (MODE) + 3) / 4)                               \
+   ? ((REGNO) < 32 || (REGNO) == FRAME_POINTER_REGNUM                  \
+      ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD   \
+      : (GET_MODE_SIZE (MODE) + 3) / 4)                                        \
    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
 /* Due to the ARCH64 descrepancy above we must override this next
@@ -1107,27 +1108,32 @@ extern int sparc_mode_class[];
 /* Register to use for pushing function arguments.  */
 #define STACK_POINTER_REGNUM 14
 
+/* The stack bias (amount by which the hardware register is offset by).  */
+#define SPARC_STACK_BIAS ((TARGET_ARCH64 && TARGET_STACK_BIAS) ? 2047 : 0)
+
 /* Actual top-of-stack address is 92/176 greater than the contents of the
    stack pointer register for !v9/v9.  That is:
    - !v9: 64 bytes for the in and local registers, 4 bytes for structure return
      address, and 6*4 bytes for the 6 register parameters.
    - v9: 128 bytes for the in and local registers + 6*8 bytes for the integer
      parameter regs.  */
-#define STACK_POINTER_OFFSET FIRST_PARM_OFFSET(0)
-
-/* The stack bias (amount by which the hardware register is offset by).  */
-#define SPARC_STACK_BIAS ((TARGET_ARCH64 && TARGET_STACK_BIAS) ? 2047 : 0)
-
-/* Is stack biased? */
-#define STACK_BIAS SPARC_STACK_BIAS
+#define STACK_POINTER_OFFSET (FIRST_PARM_OFFSET(0) + SPARC_STACK_BIAS)
 
 /* Base register for access to local variables of the function.  */
-#define FRAME_POINTER_REGNUM 30
-
-#if 0
-/* Register that is used for the return address for the flat model.  */
-#define RETURN_ADDR_REGNUM 15
-#endif
+#define HARD_FRAME_POINTER_REGNUM 30
+
+/* The soft frame pointer does not have the stack bias applied.  */
+#define FRAME_POINTER_REGNUM 101
+
+/* Given the stack bias, the stack pointer isn't actually aligned.  */
+#define INIT_EXPANDERS                                                  \
+  do {                                                                  \
+    if (cfun && cfun->emit->regno_pointer_align && SPARC_STACK_BIAS)    \
+      {                                                                         \
+       REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = BITS_PER_UNIT;      \
+       REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT; \
+      }                                                                         \
+  } while (0)
 
 /* Value should be nonzero if functions must have frame pointers.
    Zero means the frame pointer need not be set up (and parms
@@ -1138,9 +1144,11 @@ extern int sparc_mode_class[];
    Being a non-leaf function does not mean a frame pointer is needed in the
    flat window model.  However, the debugger won't be able to backtrace through
    us with out it.  */
-#define FRAME_POINTER_REQUIRED \
-  (TARGET_FLAT ? (current_function_calls_alloca || current_function_varargs \
-                 || !leaf_function_p ()) \
+#define FRAME_POINTER_REQUIRED                         \
+  (TARGET_FLAT                                         \
+   ? (current_function_calls_alloca                    \
+      || current_function_varargs                      \
+      || !leaf_function_p ())                          \
    : ! (leaf_function_p () && only_leaf_regs_used ()))
 
 /* C statement to store the difference between the frame pointer
@@ -1275,10 +1283,16 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS,
    This is an initializer for a vector of HARD_REG_SET
    of length N_REG_CLASSES.  */
 
-#define REG_CLASS_CONTENTS \
-  {{0, 0, 0, 0}, {0, 0, 0, 0xf}, {0xffff, 0, 0, 0}, \
-   {-1, 0, 0, 0}, {0, -1, 0, 0}, {0, -1, -1, 0}, \
-   {-1, -1, 0, 0}, {-1, -1, -1, 0}, {-1, -1, -1, 0x1f}}
+#define REG_CLASS_CONTENTS                             \
+  {{0, 0, 0, 0},       /* NO_REGS */                   \
+   {0, 0, 0, 0xf},     /* FPCC_REGS */                 \
+   {0xffff, 0, 0, 0},  /* I64_REGS */                  \
+   {-1, 0, 0, 0x20},   /* GENERAL_REGS */              \
+   {0, -1, 0, 0},      /* FP_REGS */                   \
+   {0, -1, -1, 0},     /* EXTRA_FP_REGS */             \
+   {-1, -1, 0, 0x20},  /* GENERAL_OR_FP_REGS */        \
+   {-1, -1, -1, 0x20}, /* GENERAL_OR_EXTRA_FP_REGS */  \
+   {-1, -1, -1, 0x3f}} /* ALL_REGS */
 
 /* The same information, inverted:
    Return the class number of the smallest class containing
@@ -1310,7 +1324,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
   88, 89, 90, 91, 92, 93, 94, 95,      /* %f56-%f63 */ \
   32, 33,                              /* %f0,%f1 */   \
   96, 97, 98, 99, 100,                 /* %fcc0-3, %icc */ \
-  1, 4, 5, 6, 7, 0, 14, 30}
+  1, 4, 5, 6, 7, 0, 14, 30, 101}
 
 /* This is the order in which to allocate registers for
    leaf functions.  If all registers can fit in the "gi" registers,
@@ -1331,7 +1345,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
   88, 89, 90, 91, 92, 93, 94, 95,      \
   32, 33,                              \
   96, 97, 98, 99, 100,                 \
-  0, 14, 30, 31}
+  0, 14, 30, 31, 101}
   
 #define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
 
@@ -1535,7 +1549,7 @@ extern const char leaf_reg_remap[];
    of the first local allocated.  */
 /* This allows space for one TFmode floating point value.  */
 #define STARTING_FRAME_OFFSET \
-  (TARGET_ARCH64 ? (SPARC_STACK_BIAS - 16) \
+  (TARGET_ARCH64 ? -16 \
    : (-SPARC_STACK_ALIGN (LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)))
 
 /* If we generate an insn to push BYTES bytes,
@@ -1548,13 +1562,11 @@ extern const char leaf_reg_remap[];
    even if this function isn't going to use it.
    v9: This is 128 for the ins and locals.  */
 #define FIRST_PARM_OFFSET(FNDECL) \
-  (TARGET_ARCH64 ? (SPARC_STACK_BIAS + 16 * UNITS_PER_WORD) \
-   : (STRUCT_VALUE_OFFSET + UNITS_PER_WORD))
+  (TARGET_ARCH64 ? 16 * UNITS_PER_WORD : STRUCT_VALUE_OFFSET + UNITS_PER_WORD)
 
 /* Offset from the argument pointer register value to the CFA.
    This is different from FIRST_PARM_OFFSET because the register window
    comes between the CFA and the arguments.  */
-
 #define ARG_POINTER_CFA_OFFSET(FNDECL)  SPARC_STACK_BIAS
 
 /* When a parameter is passed in a register, stack space is still
@@ -1568,6 +1580,17 @@ extern const char leaf_reg_remap[];
    all 6 slots even for v9.  */
 #define REG_PARM_STACK_SPACE(DECL) (6 * UNITS_PER_WORD)
 
+/* Definitions for register elimination.  */
+/* ??? In TARGET_FLAT mode we needn't have a hard frame pointer.  */
+   
+#define ELIMINABLE_REGS \
+  {{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
+
+#define CAN_ELIMINATE(FROM, TO) 1
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+  ((OFFSET) = SPARC_STACK_BIAS)
+
 /* Keep the stack pointer constant throughout the function.
    This is both an optimization and a necessity: longjmp
    doesn't behave itself when the stack pointer moves within
@@ -1996,9 +2019,12 @@ do {                                                                     \
    has been allocated, which happens in local-alloc.c.  */
 
 #define REGNO_OK_FOR_INDEX_P(REGNO) \
-((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32)
-#define REGNO_OK_FOR_BASE_P(REGNO) \
-((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32)
+((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32 \
+ || (REGNO) == FRAME_POINTER_REGNUM                            \
+ || reg_renumber[REGNO] == FRAME_POINTER_REGNUM)
+
+#define REGNO_OK_FOR_BASE_P(REGNO)  REGNO_OK_FOR_INDEX_P (REGNO)
+
 #define REGNO_OK_FOR_FP_P(REGNO) \
   (((unsigned) (REGNO) - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32)) \
    || ((unsigned) reg_renumber[REGNO] - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32)))
@@ -2092,11 +2118,13 @@ do {                                                                    \
 /* Nonzero if X is a hard reg that can be used as an index
    or if it is a pseudo reg.  */
 #define REG_OK_FOR_INDEX_P(X) \
-  (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32))
+  (REGNO (X) < 32                              \
+   || REGNO (X) == FRAME_POINTER_REGNUM                \
+   || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+
 /* Nonzero if X is a hard reg that can be used as a base reg
    or if it is a pseudo reg.  */
-#define REG_OK_FOR_BASE_P(X) \
-  (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32))
+#define REG_OK_FOR_BASE_P(X)  REG_OK_FOR_INDEX_P (X)
 
 /* 'T', 'U' are for aligned memory loads which aren't needed for arch64.  */
 
@@ -2675,7 +2703,7 @@ do {                                                                      \
  "%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",       \
  "%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",       \
  "%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",       \
- "%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc"}
+ "%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc", "%sfp" }
 
 /* Define additional names for use in asm clobbers and asm declarations.  */