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
This commit is contained in:
committed by
Richard Henderson
parent
6deb8ad892
commit
8d30c4ee01
@@ -1,3 +1,15 @@
|
||||
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
|
||||
|
||||
+29
-139
@@ -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);
|
||||
|
||||
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,
|
||||
®);
|
||||
|
||||
if (REG_NOTES (insn))
|
||||
REG_NOTES (insn) = rs6000_replace_regno (REG_NOTES (insn),
|
||||
GOT_TOC_REGNUM,
|
||||
®);
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
+15
-17
@@ -884,15 +884,19 @@ extern int rs6000_debug_arg; /* debug argument handling */
|
||||
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 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
|
||||
|
||||
Reference in New Issue
Block a user