Deal with -fpic and inlined functions

From-SVN: r12428
This commit is contained in:
Michael Meissner 1996-07-11 22:36:45 +00:00
parent c05330a923
commit 1ff7789b51
2 changed files with 109 additions and 24 deletions

View File

@ -372,24 +372,6 @@ rs6000_immed_double_const (i0, i1, mode)
return immed_double_const (i0, i1, mode);
}
/* Return the GOT register, creating it if needed. */
struct rtx_def *
rs6000_got_register (value)
rtx value;
{
if (!pic_offset_table_rtx)
{
if (reload_in_progress || reload_completed)
fatal_insn ("internal error -- needed new GOT register during reload phase to load:", value);
pic_offset_table_rtx = gen_reg_rtx (SImode);
}
return pic_offset_table_rtx;
}
/* Return non-zero if this function is known to have a null epilogue. */
@ -2077,6 +2059,81 @@ ccr_bit (op, scc_p)
abort ();
}
}
/* Return the GOT register, creating it if needed. */
struct rtx_def *
rs6000_got_register (value)
rtx value;
{
if (!pic_offset_table_rtx)
{
if (reload_in_progress || reload_completed)
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);
}
return pic_offset_table_rtx;
}
/* Replace all occurances of register FROM with an new pseduo 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 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 = gen_reg_rtx (Pmode);
return *reg;
}
return x;
}
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
@ -2098,17 +2155,39 @@ rs6000_finalize_pic ()
{
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
{
/* If a PIC register has been created, insert the pic initialization
at the function beginning. */
if (pic_offset_table_rtx)
/* Loop through all of the insns, replacing the special GOT_TOC_REGNUM
with an appropriate pseduo register. If we find we need GOT/TOC,
add the appropriate init code. */
if (flag_pic)
{
rtx insn = get_insns ();
rtx init = gen_init_v4_pic (pic_offset_table_rtx);
rtx reg = NULL_RTX;
rtx first_insn;
if (GET_CODE (insn) == NOTE)
insn = next_nonnote_insn (insn);
emit_insn_before (init, 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 (reg)
{
rtx init = gen_init_v4_pic (reg);
emit_insn_before (init, first_insn);
}
}
}
}

View File

@ -847,10 +847,16 @@ extern struct rs6000_cpu_select rs6000_select[];
/* 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. */
#define STRUCT_VALUE 0
#define STRUCT_VALUE 0
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.