m68k.h (PIC_OFFSET_TABLE_REGNUM): Use the REGNO of pic_offset_table_rtx if reload_completed.

gcc/
	* config/m68k/m68k.h (PIC_OFFSET_TABLE_REGNUM): Use the REGNO
	of pic_offset_table_rtx if reload_completed.
	(CONDITIONAL_REGISTER_USAGE): Use PIC_REG instead of
	PIC_OFFSET_TABLE_REGNUM.
	* config/m68k/m68k.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): Always
	return true.
	(m68k_save_reg): Use PIC_REG instead of PIC_OFFSET_TABLE_REGNO.
	(m68k_output_mi_thunk): Rewrite to use RTL.  Honor vcall_offset.

From-SVN: r122612
This commit is contained in:
Richard Sandiford 2007-03-06 09:04:47 +00:00 committed by Richard Sandiford
parent afcb440c3f
commit 4ab870f5c3
3 changed files with 97 additions and 50 deletions

View File

@ -1,3 +1,14 @@
2007-03-06 Richard Sandiford <richard@codesourcery.com>
* config/m68k/m68k.h (PIC_OFFSET_TABLE_REGNUM): Use the REGNO
of pic_offset_table_rtx if reload_completed.
(CONDITIONAL_REGISTER_USAGE): Use PIC_REG instead of
PIC_OFFSET_TABLE_REGNUM.
* config/m68k/m68k.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): Always
return true.
(m68k_save_reg): Use PIC_REG instead of PIC_OFFSET_TABLE_REGNO.
(m68k_output_mi_thunk): Rewrite to use RTL. Honor vcall_offset.
2007-03-06 Richard Sandiford <richard@codesourcery.com>
* config/m68k/m68k.c (m68k_save_reg): Save the PIC register in

View File

@ -191,7 +191,7 @@ int m68k_last_compare_had_fp_operands;
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK m68k_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
#undef TARGET_ASM_FILE_START_APP_OFF
#define TARGET_ASM_FILE_START_APP_OFF true
@ -745,7 +745,7 @@ m68k_initial_elimination_offset (int from, int to)
static bool
m68k_save_reg (unsigned int regno, bool interrupt_handler)
{
if (flag_pic && regno == PIC_OFFSET_TABLE_REGNUM)
if (flag_pic && regno == PIC_REG)
{
/* A function that receives a nonlocal goto must save all call-saved
registers. */
@ -4083,59 +4083,93 @@ m68k_coff_asm_named_section (const char *name, unsigned int flags,
static void
m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
HOST_WIDE_INT delta,
HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
tree function)
{
rtx xops[1];
const char *fmt;
rtx this_slot, offset, addr, mem, insn;
if (delta > 0 && delta <= 8)
asm_fprintf (file, (MOTOROLA
? "\taddq.l %I%d,4(%Rsp)\n"
: "\taddql %I%d,%Rsp@(4)\n"),
(int) delta);
else if (delta < 0 && delta >= -8)
asm_fprintf (file, (MOTOROLA
? "\tsubq.l %I%d,4(%Rsp)\n"
: "\tsubql %I%d,%Rsp@(4)\n"),
(int) -delta);
else if (TARGET_COLDFIRE)
/* Pretend to be a post-reload pass while generating rtl. */
no_new_pseudos = 1;
reload_completed = 1;
reset_block_changes ();
allocate_reg_info (FIRST_PSEUDO_REGISTER, true, true);
/* The "this" pointer is stored at 4(%sp). */
this_slot = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx, 4));
/* Add DELTA to THIS. */
if (delta != 0)
{
/* ColdFire can't add/sub a constant to memory unless it is in
the range of addq/subq. So load the value into %d0 and
then add it to 4(%sp). */
if (delta >= -128 && delta <= 127)
asm_fprintf (file, (MOTOROLA
? "\tmoveq.l %I%wd,%Rd0\n"
: "\tmoveql %I%wd,%Rd0\n"),
delta);
else
asm_fprintf (file, (MOTOROLA
? "\tmove.l %I%wd,%Rd0\n"
: "\tmovel %I%wd,%Rd0\n"),
delta);
asm_fprintf (file, (MOTOROLA
? "\tadd.l %Rd0,4(%Rsp)\n"
: "\taddl %Rd0,%Rsp@(4)\n"));
/* Make the offset a legitimate operand for memory addition. */
offset = GEN_INT (delta);
if ((delta < -8 || delta > 8)
&& (TARGET_COLDFIRE || USE_MOVQ (delta)))
{
emit_move_insn (gen_rtx_REG (Pmode, D0_REG), offset);
offset = gen_rtx_REG (Pmode, D0_REG);
}
emit_insn (gen_add3_insn (copy_rtx (this_slot),
copy_rtx (this_slot), offset));
}
else
asm_fprintf (file, (MOTOROLA
? "\tadd.l %I%wd,4(%Rsp)\n"
: "\taddl %I%wd,%Rsp@(4)\n"),
delta);
xops[0] = DECL_RTL (function);
/* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
if (vcall_offset != 0)
{
/* Set the static chain register to *THIS. */
emit_move_insn (static_chain_rtx, this_slot);
emit_move_insn (static_chain_rtx, gen_rtx_MEM (Pmode, static_chain_rtx));
gcc_assert (MEM_P (xops[0])
&& symbolic_operand (XEXP (xops[0], 0), VOIDmode));
xops[0] = XEXP (xops[0], 0);
/* Set ADDR to a legitimate address for *THIS + VCALL_OFFSET. */
addr = plus_constant (static_chain_rtx, vcall_offset);
if (!m68k_legitimate_address_p (Pmode, addr, true))
{
emit_insn (gen_rtx_SET (VOIDmode, static_chain_rtx, addr));
addr = static_chain_rtx;
}
fmt = m68k_symbolic_jump;
if (m68k_symbolic_jump == NULL)
fmt = "move.l %%a1@GOT(%%a5), %%a1\n\tjmp (%%a1)";
/* Load the offset into %d0 and add it to THIS. */
emit_move_insn (gen_rtx_REG (Pmode, D0_REG),
gen_rtx_MEM (Pmode, addr));
emit_insn (gen_add3_insn (copy_rtx (this_slot),
copy_rtx (this_slot),
gen_rtx_REG (Pmode, D0_REG)));
}
output_asm_insn (fmt, xops);
/* Jump to the target function. Use a sibcall if direct jumps are
allowed, otherwise load the address into a register first. */
mem = DECL_RTL (function);
if (!sibcall_operand (XEXP (mem, 0), VOIDmode))
{
gcc_assert (flag_pic);
if (!TARGET_SEP_DATA)
{
/* Use the static chain register as a temporary (call-clobbered)
GOT pointer for this function. We can use the static chain
register because it isn't live on entry to the thunk. */
REGNO (pic_offset_table_rtx) = STATIC_CHAIN_REGNUM;
emit_insn (gen_load_got (pic_offset_table_rtx));
}
legitimize_pic_address (XEXP (mem, 0), Pmode, static_chain_rtx);
mem = replace_equiv_address (mem, static_chain_rtx);
}
insn = emit_call_insn (gen_sibcall (mem, const0_rtx));
SIBLING_CALL_P (insn) = 1;
/* Run just enough of rest_of_compilation. */
insn = get_insns ();
split_all_insns_noflow ();
final_start_function (insn, file, 1);
final (insn, file, 1);
final_end_function ();
/* Clean up the vars set above. */
reload_completed = 0;
no_new_pseudos = 0;
/* Restore the original PIC register. */
if (flag_pic)
REGNO (pic_offset_table_rtx) = PIC_REG;
}
/* Worker function for TARGET_STRUCT_VALUE_RTX. */

View File

@ -316,7 +316,10 @@ Boston, MA 02110-1301, USA. */
#define FIRST_PSEUDO_REGISTER 25
/* All m68k targets (except AmigaOS) use %a5 as the PIC register */
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 13 : INVALID_REGNUM)
#define PIC_OFFSET_TABLE_REGNUM \
(!flag_pic ? INVALID_REGNUM \
: reload_completed ? REGNO (pic_offset_table_rtx) \
: PIC_REG)
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
@ -383,9 +386,8 @@ Boston, MA 02110-1301, USA. */
if (TEST_HARD_REG_BIT (x, i)) \
fixed_regs[i] = call_used_regs[i] = 1; \
} \
if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
= call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
if (flag_pic) \
fixed_regs[PIC_REG] = call_used_regs[PIC_REG] = 1; \
}
/* On the m68k, ordinary registers hold 32 bits worth;