Commit 8d30c4ee by Franz Sirl Committed by Richard Henderson

Franz Sirl <Franz.Sirl-kernel@lauterbach.com>

Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
        * 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): Disable.
        * 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.

From-SVN: r27457
parent 6deb8ad8
Wed Jun 9 15:57:57 1999 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
* 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): Disable.
* 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.
Wed Jun 9 19:44:26 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
* loop.c (loop_insn_first_p): Don't compare LUIDs when P
......
......@@ -2391,148 +2391,28 @@ 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);
/* 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;
pic_offset_table_rtx = gen_rtx_REG (Pmode, GOT_TOC_REGNUM);
}
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)
......@@ -2540,7 +2420,7 @@ rs6000_reorg (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)
{
......@@ -4121,6 +3997,20 @@ output_prolog (file, size)
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
do it here. */
if (DEFAULT_ABI == ABI_NT && info->total_size > 4096)
......
......@@ -893,6 +893,10 @@ extern int rs6000_debug_arg; /* debug argument handling */
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 argument handling */
/* 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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment