+ /* Try to turn a 24 immediate, displacement or absolute address
+ into a 8 immediate, displacement or absolute address. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_24)
+ {
+ bfd_vma value = symval;
+ value += irel->r_addend;
+
+ /* See if the value will fit in 8 bits. */
+ if ((long) value < 0x7f && (long) value > -0x80)
+ {
+ unsigned char code;
+
+ /* AM33 insns which have 24 operands are 6 bytes long and
+ will have 0xfd as the first byte. */
+
+ /* Get the first opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 3);
+
+ if (code == 0xfd)
+ {
+ /* Get the second opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+
+ /* We can not relax 0x6b, 0x7b, 0x8b, 0x9b as no 24bit
+ equivalent instructions exists. */
+ if (code != 0x6b && code != 0x7b
+ && code != 0x8b && code != 0x9b
+ && ((code & 0x0f) == 0x09 || (code & 0x0f) == 0x08
+ || (code & 0x0f) == 0x0a || (code & 0x0f) == 0x0b
+ || (code & 0x0f) == 0x0e))
+ {
+ /* Not safe if the high bit is on as relaxing may
+ move the value out of high mem and thus not fit
+ in a signed 8bit value. This is currently over
+ conservative. */
+ if ((value & 0x80) == 0)
+ {
+ /* Note that we've changed the relocation contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xfb, contents + irel->r_offset - 3);
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
+
+ /* Fix the relocation's type. */
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10300_8);
+
+ /* Delete two bytes of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax
+ again. Note that this is not required, and it
+ may be slow. */
+ *again = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+