OSDN Git Service

2003-11-12 Janis Johnson <janis187@us.ibm.com>
authorjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 12 Nov 2003 22:52:09 +0000 (22:52 +0000)
committerjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 12 Nov 2003 22:52:09 +0000 (22:52 +0000)
* rs6000-protos.h (rs6000_initial_elimination_offset): Add.
(rs6000_stack_info): Remove.  (debug_stack_info): Remove.
(rs6000_emit_eh_reg_restore): Add
* rs6000.c (rs6000_stack_t): Move from rs6000.h, change data type
of vars_size and total_size to HOST_WIDE_INT.
(emit_frame_save): Change parameter size to HOST_WIDE_INT.
(rs6000_stack_info): Make static; change data size to HOST_WIDE_INT.
(debug_stack_info): Make static; change output format of HOST_WIDE_INT
values.
(rs6000_emit_eh_reg_restore): New, with code formerly in rs6000.md.
(rs6000_initial_elimination_offset): New, with code formerly in
INITIAL_ELIMINATION_OFFSET.
* rs6000.h (rs6000_stack_t): Remove.
(INITIAL_ELIMINATION_OFFSET): Replace code with call to function
rs6000_initial_elimination_offset.
* rs6000.md (UNSPECV_EH_RR split): Replace code with call to
rs6000_emit_eh_reg_restore.

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

gcc/ChangeLog
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md

index d3820e4..dfb51cf 100644 (file)
@@ -1,3 +1,23 @@
+2003-11-12  Janis Johnson  <janis187@us.ibm.com>
+
+       * rs6000-protos.h (rs6000_initial_elimination_offset): Add.
+       (rs6000_stack_info): Remove.  (debug_stack_info): Remove.
+       (rs6000_emit_eh_reg_restore): Add
+       * rs6000.c (rs6000_stack_t): Move from rs6000.h, change data type
+       of vars_size and total_size to HOST_WIDE_INT.
+       (emit_frame_save): Change parameter size to HOST_WIDE_INT.
+       (rs6000_stack_info): Make static; change data size to HOST_WIDE_INT.
+       (debug_stack_info): Make static; change output format of HOST_WIDE_INT
+       values.
+       (rs6000_emit_eh_reg_restore): New, with code formerly in rs6000.md.
+       (rs6000_initial_elimination_offset): New, with code formerly in
+       INITIAL_ELIMINATION_OFFSET.
+       * rs6000.h (rs6000_stack_t): Remove.
+       (INITIAL_ELIMINATION_OFFSET): Replace code with call to function
+       rs6000_initial_elimination_offset.
+       * rs6000.md (UNSPECV_EH_RR split): Replace code with call to
+       rs6000_emit_eh_reg_restore.
+
 2003-11-12  Mike Stump  <mrs@apple.com>
 
        * c-typeck.c (c_convert_parm_for_inlining): Add argnum, which
index 2f50d1e..ed13c34 100644 (file)
@@ -134,6 +134,7 @@ extern int rs6000_legitimate_address (enum machine_mode, rtx, int);
 extern bool rs6000_mode_dependent_address (rtx);
 extern rtx rs6000_return_addr (int, rtx);
 extern void rs6000_output_symbol_ref (FILE*, rtx);
+extern HOST_WIDE_INT rs6000_initial_elimination_offset (int, int);
 
 extern rtx rs6000_machopic_legitimize_pic_address (rtx orig, 
                             enum machine_mode mode, rtx reg);
@@ -168,7 +169,6 @@ extern void rs6000_override_options (const char *);
 extern int direct_return (void);
 extern int first_reg_to_save (void);
 extern int first_fp_reg_to_save (void);
-extern rs6000_stack_t *rs6000_stack_info (void);
 extern void output_ascii (FILE *, const char *, int);
 extern void rs6000_gen_section_name (char **, const char *, const char *);
 extern void output_function_profiler (FILE *, int);
@@ -187,7 +187,7 @@ extern void rs6000_emit_prologue (void);
 extern void rs6000_emit_load_toc_table (int);
 extern void rs6000_aix_emit_builtin_unwind_init (void);
 extern void rs6000_emit_epilogue (int);
-extern void debug_stack_info (rs6000_stack_t *);
+extern void rs6000_emit_eh_reg_restore (rtx, rtx);
 extern const char * output_isel (rtx *);
 extern int vrsave_operation (rtx, enum machine_mode);
 extern int rs6000_register_move_cost (enum machine_mode,
index ccbf215..5ca7842 100644 (file)
 #define min(A,B)       ((A) < (B) ? (A) : (B))
 #define max(A,B)       ((A) > (B) ? (A) : (B))
 
+/* Structure used to define the rs6000 stack */
+typedef struct rs6000_stack {
+  int first_gp_reg_save;       /* first callee saved GP register used */
+  int first_fp_reg_save;       /* first callee saved FP register used */
+  int first_altivec_reg_save;  /* first callee saved AltiVec register used */
+  int lr_save_p;               /* true if the link reg needs to be saved */
+  int cr_save_p;               /* true if the CR reg needs to be saved */
+  unsigned int vrsave_mask;    /* mask of vec registers to save */
+  int toc_save_p;              /* true if the TOC needs to be saved */
+  int push_p;                  /* true if we need to allocate stack space */
+  int calls_p;                 /* true if the function makes any calls */
+  enum rs6000_abi abi;         /* which ABI to use */
+  int gp_save_offset;          /* offset to save GP regs from initial SP */
+  int fp_save_offset;          /* offset to save FP regs from initial SP */
+  int altivec_save_offset;     /* offset to save AltiVec regs from initial SP */
+  int lr_save_offset;          /* offset to save LR from initial SP */
+  int cr_save_offset;          /* offset to save CR from initial SP */
+  int vrsave_save_offset;      /* offset to save VRSAVE from initial SP */
+  int spe_gp_save_offset;      /* offset to save spe 64-bit gprs  */
+  int toc_save_offset;         /* offset to save the TOC pointer */
+  int varargs_save_offset;     /* offset to save the varargs registers */
+  int ehrd_offset;             /* offset to EH return data */
+  int reg_size;                        /* register size (4 or 8) */
+  int varargs_size;            /* size to hold V.4 args passed in regs */
+  HOST_WIDE_INT vars_size;     /* variable save area size */
+  int parm_size;               /* outgoing parameter size */
+  int save_size;               /* save area size */
+  int fixed_size;              /* fixed size of stack frame */
+  int gp_size;                 /* size of saved GP registers */
+  int fp_size;                 /* size of saved FP registers */
+  int altivec_size;            /* size of saved AltiVec registers */
+  int cr_size;                 /* size to hold CR if not in save_size */
+  int lr_size;                 /* size to hold LR if not in save_size */
+  int vrsave_size;             /* size to hold VRSAVE if not in save_size */
+  int altivec_padding_size;    /* size of altivec alignment padding if
+                                  not in save_size */
+  int spe_gp_size;             /* size of 64-bit GPR save size for SPE */
+  int spe_padding_size;
+  int toc_size;                        /* size to hold TOC if not in save_size */
+  HOST_WIDE_INT total_size;    /* total bytes allocated for stack */
+  int spe_64bit_regs_used;
+} rs6000_stack_t;
+
 /* Target cpu type */
 
 enum processor_type rs6000_cpu;
@@ -222,7 +265,7 @@ static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
 static rtx spe_synthesize_frame_save (rtx);
 static bool spe_func_has_64bit_regs_p (void);
 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
-                            int, int);
+                            int, HOST_WIDE_INT);
 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int);
 static unsigned rs6000_hash_constant (rtx);
@@ -317,6 +360,8 @@ static rtx spe_expand_builtin (tree, rtx, bool *);
 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
+static rs6000_stack_t *rs6000_stack_info (void);
+static void debug_stack_info (rs6000_stack_t *);
 
 static rtx altivec_expand_builtin (tree, rtx, bool *);
 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
@@ -10269,14 +10314,14 @@ is_altivec_return_reg (rtx reg, void *xyes)
 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
 #endif
 
-rs6000_stack_t *
+static rs6000_stack_t *
 rs6000_stack_info (void)
 {
   static rs6000_stack_t info, zero_info;
   rs6000_stack_t *info_ptr = &info;
   int reg_size = TARGET_POWERPC64 ? 8 : 4;
   int ehrd_size;
-  int total_raw_size;
+  HOST_WIDE_INT total_raw_size;
 
   /* Zero all fields portably.  */
   info = zero_info;
@@ -10608,7 +10653,7 @@ spe_func_has_64bit_regs_p (void)
   return false;
 }
 
-void
+static void
 debug_stack_info (rs6000_stack_t *info)
 {
   const char *abi_string;
@@ -10697,13 +10742,15 @@ debug_stack_info (rs6000_stack_t *info)
     fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
 
   if (info->total_size)
-    fprintf (stderr, "\ttotal_size          = %5d\n", info->total_size);
+    fprintf (stderr, "\ttotal_size          = "HOST_WIDE_INT_PRINT_DEC"\n",
+            info->total_size);
 
   if (info->varargs_size)
     fprintf (stderr, "\tvarargs_size        = %5d\n", info->varargs_size);
 
   if (info->vars_size)
-    fprintf (stderr, "\tvars_size           = %5d\n", info->vars_size);
+    fprintf (stderr, "\tvars_size           = "HOST_WIDE_INT_PRINT_DEC"\n",
+            info->vars_size);
 
   if (info->parm_size)
     fprintf (stderr, "\tparm_size           = %5d\n", info->parm_size);
@@ -10976,6 +11023,42 @@ rs6000_emit_load_toc_table (int fromprolog)
     abort ();
 }
 
+/* Emit instructions to restore the link register after determining where
+   its value has been stored.  */
+
+void
+rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
+{
+  rs6000_stack_t *info = rs6000_stack_info ();
+  rtx operands[2];
+
+  operands[0] = source;
+  operands[1] = scratch;
+
+  if (info->lr_save_p)
+    {
+      rtx frame_rtx = stack_pointer_rtx;
+      HOST_WIDE_INT sp_offset = 0;
+      rtx tmp;
+
+      if (frame_pointer_needed
+         || current_function_calls_alloca
+         || info->total_size > 32767)
+       {
+         emit_move_insn (operands[1], gen_rtx_MEM (Pmode, frame_rtx));
+         frame_rtx = operands[1];
+       }
+      else if (info->push_p)
+       sp_offset = info->total_size;
+
+      tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
+      tmp = gen_rtx_MEM (Pmode, tmp);
+      emit_move_insn (tmp, operands[0]);
+    }
+  else
+    emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
+}
+
 int   
 get_TOC_alias_set (void)
 {
@@ -11374,7 +11457,7 @@ generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
 
 static void
 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode, 
-                unsigned int regno, int offset, int total_size)
+                unsigned int regno, int offset, HOST_WIDE_INT total_size)
 {
   rtx reg, offset_rtx, insn, mem, addr, int_rtx;
   rtx replacea, replaceb;
@@ -15575,6 +15658,28 @@ rs6000_libcall_value (enum machine_mode mode)
   return gen_rtx_REG (mode, regno);
 }
 
+/* Define the offset between two registers, FROM to be eliminated and its
+   replacement TO, at the start of a routine.  */
+HOST_WIDE_INT
+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)
+    offset = info->push_p ? 0 : -info->total_size;
+  else if (from == ARG_POINTER_REGNUM && to == 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;
+  else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
+    offset = 0;
+  else
+    abort ();
+
+  return offset;
+}
+
 /* Return true if TYPE is of type __ev64_opaque__.  */
 
 static bool
index 37d851b..2e93b8a 100644 (file)
@@ -1491,49 +1491,6 @@ enum rs6000_abi {
 
 extern enum rs6000_abi rs6000_current_abi;     /* available for use by subtarget */
 
-/* Structure used to define the rs6000 stack */
-typedef struct rs6000_stack {
-  int first_gp_reg_save;       /* first callee saved GP register used */
-  int first_fp_reg_save;       /* first callee saved FP register used */
-  int first_altivec_reg_save;  /* first callee saved AltiVec register used */
-  int lr_save_p;               /* true if the link reg needs to be saved */
-  int cr_save_p;               /* true if the CR reg needs to be saved */
-  unsigned int vrsave_mask;    /* mask of vec registers to save */
-  int toc_save_p;              /* true if the TOC needs to be saved */
-  int push_p;                  /* true if we need to allocate stack space */
-  int calls_p;                 /* true if the function makes any calls */
-  enum rs6000_abi abi;         /* which ABI to use */
-  int gp_save_offset;          /* offset to save GP regs from initial SP */
-  int fp_save_offset;          /* offset to save FP regs from initial SP */
-  int altivec_save_offset;     /* offset to save AltiVec regs from initial SP */
-  int lr_save_offset;          /* offset to save LR from initial SP */
-  int cr_save_offset;          /* offset to save CR from initial SP */
-  int vrsave_save_offset;      /* offset to save VRSAVE from initial SP */
-  int spe_gp_save_offset;      /* offset to save spe 64-bit gprs  */
-  int toc_save_offset;         /* offset to save the TOC pointer */
-  int varargs_save_offset;     /* offset to save the varargs registers */
-  int ehrd_offset;             /* offset to EH return data */
-  int reg_size;                        /* register size (4 or 8) */
-  int varargs_size;            /* size to hold V.4 args passed in regs */
-  int vars_size;               /* variable save area size */
-  int parm_size;               /* outgoing parameter size */
-  int save_size;               /* save area size */
-  int fixed_size;              /* fixed size of stack frame */
-  int gp_size;                 /* size of saved GP registers */
-  int fp_size;                 /* size of saved FP registers */
-  int altivec_size;            /* size of saved AltiVec registers */
-  int cr_size;                 /* size to hold CR if not in save_size */
-  int lr_size;                 /* size to hold LR if not in save_size */
-  int vrsave_size;             /* size to hold VRSAVE if not in save_size */
-  int altivec_padding_size;    /* size of altivec alignment padding if
-                                  not in save_size */
-  int spe_gp_size;             /* size of 64-bit GPR save size for SPE */
-  int spe_padding_size;
-  int toc_size;                        /* size to hold TOC if not in save_size */
-  int total_size;              /* total bytes allocated for stack */
-  int spe_64bit_regs_used;
-} rs6000_stack_t;
-
 /* Define this if pushing a word on the stack
    makes the stack pointer a smaller address.  */
 #define STACK_GROWS_DOWNWARD
@@ -1984,21 +1941,8 @@ typedef struct rs6000_args
 
 /* 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)                   \
-{                                                                      \
-  rs6000_stack_t *info = rs6000_stack_info ();                         \
-                                                                       \
- if ((FROM) == 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)        \
-   (OFFSET) = info->total_size;                                                \
- else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM)        \
-   (OFFSET) = (info->push_p) ? info->total_size : 0;                   \
-  else if ((FROM) == RS6000_PIC_OFFSET_TABLE_REGNUM)                   \
-    (OFFSET) = 0;                                                      \
-  else                                                                 \
-    abort ();                                                          \
-}
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+  ((OFFSET) = rs6000_initial_elimination_offset(FROM, TO))
 \f
 /* Addressing modes, and classification of registers for them.  */
 
index 57d5694..1c7f38b 100644 (file)
   [(const_int 0)]
   "
 {
-  rs6000_stack_t *info = rs6000_stack_info ();
-
-  if (info->lr_save_p)
-    {
-      rtx frame_rtx = stack_pointer_rtx;
-      int sp_offset = 0;
-      rtx tmp;
-
-      if (frame_pointer_needed
-         || current_function_calls_alloca
-         || info->total_size > 32767)
-       {
-         emit_move_insn (operands[1], gen_rtx_MEM (Pmode, frame_rtx));
-         frame_rtx = operands[1];
-       }
-      else if (info->push_p)
-       sp_offset = info->total_size;
-
-      tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
-      tmp = gen_rtx_MEM (Pmode, tmp);
-      emit_move_insn (tmp, operands[0]);
-    }
-  else
-    emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
+  rs6000_emit_eh_reg_restore (operands[0], operands[1]);
   DONE;
 }")