diff options
author | Richard Sandiford <richard@codesourcery.com> | 2006-12-15 18:10:22 +0000 |
---|---|---|
committer | Richard Sandiford <richard@codesourcery.com> | 2006-12-15 18:10:22 +0000 |
commit | 6d2097125c18f08d417f7ce8d4c2b0551e0919bb (patch) | |
tree | 48d8a2c88d640bba7e12cadea8098c9eaabcfc3f | |
parent | bff62628a36e559c71ad4120f68644a0961d41ff (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.csl | 17 | ||||
-rw-r--r-- | gcc/config/m68k/m68k.c | 183 | ||||
-rw-r--r-- | gcc/config/m68k/m68k.h | 10 | ||||
-rw-r--r-- | gcc/config/m68k/m68k.md | 8 |
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) |