- if (linkrelax && fixp->fx_subsy
- && (fixp->fx_r_type == BFD_RELOC_8
- || fixp->fx_r_type == BFD_RELOC_16
- || fixp->fx_r_type == BFD_RELOC_32))
- {
- int diff_size = 0;
- bfd_vma diff_value, diff_mask = 0;
-
- switch (fixp->fx_r_type)
- {
- case BFD_RELOC_8:
- fixp->fx_r_type = BFD_RELOC_XTENSA_DIFF8;
- diff_size = 1;
- diff_mask = 0xff;
- break;
- case BFD_RELOC_16:
- fixp->fx_r_type = BFD_RELOC_XTENSA_DIFF16;
- diff_size = 2;
- diff_mask = 0xffff;
- break;
- case BFD_RELOC_32:
- fixp->fx_r_type = BFD_RELOC_XTENSA_DIFF32;
- diff_size = 4;
- diff_mask = 0xffffffff;
- break;
- default:
- break;
- }
-
- /* An offset is only allowed when it results from adjusting a local
- symbol into a section-relative offset. If the offset came from the
- original expression, tc_fix_adjustable will have prevented the fix
- from being converted to a section-relative form so that we can flag
- the error here. */
- if (fixp->fx_offset != 0 && !symbol_section_p (fixp->fx_addsy))
- {
- as_bad_where (fixp->fx_file, fixp->fx_line,
- _("cannot represent subtraction with an offset"));
- free (reloc->sym_ptr_ptr);
- free (reloc);
- return NULL;
- }
-
- assert (S_GET_SEGMENT (fixp->fx_addsy)
- == S_GET_SEGMENT (fixp->fx_subsy));
-
- diff_value = (S_GET_VALUE (fixp->fx_addsy) + fixp->fx_offset
- - S_GET_VALUE (fixp->fx_subsy));
-
- /* Check for overflow. */
- if ((diff_value & ~diff_mask) != 0)
- {
- as_bad_where (fixp->fx_file, fixp->fx_line,
- _("value of %ld too large"), diff_value);
- free (reloc->sym_ptr_ptr);
- free (reloc);
- return NULL;
- }
-
- md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
- diff_value, diff_size);
- reloc->addend = fixp->fx_offset - diff_value;
- }
- else
- {
- reloc->addend = fixp->fx_offset;
-
- switch (fixp->fx_r_type)
- {
- case BFD_RELOC_XTENSA_SLOT0_OP:
- case BFD_RELOC_XTENSA_SLOT1_OP:
- case BFD_RELOC_XTENSA_SLOT2_OP:
- case BFD_RELOC_XTENSA_SLOT3_OP:
- case BFD_RELOC_XTENSA_SLOT4_OP:
- case BFD_RELOC_XTENSA_SLOT5_OP:
- case BFD_RELOC_XTENSA_SLOT6_OP:
- case BFD_RELOC_XTENSA_SLOT7_OP:
- case BFD_RELOC_XTENSA_SLOT8_OP:
- case BFD_RELOC_XTENSA_SLOT9_OP:
- case BFD_RELOC_XTENSA_SLOT10_OP:
- case BFD_RELOC_XTENSA_SLOT11_OP:
- case BFD_RELOC_XTENSA_SLOT12_OP:
- case BFD_RELOC_XTENSA_SLOT13_OP:
- case BFD_RELOC_XTENSA_SLOT14_OP:
- /* As a special case, the immediate value for a CONST16 opcode
- should not be applied, since this kind of relocation is
- handled specially for CONST16 and is not really PC-relative.
- Rather than decode the opcode here, just wait and handle it
- in xg_apply_tentative_value. */
- apply_tentative_value = TRUE;
- break;
-
- case BFD_RELOC_XTENSA_SLOT0_ALT:
- case BFD_RELOC_XTENSA_SLOT1_ALT:
- case BFD_RELOC_XTENSA_SLOT2_ALT:
- case BFD_RELOC_XTENSA_SLOT3_ALT:
- case BFD_RELOC_XTENSA_SLOT4_ALT:
- case BFD_RELOC_XTENSA_SLOT5_ALT:
- case BFD_RELOC_XTENSA_SLOT6_ALT:
- case BFD_RELOC_XTENSA_SLOT7_ALT:
- case BFD_RELOC_XTENSA_SLOT8_ALT:
- case BFD_RELOC_XTENSA_SLOT9_ALT:
- case BFD_RELOC_XTENSA_SLOT10_ALT:
- case BFD_RELOC_XTENSA_SLOT11_ALT:
- case BFD_RELOC_XTENSA_SLOT12_ALT:
- case BFD_RELOC_XTENSA_SLOT13_ALT:
- case BFD_RELOC_XTENSA_SLOT14_ALT:
- case BFD_RELOC_XTENSA_ASM_EXPAND:
- case BFD_RELOC_32:
- case BFD_RELOC_XTENSA_PLT:
- case BFD_RELOC_VTABLE_INHERIT:
- case BFD_RELOC_VTABLE_ENTRY:
- break;
-
- case BFD_RELOC_XTENSA_ASM_SIMPLIFY:
- as_warn (_("emitting simplification relocation"));
- break;
-
- default:
- as_warn (_("emitting unknown relocation"));
- }
- }