summaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2004-01-12 15:02:20 +0000
committerNick Clifton <nickc@redhat.com>2004-01-12 15:02:20 +0000
commitf3c94a6a66a45b9edd715d955ab96fbaaf1c69f3 (patch)
treeaf36cab76d043ed21601f05aed2d7850b2684da9 /bfd
parent0f9c40dbfe72dae13a0d77d5f0d105393b160d8f (diff)
downloadgdb-f3c94a6a66a45b9edd715d955ab96fbaaf1c69f3.tar.gz
Add support for relaxation of bit manipulation instructions.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/coff-h8300.c27
-rw-r--r--bfd/elf32-h8300.c52
2 files changed, 61 insertions, 18 deletions
diff --git a/bfd/coff-h8300.c b/bfd/coff-h8300.c
index e9d19643e43..dc35ea98d73 100644
--- a/bfd/coff-h8300.c
+++ b/bfd/coff-h8300.c
@@ -1,6 +1,6 @@
/* BFD back-end for Renesas H8/300 COFF binaries.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Steve Chamberlain, <sac@cygnus.com>.
@@ -666,6 +666,7 @@ h8300_reloc16_extra_cases (bfd *abfd, struct bfd_link_info *link_info,
bfd_vma value;
bfd_vma dot;
int gap, tmp;
+ unsigned char temp_code;
switch (reloc->howto->type)
{
@@ -947,8 +948,12 @@ h8300_reloc16_extra_cases (bfd *abfd, struct bfd_link_info *link_info,
if (data[dst_address - 2] != 0x6a)
abort ();
+ temp_code = data[src_address - 1];
+ if ((temp_code & 0x10) != 0x10)
+ temp_code &= 0xf0;
+
/* Fix up the opcode. */
- switch (data[src_address - 1] & 0xf0)
+ switch (temp_code)
{
case 0x00:
data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20;
@@ -956,6 +961,12 @@ h8300_reloc16_extra_cases (bfd *abfd, struct bfd_link_info *link_info,
case 0x80:
data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30;
break;
+ case 0x18:
+ data[dst_address - 2] = 0x7f;
+ break;
+ case 0x10:
+ data[dst_address - 2] = 0x7e;
+ break;
default:
abort ();
}
@@ -972,8 +983,12 @@ h8300_reloc16_extra_cases (bfd *abfd, struct bfd_link_info *link_info,
if (data[dst_address - 2] != 0x6a)
abort ();
+ temp_code = data[src_address - 1];
+ if ((temp_code & 0x30) != 0x30)
+ temp_code &= 0xf0;
+
/* Fix up the opcode. */
- switch (data[src_address - 1] & 0xf0)
+ switch (temp_code)
{
case 0x20:
data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20;
@@ -981,6 +996,12 @@ h8300_reloc16_extra_cases (bfd *abfd, struct bfd_link_info *link_info,
case 0xa0:
data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30;
break;
+ case 0x38:
+ data[dst_address - 2] = 0x7f;
+ break;
+ case 0x30:
+ data[dst_address - 2] = 0x7e;
+ break;
default:
abort ();
}
diff --git a/bfd/elf32-h8300.c b/bfd/elf32-h8300.c
index c3e94ccb752..c803af176e9 100644
--- a/bfd/elf32-h8300.c
+++ b/bfd/elf32-h8300.c
@@ -1010,6 +1010,7 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
if (value >= 0xffffff00u)
{
unsigned char code;
+ unsigned char temp_code;
/* Note that we've changed the relocs, section contents,
etc. */
@@ -1024,18 +1025,29 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
if (code != 0x6a)
abort ();
- code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+ temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+ if ((temp_code & 0x10) != 0x10)
+ temp_code &= 0xf0;
- if ((code & 0xf0) == 0x00)
- bfd_put_8 (abfd,
- (code & 0xf) | 0x20,
- contents + irel->r_offset - 2);
- else if ((code & 0xf0) == 0x80)
- bfd_put_8 (abfd,
- (code & 0xf) | 0x30,
- contents + irel->r_offset - 2);
- else
- abort ();
+ switch (temp_code)
+ {
+ case 0x00:
+ bfd_put_8 (abfd, (code & 0xf) | 0x20,
+ contents + irel->r_offset - 2);
+ break;
+ case 0x80:
+ bfd_put_8 (abfd, (code & 0xf) | 0x30,
+ contents + irel->r_offset - 2);
+ break;
+ case 0x18:
+ bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
+ break;
+ case 0x10:
+ bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
+ break;
+ default:
+ abort ();
+ }
/* Fix the relocation's type. */
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
@@ -1066,6 +1078,7 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
if (value >= 0xffffff00u)
{
unsigned char code;
+ unsigned char temp_code;
/* Note that we've changed the relocs, section contents,
etc. */
@@ -1080,9 +1093,12 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
if (code != 0x6a)
abort ();
- code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+ temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ if ((temp_code & 0x30) != 0x30)
+ temp_code &= 0xf0;
- switch (code & 0xf0)
+ switch (temp_code)
{
case 0x20:
bfd_put_8 (abfd, (code & 0xf) | 0x20,
@@ -1092,8 +1108,14 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
bfd_put_8 (abfd, (code & 0xf) | 0x30,
contents + irel->r_offset - 2);
break;
+ case 0x38:
+ bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
+ break;
+ case 0x30:
+ bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
+ break;
default:
- abort ();
+ abort();
}
/* Fix the relocation's type. */
@@ -1113,7 +1135,7 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
}
}
- /* FALLTHRU */
+ /* Fall through. */
/* This is a 24/32bit absolute address in a "mov" insn, which may
become a 16-bit absolute address if it is in the right range. */