aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard@codesourcery.com>2006-12-15 18:10:22 +0000
committerRichard Sandiford <richard@codesourcery.com>2006-12-15 18:10:22 +0000
commit6d2097125c18f08d417f7ce8d4c2b0551e0919bb (patch)
tree48d8a2c88d640bba7e12cadea8098c9eaabcfc3f
parentbff62628a36e559c71ad4120f68644a0961d41ff (diff)
gcc/
* 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_init_pic): Delete. (m68k_expand_prologue): Update call to gen_load_got. (m68k_output_mi_thunk): Rewrite to use RTL. Honor vcall_offset. * 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.md (load_got): Replace hard-coded destination register with a match_operand. Handle both assembler dialects in the TARGET_ID_SHARED_LIBRARY case. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/csl/coldfire-4_1@119933 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog.csl17
-rw-r--r--gcc/config/m68k/m68k.c183
-rw-r--r--gcc/config/m68k/m68k.h10
-rw-r--r--gcc/config/m68k/m68k.md8
4 files changed, 109 insertions, 109 deletions
diff --git a/ChangeLog.csl b/ChangeLog.csl
index f4b44ea064b..fbc9e4f21b6 100644
--- a/ChangeLog.csl
+++ b/ChangeLog.csl
@@ -1,6 +1,23 @@
2006-12-15 Richard Sandiford <richard@codesourcery.com>
gcc/
+ * 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_init_pic): Delete.
+ (m68k_expand_prologue): Update call to gen_load_got.
+ (m68k_output_mi_thunk): Rewrite to use RTL. Honor vcall_offset.
+ * 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.md (load_got): Replace hard-coded destination
+ register with a match_operand. Handle both assembler dialects
+ in the TARGET_ID_SHARED_LIBRARY case.
+
+2006-12-15 Richard Sandiford <richard@codesourcery.com>
+
+ gcc/
* config/m68k/m68k.md (bordered, bunordered, buneq, bunge, bungt)
(bunle, bunlt, bltgt, bordered_rev, bunordered_rev, buneq_rev)
(bunge_rev, bunle_rev, bunlt_rev, bltgt_rev): Change condition
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 85e6b42ce0d..ad2a99f01a0 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -171,7 +171,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_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS MASK_STRICT_ALIGNMENT
@@ -720,7 +720,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)
{
/* We need to restore the PIC register on exceptional returns. */
if (current_function_calls_eh_return)
@@ -776,51 +776,6 @@ m68k_save_reg (unsigned int regno, bool interrupt_handler)
return !call_used_regs[regno];
}
-/* Initialize PIC_REGNO as a PIC reg. */
-
-static void
-m68k_init_pic (FILE *stream, int pic_regno)
-{
- if (TARGET_ID_SHARED_LIBRARY)
- {
- asm_fprintf (stream, "\tmovel %s@(%s), %s\n",
- M68K_REGNAME(PIC_OFFSET_TABLE_REGNUM),
- m68k_library_id_string,
- M68K_REGNAME(pic_regno));
- }
- else
- {
- if (MOTOROLA)
- {
- if (TARGET_COLDFIRE)
- {
- /* Load the full 32-bit PC-relative offset of
- _GLOBAL_OFFSET_TABLE_ into the PIC register, then use
- it to calculate the absolute value. The offset and
- "lea" operation word together occupy 6 bytes. */
- asm_fprintf (stream, "\tmove.l %I%U%s@GOTPC, %s\n",
- "_GLOBAL_OFFSET_TABLE_",
- M68K_REGNAME(pic_regno));
- asm_fprintf (stream, "\tlea (-6, %Rpc, %s), %s\n",
- M68K_REGNAME(pic_regno),
- M68K_REGNAME(pic_regno));
- }
- else
- asm_fprintf (stream, "\t%Olea (%Rpc, %U%s@GOTPC), %s\n",
- "_GLOBAL_OFFSET_TABLE_",
- M68K_REGNAME(pic_regno));
- }
- else
- {
- asm_fprintf (stream, "\tmovel %I%U_GLOBAL_OFFSET_TABLE_, %s\n",
- M68K_REGNAME(pic_regno));
- asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",
- M68K_REGNAME(pic_regno),
- M68K_REGNAME(pic_regno));
- }
- }
-}
-
/* Emit RTL for a MOVEM or FMOVEM instruction. BASE + OFFSET represents
the lowest memory address. COUNT is the number of registers to be
moved, with register REGNO + I being moved if bit I of MASK is set.
@@ -1026,7 +981,7 @@ m68k_expand_prologue (void)
&& !TARGET_SEP_DATA
&& current_function_uses_pic_offset_table)
{
- insn = emit_insn (gen_load_got ());
+ insn = emit_insn (gen_load_got (pic_offset_table_rtx));
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
const0_rtx,
REG_NOTES (insn));
@@ -4050,68 +4005,92 @@ 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;
-
- 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)
+ rtx this_slot, offset, addr, mem, insn;
+
+ /* 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 (TARGET_COLDFIRE && (delta < -8 || delta > 8))
+ {
+ 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);
- gcc_assert (MEM_P (xops[0])
- && symbolic_operand (XEXP (xops[0], 0), VOIDmode));
- xops[0] = XEXP (xops[0], 0);
-
- fmt = m68k_symbolic_jump;
- if (m68k_symbolic_jump == NULL)
+
+ /* 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));
+
+ /* 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;
+ }
+
+ /* 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)));
+ }
+
+ /* 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))
{
- /* Thunks do not use the static chain register. Use it as a
- temporary register here. */
gcc_assert (flag_pic);
- m68k_init_pic (file, STATIC_CHAIN_REGNUM);
- /* We provide REGISTER_PREFIX here, because it is either empty
- or "%". When it's "%" we want "%%" in the format string. */
- fmt = "move.l"
- " %a0@GOT(" REGISTER_PREFIX M68K_STATIC_CHAIN_REG_NAME "),"
- " " REGISTER_PREFIX M68K_STATIC_CHAIN_REG_NAME "\n"
- "\tjmp (" REGISTER_PREFIX M68K_STATIC_CHAIN_REG_NAME ")";
+ 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);
}
-
- output_asm_insn (fmt, xops);
+ 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. */
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index f656bae7fdc..9c3c3610bb5 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -306,7 +306,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.
@@ -373,9 +376,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;
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 0866b9ed608..92506087380 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -6655,13 +6655,15 @@
"unlk %0")
(define_insn "load_got"
- [(set (reg:SI PIC_REG)
+ [(set (match_operand:SI 0 "register_operand" "=a")
(unspec:SI [(const_int 0)] UNSPEC_GOT))]
""
{
- operands[0] = pic_offset_table_rtx;
if (TARGET_ID_SHARED_LIBRARY)
- return "movel %0@(%?), %0";
+ {
+ operands[1] = gen_rtx_REG (Pmode, PIC_REG);
+ return MOTOROLA ? "move.l %?(%1),%0" : "movel %1@(%?), %0";
+ }
else if (MOTOROLA)
{
if (TARGET_COLDFIRE)