From c9f5444e0ae58e5fd15e084521c04248a21b2e9e Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Fri, 3 May 1996 19:07:31 +0000 Subject: [PATCH] * coff-h8300.c (reloc_howto_type): Add howto entry for R_PCRWORD_B. (rtype2howto): Handle R_PCRWORD_B. (h8300_reloc16_extra_cases): Handle R_PCRWORD_B. (h8300_reloc_16_estimate): Likewise. Try to turn a 16bit pc-relative branch (R_PCRWORD) into an 8bit pc-relative branch (R_PCWORD_B). So we can turn 16bit pcrel branches into 8bit pcrel branches on the H8/300H. HMSE. --- bfd/ChangeLog | 10 ++++++ bfd/coff-h8300.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 69c0a3b820..99c3e355dd 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +Fri May 3 13:07:35 1996 Jeffrey A Law (law@cygnus.com) + + * coff-h8300.c (reloc_howto_type): Add howto entry for + R_PCRWORD_B. + (rtype2howto): Handle R_PCRWORD_B. + (h8300_reloc16_extra_cases): Handle R_PCRWORD_B. + (h8300_reloc_16_estimate): Likewise. Try to turn a 16bit + pc-relative branch (R_PCRWORD) into an 8bit pc-relative + branch (R_PCWORD_B). + Fri May 3 10:47:41 1996 Ian Lance Taylor * aoutx.h (translate_from_native_sym_flags): Set the section for diff --git a/bfd/coff-h8300.c b/bfd/coff-h8300.c index dc9385f7b2..8cf73db2b4 100644 --- a/bfd/coff-h8300.c +++ b/bfd/coff-h8300.c @@ -177,7 +177,7 @@ h8300_coff_link_hash_table_create (abfd) bfd_alloc (abfd, sizeof (struct h8300_coff_link_hash_table))); if (ret == NULL) return NULL; - if (!_bfd_link_hash_table_init (&ret->root.root, abfd, generic_link_hash_newfunc)) + if (!_bfd_link_hash_table_init (&ret->root.root, abfd, _bfd_generic_link_hash_newfunc)) { bfd_release (abfd, ret); return NULL; @@ -242,6 +242,9 @@ static reloc_howto_type howto_table[] = the function vector's entry in the jsr instruction. */ HOWTO (R_MEM_INDIRECT, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "8/indirect", false, 0x000000ff, 0x000000ff, false), + /* Internal reloc for relaxing. This is created when a 16bit pc-relative + branch is turned into an 8bit pc-relative branch. */ + HOWTO (R_PCRWORD_B, 0, 0, 8, true, 0, complain_overflow_bitfield, special, "pcrecl/16", false, 0x000000ff, 0x000000ff, false), }; @@ -326,6 +329,9 @@ rtype2howto (internal, dst) case R_MEM_INDIRECT: internal->howto = howto_table + 14; break; + case R_PCRWORD_B: + internal->howto = howto_table + 15; + break; default: abort (); break; @@ -400,6 +406,7 @@ h8300_reloc16_estimate(abfd, input_section, reloc, shrink, link_info) { case R_MOVB2: case R_JMP2: + case R_PCRWORD_B: shrink+=2; break; @@ -470,6 +477,34 @@ h8300_reloc16_estimate(abfd, input_section, reloc, shrink, link_info) reloc->howto = reloc->howto + 1; /* The place to relc moves back by one */ + /* This will be two bytes smaller in the long run */ + shrink +=2 ; + bfd_perform_slip(abfd, 2, input_section, address); + } + break; + + case R_PCRWORD: + + value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); + + dot = input_section->output_section->vma + + input_section->output_offset + address - 2; + + /* See if the address we're looking at within 127 bytes of where + we are, if so then we can use a small branch rather than the + jump we were going to */ + + gap = value - (dot - shrink); + + + if (-120 < (long)gap && (long)gap < 120 ) + { + + /* Change the reloc type from 16bit, possible 8 to 8bit + possible 16 */ + reloc->howto = howto_table + 15; + /* The place to relc moves back by one */ + /* This will be two bytes smaller in the long run */ shrink +=2 ; bfd_perform_slip(abfd, 2, input_section, address); @@ -477,7 +512,6 @@ h8300_reloc16_estimate(abfd, input_section, reloc, shrink, link_info) break; } - return shrink; } @@ -490,6 +524,8 @@ h8300_reloc16_estimate(abfd, input_section, reloc, shrink, link_info) R_JMP1 R_JMP2 jmp or pcrel branch R_JMPL1 R_JMPL_B8 24jmp or pcrel branch R_MOVLB1 R_MOVLB2 24 or 8 bit reloc for mov.b + R_PCRWORD R_PCRWORD_B 8 bit pcrel branch from 16bit pcrel + branch. */ @@ -644,7 +680,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, case R_JMP2: - /* Speciial relaxed type */ + /* Special relaxed type */ { bfd_vma dot = link_order->offset + dst_address @@ -678,6 +714,55 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, break; } break; + + case R_PCRWORD_B: + + /* Special relaxed type */ + { + bfd_vma dot = link_order->offset + + dst_address + + link_order->u.indirect.section->output_section->vma - 2; + + int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section) + - dot - 1); + + if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00)) + abort (); + + switch (data[dst_address - 2]) + { + int tmp; + + case 0x58: + /* bCC:16 -> bCC:8 */ + /* Get the condition code from the original insn. */ + tmp = data[dst_address - 1]; + tmp &= 0xf0; + tmp >>= 4; + + /* Now or in the high nibble of the opcode. */ + tmp |= 0x40; + + /* Write it. */ + bfd_put_8 (abfd, tmp, 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 8bit reloc is applied at + dst_address - 1, so the next insn should begin at dst_address. + + src_address is advanced by two (original reloc was 16bits). */ + src_address += 2; + + break; + } + break; case R_JMPL_B8: /* 24 bit branch which is now 8 bits */