aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/archures.c1
-rw-r--r--bfd/bfd-in2.h1
-rw-r--r--bfd/cpu-m10300.c19
-rw-r--r--bfd/elf-m10300.c160
5 files changed, 189 insertions, 3 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index ec7e767..f7d3ffa 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+Tue Nov 30 22:41:14 1999 Jeffrey A Law (law@cygnus.com)
+
+ * archures.c (bfd_mach_am33): Define.
+ * bfd-in2.h: Rebuilt.
+ * cpu-m10300.c (bfd_am33_arch): Add to the mn103 architecture list
+ * elf-m10300.c (mn10300_elf_relax_section): Handle am33 instructions.
+ (compute_function_info): Handle additional registers saved by
+ movm on the am33.
+ (elf_mn10300_mach): Handle E_MN10300_MACH_AM33.
+ (_bfd_mn10300_elf_final_write_processing): Handle bfd_mach_am33.
+
1999-11-29 Jim Blandy <jimb@cygnus.com>
* elf.c (bfd_get_elf_phdrs, bfd_get_elf_phdr_upper_bound): New
diff --git a/bfd/archures.c b/bfd/archures.c
index 66b16bb..dac223a 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -188,6 +188,7 @@ DESCRIPTION
. bfd_arch_mn10200, {* Matsushita MN10200 *}
. bfd_arch_mn10300, {* Matsushita MN10300 *}
.#define bfd_mach_mn10300 300
+.#define bfd_mach_am33 330
. bfd_arch_fr30,
.#define bfd_mach_fr30 0x46523330
. bfd_arch_mcore,
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 50539b124..93c9b7e 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1376,6 +1376,7 @@ enum bfd_architecture
bfd_arch_mn10200, /* Matsushita MN10200 */
bfd_arch_mn10300, /* Matsushita MN10300 */
#define bfd_mach_mn10300 300
+#define bfd_mach_am33 330
bfd_arch_fr30,
#define bfd_mach_fr30 0x46523330
bfd_arch_mcore,
diff --git a/bfd/cpu-m10300.c b/bfd/cpu-m10300.c
index 5aa0bfe..aa5d097 100644
--- a/bfd/cpu-m10300.c
+++ b/bfd/cpu-m10300.c
@@ -21,7 +21,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "sysdep.h"
#include "libbfd.h"
-#define NEXT NULL
+const bfd_arch_info_type bfd_am33_arch =
+ {
+ 32, /* 16 bits in a word */
+ 32, /* 16 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_mn10300,
+ 330,
+ "am33",
+ "am33",
+ 2,
+ false,
+ bfd_default_compatible,
+ bfd_default_scan ,
+ 0,
+ };
const bfd_arch_info_type bfd_mn10300_arch =
{
@@ -36,6 +50,5 @@ const bfd_arch_info_type bfd_mn10300_arch =
true, /* the one and only */
bfd_default_compatible,
bfd_default_scan ,
- NEXT,
+ &bfd_am33_arch,
};
-
diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c
index c46dc0c..5dbd2d6 100644
--- a/bfd/elf-m10300.c
+++ b/bfd/elf-m10300.c
@@ -1903,6 +1903,79 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
*again = true;
}
+ /* 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;
+ }
+ }
+
+ }
+ }
+ }
/* Try to turn a 32bit immediate, displacement or absolute address
into a 16bit immediate, displacement or absolute address. */
@@ -1911,6 +1984,74 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
bfd_vma value = symval;
value += irel->r_addend;
+ /* See if the value will fit in 24 bits.
+ We allow any 16bit match here. We prune those we can't
+ handle below. */
+ if ((long)value < 0x7fffff && (long)value > -0x800000)
+ {
+ unsigned char code;
+
+ /* AM33 insns which have 32bit operands are 7 bytes long and
+ will have 0xfe as the first byte. */
+
+ /* Get the first opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 3);
+
+ if (code == 0xfe)
+ {
+ /* Get the second opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+
+ /* All the am33 32 -> 24 relaxing possibilities. */
+ /* 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 16bit value. This is currently over
+ conservative. */
+ if ((value & 0x8000) == 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, 0xfd, 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_24);
+
+ /* Delete one byte of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 3, 1))
+ 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;
+ }
+ }
+
+ }
+ }
/* See if the value will fit in 16 bits.
We allow any 16bit match here. We prune those we can't
@@ -2333,6 +2474,20 @@ compute_function_info (abfd, hash, addr, contents)
if (hash->movm_args & 0x08)
hash->movm_stack_size += 8 * 4;
+ if (bfd_get_mach (abfd) == bfd_mach_am33)
+ {
+ /* "exother" space. e0, e1, mdrq, mcrh, mcrl, mcvf */
+ if (hash->movm_args & 0x1)
+ hash->movm_stack_size += 6 * 4;
+
+ /* exreg1 space. e4, e5, e6, e7 */
+ if (hash->movm_args & 0x2)
+ hash->movm_stack_size += 4 * 4;
+
+ /* exreg0 space. e2, e3 */
+ if (hash->movm_args & 0x4)
+ hash->movm_stack_size += 2 * 4;
+ }
}
/* Now look for the two stack adjustment variants. */
@@ -2724,6 +2879,8 @@ elf_mn10300_mach (flags)
default:
return bfd_mach_mn10300;
+ case E_MN10300_MACH_AM33:
+ return bfd_mach_am33;
}
}
@@ -2746,6 +2903,9 @@ _bfd_mn10300_elf_final_write_processing (abfd, linker)
val = E_MN10300_MACH_MN10300;
break;
+ case bfd_mach_am33:
+ val = E_MN10300_MACH_AM33;
+ break;
}
elf_elfheader (abfd)->e_flags &= ~ (EF_MN10300_MACH);