+ /* This is a 24-/32-bit absolute address in one of the following
+ instructions:
+
+ "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
+ "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", "ldc.w",
+ "stc.w" and "mov.[bwl]"
+
+ We may relax this into an 16-bit absolute address if it's in
+ the right range. */
+ case R_MOVL2:
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+ value = bfd_h8300_pad_address (abfd, value);
+
+ /* Sanity check. */
+ if (value <= 0x7fff || value >= 0xffff8000u)
+ {
+ /* Insert the 16-bit value into the proper location. */
+ bfd_put_16 (abfd, value, data + dst_address);
+
+ /* Fix the opcode. For all the instructions that belong to
+ this relaxation, we simply need to turn off bit 0x20 in
+ the previous byte. */
+ data[dst_address - 1] &= ~0x20;
+ dst_address += 2;
+ src_address += 4;
+ }
+ else
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+ break;
+
+ /* A 16-bit absolute branch that is now an 8-bit pc-relative branch. */
+ case R_JMP2:
+ /* Get the address of the target of this branch. */
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* Get the address of the next instruction. */
+ dot = (input_section->output_offset
+ + dst_address
+ + link_order->u.indirect.section->output_section->vma + 1);
+
+ gap = value - dot;
+
+ /* Sanity check. */
+ if (gap < -128 || gap > 126)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+
+ /* Now fix the instruction itself. */
+ switch (data[dst_address - 1])
+ {
+ case 0x5e:
+ /* jsr -> bsr */
+ bfd_put_8 (abfd, 0x55, data + dst_address - 1);
+ break;
+ case 0x5a:
+ /* jmp -> bra */
+ bfd_put_8 (abfd, 0x40, data + dst_address - 1);
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* Write out the 8-bit value. */
+ bfd_put_8 (abfd, gap, data + dst_address);
+
+ dst_address += 1;
+ src_address += 3;
+
+ break;
+
+ /* A 16-bit pc-relative branch that is now an 8-bit pc-relative branch. */
+ case R_PCRWORD_B:
+ /* Get the address of the target of this branch. */
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* Get the address of the instruction (not the reloc). */
+ dot = (input_section->output_offset
+ + dst_address
+ + link_order->u.indirect.section->output_section->vma - 1);
+
+ gap = value - dot;
+
+ /* Sanity check. */
+ if (gap < -128 || gap > 126)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+
+ /* Now fix the instruction. */
+ switch (data[dst_address - 2])
+ {
+ case 0x58:
+ /* bCC:16 -> bCC:8 */
+ /* Get the second byte of the original insn, which contains
+ the condition code. */
+ tmp = data[dst_address - 1];
+
+ /* Compute the fisrt byte of the relaxed instruction. The
+ original sequence 0x58 0xX0 is relaxed to 0x4X, where X
+ represents the condition code. */
+ tmp &= 0xf0;
+ tmp >>= 4;
+ tmp |= 0x40;
+
+ /* Write it. */
+ bfd_put_8 (abfd, tmp, data + dst_address - 2);
+ break;
+
+ case 0x5c:
+ /* bsr:16 -> bsr:8 */
+ bfd_put_8 (abfd, 0x55, data + dst_address - 2);
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* Output the target. */
+ bfd_put_8 (abfd, gap, data + dst_address - 1);
+
+ /* We don't advance dst_address -- the 8-bit reloc is applied at
+ dst_address - 1, so the next insn should begin at dst_address. */
+ src_address += 2;
+
+ break;
+
+ /* Similarly for a 24-bit absolute that is now 8 bits. */
+ case R_JMPL2:
+ /* Get the address of the target of this branch. */
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* Get the address of the instruction (not the reloc). */
+ dot = (input_section->output_offset
+ + dst_address
+ + link_order->u.indirect.section->output_section->vma + 2);
+
+ gap = value - dot;
+
+ /* Fix the instruction. */
+ switch (data[src_address])
+ {
+ case 0x5e:
+ /* jsr -> bsr */
+ bfd_put_8 (abfd, 0x55, data + dst_address);
+ break;
+ case 0x5a:
+ /* jmp ->bra */
+ bfd_put_8 (abfd, 0x40, data + dst_address);
+ break;
+ default:
+ abort ();
+ }
+
+ bfd_put_8 (abfd, gap, data + dst_address + 1);
+ dst_address += 2;
+ src_address += 4;
+
+ break;
+
+ /* This is a 16-bit absolute address in one of the following
+ instructions:
+
+ "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
+ "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
+ "mov.b"
+
+ We may relax this into an 8-bit absolute address if it's in
+ the right range. */
+ case R_MOV16B2:
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* All instructions with R_H8_DIR16B2 start with 0x6a. */
+ if (data[dst_address - 2] != 0x6a)