| 1 | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33256 |
| 2 | |
| 3 | --- a/gcc/config/mips/mips.c |
| 4 | +++ b/gcc/config/mips/mips.c |
| 5 | @@ -1252,6 +1252,20 @@ mips_split_const (rtx x, rtx *base, HOST |
| 6 | *base = x; |
| 7 | } |
| 8 | |
| 9 | +/* Classify symbolic expression X, given that it appears in context |
| 10 | + CONTEXT. */ |
| 11 | + |
| 12 | +static enum mips_symbol_type |
| 13 | +mips_classify_symbolic_expression (rtx x) |
| 14 | +{ |
| 15 | + HOST_WIDE_INT offset; |
| 16 | + |
| 17 | + mips_split_const (x, &x, &offset); |
| 18 | + if (UNSPEC_ADDRESS_P (x)) |
| 19 | + return UNSPEC_ADDRESS_TYPE (x); |
| 20 | + |
| 21 | + return mips_classify_symbol (x); |
| 22 | +} |
| 23 | |
| 24 | /* Return true if SYMBOL is a SYMBOL_REF and OFFSET + SYMBOL points |
| 25 | to the same object as SYMBOL. */ |
| 26 | @@ -1493,8 +1507,17 @@ mips_classify_address (struct mips_addre |
| 27 | info->type = ADDRESS_LO_SUM; |
| 28 | info->reg = XEXP (x, 0); |
| 29 | info->offset = XEXP (x, 1); |
| 30 | + /* We have to trust the creator of the LO_SUM to do something vaguely |
| 31 | + sane. Target-independent code that creates a LO_SUM should also |
| 32 | + create and verify the matching HIGH. Target-independent code that |
| 33 | + adds an offset to a LO_SUM must prove that the offset will not |
| 34 | + induce a carry. Failure to do either of these things would be |
| 35 | + a bug, and we are not required to check for it here. The MIPS |
| 36 | + backend itself should only create LO_SUMs for valid symbolic |
| 37 | + constants, with the high part being either a HIGH or a copy |
| 38 | + of _gp. */ |
| 39 | + info->symbol_type = mips_classify_symbolic_expression (info->offset); |
| 40 | return (mips_valid_base_register_p (info->reg, mode, strict) |
| 41 | - && mips_symbolic_constant_p (info->offset, &info->symbol_type) |
| 42 | && mips_symbolic_address_p (info->symbol_type, mode) |
| 43 | && mips_lo_relocs[info->symbol_type] != 0); |
| 44 | |
| 45 | @@ -5575,7 +5598,8 @@ print_operand_reloc (FILE *file, rtx op, |
| 46 | rtx base; |
| 47 | HOST_WIDE_INT offset; |
| 48 | |
| 49 | - if (!mips_symbolic_constant_p (op, &symbol_type) || relocs[symbol_type] == 0) |
| 50 | + symbol_type = mips_classify_symbolic_expression (op); |
| 51 | + if (relocs[symbol_type] == 0) |
| 52 | fatal_insn ("PRINT_OPERAND, invalid operand for relocation", op); |
| 53 | |
| 54 | /* If OP uses an UNSPEC address, we want to print the inner symbol. */ |
| 55 | |