This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [PATCH] -fpic problems on PPC, a different approach


Am Wed, 09 Jun 1999 schrieb Richard Henderson:
>On Wed, Jun 09, 1999 at 06:57:10PM +0200, Franz Sirl wrote:
>> Ok, so nothing to worry about for me. Should I add a comment to
>> rs6000_got_register, explaining that setting regs_ever_live here
>> can go away when flow2 is fixed lifetimewise?
>
>Well, flow2 isn't really broken per se, it's just an ugly problem. 
>Reload's view of what saved registers are live affects the size of
>the register save area, which affects frame elimination offsets. 
>So if flow2 changes the set of live saved registers, all the stack
>offsets wind up skewed and we lose.
>
>But adding a comment isn't ever a bad idea.  ;-)
>
>> >> -      fputs (TARGET_MINIMAL_TOC ? reg_names[30] : reg_names[2], file);
>> >> +      fputs (TARGET_MINIMAL_TOC ? reg_names[30] : reg_names[2 \
>> >> /* PIC_OFFSET_TABLE_REGNUM? */ ], file);
>> >
>> >This is AIX TOC related.  It should not change.
>> >
>> >> -	fprintf (file, "(%s)", reg_names[ TARGET_MINIMAL_TOC ? 30 : 2 ]);
>> >> +	fprintf (file, "(%s)", reg_names[ TARGET_MINIMAL_TOC ? 30 : 2 \
>> >> /* PIC_OFFSET_TABLE_REGNUM? */ ]);
>> >
>> >Same here.
>> 
>> Uhm, I'm not so sure about this. The TOC approach is used on svr4/ppc for
>> -fPIC. And there's a switch -mminimal-toc that sets TARGET_MINIMAL_TOC and
>> it's valid for -fpic. But I haven't been able to get an overview on all the
>> ABI interactions so far, so I left the reorg in and marked (at least in this
>> first version of the patch) the questionable places in the code.
>
>As far as I could grok from svr4.h, you'll never have a non-minimal toc
>with ABI_V4.  You'll either have something that looks like standard ELF
>pic with .got and such, or you'll use a minimiatoc.
>
>Oh well.  Keep it marked and we'll come back to it later.
>
>> Don't think so, -fpic looks fundamentally different from -fPIC on PPC/SYSV.
>> I don't know what the reason behind that is, maybe -fPIC can be merged into
>> -fpic now, but I think this would be a change more suitable for the mainline
>> than the branch.
>
>Ok.

I have made the suggested changes. Additionally I replaced TARGET_ELF with
(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) in my patch, which seems
to be the more common way to check for this. FYI, the compiler bootstrapped and
checked without regressions and the -fpic cases fixed with yesterdays patch.

Can this go into the branch please?

Franz.

	* rs6000.md (movsi_got_internal_mem): Delete.
	* rs6000.h (CONDITIONAL_REGISTER_USAGE): Mark PIC_OFFSET_TABLE_REGNUM.
	(GOT_TOC_REGNUM): Delete.
	(PIC_OFFSET_TABLE_REGNUM): Define.
	(FINALIZE_PIC): make a comment of it
	* rs6000.c (rs6000_got_register): New code for fixed pic register.
	(rs6000_replace_regno): Delete.
	(rs6000_finalize_pic): Likewise.
	(output_prolog): Handle PIC_OFFSET_TABLE_REGNUM


? cdiff
Index: rs6000.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.70.4.1
diff -u -p -r1.70.4.1 rs6000.c
--- rs6000.c	1999/05/28 02:41:43	1.70.4.1
+++ rs6000.c	1999/06/09 20:32:17
@@ -2391,156 +2391,36 @@ ccr_bit (op, scc_p)
     }
 }
 
-/* Return the GOT register, creating it if needed.  */
+/* Return the GOT register.  */
 
 struct rtx_def *
 rs6000_got_register (value)
      rtx value;
 {
-  if (! current_function_uses_pic_offset_table || ! pic_offset_table_rtx)
-    {
-      if (no_new_pseudos)
-	fatal_insn ("internal error -- needed new GOT register during reload phase to load:",
-		    value);
-
-      current_function_uses_pic_offset_table = 1;
-      pic_offset_table_rtx = gen_rtx_REG (Pmode, GOT_TOC_REGNUM);
-    }
+  /* The second flow pass currently (June 1999) can't update regs_ever_live
+     without disturbing other parts of the compiler, so update it here to
+     make the prolog/epilogue code happy. */
+  if (no_new_pseudos && !regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
+    regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
 
+  current_function_uses_pic_offset_table = 1;
   return pic_offset_table_rtx;
 }
 
-
-/* Replace all occurrences of register FROM with an new pseudo register in an insn X.
-   Store the pseudo register used in REG.
-   This is only safe during FINALIZE_PIC, since the registers haven't been setup
-   yet.  */
-
-static rtx
-rs6000_replace_regno (x, from, reg)
-     rtx x;
-     int from;
-     rtx *reg;
-{
-  register int i, j;
-  register const char *fmt;
-
-  /* Allow this function to make replacements in EXPR_LISTs.  */
-  if (!x)
-    return x;
-
-  switch (GET_CODE (x))
-    {
-    case SCRATCH:
-    case PC:
-    case CC0:
-    case CONST_INT:
-    case CONST_DOUBLE:
-    case CONST:
-    case SYMBOL_REF:
-    case LABEL_REF:
-      return x;
-
-    case REG:
-      if (REGNO (x) == from)
-	{
-	  if (! *reg)
-	    *reg = pic_offset_table_rtx = gen_reg_rtx (Pmode);
-
-	  return *reg;
-	}
-
-      return x;
-
-    default:
-      break;
-    }
-
-  fmt = GET_RTX_FORMAT (GET_CODE (x));
-  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
-    {
-      if (fmt[i] == 'e')
-	XEXP (x, i) = rs6000_replace_regno (XEXP (x, i), from, reg);
-      else if (fmt[i] == 'E')
-	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-	  XVECEXP (x, i, j) = rs6000_replace_regno (XVECEXP (x, i, j), from, reg);
-    }
-
-  return x;
-}  
-
-
-/* By generating position-independent code, when two different
-   programs (A and B) share a common library (libC.a), the text of
-   the library can be shared whether or not the library is linked at
-   the same address for both programs.  In some of these
-   environments, position-independent code requires not only the use
-   of different addressing modes, but also special code to enable the
-   use of these addressing modes.
-
-   The `FINALIZE_PIC' macro serves as a hook to emit these special
-   codes once the function is being compiled into assembly code, but
-   not before.  (It is not done before, because in the case of
-   compiling an inline function, it would lead to multiple PIC
-   prologues being included in functions which used inline functions
-   and were compiled to assembly language.)  */
-
-void
-rs6000_finalize_pic ()
-{
-  /* Loop through all of the insns, replacing the special GOT_TOC_REGNUM
-     with an appropriate pseudo register.  If we find we need GOT/TOC,
-     add the appropriate init code.  */
-  if (flag_pic && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
-    {
-      rtx insn = get_insns ();
-      rtx reg = NULL_RTX;
-      rtx first_insn;
-      rtx last_insn = NULL_RTX;
-
-      if (GET_CODE (insn) == NOTE)
-	insn = next_nonnote_insn (insn);
-
-      first_insn = insn;
-      for ( ; insn != NULL_RTX; insn = NEXT_INSN (insn))
-	{
-	  if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
-	    {
-	      PATTERN (insn) = rs6000_replace_regno (PATTERN (insn),
-						     GOT_TOC_REGNUM,
-						     &reg);
-
-	      if (REG_NOTES (insn))
-		REG_NOTES (insn) = rs6000_replace_regno (REG_NOTES (insn),
-							 GOT_TOC_REGNUM,
-							 &reg);
-	    }
-
-	  if (GET_CODE (insn) != NOTE)
-	    last_insn = insn;
-	}
-
-      if (reg)
-	{
-	  rtx init = gen_init_v4_pic (reg);
-	  emit_insn_before (init, first_insn);
-	  if (!optimize && last_insn)
-	    emit_insn_after (gen_rtx_USE (VOIDmode, reg), last_insn);
-	}
-    }
-}
-
-
 /* Search for any occurrence of the GOT_TOC register marker that should
-   have been eliminated, but may have crept back in.  */
+   have been eliminated, but may have crept back in.
 
+   This function could completely go away now (June 1999), but we leave it 
+   in for a while until all the possible issues with the new -fpic handling 
+   are resolved. */
+
 void
 rs6000_reorg (insn)
      rtx insn;
 {
   if (flag_pic && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
     {
-      rtx got_reg = gen_rtx_REG (Pmode, GOT_TOC_REGNUM);
+      rtx got_reg = gen_rtx_REG (Pmode, 2);
       for ( ; insn != NULL_RTX; insn = NEXT_INSN (insn))
 	if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
 	    && reg_mentioned_p (got_reg, PATTERN (insn)))
@@ -2556,7 +2436,6 @@ struct machine_function
   int save_toc_p;
   int fpmem_size;
   int fpmem_offset;
-  rtx pic_offset_table_rtx;
 };
 
 /* Functions to save and restore rs6000_fpmem_size.
@@ -2574,7 +2453,6 @@ rs6000_save_machine_status (p)
   machine->sysv_varargs_p = rs6000_sysv_varargs_p;
   machine->fpmem_size     = rs6000_fpmem_size;
   machine->fpmem_offset   = rs6000_fpmem_offset;
-  machine->pic_offset_table_rtx = pic_offset_table_rtx;
 }
 
 void
@@ -2586,7 +2464,6 @@ rs6000_restore_machine_status (p)
   rs6000_sysv_varargs_p = machine->sysv_varargs_p;
   rs6000_fpmem_size     = machine->fpmem_size;
   rs6000_fpmem_offset   = machine->fpmem_offset;
-  pic_offset_table_rtx  = machine->pic_offset_table_rtx;
 
   free (machine);
   p->machine = (struct machine_function *)0;
@@ -2601,7 +2478,6 @@ rs6000_init_expanders ()
   rs6000_sysv_varargs_p = 0;
   rs6000_fpmem_size = 0;
   rs6000_fpmem_offset = 0;
-  pic_offset_table_rtx = (rtx)0;
 
   /* Arrange to save and restore machine status around nested functions.  */
   save_machine_status = rs6000_save_machine_status;
@@ -2646,7 +2522,7 @@ print_operand (file, x, code)
 
     case '*':
       /* Write the register number of the TOC register.  */
-      fputs (TARGET_MINIMAL_TOC ? reg_names[30] : reg_names[2], file);
+      fputs (TARGET_MINIMAL_TOC ? reg_names[30] : reg_names[2 /* PIC_OFFSET_TABLE_REGNUM? */ ], file);
       return;
 
     case '$':
@@ -3252,7 +3128,7 @@ print_operand_address (file, x)
 	;
 #endif
       else
-	fprintf (file, "(%s)", reg_names[ TARGET_MINIMAL_TOC ? 30 : 2 ]);
+	fprintf (file, "(%s)", reg_names[ TARGET_MINIMAL_TOC ? 30 : 2 /* PIC_OFFSET_TABLE_REGNUM? */ ]);
     }
   else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
     {
@@ -4119,6 +3995,20 @@ output_prolog (file, size)
       else
 	asm_fprintf (file, store_reg, reg_names[12], info->cr_save_offset + sp_offset,
 		     reg_names[sp_reg]);
+    }
+
+  /* If we need PIC_OFFSET_TABLE_REGNUM, initialize it now */
+  if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) 
+      && flag_pic == 1 && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
+    {
+      if (!info->lr_save_p)
+	asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
+
+      fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
+      asm_fprintf (file, "\tmflr %s\n", reg_names[PIC_OFFSET_TABLE_REGNUM]);
+
+      if (!info->lr_save_p)
+	asm_fprintf (file, "\tmtlr %s\n", reg_names[0]);
     }
 
   /* NT needs us to probe the stack frame every 4k pages for large frames, so
Index: rs6000.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.49
diff -u -p -r1.49 rs6000.h
--- rs6000.h	1999/05/13 12:38:42	1.49
+++ rs6000.h	1999/06/09 20:32:18
@@ -884,15 +884,19 @@ extern int rs6000_debug_arg;		/* debug a
    64-bit AIX reserves GPR13 for thread-private data.
    Conditionally disable FPRs.  */
 
-#define CONDITIONAL_REGISTER_USAGE	\
-{					\
-  if (! TARGET_POWER)			\
-    fixed_regs[64] = 1;			\
-  if (TARGET_64BIT)			\
-    fixed_regs[13] = call_used_regs[13] = 1; \
-  if (TARGET_SOFT_FLOAT)		\
-    for (i = 32; i < 64; i++)		\
-      fixed_regs[i] = call_used_regs[i] = 1; \
+#define CONDITIONAL_REGISTER_USAGE					\
+{									\
+  if (! TARGET_POWER)							\
+    fixed_regs[64] = 1;							\
+  if (TARGET_64BIT)							\
+    fixed_regs[13] = call_used_regs[13] = 1; 				\
+  if (TARGET_SOFT_FLOAT)						\
+    for (i = 32; i < 64; i++)						\
+      fixed_regs[i] = call_used_regs[i] = 1; 				\
+  if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)		\
+      && flag_pic == 1)							\
+    fixed_regs[PIC_OFFSET_TABLE_REGNUM]					\
+      = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;			\
 }
 
 /* Specify the registers used for certain standard purposes.
@@ -925,12 +929,6 @@ extern int rs6000_debug_arg;		/* debug a
 /* Special register that represents memory, used for float/int conversions.  */
 #define FPMEM_REGNUM 76
 
-/* Register to use as a placeholder for the GOT/allocated TOC register.
-   FINALIZE_PIC will change all uses of this register to a an appropriate
-   pseudo register when it adds the code to setup the GOT.  We use r2
-   because it is a reserved register in all of the ABI's.  */
-#define GOT_TOC_REGNUM 2
-
 /* Place that structure value return address is placed.
 
    On the RS/6000, it is passed as an extra parameter.  */
@@ -2105,7 +2103,7 @@ do {                                    
    this macro is not defined, it is up to the machine-dependent files
    to allocate such a register (if necessary).  */
 
-/* #define PIC_OFFSET_TABLE_REGNUM */
+#define PIC_OFFSET_TABLE_REGNUM 30
 
 /* Define this macro if the register defined by
    `PIC_OFFSET_TABLE_REGNUM' is clobbered by calls.  Do not define
@@ -2128,7 +2126,7 @@ do {                                    
    prologues being included in functions which used inline functions
    and were compiled to assembly language.)  */
 
-#define FINALIZE_PIC rs6000_finalize_pic ()
+/* #define FINALIZE_PIC */
 
 /* A C expression that is nonzero if X is a legitimate immediate
    operand on the target machine when generating position independent
Index: rs6000.md
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.55
diff -u -p -r1.55 rs6000.md
--- rs6000.md	1999/05/13 12:38:44	1.55
+++ rs6000.md	1999/06/09 20:32:20
@@ -5809,21 +5809,6 @@
   "{l|lwz} %0,%a1@got(%2)"
   [(set_attr "type" "load")])
 
-;; Sometimes, though, the GOT `register' will be on the stack. Deal with
-;; this case specially.
-;; Force final to split this insn (if it hasn't been split already) to
-;; avoid having to create a suitable output template.
-(define_insn "*movsi_got_internal_mem"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(unspec [(match_operand:SI 1 "got_no_const_operand" "")
-		 (match_operand:SI 2 "memory_operand" "m")] 8))]
-  "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
-    && flag_pic == 1
-    && (reload_in_progress || reload_completed)"
-  "#"
-  [(set_attr "type" "load")
-   (set_attr "length" "8")])
-
 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
 ;; didn't get allocated to a hard register.
 (define_split 
? cdiff
Index: rs6000.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.70.4.1
diff -u -p -r1.70.4.1 rs6000.c
--- rs6000.c	1999/05/28 02:41:43	1.70.4.1
+++ rs6000.c	1999/06/09 20:32:17
@@ -2391,156 +2391,36 @@ ccr_bit (op, scc_p)
     }
 }
 
-/* Return the GOT register, creating it if needed.  */
+/* Return the GOT register.  */
 
 struct rtx_def *
 rs6000_got_register (value)
      rtx value;
 {
-  if (! current_function_uses_pic_offset_table || ! pic_offset_table_rtx)
-    {
-      if (no_new_pseudos)
-	fatal_insn ("internal error -- needed new GOT register during reload phase to load:",
-		    value);
-
-      current_function_uses_pic_offset_table = 1;
-      pic_offset_table_rtx = gen_rtx_REG (Pmode, GOT_TOC_REGNUM);
-    }
+  /* The second flow pass currently (June 1999) can't update regs_ever_live
+     without disturbing other parts of the compiler, so update it here to
+     make the prolog/epilogue code happy. */
+  if (no_new_pseudos && !regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
+    regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
 
+  current_function_uses_pic_offset_table = 1;
   return pic_offset_table_rtx;
 }
 
-
-/* Replace all occurrences of register FROM with an new pseudo register in an insn X.
-   Store the pseudo register used in REG.
-   This is only safe during FINALIZE_PIC, since the registers haven't been setup
-   yet.  */
-
-static rtx
-rs6000_replace_regno (x, from, reg)
-     rtx x;
-     int from;
-     rtx *reg;
-{
-  register int i, j;
-  register const char *fmt;
-
-  /* Allow this function to make replacements in EXPR_LISTs.  */
-  if (!x)
-    return x;
-
-  switch (GET_CODE (x))
-    {
-    case SCRATCH:
-    case PC:
-    case CC0:
-    case CONST_INT:
-    case CONST_DOUBLE:
-    case CONST:
-    case SYMBOL_REF:
-    case LABEL_REF:
-      return x;
-
-    case REG:
-      if (REGNO (x) == from)
-	{
-	  if (! *reg)
-	    *reg = pic_offset_table_rtx = gen_reg_rtx (Pmode);
-
-	  return *reg;
-	}
-
-      return x;
-
-    default:
-      break;
-    }
-
-  fmt = GET_RTX_FORMAT (GET_CODE (x));
-  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
-    {
-      if (fmt[i] == 'e')
-	XEXP (x, i) = rs6000_replace_regno (XEXP (x, i), from, reg);
-      else if (fmt[i] == 'E')
-	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-	  XVECEXP (x, i, j) = rs6000_replace_regno (XVECEXP (x, i, j), from, reg);
-    }
-
-  return x;
-}  
-
-
-/* By generating position-independent code, when two different
-   programs (A and B) share a common library (libC.a), the text of
-   the library can be shared whether or not the library is linked at
-   the same address for both programs.  In some of these
-   environments, position-independent code requires not only the use
-   of different addressing modes, but also special code to enable the
-   use of these addressing modes.
-
-   The `FINALIZE_PIC' macro serves as a hook to emit these special
-   codes once the function is being compiled into assembly code, but
-   not before.  (It is not done before, because in the case of
-   compiling an inline function, it would lead to multiple PIC
-   prologues being included in functions which used inline functions
-   and were compiled to assembly language.)  */
-
-void
-rs6000_finalize_pic ()
-{
-  /* Loop through all of the insns, replacing the special GOT_TOC_REGNUM
-     with an appropriate pseudo register.  If we find we need GOT/TOC,
-     add the appropriate init code.  */
-  if (flag_pic && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
-    {
-      rtx insn = get_insns ();
-      rtx reg = NULL_RTX;
-      rtx first_insn;
-      rtx last_insn = NULL_RTX;
-
-      if (GET_CODE (insn) == NOTE)
-	insn = next_nonnote_insn (insn);
-
-      first_insn = insn;
-      for ( ; insn != NULL_RTX; insn = NEXT_INSN (insn))
-	{
-	  if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
-	    {
-	      PATTERN (insn) = rs6000_replace_regno (PATTERN (insn),
-						     GOT_TOC_REGNUM,
-						     &reg);
-
-	      if (REG_NOTES (insn))
-		REG_NOTES (insn) = rs6000_replace_regno (REG_NOTES (insn),
-							 GOT_TOC_REGNUM,
-							 &reg);
-	    }
-
-	  if (GET_CODE (insn) != NOTE)
-	    last_insn = insn;
-	}
-
-      if (reg)
-	{
-	  rtx init = gen_init_v4_pic (reg);
-	  emit_insn_before (init, first_insn);
-	  if (!optimize && last_insn)
-	    emit_insn_after (gen_rtx_USE (VOIDmode, reg), last_insn);
-	}
-    }
-}
-
-
 /* Search for any occurrence of the GOT_TOC register marker that should
-   have been eliminated, but may have crept back in.  */
+   have been eliminated, but may have crept back in.
 
+   This function could completely go away now (June 1999), but we leave it 
+   in for a while until all the possible issues with the new -fpic handling 
+   are resolved. */
+
 void
 rs6000_reorg (insn)
      rtx insn;
 {
   if (flag_pic && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
     {
-      rtx got_reg = gen_rtx_REG (Pmode, GOT_TOC_REGNUM);
+      rtx got_reg = gen_rtx_REG (Pmode, 2);
       for ( ; insn != NULL_RTX; insn = NEXT_INSN (insn))
 	if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
 	    && reg_mentioned_p (got_reg, PATTERN (insn)))
@@ -2556,7 +2436,6 @@ struct machine_function
   int save_toc_p;
   int fpmem_size;
   int fpmem_offset;
-  rtx pic_offset_table_rtx;
 };
 
 /* Functions to save and restore rs6000_fpmem_size.
@@ -2574,7 +2453,6 @@ rs6000_save_machine_status (p)
   machine->sysv_varargs_p = rs6000_sysv_varargs_p;
   machine->fpmem_size     = rs6000_fpmem_size;
   machine->fpmem_offset   = rs6000_fpmem_offset;
-  machine->pic_offset_table_rtx = pic_offset_table_rtx;
 }
 
 void
@@ -2586,7 +2464,6 @@ rs6000_restore_machine_status (p)
   rs6000_sysv_varargs_p = machine->sysv_varargs_p;
   rs6000_fpmem_size     = machine->fpmem_size;
   rs6000_fpmem_offset   = machine->fpmem_offset;
-  pic_offset_table_rtx  = machine->pic_offset_table_rtx;
 
   free (machine);
   p->machine = (struct machine_function *)0;
@@ -2601,7 +2478,6 @@ rs6000_init_expanders ()
   rs6000_sysv_varargs_p = 0;
   rs6000_fpmem_size = 0;
   rs6000_fpmem_offset = 0;
-  pic_offset_table_rtx = (rtx)0;
 
   /* Arrange to save and restore machine status around nested functions.  */
   save_machine_status = rs6000_save_machine_status;
@@ -2646,7 +2522,7 @@ print_operand (file, x, code)
 
     case '*':
       /* Write the register number of the TOC register.  */
-      fputs (TARGET_MINIMAL_TOC ? reg_names[30] : reg_names[2], file);
+      fputs (TARGET_MINIMAL_TOC ? reg_names[30] : reg_names[2 /* PIC_OFFSET_TABLE_REGNUM? */ ], file);
       return;
 
     case '$':
@@ -3252,7 +3128,7 @@ print_operand_address (file, x)
 	;
 #endif
       else
-	fprintf (file, "(%s)", reg_names[ TARGET_MINIMAL_TOC ? 30 : 2 ]);
+	fprintf (file, "(%s)", reg_names[ TARGET_MINIMAL_TOC ? 30 : 2 /* PIC_OFFSET_TABLE_REGNUM? */ ]);
     }
   else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
     {
@@ -4119,6 +3995,20 @@ output_prolog (file, size)
       else
 	asm_fprintf (file, store_reg, reg_names[12], info->cr_save_offset + sp_offset,
 		     reg_names[sp_reg]);
+    }
+
+  /* If we need PIC_OFFSET_TABLE_REGNUM, initialize it now */
+  if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) 
+      && flag_pic == 1 && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
+    {
+      if (!info->lr_save_p)
+	asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
+
+      fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
+      asm_fprintf (file, "\tmflr %s\n", reg_names[PIC_OFFSET_TABLE_REGNUM]);
+
+      if (!info->lr_save_p)
+	asm_fprintf (file, "\tmtlr %s\n", reg_names[0]);
     }
 
   /* NT needs us to probe the stack frame every 4k pages for large frames, so
Index: rs6000.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.49
diff -u -p -r1.49 rs6000.h
--- rs6000.h	1999/05/13 12:38:42	1.49
+++ rs6000.h	1999/06/09 20:32:18
@@ -884,15 +884,19 @@ extern int rs6000_debug_arg;		/* debug a
    64-bit AIX reserves GPR13 for thread-private data.
    Conditionally disable FPRs.  */
 
-#define CONDITIONAL_REGISTER_USAGE	\
-{					\
-  if (! TARGET_POWER)			\
-    fixed_regs[64] = 1;			\
-  if (TARGET_64BIT)			\
-    fixed_regs[13] = call_used_regs[13] = 1; \
-  if (TARGET_SOFT_FLOAT)		\
-    for (i = 32; i < 64; i++)		\
-      fixed_regs[i] = call_used_regs[i] = 1; \
+#define CONDITIONAL_REGISTER_USAGE					\
+{									\
+  if (! TARGET_POWER)							\
+    fixed_regs[64] = 1;							\
+  if (TARGET_64BIT)							\
+    fixed_regs[13] = call_used_regs[13] = 1; 				\
+  if (TARGET_SOFT_FLOAT)						\
+    for (i = 32; i < 64; i++)						\
+      fixed_regs[i] = call_used_regs[i] = 1; 				\
+  if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)		\
+      && flag_pic == 1)							\
+    fixed_regs[PIC_OFFSET_TABLE_REGNUM]					\
+      = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;			\
 }
 
 /* Specify the registers used for certain standard purposes.
@@ -925,12 +929,6 @@ extern int rs6000_debug_arg;		/* debug a
 /* Special register that represents memory, used for float/int conversions.  */
 #define FPMEM_REGNUM 76
 
-/* Register to use as a placeholder for the GOT/allocated TOC register.
-   FINALIZE_PIC will change all uses of this register to a an appropriate
-   pseudo register when it adds the code to setup the GOT.  We use r2
-   because it is a reserved register in all of the ABI's.  */
-#define GOT_TOC_REGNUM 2
-
 /* Place that structure value return address is placed.
 
    On the RS/6000, it is passed as an extra parameter.  */
@@ -2105,7 +2103,7 @@ do {                                    
    this macro is not defined, it is up to the machine-dependent files
    to allocate such a register (if necessary).  */
 
-/* #define PIC_OFFSET_TABLE_REGNUM */
+#define PIC_OFFSET_TABLE_REGNUM 30
 
 /* Define this macro if the register defined by
    `PIC_OFFSET_TABLE_REGNUM' is clobbered by calls.  Do not define
@@ -2128,7 +2126,7 @@ do {                                    
    prologues being included in functions which used inline functions
    and were compiled to assembly language.)  */
 
-#define FINALIZE_PIC rs6000_finalize_pic ()
+/* #define FINALIZE_PIC */
 
 /* A C expression that is nonzero if X is a legitimate immediate
    operand on the target machine when generating position independent
Index: rs6000.md
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.55
diff -u -p -r1.55 rs6000.md
--- rs6000.md	1999/05/13 12:38:44	1.55
+++ rs6000.md	1999/06/09 20:32:20
@@ -5809,21 +5809,6 @@
   "{l|lwz} %0,%a1@got(%2)"
   [(set_attr "type" "load")])
 
-;; Sometimes, though, the GOT `register' will be on the stack. Deal with
-;; this case specially.
-;; Force final to split this insn (if it hasn't been split already) to
-;; avoid having to create a suitable output template.
-(define_insn "*movsi_got_internal_mem"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(unspec [(match_operand:SI 1 "got_no_const_operand" "")
-		 (match_operand:SI 2 "memory_operand" "m")] 8))]
-  "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
-    && flag_pic == 1
-    && (reload_in_progress || reload_completed)"
-  "#"
-  [(set_attr "type" "load")
-   (set_attr "length" "8")])
-
 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
 ;; didn't get allocated to a hard register.
 (define_split 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]