From: Jeff Law Date: Wed, 1 Dec 1999 10:14:02 +0000 (+0000) Subject: * archures.c (bfd_mach_am33): Define. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=31f8dc8fceba2e10cc6d503cc6280db0504dd7f7;p=binutils-gdb.git * 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. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ec7e767a8d0..f7d3ffa9a17 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 * elf.c (bfd_get_elf_phdrs, bfd_get_elf_phdr_upper_bound): New diff --git a/bfd/archures.c b/bfd/archures.c index 66b16bbfc56..dac223ab16e 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 50539b124bc..93c9b7e8158 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 5aa0bfe9c88..aa5d0973ae7 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 c46dc0c7961..5dbd2d6d4d7 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);