diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dddf99091eb..20e0b7290f4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-03-09 Andreas Schwab + + PR target/43294 + * config/m68k/m68k.c (TARGET_DELEGITIMIZE_ADDRESS): Define. + (m68k_delegitimize_address): New function. + 2010-03-09 Jakub Jelinek PR debug/43299 diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 8db98fc4f46..faee39e6723 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -1,6 +1,6 @@ /* Subroutines for insn-output.c for Motorola 68000 family. Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -154,6 +154,7 @@ static bool m68k_return_in_memory (const_tree, const_tree); #endif static void m68k_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; static void m68k_trampoline_init (rtx, tree, rtx); +static rtx m68k_delegitimize_address (rtx); /* Specify the identification number of the library being built */ @@ -271,6 +272,9 @@ const char *m68k_library_id_string = "_current_shared_library_a5_offset_"; #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT m68k_trampoline_init +#undef TARGET_DELEGITIMIZE_ADDRESS +#define TARGET_DELEGITIMIZE_ADDRESS m68k_delegitimize_address + static const struct attribute_spec m68k_attribute_table[] = { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ @@ -4616,6 +4620,57 @@ m68k_output_dwarf_dtprel (FILE *file, int size, rtx x) fputs ("@TLSLDO+0x8000", file); } +/* In the name of slightly smaller debug output, and to cater to + general assembler lossage, recognize various UNSPEC sequences + and turn them back into a direct symbol reference. */ + +static rtx +m68k_delegitimize_address (rtx x) +{ + rtx orig_x = delegitimize_mem_from_attrs (x); + rtx y; + rtx addend = NULL_RTX; + rtx result; + + x = orig_x; + if (MEM_P (x)) + x = XEXP (x, 0); + + if (GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 1)) == CONST + && REG_P (XEXP (x, 0)) + && REGNO (XEXP (x, 0)) == PIC_REG) + { + y = x = XEXP (XEXP (x, 1), 0); + + /* Handle an addend. */ + if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS) + && CONST_INT_P (XEXP (x, 1))) + { + addend = XEXP (x, 1); + x = XEXP (x, 0); + } + + if (GET_CODE (x) == UNSPEC + && (XINT (x, 1) == UNSPEC_RELOC16 + || XINT (x, 1) == UNSPEC_RELOC32)) + { + result = XVECEXP (x, 0, 0); + if (addend) + { + if (GET_CODE (y) == PLUS) + result = gen_rtx_PLUS (Pmode, result, addend); + else + result = gen_rtx_MINUS (Pmode, result, addend); + result = gen_rtx_CONST (Pmode, result); + } + return result; + } + } + + return orig_x; +} + /* A C compound statement to output to stdio stream STREAM the assembler syntax for an instruction operand that is a memory