diff options
Diffstat (limited to 'gas/config/tc-mips.c')
-rw-r--r-- | gas/config/tc-mips.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 74c7a10..318b0b5 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -14057,15 +14057,7 @@ md_pcrel_from (fixS *fixP) /* Return the address of the delay slot. */ return addr + 4; - case BFD_RELOC_32_PCREL: - return addr; - default: - /* We have no relocation type for PC relative MIPS16 instructions. */ - if (fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != now_seg) - as_bad_where (fixP->fx_file, fixP->fx_line, - _("PC relative MIPS16 instruction references" - " a different section")); return addr; } } @@ -14262,13 +14254,38 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) unsigned long insn; reloc_howto_type *howto; - /* We ignore generic BFD relocations we don't know about. */ - howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type); - if (! howto) - return; + if (fixP->fx_pcrel) + switch (fixP->fx_r_type) + { + case BFD_RELOC_16_PCREL_S2: + case BFD_RELOC_MICROMIPS_7_PCREL_S1: + case BFD_RELOC_MICROMIPS_10_PCREL_S1: + case BFD_RELOC_MICROMIPS_16_PCREL_S1: + case BFD_RELOC_32_PCREL: + break; + + case BFD_RELOC_32: + fixP->fx_r_type = BFD_RELOC_32_PCREL; + break; + + default: + as_bad_where (fixP->fx_file, fixP->fx_line, + _("PC-relative reference to a different section")); + break; + } + + /* Handle BFD_RELOC_8, since it's easy. Punt on other bfd relocations + that have no MIPS ELF equivalent. */ + if (fixP->fx_r_type != BFD_RELOC_8) + { + howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type); + if (!howto) + return; + } gas_assert (fixP->fx_size == 2 || fixP->fx_size == 4 + || fixP->fx_r_type == BFD_RELOC_8 || fixP->fx_r_type == BFD_RELOC_16 || fixP->fx_r_type == BFD_RELOC_64 || fixP->fx_r_type == BFD_RELOC_CTOR @@ -14280,12 +14297,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) buf = fixP->fx_frag->fr_literal + fixP->fx_where; - gas_assert (!fixP->fx_pcrel || fixP->fx_r_type == BFD_RELOC_16_PCREL_S2 - || fixP->fx_r_type == BFD_RELOC_MICROMIPS_7_PCREL_S1 - || fixP->fx_r_type == BFD_RELOC_MICROMIPS_10_PCREL_S1 - || fixP->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1 - || fixP->fx_r_type == BFD_RELOC_32_PCREL); - /* Don't treat parts of a composite relocation as done. There are two reasons for this: @@ -14435,6 +14446,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) case BFD_RELOC_32: case BFD_RELOC_32_PCREL: case BFD_RELOC_16: + case BFD_RELOC_8: /* If we are deleting this reloc entry, we must fill in the value now. This can happen if we have a .word which is not resolved when it appears but is later defined. */ |