PR target/45250
authordanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Sep 2010 23:32:06 +0000 (23:32 +0000)
committerdanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Sep 2010 23:32:06 +0000 (23:32 +0000)
* config/pa/pa.md (nonlocal_goto): Restore hard frame pointer using
hard_frame_pointer_rtx instead of virtual_stack_vars_rtx.
(builtin_longjmp): Likewise.
(allocate_stack): Use hard_frame_pointer_rtx instead of
frame_pointer_rtx.
* config/pa/pa-protos.h (pa_initial_elimination_offset): Declare.
* config/pa/pa.c (pa_internal_arg_pointer): Declare.
(pa_can_eliminate): Likewise.
(TARGET_INTERNAL_ARG_POINTER): Define.
(TARGET_CAN_ELIMINATE): Define.
(hppa_expand_prologue): Use hard frame pointer instead of soft frame
pointer.
(hppa_expand_epilogue, pa_eh_return_handler_rtx): Likewise.
(pa_internal_arg_pointer, pa_can_eliminate,
pa_initial_elimination_offset): New.
* config/pa/pa.h (FRAME_POINTER_REGNUM): Set to new general register.
(HARD_FRAME_POINTER_REGNUM): Set to register three.
(INITIAL_FRAME_POINTER_OFFSET): Delete.
(ELIMINABLE_REGS, INITIAL_ELIMINATION_OFFSET, DWARF_FRAME_REGISTERS):
Define.
(DWARF_ALT_FRAME_RETURN_COLUMN, REGNO_OK_FOR_INDEX_P,
REGNO_OK_FOR_BASE_P): Update to include soft frame pointer.
* config/pa/pa32-regs.h (FIRST_PSEUDO_REGISTER): Increase by one.
(FIXED_REGISTERS, CALL_USED_REGISTERS, REG_ALLOC_ORDER,
REG_CLASS_CONTENTS, REGNO_REG_CLASS, REGISTER_NAMES): Update to include
new soft frame pointer.
* config/pa/pa64-regs.h: Likewise.

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

gcc/ChangeLog
gcc/config/pa/pa-protos.h
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pa/pa.md
gcc/config/pa/pa32-regs.h
gcc/config/pa/pa64-regs.h

index f4ebde1..05be760 100644 (file)
@@ -1,3 +1,34 @@
+2010-09-08  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       PR target/45250
+       * config/pa/pa.md (nonlocal_goto): Restore hard frame pointer using
+       hard_frame_pointer_rtx instead of virtual_stack_vars_rtx.
+       (builtin_longjmp): Likewise.
+       (allocate_stack): Use hard_frame_pointer_rtx instead of
+       frame_pointer_rtx.
+       * config/pa/pa-protos.h (pa_initial_elimination_offset): Declare.
+       * config/pa/pa.c (pa_internal_arg_pointer): Declare.
+       (pa_can_eliminate): Likewise.
+       (TARGET_INTERNAL_ARG_POINTER): Define.
+       (TARGET_CAN_ELIMINATE): Define.
+       (hppa_expand_prologue): Use hard frame pointer instead of soft frame
+       pointer.
+       (hppa_expand_epilogue, pa_eh_return_handler_rtx): Likewise.
+       (pa_internal_arg_pointer, pa_can_eliminate,
+       pa_initial_elimination_offset): New.
+       * config/pa/pa.h (FRAME_POINTER_REGNUM): Set to new general register.
+       (HARD_FRAME_POINTER_REGNUM): Set to register three.
+       (INITIAL_FRAME_POINTER_OFFSET): Delete.
+       (ELIMINABLE_REGS, INITIAL_ELIMINATION_OFFSET, DWARF_FRAME_REGISTERS):
+       Define.
+       (DWARF_ALT_FRAME_RETURN_COLUMN, REGNO_OK_FOR_INDEX_P,
+       REGNO_OK_FOR_BASE_P): Update to include soft frame pointer.
+       * config/pa/pa32-regs.h (FIRST_PSEUDO_REGISTER): Increase by one.
+       (FIXED_REGISTERS, CALL_USED_REGISTERS, REG_ALLOC_ORDER,
+       REG_CLASS_CONTENTS, REGNO_REG_CLASS, REGISTER_NAMES): Update to include
+       new soft frame pointer.
+       * config/pa/pa64-regs.h: Likewise.
+
 2010-09-08  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.h (EH_RETURN_DATA_REGNO) Use DX_REG instead of
index 68d7591..8097c58 100644 (file)
@@ -171,6 +171,7 @@ extern void pa_hpux_asm_output_external (FILE *, tree, const char *);
 extern bool pa_cannot_change_mode_class (enum machine_mode, enum machine_mode,
                                         enum reg_class);
 extern bool pa_modes_tieable_p (enum machine_mode, enum machine_mode);
+extern HOST_WIDE_INT pa_initial_elimination_offset (int, int);
 
 extern const int magic_milli[];
 extern int shadd_constant_p (int);
index 9c24f01..754d27a 100644 (file)
@@ -174,6 +174,8 @@ static void pa_trampoline_init (rtx, tree, rtx);
 static rtx pa_trampoline_adjust_address (rtx);
 static rtx pa_delegitimize_address (rtx);
 static bool pa_print_operand_punct_valid_p (unsigned char);
+static rtx pa_internal_arg_pointer (void);
+static bool pa_can_eliminate (const int, const int);
 
 /* The following extra sections are only used for SOM.  */
 static GTY(()) section *som_readonly_data_section;
@@ -360,6 +362,10 @@ static size_t n_deferred_plabels = 0;
 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS pa_trampoline_adjust_address
 #undef TARGET_DELEGITIMIZE_ADDRESS
 #define TARGET_DELEGITIMIZE_ADDRESS pa_delegitimize_address
+#undef TARGET_INTERNAL_ARG_POINTER
+#define TARGET_INTERNAL_ARG_POINTER pa_internal_arg_pointer
+#undef TARGET_CAN_ELIMINATE
+#define TARGET_CAN_ELIMINATE pa_can_eliminate
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
@@ -3762,11 +3768,11 @@ hppa_expand_prologue (void)
             pointer by actual_fsize bytes.  Two versions, first
             handles small (<8k) frames.  The second handles large (>=8k)
             frames.  */
-         insn = emit_move_insn (tmpreg, frame_pointer_rtx);
+         insn = emit_move_insn (tmpreg, hard_frame_pointer_rtx);
          if (DO_FRAME_NOTES)
            RTX_FRAME_RELATED_P (insn) = 1;
 
-         insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
+         insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
          if (DO_FRAME_NOTES)
            RTX_FRAME_RELATED_P (insn) = 1;
 
@@ -3810,7 +3816,7 @@ hppa_expand_prologue (void)
                                       GEN_INT (TARGET_64BIT ? -8 : -4));
 
              emit_move_insn (gen_rtx_MEM (word_mode, addr),
-                             frame_pointer_rtx);
+                             hard_frame_pointer_rtx);
            }
          else
            emit_insn (gen_blockage ());
@@ -3853,7 +3859,7 @@ hppa_expand_prologue (void)
              if (regno == INVALID_REGNUM)
                break;
 
-             store_reg (regno, offset, FRAME_POINTER_REGNUM);
+             store_reg (regno, offset, HARD_FRAME_POINTER_REGNUM);
              offset += UNITS_PER_WORD;
            }
        }
@@ -3861,7 +3867,7 @@ hppa_expand_prologue (void)
       for (i = 18; i >= 4; i--)
        if (df_regs_ever_live_p (i) && ! call_used_regs[i])
          {
-           store_reg (i, offset, FRAME_POINTER_REGNUM);
+           store_reg (i, offset, HARD_FRAME_POINTER_REGNUM);
            offset += UNITS_PER_WORD;
            gr_saved++;
          }
@@ -3950,8 +3956,8 @@ hppa_expand_prologue (void)
         save area.  */
       if (frame_pointer_needed)
        {
-         set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset, 0);
-         base = frame_pointer_rtx;
+         set_reg_plus_d (1, HARD_FRAME_POINTER_REGNUM, offset, 0);
+         base = hard_frame_pointer_rtx;
        }
       else
        {
@@ -4149,7 +4155,7 @@ hppa_expand_epilogue (void)
       ret_off = TARGET_64BIT ? -16 : -20;
       if (frame_pointer_needed)
        {
-         load_reg (2, ret_off, FRAME_POINTER_REGNUM);
+         load_reg (2, ret_off, HARD_FRAME_POINTER_REGNUM);
          ret_off = 0;
        }
       else
@@ -4180,7 +4186,7 @@ hppa_expand_epilogue (void)
              if (regno == INVALID_REGNUM)
                break;
 
-             load_reg (regno, offset, FRAME_POINTER_REGNUM);
+             load_reg (regno, offset, HARD_FRAME_POINTER_REGNUM);
              offset += UNITS_PER_WORD;
            }
        }
@@ -4188,7 +4194,7 @@ hppa_expand_epilogue (void)
       for (i = 18; i >= 4; i--)
        if (df_regs_ever_live_p (i) && ! call_used_regs[i])
          {
-           load_reg (i, offset, FRAME_POINTER_REGNUM);
+           load_reg (i, offset, HARD_FRAME_POINTER_REGNUM);
            offset += UNITS_PER_WORD;
          }
     }
@@ -4247,7 +4253,7 @@ hppa_expand_epilogue (void)
     {
       /* Adjust the register to index off of.  */
       if (frame_pointer_needed)
-       set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset, 0);
+       set_reg_plus_d (1, HARD_FRAME_POINTER_REGNUM, offset, 0);
       else
        set_reg_plus_d (1, STACK_POINTER_REGNUM, offset, 0);
 
@@ -4275,8 +4281,9 @@ hppa_expand_epilogue (void)
     {
       rtx delta = GEN_INT (-64);
 
-      set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64, 0);
-      emit_insn (gen_pre_load (frame_pointer_rtx, stack_pointer_rtx, delta));
+      set_reg_plus_d (STACK_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM, 64, 0);
+      emit_insn (gen_pre_load (hard_frame_pointer_rtx,
+                              stack_pointer_rtx, delta));
     }
   /* If we were deferring a callee register restore, do it now.  */
   else if (merge_sp_adjust_with_load)
@@ -5920,7 +5927,7 @@ pa_eh_return_handler_rtx (void)
 {
   rtx tmp;
 
-  tmp = gen_rtx_PLUS (word_mode, frame_pointer_rtx,
+  tmp = gen_rtx_PLUS (word_mode, hard_frame_pointer_rtx,
                      TARGET_64BIT ? GEN_INT (-16) : GEN_INT (-20));
   tmp = gen_rtx_MEM (word_mode, tmp);
   tmp->volatil = 1;
@@ -10100,4 +10107,48 @@ pa_delegitimize_address (rtx orig_x)
   return x;
 }
 \f
+static rtx
+pa_internal_arg_pointer (void)
+{
+  /* The argument pointer and the hard frame pointer are the same in
+     the 32-bit runtime, so we don't need a copy.  */
+  if (TARGET_64BIT)
+    return copy_to_reg (virtual_incoming_args_rtx);
+  else
+    return virtual_incoming_args_rtx;
+}
+
+/* Given FROM and TO register numbers, say whether this elimination is allowed.
+   Frame pointer elimination is automatically handled.  */
+
+static bool
+pa_can_eliminate (const int from, const int to)
+{
+  /* The argument cannot be eliminated in the 64-bit runtime.  */
+  if (TARGET_64BIT && from == ARG_POINTER_REGNUM)
+    return false;
+
+  return (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM
+          ? ! frame_pointer_needed
+          : true);
+}
+
+/* Define the offset between two registers, FROM to be eliminated and its
+   replacement TO, at the start of a routine.  */
+HOST_WIDE_INT
+pa_initial_elimination_offset (int from, int to)
+{
+  HOST_WIDE_INT offset;
+
+  if ((from == HARD_FRAME_POINTER_REGNUM || from == FRAME_POINTER_REGNUM)
+      && to == STACK_POINTER_REGNUM)
+    offset = -compute_frame_size (get_frame_size (), 0);
+  else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
+    offset = 0;
+  else
+    gcc_unreachable ();
+
+  return offset;
+}
+
 #include "gt-pa.h"
index f8c5357..ae768b2 100644 (file)
@@ -344,8 +344,11 @@ typedef struct GTY(()) machine_function
 /* Register to use for pushing function arguments.  */
 #define STACK_POINTER_REGNUM 30
 
+/* Fixed register for local variable access.  Always eliminated.  */
+#define FRAME_POINTER_REGNUM (TARGET_64BIT ? 61 : 89)
+
 /* Base register for access to local variables of the function.  */
-#define FRAME_POINTER_REGNUM 3
+#define HARD_FRAME_POINTER_REGNUM 3
 
 /* Don't allow hard registers to be renamed into r2 unless r2
    is already live or already being saved (due to eh).  */
@@ -353,15 +356,6 @@ typedef struct GTY(()) machine_function
 #define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \
   ((NEW_REG) != 2 || df_regs_ever_live_p (2) || crtl->calls_eh_return)
 
-/* C statement to store the difference between the frame pointer
-   and the stack pointer values immediately after the function prologue.
-
-   Note, we always pretend that this is a leaf function because if
-   it's not, there's no point in trying to eliminate the
-   frame pointer.  If it is a leaf function, we guessed right!  */
-#define INITIAL_FRAME_POINTER_OFFSET(VAR) \
-  do {(VAR) = - compute_frame_size (get_frame_size (), 0);} while (0)
-
 /* Base register for access to arguments of the function.  */
 #define ARG_POINTER_REGNUM (TARGET_64BIT ? 29 : 3)
 
@@ -385,6 +379,31 @@ extern struct rtx_def *hppa_pic_save_rtx (void);
    is passed to a function.  */
 #define PA_STRUCT_VALUE_REGNUM 28
 
+/* Definitions for register eliminations.
+
+   We have two registers that can be eliminated.  First, the frame pointer
+   register can often be eliminated in favor of the stack pointer register.
+   Secondly, the argument pointer register can always be eliminated in the
+   32-bit runtimes.  */
+
+/* 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.
+
+   The argument pointer cannot be eliminated in the 64-bit runtime.  It
+   is the same register as the hard frame pointer in the 32-bit runtime.
+   So, it does not need to be listed.  */
+#define ELIMINABLE_REGS                                 \
+{{ HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},    \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},         \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM} }
+
+/* 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) = pa_initial_elimination_offset(FROM, TO))
+
 /* Describe how we implement __builtin_eh_return.  */
 #define EH_RETURN_DATA_REGNO(N)        \
   ((N) < 3 ? (N) + 20 : (N) == 3 ? 31 : INVALID_REGNUM)
@@ -394,6 +413,10 @@ extern struct rtx_def *hppa_pic_save_rtx (void);
 /* Offset from the frame pointer register value to the top of stack.  */
 #define FRAME_POINTER_CFA_OFFSET(FNDECL) 0
 
+/* The maximum number of hard registers that can be saved in the call
+   frame.  The soft frame pointer is not included.  */
+#define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER - 1)
+
 /* A C expression whose value is RTL representing the location of the
    incoming return address at the beginning of any function, before the
    prologue.  You only need to define this macro if you want to support
@@ -408,7 +431,7 @@ extern struct rtx_def *hppa_pic_save_rtx (void);
 
    Column 0 is not used but unfortunately its register size is set to
    4 bytes (sizeof CCmode) so it can't be used on 64-bit targets.  */
-#define DWARF_ALT_FRAME_RETURN_COLUMN FIRST_PSEUDO_REGISTER
+#define DWARF_ALT_FRAME_RETURN_COLUMN (FIRST_PSEUDO_REGISTER - 1)
 
 /* This macro chooses the encoding of pointers embedded in the exception
    handling sections.  If at all possible, this should be defined such
@@ -777,12 +800,14 @@ extern int may_call_alloca;
 
 #define REGNO_OK_FOR_INDEX_P(X) \
   ((X) && ((X) < 32                                                    \
-   || (X >= FIRST_PSEUDO_REGISTER                                      \
+   || ((X) == FRAME_POINTER_REGNUM)                                    \
+   || ((X) >= FIRST_PSEUDO_REGISTER                                    \
        && reg_renumber                                                 \
        && (unsigned) reg_renumber[X] < 32)))
 #define REGNO_OK_FOR_BASE_P(X) \
   ((X) && ((X) < 32                                                    \
-   || (X >= FIRST_PSEUDO_REGISTER                                      \
+   || ((X) == FRAME_POINTER_REGNUM)                                    \
+   || ((X) >= FIRST_PSEUDO_REGISTER                                    \
        && reg_renumber                                                 \
        && (unsigned) reg_renumber[X] < 32)))
 #define REGNO_OK_FOR_FP_P(X) \
@@ -931,12 +956,16 @@ extern int may_call_alloca;
 /* 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) \
-  (REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+  (REGNO (X) && (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) \
-  (REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+  (REGNO (X) && (REGNO (X) < 32                                \
+   || REGNO (X) == FRAME_POINTER_REGNUM                                \
+   || REGNO (X) >= FIRST_PSEUDO_REGISTER))
 
 #else
 
index cfe843d..a68989f 100644 (file)
   /* Restore the frame pointer.  The virtual_stack_vars_rtx is saved
      instead of the hard_frame_pointer_rtx in the save area.  As a
      result, an extra instruction is needed to adjust for the offset
-     of the virtual stack variables and the frame pointer.  */
+     of the virtual stack variables and the hard frame pointer.  */
   if (GET_CODE (fp) != REG)
     fp = force_reg (Pmode, fp);
-  emit_move_insn (virtual_stack_vars_rtx, fp);
+  emit_move_insn (hard_frame_pointer_rtx, plus_constant (fp, -8));
 
   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
 
@@ -8517,15 +8517,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
 
   /* Restore the frame pointer.  The virtual_stack_vars_rtx is saved
      instead of the hard_frame_pointer_rtx in the save area.  We need
-     to adjust for the offset between these two values when we have
-     a nonlocal_goto pattern.  When we don't have a nonlocal_goto
-     pattern, the receiver performs the adjustment.  */
-#ifdef HAVE_nonlocal_goto
-  if (HAVE_nonlocal_goto)
-    emit_move_insn (virtual_stack_vars_rtx, force_reg (Pmode, fp));
-  else
-#endif
-    emit_move_insn (hard_frame_pointer_rtx, fp);
+     to adjust for the offset between these two values.  */
+  if (GET_CODE (fp) != REG)
+    fp = force_reg (Pmode, fp);
+  emit_move_insn (hard_frame_pointer_rtx, plus_constant (fp, -8));
 
   /* This bit is the same as expand_builtin_longjmp.  */
   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
@@ -9528,7 +9523,7 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
     {
       addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
                           GEN_INT (TARGET_64BIT ? -8 : -4));
-      emit_move_insn (gen_rtx_MEM (word_mode, addr), frame_pointer_rtx);
+      emit_move_insn (gen_rtx_MEM (word_mode, addr), hard_frame_pointer_rtx);
     }
   if (!TARGET_64BIT && flag_pic)
     {
index 4a2976c..21aa719 100644 (file)
@@ -1,5 +1,5 @@
 /* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008 Free Software Foundation, Inc.
+   2008, 2010 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -43,8 +43,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    has different fp units: define separate register sets for the 1.0
    and 1.1 fp units.  */
 
-#define FIRST_PSEUDO_REGISTER 89  /* 32 general regs + 56 fp regs +
-                                    + 1 shift reg */
+#define FIRST_PSEUDO_REGISTER 90  /* 32 general regs + 56 fp regs +
+                                    + 1 shift reg + frame pointer */
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
@@ -96,7 +96,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   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}
+  /* shift register and soft frame pointer */ \
+  0, 1}
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -117,7 +118,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   0, 0, 0, 0, 1, 1, 1, 1, \
   1, 1, 1, 1, 1, 1, 1, 1, \
   1, 1, 1, 1, 1, 1, 1, 1, \
-  1}
+  /* shift register and soft frame pointer */ \
+  1, 1}
 
 #define CONDITIONAL_REGISTER_USAGE \
 {                                              \
@@ -172,7 +174,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    3,  4,  5,  6,  7,  8,  9, 10,      \
   11, 12, 13, 14, 15, 16, 17, 18,      \
   /* special registers.  */            \
-   1, 30,  0, 88}
+   1, 30,  0, 88, 89}
 
 
 /* Return number of consecutive hard regs needed starting at reg REGNO
@@ -304,12 +306,12 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
 #define REG_CLASS_CONTENTS     \
  {{0x00000000, 0x00000000, 0x00000000},        /* NO_REGS */                   \
   {0x00000002, 0x00000000, 0x00000000},        /* R1_REGS */                   \
-  {0xfffffffe, 0x00000000, 0x00000000},        /* GENERAL_REGS */              \
+  {0xfffffffe, 0x00000000, 0x02000000},        /* GENERAL_REGS */              \
   {0x00000000, 0xff000000, 0x00ffffff},        /* FPUPPER_REGS */              \
   {0x00000000, 0xffffffff, 0x00ffffff},        /* FP_REGS */                   \
-  {0xfffffffe, 0xffffffff, 0x00ffffff},        /* GENERAL_OR_FP_REGS */        \
+  {0xfffffffe, 0xffffffff, 0x02ffffff},        /* GENERAL_OR_FP_REGS */        \
   {0x00000000, 0x00000000, 0x01000000},        /* SHIFT_REGS */                \
-  {0xfffffffe, 0xffffffff, 0x01ffffff}}        /* ALL_REGS */
+  {0xfffffffe, 0xffffffff, 0x03ffffff}}        /* ALL_REGS */
 
 /* The following macro defines cover classes for Integrated Register
    Allocator.  Cover classes is a set of non-intersected register
@@ -336,7 +338,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
 #define REGNO_REG_CLASS(REGNO)                                         \
   ((REGNO) == 0 ? NO_REGS                                              \
    : (REGNO) == 1 ? R1_REGS                                            \
-   : (REGNO) < 32 ? GENERAL_REGS                                       \
+   : (REGNO) < 32 || (REGNO) == 89 ? GENERAL_REGS                      \
    : (REGNO) < 56 ? FP_REGS                                            \
    : (REGNO) < 88 ? FPUPPER_REGS                                       \
    : SHIFT_REGS)
@@ -370,7 +372,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
  "%fr20", "%fr20R", "%fr21", "%fr21R", "%fr22", "%fr22R", "%fr23", "%fr23R", \
  "%fr24", "%fr24R", "%fr25", "%fr25R", "%fr26", "%fr26R", "%fr27", "%fr27R", \
  "%fr28", "%fr28R", "%fr29", "%fr29R", "%fr30", "%fr30R", "%fr31", "%fr31R", \
- "SAR"}
+ "SAR",   "sfp"}
 
 #define ADDITIONAL_REGISTER_NAMES \
 {{"%fr4L",32}, {"%fr5L",34}, {"%fr6L",36}, {"%fr7L",38},               \
index 042e0c4..32e2fa2 100644 (file)
@@ -1,5 +1,5 @@
 /* Configuration for GCC-compiler for PA-RISC.
-   Copyright (C) 1999, 2000, 2003, 2004, 2007, 2008
+   Copyright (C) 1999, 2000, 2003, 2004, 2007, 2008, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -38,8 +38,8 @@ along with GCC; see the file COPYING3.  If not see
    issue as using the halves independently triggers false dependency stalls
    anyway.  */
 
-#define FIRST_PSEUDO_REGISTER 61  /* 32 general regs + 28 fp regs +
-                                    + 1 shift reg */
+#define FIRST_PSEUDO_REGISTER 62  /* 32 general regs + 28 fp regs +
+                                    + 1 shift reg + frame pointer */
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
@@ -79,8 +79,8 @@ along with GCC; see the file COPYING3.  If not see
   0, 0, 0, 0, 0, 0, 0, 0, \
   0, 0, 0, 0, 0, 0, 0, 0, \
   0, 0, 0, 0,            \
-  /* shift register */   \
-  0}
+  /* shift register and soft frame pointer */    \
+  0, 1}
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -98,8 +98,8 @@ along with GCC; see the file COPYING3.  If not see
   0, 0, 0, 0, 0, 0, 0, 0, \
   0, 0, 1, 1, 1, 1, 1, 1, \
   1, 1, 1, 1,            \
-  /* shift register */    \
-  1}
+  /* shift register and soft frame pointer */    \
+  1, 1}
 
 #define CONDITIONAL_REGISTER_USAGE \
 {                                              \
@@ -137,7 +137,7 @@ along with GCC; see the file COPYING3.  If not see
    3,  4,  5,  6,  7,  8,  9, 10,      \
   11, 12, 13, 14, 15, 16, 17, 18,      \
   /* special registers.  */            \
-   1, 27, 30,  0, 60}
+   1, 27, 30,  0, 60, 61}
 
 
 /* Return number of consecutive hard regs needed starting at reg REGNO
@@ -235,12 +235,12 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
 #define REG_CLASS_CONTENTS     \
  {{0x00000000, 0x00000000},    /* NO_REGS */                   \
   {0x00000002, 0x00000000},    /* R1_REGS */                   \
-  {0xfffffffe, 0x00000000},    /* GENERAL_REGS */              \
+  {0xfffffffe, 0x20000000},    /* GENERAL_REGS */              \
   {0x00000000, 0x00000000},    /* FPUPPER_REGS */              \
   {0x00000000, 0x0fffffff},    /* FP_REGS */                   \
-  {0xfffffffe, 0x0fffffff},    /* GENERAL_OR_FP_REGS */        \
+  {0xfffffffe, 0x2fffffff},    /* GENERAL_OR_FP_REGS */        \
   {0x00000000, 0x10000000},    /* SHIFT_REGS */                \
-  {0xfffffffe, 0x1fffffff}}    /* ALL_REGS */
+  {0xfffffffe, 0x3fffffff}}    /* ALL_REGS */
 
 /* The following macro defines cover classes for Integrated Register
    Allocator.  Cover classes is a set of non-intersected register
@@ -267,7 +267,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
 #define REGNO_REG_CLASS(REGNO)                                         \
   ((REGNO) == 0 ? NO_REGS                                              \
    : (REGNO) == 1 ? R1_REGS                                            \
-   : (REGNO) < 32 ? GENERAL_REGS                                       \
+   : (REGNO) < 32 || (REGNO) == 61 ? GENERAL_REGS                      \
    : (REGNO) < 60 ? FP_REGS                                            \
    : SHIFT_REGS)
 
@@ -293,7 +293,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
  "%fr4",  "%fr5",   "%fr6",  "%fr7",   "%fr8",  "%fr9",   "%fr10", "%fr11",  \
  "%fr12", "%fr13",  "%fr14", "%fr15",  "%fr16", "%fr17",  "%fr18", "%fr19",  \
  "%fr20", "%fr21",  "%fr22", "%fr23",  "%fr24", "%fr25",  "%fr26", "%fr27",  \
- "%fr28", "%fr29",  "%fr30", "%fr31", "SAR"}
+ "%fr28", "%fr29",  "%fr30", "%fr31",  "SAR",   "sfp"}
 
 #define ADDITIONAL_REGISTER_NAMES \
  {{"%cr11",60}}