PR target/43294: delegitimize_address for m68k

Andreas Schwab schwab@linux-m68k.org
Tue Mar 9 22:11:00 GMT 2010


Tested on m68k-linux.

Andreas.

2010-03-09  Andreas Schwab  <schwab@linux-m68k.org>

	PR target/43294
	* config/m68k/m68k.c (TARGET_DELEGITIMIZE_ADDRESS): Define.
	(m68k_delegitimize_address): New function.

Index: config/m68k/m68k.c
===================================================================
--- config/m68k/m68k.c	(revision 157327)
+++ config/m68k/m68k.c	(working copy)
@@ -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
 #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 = "_c
 #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, in
   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

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



More information about the Gcc-patches mailing list