gcc: fix 4.1.2 ICE on mips (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33256)
authorNicolas Thill <nico@openwrt.org>
Sun, 11 Oct 2009 02:52:08 +0000 (02:52 +0000)
committerNicolas Thill <nico@openwrt.org>
Sun, 11 Oct 2009 02:52:08 +0000 (02:52 +0000)
SVN-Revision: 18029

toolchain/gcc/patches/4.1.2/953-bug_33256.patch [new file with mode: 0644]

diff --git a/toolchain/gcc/patches/4.1.2/953-bug_33256.patch b/toolchain/gcc/patches/4.1.2/953-bug_33256.patch
new file mode 100644 (file)
index 0000000..6388e47
--- /dev/null
@@ -0,0 +1,54 @@
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33256
+
+--- a/gcc/config/mips/mips.c
++++ b/gcc/config/mips/mips.c
+@@ -1252,6 +1252,20 @@ mips_split_const (rtx x, rtx *base, HOST
+   *base = x;
+ }
++/* Classify symbolic expression X, given that it appears in context
++   CONTEXT.  */
++
++static enum mips_symbol_type
++mips_classify_symbolic_expression (rtx x)
++{
++  HOST_WIDE_INT offset;
++
++  mips_split_const (x, &x, &offset);
++  if (UNSPEC_ADDRESS_P (x))
++    return UNSPEC_ADDRESS_TYPE (x);
++
++  return mips_classify_symbol (x);
++}
+ /* Return true if SYMBOL is a SYMBOL_REF and OFFSET + SYMBOL points
+    to the same object as SYMBOL.  */
+@@ -1493,8 +1507,17 @@ mips_classify_address (struct mips_addre
+       info->type = ADDRESS_LO_SUM;
+       info->reg = XEXP (x, 0);
+       info->offset = XEXP (x, 1);
++      /* We have to trust the creator of the LO_SUM to do something vaguely
++       sane.  Target-independent code that creates a LO_SUM should also
++       create and verify the matching HIGH.  Target-independent code that
++       adds an offset to a LO_SUM must prove that the offset will not
++       induce a carry.  Failure to do either of these things would be
++       a bug, and we are not required to check for it here.  The MIPS
++       backend itself should only create LO_SUMs for valid symbolic
++       constants, with the high part being either a HIGH or a copy
++       of _gp. */
++      info->symbol_type = mips_classify_symbolic_expression (info->offset);
+       return (mips_valid_base_register_p (info->reg, mode, strict)
+-            && mips_symbolic_constant_p (info->offset, &info->symbol_type)
+             && mips_symbolic_address_p (info->symbol_type, mode)
+             && mips_lo_relocs[info->symbol_type] != 0);
+@@ -5575,7 +5598,8 @@ print_operand_reloc (FILE *file, rtx op,
+   rtx base;
+   HOST_WIDE_INT offset;
+-  if (!mips_symbolic_constant_p (op, &symbol_type) || relocs[symbol_type] == 0)
++  symbol_type = mips_classify_symbolic_expression (op);
++  if (relocs[symbol_type] == 0)
+     fatal_insn ("PRINT_OPERAND, invalid operand for relocation", op);
+   /* If OP uses an UNSPEC address, we want to print the inner symbol.  */