]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000.h (FIRST_PSEUDO_REGISTER): Increment.
authorJakub Jelinek <jakub@redhat.com>
Thu, 30 Jun 2005 14:26:32 +0000 (16:26 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 30 Jun 2005 14:26:32 +0000 (16:26 +0200)
* config/rs6000/rs6000.h (FIRST_PSEUDO_REGISTER): Increment.
(DWARF_FRAME_REGISTERS, DWARF_REG_TO_UNWIND_COLUMN): Adjust, so
that addition of sfp doesn't change these.
(FIXED_REGISTERS, CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS,
REG_ALLOC_ORDER): Add sfp.
(INT_REGNO_P): Include FRAME_POINTER_REGNUM.
(FRAME_POINTER_REGNUM): Define to 113.
(HARD_FRAME_POINTER_REGNUM): Define to 31.
(REG_CLASS_CONTENTS, REGNO_REG_CLASS): Add sfp.
(STARTING_FRAME_OFFSET): Set to 0 for FRAME_GROWS_DOWNWARD.
(ELIMINABLE_REGS): Never eliminate to
FRAME_POINTER_REGNUM, but HARD_FRAME_POINTER_REGNUM
instead.  Add eliminations from FRAME_POINTER_REGNUM.
(REGNO_OK_FOR_INDEX_P, REGNO_OK_FOR_BASE_P, INT_REG_OK_FOR_INDEX_P):
Include FRAME_POINTER_REGNUM.
(REGISTER_NAMES): Add sfp.
* config/rs6000/rs6000.c (rs6000_reg_names): Add sfp.
(alt_reg_names): Likewise.
(rs6000_stack_info): Handle FRAME_GROWS_DOWNWARD.
(rs6000_emit_prologue): Use HARD_FRAME_POINTER_REGNUM
instead of FRAME_POINTER_REGNUM.
(rs6000_initial_elimination_offset): Never eliminate to
FRAME_POINTER_REGNUM, but HARD_FRAME_POINTER_REGNUM
instead.  Add elimination offsets from FRAME_POINTER_REGNUM.

From-SVN: r101467

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h

index 2f50e07c6075583f92843a71a3c69d5d3019cbc7..de9323b5c76c52278d468475ea41123f38443f86 100644 (file)
@@ -1,5 +1,30 @@
 2005-06-30  Jakub Jelinek  <jakub@redhat.com>
 
+       * config/rs6000/rs6000.h (FIRST_PSEUDO_REGISTER): Increment.
+       (DWARF_FRAME_REGISTERS, DWARF_REG_TO_UNWIND_COLUMN): Adjust, so
+       that addition of sfp doesn't change these.
+       (FIXED_REGISTERS, CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS,
+       REG_ALLOC_ORDER): Add sfp.
+       (INT_REGNO_P): Include FRAME_POINTER_REGNUM.
+       (FRAME_POINTER_REGNUM): Define to 113.
+       (HARD_FRAME_POINTER_REGNUM): Define to 31.
+       (REG_CLASS_CONTENTS, REGNO_REG_CLASS): Add sfp.
+       (STARTING_FRAME_OFFSET): Set to 0 for FRAME_GROWS_DOWNWARD.
+       (ELIMINABLE_REGS): Never eliminate to
+       FRAME_POINTER_REGNUM, but HARD_FRAME_POINTER_REGNUM
+       instead.  Add eliminations from FRAME_POINTER_REGNUM.
+       (REGNO_OK_FOR_INDEX_P, REGNO_OK_FOR_BASE_P, INT_REG_OK_FOR_INDEX_P):
+       Include FRAME_POINTER_REGNUM.
+       (REGISTER_NAMES): Add sfp.
+       * config/rs6000/rs6000.c (rs6000_reg_names): Add sfp.
+       (alt_reg_names): Likewise.
+       (rs6000_stack_info): Handle FRAME_GROWS_DOWNWARD.
+       (rs6000_emit_prologue): Use HARD_FRAME_POINTER_REGNUM
+       instead of FRAME_POINTER_REGNUM.
+       (rs6000_initial_elimination_offset): Never eliminate to
+       FRAME_POINTER_REGNUM, but HARD_FRAME_POINTER_REGNUM
+       instead.  Add elimination offsets from FRAME_POINTER_REGNUM.
+
        * config/rs6000/sysv4.h (RS6000_VARARGS_AREA): Only return non-zero
        if DEFAULT_ABI == ABI_V4.
 
index 96564e188ab0e7ef32f2c780f460cb7dc0905bef..68cd2b73cdb904a3d8f316ca514cedb1579e5e4f 100644 (file)
@@ -767,7 +767,9 @@ char rs6000_reg_names[][8] =
       "24", "25", "26", "27", "28", "29", "30", "31",
       "vrsave", "vscr",
       /* SPE registers.  */
-      "spe_acc", "spefscr"
+      "spe_acc", "spefscr",
+      /* Soft frame pointer.  */
+      "sfp"
 };
 
 #ifdef TARGET_REGNAMES
@@ -791,7 +793,9 @@ static const char alt_reg_names[][8] =
   "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
   "vrsave", "vscr",
   /* SPE registers.  */
-  "spe_acc", "spefscr"
+  "spe_acc", "spefscr",
+  /* Soft frame pointer.  */
+  "sfp"
 };
 #endif
 \f
@@ -12100,6 +12104,13 @@ rs6000_stack_info (void)
   info_ptr->vars_size    = RS6000_ALIGN (get_frame_size (), 8);
   info_ptr->parm_size    = RS6000_ALIGN (current_function_outgoing_args_size,
                                         TARGET_ALTIVEC ? 16 : 8);
+  if (FRAME_GROWS_DOWNWARD)
+    info_ptr->vars_size
+      += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->varargs_size
+                      + info_ptr->vars_size + info_ptr->parm_size,
+                      ABI_STACK_BOUNDARY / BITS_PER_UNIT)
+        - (info_ptr->fixed_size + info_ptr->varargs_size
+           + info_ptr->vars_size + info_ptr->parm_size);
 
   if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
     info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
@@ -13767,7 +13778,7 @@ rs6000_emit_prologue (void)
   /* Set frame pointer, if needed.  */
   if (frame_pointer_needed)
     {
-      insn = emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),
+      insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
                             sp_reg_rtx);
       RTX_FRAME_RELATED_P (insn) = 1;
     }
@@ -18228,9 +18239,21 @@ rs6000_initial_elimination_offset (int from, int to)
   rs6000_stack_t *info = rs6000_stack_info ();
   HOST_WIDE_INT offset;
 
-  if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+  if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
     offset = info->push_p ? 0 : -info->total_size;
-  else if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
+  else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+    {
+      offset = info->push_p ? 0 : -info->total_size;
+      if (FRAME_GROWS_DOWNWARD)
+       offset += info->fixed_size + info->varargs_size
+                 + info->vars_size + info->parm_size;
+    }
+  else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
+    offset = FRAME_GROWS_DOWNWARD
+            ? info->fixed_size + info->varargs_size
+              + info->vars_size + info->parm_size
+            : 0;
+  else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
     offset = info->total_size;
   else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
     offset = info->push_p ? info->total_size : 0;
index fa7340f393fc53d04b66fbff554947d9f27a8637..725e9d3b2d492f7225aa6a01562e1efcf83de704 100644 (file)
@@ -568,15 +568,18 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    We also create a pseudo register for float/int conversions, that will
    really represent the memory location used.  It is represented here as
    a register, in order to work around problems in allocating stack storage
-   in inline functions.  */
+   in inline functions.
 
-#define FIRST_PSEUDO_REGISTER 113
+   Another pseudo (not included in DWARF_FRAME_REGISTERS) is soft frame
+   pointer, which is eventually eliminated in favor of SP or FP.  */
+
+#define FIRST_PSEUDO_REGISTER 114
 
 /* This must be included for pre gcc 3.0 glibc compatibility.  */
 #define PRE_GCC3_DWARF_FRAME_REGISTERS 77
 
 /* Add 32 dwarf columns for synthetic SPE registers.  */
-#define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER + 32)
+#define DWARF_FRAME_REGISTERS ((FIRST_PSEUDO_REGISTER - 1) + 32)
 
 /* The SPE has an additional 32 synthetic registers, with DWARF debug
    info numbering for these registers starting at 1200.  While eh_frame
@@ -592,7 +595,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    We must map them here to avoid huge unwinder tables mostly consisting
    of unused space.  */
 #define DWARF_REG_TO_UNWIND_COLUMN(r) \
-  ((r) > 1200 ? ((r) - 1200 + FIRST_PSEUDO_REGISTER) : (r))
+  ((r) > 1200 ? ((r) - 1200 + FIRST_PSEUDO_REGISTER - 1) : (r))
 
 /* Use gcc hard register numbering for eh_frame.  */
 #define DWARF_FRAME_REGNUM(REGNO) (REGNO)
@@ -617,7 +620,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    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, 0, 0, 0, 0, 0, 0, \
    1, 1                                                   \
-   , 1, 1                                          \
+   , 1, 1, 1                                       \
 }
 
 /* 1 for registers not available across function calls.
@@ -637,7 +640,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    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, 0, 0, 0, 0, 0, 0, \
    1, 1                                                   \
-   , 1, 1                                          \
+   , 1, 1, 1                                       \
 }
 
 /* Like `CALL_USED_REGISTERS' except this macro doesn't require that
@@ -656,7 +659,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    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, 0, 0, 0, 0, 0, 0, \
    0, 0                                                   \
-   , 0, 0                                          \
+   , 0, 0, 0                                       \
 }
 
 #define MQ_REGNO     64
@@ -708,6 +711,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
        v31 - v20       (saved; order given to save least number)
        vrsave, vscr    (fixed)
        spe_acc, spefscr (fixed)
+       sfp             (fixed)
 */
 
 #if FIXED_R2 == 1
@@ -739,7 +743,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    96, 95, 94, 93, 92, 91,                                     \
    108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97,    \
    109, 110,                                                   \
-   111, 112                                                    \
+   111, 112, 113                                               \
 }
 
 /* True if register is floating-point.  */
@@ -752,7 +756,8 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define CR_REGNO_NOT_CR0_P(N) ((N) >= 69 && (N) <= 75)
 
 /* True if register is an integer register.  */
-#define INT_REGNO_P(N) ((N) <= 31 || (N) == ARG_POINTER_REGNUM)
+#define INT_REGNO_P(N) \
+  ((N) <= 31 || (N) == ARG_POINTER_REGNUM || (N) == FRAME_POINTER_REGNUM)
 
 /* SPE SIMD registers are just the GPRs.  */
 #define SPE_SIMD_REGNO_P(N) ((N) <= 31)
@@ -874,7 +879,10 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define STACK_POINTER_REGNUM 1
 
 /* Base register for access to local variables of the function.  */
-#define FRAME_POINTER_REGNUM 31
+#define HARD_FRAME_POINTER_REGNUM 31
+
+/* Base register for access to local variables of the function.  */
+#define FRAME_POINTER_REGNUM 113
 
 /* Value should be nonzero if functions must have frame pointers.
    Zero means the frame pointer need not be set up (and parms
@@ -986,26 +994,26 @@ enum reg_class
 #define REG_CLASS_CONTENTS                                                  \
 {                                                                           \
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */         \
-  { 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */       \
-  { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */     \
+  { 0xfffffffe, 0x00000000, 0x00000008, 0x00020000 }, /* BASE_REGS */       \
+  { 0xffffffff, 0x00000000, 0x00000008, 0x00020000 }, /* GENERAL_REGS */     \
   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */       \
   { 0x00000000, 0x00000000, 0xffffe000, 0x00001fff }, /* ALTIVEC_REGS */     \
   { 0x00000000, 0x00000000, 0x00000000, 0x00002000 }, /* VRSAVE_REGS */             \
   { 0x00000000, 0x00000000, 0x00000000, 0x00004000 }, /* VSCR_REGS */       \
   { 0x00000000, 0x00000000, 0x00000000, 0x00008000 }, /* SPE_ACC_REGS */     \
   { 0x00000000, 0x00000000, 0x00000000, 0x00010000 }, /* SPEFSCR_REGS */     \
-  { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
+  { 0xffffffff, 0xffffffff, 0x00000008, 0x00020000 }, /* NON_SPECIAL_REGS */ \
   { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */         \
   { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */       \
   { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */        \
   { 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \
   { 0x00000000, 0x00000000, 0x00000007, 0x00002000 }, /* SPECIAL_REGS */     \
-  { 0xffffffff, 0x00000000, 0x0000000f, 0x00002000 }, /* SPEC_OR_GEN_REGS */ \
+  { 0xffffffff, 0x00000000, 0x0000000f, 0x00022000 }, /* SPEC_OR_GEN_REGS */ \
   { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */        \
   { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */         \
   { 0xffffffff, 0x00000000, 0x0000efff, 0x00000000 }, /* NON_FLOAT_REGS */   \
   { 0x00000000, 0x00000000, 0x00001000, 0x00000000 }, /* XER_REGS */        \
-  { 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff }  /* ALL_REGS */        \
+  { 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff }  /* ALL_REGS */        \
 }
 
 /* The same information, inverted:
@@ -1026,9 +1034,10 @@ enum reg_class
   : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS  \
   : (REGNO) == XER_REGNO ? XER_REGS            \
   : (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS      \
-  : (REGNO) == VSCR_REGNO ? VRSAVE_REGS        \
+  : (REGNO) == VSCR_REGNO ? VRSAVE_REGS                \
   : (REGNO) == SPE_ACC_REGNO ? SPE_ACC_REGS    \
   : (REGNO) == SPEFSCR_REGNO ? SPEFSCR_REGS    \
+  : (REGNO) == FRAME_POINTER_REGNUM ? BASE_REGS        \
   : NO_REGS)
 
 /* The class value for index registers, and the one for base regs.  */
@@ -1262,10 +1271,12 @@ extern enum rs6000_abi rs6000_current_abi;      /* available for use by subtarget */
    outgoing parameter area.  */
 
 #define STARTING_FRAME_OFFSET                                          \
-  (RS6000_ALIGN (current_function_outgoing_args_size,                  \
-                TARGET_ALTIVEC ? 16 : 8)                               \
-   + RS6000_VARARGS_AREA                                               \
-   + RS6000_SAVE_AREA)
+  (FRAME_GROWS_DOWNWARD                                                        \
+   ? 0                                                                 \
+   : (RS6000_ALIGN (current_function_outgoing_args_size,               \
+                   TARGET_ALTIVEC ? 16 : 8)                            \
+      + RS6000_VARARGS_AREA                                            \
+      + RS6000_SAVE_AREA))
 
 /* Offset from the stack pointer register to an item dynamically
    allocated on the stack, e.g., by `alloca'.
@@ -1603,10 +1614,12 @@ typedef struct rs6000_args
    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.  */
-#define ELIMINABLE_REGS                                \
-{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},        \
- { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},  \
- { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM},  \
+#define ELIMINABLE_REGS                                        \
+{{ HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},   \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},                \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},   \
+ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},          \
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},     \
  { RS6000_PIC_OFFSET_TABLE_REGNUM, RS6000_PIC_OFFSET_TABLE_REGNUM } }
 
 /* Given FROM and TO register numbers, say whether this elimination is allowed.
@@ -1646,14 +1659,18 @@ typedef struct rs6000_args
 #define REGNO_OK_FOR_INDEX_P(REGNO)                            \
 ((REGNO) < FIRST_PSEUDO_REGISTER                               \
  ? (REGNO) <= 31 || (REGNO) == 67                              \
+   || (REGNO) == FRAME_POINTER_REGNUM                          \
  : (reg_renumber[REGNO] >= 0                                   \
-    && (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67)))
+    && (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67 \
+       || reg_renumber[REGNO] == FRAME_POINTER_REGNUM)))
 
 #define REGNO_OK_FOR_BASE_P(REGNO)                             \
 ((REGNO) < FIRST_PSEUDO_REGISTER                               \
  ? ((REGNO) > 0 && (REGNO) <= 31) || (REGNO) == 67             \
+   || (REGNO) == FRAME_POINTER_REGNUM                          \
  : (reg_renumber[REGNO] > 0                                    \
-    && (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67)))
+    && (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67 \
+       || reg_renumber[REGNO] == FRAME_POINTER_REGNUM)))
 \f
 /* Maximum number of registers that can appear in a valid memory address.  */
 
@@ -1710,6 +1727,7 @@ typedef struct rs6000_args
   ((! (STRICT)                                                 \
     && (REGNO (X) <= 31                                                \
        || REGNO (X) == ARG_POINTER_REGNUM                      \
+       || REGNO (X) == FRAME_POINTER_REGNUM                    \
        || REGNO (X) >= FIRST_PSEUDO_REGISTER))                 \
    || ((STRICT) && REGNO_OK_FOR_INDEX_P (REGNO (X))))
 
@@ -2188,6 +2206,7 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
   &rs6000_reg_names[110][0],   /* vscr  */                             \
   &rs6000_reg_names[111][0],   /* spe_acc */                           \
   &rs6000_reg_names[112][0],   /* spefscr */                           \
+  &rs6000_reg_names[113][0],   /* sfp  */                              \
 }
 
 /* Table of additional register names to use in user input.  */