aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2013-03-21 16:08:07 +0000
committerNick Clifton <nickc@redhat.com>2013-03-21 16:08:07 +0000
commit81f5558e3d93654ed79b6ea28850a4798ea1404f (patch)
tree09a020b2f58cf3b34739e07297561af0184b61ba
parentb2f83c08372136fe9fe7d1df2feb5566c8b883fb (diff)
downloadgdb-81f5558e3d93654ed79b6ea28850a4798ea1404f.zip
gdb-81f5558e3d93654ed79b6ea28850a4798ea1404f.tar.gz
gdb-81f5558e3d93654ed79b6ea28850a4798ea1404f.tar.bz2
* elf32-h8300 (h8_relax_section): Add new relaxation of mov
@(disp:32,ERx) to mov @(disp:16,ERx). (R_H8_DISP32A16): New reloc. Comments added and corrected. * reloc.c (BFD_RELOC_H8_DISP32A16): New reloc. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. * ld.texinfo (H8/300): Add description of relaxation of mov @(disp:32,ERx) to mov @(disp:16,ERx). * ld-h8300/h8300.exp: Add new relax-7 test on ELF. * ld-h8300/relax-2.s: Add other direction and .w/.l variants of mov insns. * ld-h8300/relax-2.d: Update expected disassembly. * ld-h8300/relax-7a.s: New: tests for mov @(disp:32,ERx) -> mov @(disp:16,ERx). * ld-h8300/relax-7b.s: New: Likewise. * ld-h8300/relax-7.d: New: expected disassembly. * config/tc-h8300.c (do_a_fix_imm): Add relaxation of mov @(disp:32,ERx) to mov @(disp:16,ERx) insns by new reloc R_H8_DISP32A16. * config/tc-h8300.h: Remove duplicated defines.
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/bfd-in2.h1
-rw-r--r--bfd/elf32-h8300.c212
-rw-r--r--bfd/elflink.c1
-rw-r--r--bfd/libbfd.h1
-rw-r--r--bfd/reloc.c7
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-h8300.c33
-rw-r--r--gas/config/tc-h8300.h6
-rw-r--r--include/elf/ChangeLog5
-rw-r--r--include/elf/h8.h5
-rw-r--r--include/opcode/ChangeLog5
-rw-r--r--include/opcode/h8300.h14
-rw-r--r--ld/ChangeLog5
-rw-r--r--ld/ld.texinfo10
-rw-r--r--ld/testsuite/ChangeLog11
-rw-r--r--ld/testsuite/ld-h8300/h8300.exp3
-rw-r--r--ld/testsuite/ld-h8300/relax-2.d14
-rw-r--r--ld/testsuite/ld-h8300/relax-2.s16
-rw-r--r--ld/testsuite/ld-h8300/relax-7.d81
-rw-r--r--ld/testsuite/ld-h8300/relax-7a.s66
-rw-r--r--ld/testsuite/ld-h8300/relax-7b.s19
22 files changed, 449 insertions, 83 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index a7d29dc..8439b55 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,13 @@
+2013-03-21 Michael Schewe <michael.schewe@gmx.net>
+
+ * elf32-h8300 (h8_relax_section): Add new relaxation of mov
+ @(disp:32,ERx) to mov @(disp:16,ERx).
+ (R_H8_DISP32A16): New reloc.
+ Comments added and corrected.
+ * reloc.c (BFD_RELOC_H8_DISP32A16): New reloc.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
2013-03-21 Kai Tietz <ktietz@redhat.com>
* coffgen.c (coff_real_object_p): Make global.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 2f49b1d..55ebb79 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -4869,6 +4869,7 @@ a matching LO8XG part. */
BFD_RELOC_H8_DIR24A8,
BFD_RELOC_H8_DIR24R8,
BFD_RELOC_H8_DIR32A16,
+ BFD_RELOC_H8_DISP32A16,
/* Sony Xstormy16 Relocations. */
BFD_RELOC_XSTORMY16_REL_12,
diff --git a/bfd/elf32-h8300.c b/bfd/elf32-h8300.c
index 43ac16e..4cfc30e 100644
--- a/bfd/elf32-h8300.c
+++ b/bfd/elf32-h8300.c
@@ -1,6 +1,5 @@
/* BFD back-end for Renesas H8/300 ELF binaries.
- Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006,
- 2007, 2008, 2009, 2010, 2012 Free Software Foundation, Inc.
+ Copyright 1993-2013 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -185,7 +184,21 @@ static reloc_howto_type h8_elf_howto_table[] =
0, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
-#define R_H8_PCREL16_X (R_H8_DIR32A16_X + 1)
+#define R_H8_DISP32A16_X (R_H8_DIR32A16_X + 1)
+ HOWTO (R_H8_DISP32A16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ special, /* special_function */
+ "R_H8_DISP32A16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#define R_H8_PCREL16_X (R_H8_DISP32A16_X + 1)
HOWTO (R_H8_PCREL16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
@@ -234,6 +247,7 @@ static const struct elf_reloc_map h8_reloc_map[] = {
{ BFD_RELOC_H8_DIR24A8, R_H8_DIR24A8_X },
{ BFD_RELOC_H8_DIR24R8, R_H8_DIR24R8_X },
{ BFD_RELOC_H8_DIR32A16, R_H8_DIR32A16_X },
+ { BFD_RELOC_H8_DISP32A16, R_H8_DISP32A16_X },
{ BFD_RELOC_16_PCREL, R_H8_PCREL16_X },
{ BFD_RELOC_8_PCREL, R_H8_PCREL8_X },
};
@@ -338,6 +352,7 @@ elf32_h8_final_link_relocate (unsigned long r_type, bfd *input_bfd,
case R_H8_DIR32:
case R_H8_DIR32A16:
+ case R_H8_DISP32A16:
case R_H8_DIR24A8:
value += addend;
bfd_put_32 (input_bfd, value, hit_data);
@@ -670,7 +685,9 @@ elf32_h8_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
bset:24/32 -> bset:16 2 bytes
(also applicable to other bit manipulation instructions)
- mov.[bwl]:24/32 -> mov.[bwl]:16 2 bytes */
+ mov.[bwl]:24/32 -> mov.[bwl]:16 2 bytes
+
+ mov.[bwl] @(displ:24/32+ERx) -> mov.[bwl] @(displ:16+ERx) 4 bytes. */
static bfd_boolean
elf32_h8_relax_section (bfd *abfd, asection *sec,
@@ -725,13 +742,19 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
some long jumps created by the compiler. */
if (irel != internal_relocs)
last_reloc = irel - 1;
-
- if (ELF32_R_TYPE (irel->r_info) != R_H8_DIR24R8
- && ELF32_R_TYPE (irel->r_info) != R_H8_PCREL16
- && ELF32_R_TYPE (irel->r_info) != R_H8_DIR16A8
- && ELF32_R_TYPE (irel->r_info) != R_H8_DIR24A8
- && ELF32_R_TYPE (irel->r_info) != R_H8_DIR32A16)
- continue;
+
+ switch(ELF32_R_TYPE (irel->r_info))
+ {
+ case R_H8_DIR24R8:
+ case R_H8_PCREL16:
+ case R_H8_DIR16A8:
+ case R_H8_DIR24A8:
+ case R_H8_DIR32A16:
+ case R_H8_DISP32A16:
+ break;
+ default:
+ continue;
+ }
/* Get the section contents if we haven't done so already. */
if (contents == NULL)
@@ -807,8 +830,8 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
the linker is run. */
switch (ELF32_R_TYPE (irel->r_info))
{
- /* Try to turn a 24-bit absolute branch/call into an 8-bit
- pc-relative branch/call. */
+ /* Try to turn a 24-bit absolute branch/call into an 8-bit
+ pc-relative branch/call. */
case R_H8_DIR24R8:
{
bfd_vma value = symval + irel->r_addend;
@@ -848,19 +871,19 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
Only perform this optimisation for jumps (code 0x5a) not
subroutine calls, as otherwise it could transform:
- mov.w r0,r0
- beq .L1
- jsr @_bar
- .L1: rts
- _bar: rts
+ mov.w r0,r0
+ beq .L1
+ jsr @_bar
+ .L1: rts
+ _bar: rts
into:
- mov.w r0,r0
- bne _bar
- rts
- _bar: rts
+ mov.w r0,r0
+ bne _bar
+ rts
+ _bar: rts
which changes the call (jsr) into a branch (bne). */
- if (code == 0x5a
+ if (code == 0x5a /* jmp24. */
&& (int) gap <= 130
&& (int) gap >= -128
&& last_reloc
@@ -904,7 +927,7 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
code ^= 1;
bfd_put_8 (abfd,
code,
- contents + last_reloc->r_offset - 1);
+ contents + last_reloc->r_offset - 1);
/* Delete four bytes of data. */
if (!elf32_h8_relax_delete_bytes (abfd, sec,
@@ -918,11 +941,11 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
}
if (code == 0x5e)
- /* This is jsr. */
- bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 1);
+ /* This is jsr24 */
+ bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 1); /* bsr8. */
else if (code == 0x5a)
- /* This is jmp. */
- bfd_put_8 (abfd, 0x40, contents + irel->r_offset - 1);
+ /* This is jmp24 */
+ bfd_put_8 (abfd, 0x40, contents + irel->r_offset - 1); /* bra8. */
else
abort ();
@@ -942,8 +965,8 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
break;
}
- /* Try to turn a 16-bit pc-relative branch into a 8-bit pc-relative
- branch. */
+ /* Try to turn a 16-bit pc-relative branch into a 8-bit pc-relative
+ branch. */
case R_H8_PCREL16:
{
bfd_vma value = symval + irel->r_addend;
@@ -980,18 +1003,18 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
contains the condition code. */
code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
- /* Compute the fisrt byte of the relaxed
+ /* Compute the first byte of the relaxed
instruction. The original sequence 0x58 0xX0
is relaxed to 0x4X, where X represents the
condition code. */
code &= 0xf0;
code >>= 4;
code |= 0x40;
- bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 2); /* bCC:8. */
}
- else if (code == 0x5c)
+ else if (code == 0x5c) /* bsr16. */
/* This is bsr. */
- bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2);
+ bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2); /* bsr8. */
else
/* Might be MOVSD. */
break;
@@ -1013,15 +1036,15 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
break;
}
- /* This is a 16-bit absolute address in one of the following
- instructions:
+ /* 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. */
+ We may relax this into an 8-bit absolute address if it's in
+ the right range. */
case R_H8_DIR16A8:
{
bfd_vma value;
@@ -1101,15 +1124,15 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
break;
}
- /* This is a 24-bit absolute address in one of the following
- instructions:
+ /* This is a 24-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. */
+ We may relax this into an 8-bit absolute address if it's in
+ the right range. */
case R_H8_DIR24A8:
{
bfd_vma value;
@@ -1176,7 +1199,7 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
R_H8_DIR8);
irel->r_offset--;
- /* Delete two bytes of data. */
+ /* Delete four bytes of data. */
if (!elf32_h8_relax_delete_bytes (abfd, sec,
irel->r_offset + 1, 4))
goto error_return;
@@ -1193,9 +1216,9 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
/* 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]"
+ "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. */
@@ -1218,7 +1241,7 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
if (irel->r_offset >= 4)
{
- /* Check for 4-byte MOVA relaxation. */
+ /* Check for 4-byte MOVA relaxation (SH-specific). */
int second_reloc = 0;
op_ptr = contents + irel->r_offset - 4;
@@ -1239,6 +1262,7 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
second_reloc = 1;
}
}
+
if (irel + 1 < irelend)
{
Elf_Internal_Rela *next_reloc = irel + 1;
@@ -1284,7 +1308,7 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
}
}
- /* Now check for short version of MOVA. */
+ /* Now check for short version of MOVA. (SH-specific) */
op_ptr = contents + irel->r_offset - 2;
op0 = bfd_get_8 (abfd, op_ptr + 0);
op1 = bfd_get_8 (abfd, op_ptr + 1);
@@ -1321,9 +1345,99 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
Note that this is not required, and it may be slow. */
*again = TRUE;
}
- break;
+ break; /* case R_H8_DIR32A16 */
}
+ case R_H8_DISP32A16:
+ /* mov.[bwl] @(displ:24/32+ERx) -> mov.[bwl] @(displ:16+ERx) 4 bytes
+ It is assured that instruction uses at least 4 bytes opcode before
+ reloc entry addressing mode "register indirect with displacement"
+ relaxing options (all saving 4 bytes):
+ 0x78 0sss0000 0x6A 0010dddd disp:32 mov.b @(d:32,ERs),Rd ->
+ 0x6E 0sssdddd disp:16 mov.b @(d:16,ERs),Rd
+ 0x78 0sss0000 0x6B 0010dddd disp:32 mov.w @(d:32,ERs),Rd ->
+ 0x6F 0sssdddd disp:16 mov.w @(d:16,ERs),Rd
+ 0x01 0x00 0x78 0sss0000 0x6B 00100ddd disp:32 mov.l @(d:32,ERs),ERd ->
+ 0x01 0x00 0x6F 0sss0ddd disp:16 mov.l @(d:16,ERs),ERd
+
+ 0x78 0ddd0000 0x6A 1010ssss disp:32 mov.b Rs,@(d:32,ERd) ->
+ 0x6E 1dddssss disp:16 mov.b Rs,@(d:16,ERd)
+ 0x78 0ddd0000 0x6B 1010ssss disp:32 mov.w Rs,@(d:32,ERd) ->
+ 0x6F 1dddssss disp:16 mov.w Rs,@(d:16,ERd)
+ 0x01 0x00 0x78 xddd0000 0x6B 10100sss disp:32 mov.l ERs,@(d:32,ERd) ->
+ 0x01 0x00 0x6F 1ddd0sss disp:16 mov.l ERs,@(d:16,ERd)
+ mov.l prefix 0x01 0x00 can be left as is and mov.l handled same
+ as mov.w/ */
+ {
+ bfd_vma value;
+
+ value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
+ if (value <= 0x7fff || value >= 0xffff8000u)
+ {
+ unsigned char op0, op1, op2, op3, op0n, op1n;
+ int relax = 0;
+
+ /* Note that we've changed the relocs, section contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ if (irel->r_offset >= 4)
+ {
+ op0 = bfd_get_8 (abfd, contents + irel->r_offset - 4);
+ op1 = bfd_get_8 (abfd, contents + irel->r_offset - 3);
+ op2 = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+ op3 = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ if (op0 == 0x78)
+ {
+ switch(op2)
+ {
+ case 0x6A:
+ if ((op1 & 0x8F) == 0x00 && (op3 & 0x70) == 0x20)
+ {
+ /* mov.b. */
+ op0n = 0x6E;
+ relax = 1;
+ }
+ break;
+ case 0x6B:
+ if ((op1 & 0x0F) == 0x00 && (op3 & 0x70) == 0x20)
+ {
+ /* mov.w/l. */
+ op0n = 0x6F;
+ relax = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (relax)
+ {
+ op1n = (op3 & 0x8F) | (op1 & 0x70);
+ bfd_put_8 (abfd, op0n, contents + irel->r_offset - 4);
+ bfd_put_8 (abfd, op1n, contents + irel->r_offset - 3);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_H8_DIR16);
+ irel->r_offset -= 2;
+
+ /* Delete four bytes of data. */
+ if (!elf32_h8_relax_delete_bytes (abfd, sec, irel->r_offset + 2, 4))
+ 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;
+
default:
break;
}
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 6ccf625..fa805bc 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -4498,6 +4498,7 @@ error_free_dyn:
--no-add-needed is used and the reference was not
a weak one. */
if (undef_bfd != NULL
+ && h->ref_regular_nonweak
&& (elf_dyn_lib_class (abfd) & DYN_NO_NEEDED) != 0)
{
(*_bfd_error_handler)
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 857d1ea..6a4b572 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2349,6 +2349,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_H8_DIR24A8",
"BFD_RELOC_H8_DIR24R8",
"BFD_RELOC_H8_DIR32A16",
+ "BFD_RELOC_H8_DISP32A16",
"BFD_RELOC_XSTORMY16_REL_12",
"BFD_RELOC_XSTORMY16_12",
"BFD_RELOC_XSTORMY16_24",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index b59ca00..e93b3b9 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -1,8 +1,5 @@
/* BFD support for handling relocation entries.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
- 2012
- Free Software Foundation, Inc.
+ Copyright 1990-2013 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@@ -5584,6 +5581,8 @@ ENUMX
BFD_RELOC_H8_DIR24R8
ENUMX
BFD_RELOC_H8_DIR32A16
+ENUMX
+ BFD_RELOC_H8_DISP32A16
ENUMDOC
H8 elf Relocations.
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 4e09946..c36941a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,10 @@
+2013-03-21 Michael Schewe <michael.schewe@gmx.net>
+
+ * config/tc-h8300.c (do_a_fix_imm): Add relaxation of mov
+ @(disp:32,ERx) to mov @(disp:16,ERx) insns by new reloc
+ R_H8_DISP32A16.
+ * config/tc-h8300.h: Remove duplicated defines.
+
2013-03-21 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
PR gas/15282
diff --git a/gas/config/tc-h8300.c b/gas/config/tc-h8300.c
index bbf8c0e..032831b 100644
--- a/gas/config/tc-h8300.c
+++ b/gas/config/tc-h8300.c
@@ -1,7 +1,5 @@
/* tc-h8300.c -- Assemble code for the Renesas H8/300
- Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012
- Free Software Foundation, Inc.
+ Copyright 1991-2013 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -1396,7 +1394,12 @@ do_a_fix_imm (int offset, int nibble, struct h8_op *operand, int relaxmode, cons
bytes[3] |= operand->exp.X_add_number >> 0;
if (relaxmode != 0)
{
- idx = (relaxmode == 2) ? R_MOV24B1 : R_MOVL1;
+#ifdef OBJ_ELF
+ if ((operand->mode & MODE) == DISP && relaxmode == 1)
+ idx = BFD_RELOC_H8_DISP32A16;
+ else
+#endif
+ idx = (relaxmode == 2) ? R_MOV24B1 : R_MOVL1;
fix_new_exp (frag_now, offset, 4, &operand->exp, 0, idx);
}
break;
@@ -1410,6 +1413,11 @@ do_a_fix_imm (int offset, int nibble, struct h8_op *operand, int relaxmode, cons
case L_32:
size = 4;
where = (operand->mode & SIZE) == L_24 ? -1 : 0;
+#ifdef OBJ_ELF
+ if ((operand->mode & MODE) == DISP && relaxmode == 1)
+ idx = BFD_RELOC_H8_DISP32A16;
+ else
+#endif
if (relaxmode == 2)
idx = R_MOV24B1;
else if (relaxmode == 1)
@@ -1616,7 +1624,7 @@ build_bytes (const struct h8_instruction *this_try, struct h8_op *operand)
for (i = 0; i < this_try->length; i++)
output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1];
- /* Note if this is a movb or a bit manipulation instruction
+ /* Note if this is a mov.b or a bit manipulation instruction
there is a special relaxation which only applies. */
if ( this_try->opcode->how == O (O_MOV, SB)
|| this_try->opcode->how == O (O_BCLR, SB)
@@ -1642,10 +1650,17 @@ build_bytes (const struct h8_instruction *this_try, struct h8_op *operand)
int x_mode = x & MODE;
if (x_mode == IMM || x_mode == DISP)
- do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
- op_at[i] & 1, operand + i, (x & MEMRELAX) != 0,
- this_try);
-
+ {
+#ifndef OBJ_ELF
+ /* Remove MEMRELAX flag added in h8300.h on mov with
+ addressing mode "register indirect with displacement". */
+ if (x_mode == DISP)
+ x &= ~MEMRELAX;
+#endif
+ do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
+ op_at[i] & 1, operand + i, (x & MEMRELAX) != 0,
+ this_try);
+ }
else if (x_mode == ABS)
do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
op_at[i] & 1, operand + i,
diff --git a/gas/config/tc-h8300.h b/gas/config/tc-h8300.h
index f86cf94..0a2e828 100644
--- a/gas/config/tc-h8300.h
+++ b/gas/config/tc-h8300.h
@@ -1,7 +1,5 @@
/* This file is tc-h8300.h
- Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright 1987-2013 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -60,8 +58,6 @@ struct internal_reloc;
ports. */
#define R_MOV24B1 BFD_RELOC_H8_DIR24A8
#define R_MOVL1 BFD_RELOC_H8_DIR32A16
-#define R_MOV24B1 BFD_RELOC_H8_DIR24A8
-#define R_MOVL1 BFD_RELOC_H8_DIR32A16
#define R_RELLONG BFD_RELOC_32
#define R_MOV16B1 BFD_RELOC_H8_DIR16A8
#define R_RELWORD BFD_RELOC_16
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
index f08ca6b..c7265920 100644
--- a/include/elf/ChangeLog
+++ b/include/elf/ChangeLog
@@ -1,3 +1,8 @@
+2013-03-21 Michael Schewe <michael.schewe@gmx.net>
+
+ * h8.h: Add new reloc R_H8_DISP32A16 for relaxation of
+ mov @(disp:32,ERx) to mov @(disp:16,ERx).
+
2013-03-08 Andreas Arnez <arnez@linux.vnet.ibm.com>
* common.h (NT_S390_TDB): Define.
diff --git a/include/elf/h8.h b/include/elf/h8.h
index 36aef6a..2a3d905 100644
--- a/include/elf/h8.h
+++ b/include/elf/h8.h
@@ -1,5 +1,5 @@
/* H8300/h8500 ELF support for BFD.
- Copyright 2001, 2003, 2010 Free Software Foundation, Inc.
+ Copyright 2001-2013 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -23,7 +23,7 @@
#include "elf/reloc-macros.h"
/* Relocations. */
-/* Relocations 59..63 are GNU extensions. */
+/* Relocations 59..64 are GNU extensions. */
START_RELOC_NUMBERS (elf_h8_reloc_type)
RELOC_NUMBER (R_H8_NONE, 0)
RELOC_NUMBER (R_H8_DIR32, 1)
@@ -65,6 +65,7 @@ START_RELOC_NUMBERS (elf_h8_reloc_type)
RELOC_NUMBER (R_H8_DIR24A8, 61)
RELOC_NUMBER (R_H8_DIR24R8, 62)
RELOC_NUMBER (R_H8_DIR32A16, 63)
+ RELOC_NUMBER (R_H8_DISP32A16, 64)
RELOC_NUMBER (R_H8_ABS32, 65)
RELOC_NUMBER (R_H8_ABS32A16, 127)
RELOC_NUMBER (R_H8_SYM, 128)
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index cc7ef5f..bdf990e 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -1,3 +1,8 @@
+2013-03-21 Michael Schewe <michael.schewe@gmx.net>
+
+ * h8300.h: Add MEMRELAX flag for mov.b/w/l @(d:32,ERs),Rd
+ and mov.b/w/l Rs,@(d:32,ERd).
+
2013-03-20 Alexis Deruelle <alexis.deruelle@gmail.com>
PR gas/15082
diff --git a/include/opcode/h8300.h b/include/opcode/h8300.h
index 81b1c08..3296deb 100644
--- a/include/opcode/h8300.h
+++ b/include/opcode/h8300.h
@@ -1,7 +1,5 @@
/* Opcode table for the H8/300
- Copyright 1991, 1992, 1993, 1994, 1996, 1997, 1998, 2000, 2001, 2002,
- 2003, 2004, 2005, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright 1991-2013 Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>.
This file is part of GDB, the GNU Debugger and GAS, the GNU Assembler.
@@ -553,7 +551,7 @@ struct h8_opcode
{CODE, AV_H8, 6, NAME, {{SRC, RDPREDEC, E}}, {{ 6, OP3, B31 | RDPREDEC, SRC, E}}}, \
{CODE, AV_H8SX, 0, NAME, {{SRC, DISP2DST, E}}, {{PREFIX, B30 | B20 | DISP2DST, 6, OP1, B31 | DSTDISPREG, SRC, E}}}, \
{CODE, AV_H8, 6, NAME, {{SRC, DISP16DST, E}}, {{ 6, OP4, B31 | DSTDISPREG, SRC, DSTDISP16LIST, E}}}, \
- {CODE, AV_H8, 6, NAME, {{SRC, DISP32DST, E}}, {{7, 8, B30 | DSTDISPREG, 0, 6, OP2, 10, SRC, DSTDISP32LIST, E}}}, \
+ {CODE, AV_H8, 6, NAME, {{SRC, DISP32DST, E}}, {{7, 8, B30 | DSTDISPREG, 0, 6, OP2, 10, SRC, MEMRELAX | DSTDISP32LIST, E}}}, \
{CODE, AV_H8SX, 0, NAME, {{SRC, INDEXB16D, E}}, {{PREFIX, 1, 6, OP4, B31 | DSTDISPREG, SRC, DSTDISP16LIST, E}}}, \
{CODE, AV_H8SX, 0, NAME, {{SRC, INDEXW16D, E}}, {{PREFIX, 2, 6, OP4, B31 | DSTDISPREG, SRC, DSTDISP16LIST, E}}}, \
{CODE, AV_H8SX, 0, NAME, {{SRC, INDEXL16D, E}}, {{PREFIX, 3, 6, OP4, B31 | DSTDISPREG, SRC, DSTDISP16LIST, E}}}, \
@@ -571,7 +569,7 @@ struct h8_opcode
{CODE, AV_H8SX, 0, NAME, {{RSPREDEC, DST, E}}, {{PREFIX, 3, 6, OP3, B30 | RSPREDEC, DST, E}}}, \
{CODE, AV_H8SX, 0, NAME, {{DISP2SRC, DST, E}}, {{PREFIX, B30 | B20 | DISP2SRC, 6, OP1, B30 | DISPREG, DST, E}}}, \
{CODE, AV_H8, 6, NAME, {{DISP16SRC, DST, E}}, {{ 6, OP4, B30 | DISPREG, DST, DISP16LIST, E}}}, \
- {CODE, AV_H8, 6, NAME, {{DISP32SRC, DST, E}}, {{7, 8, B30 | DISPREG, 0, 6, OP2, 2, DST, DISP32LIST, E}}}, \
+ {CODE, AV_H8, 6, NAME, {{DISP32SRC, DST, E}}, {{7, 8, B30 | DISPREG, 0, 6, OP2, 2, DST, MEMRELAX | DISP32LIST, E}}}, \
{CODE, AV_H8SX, 0, NAME, {{INDEXB16, DST, E}}, {{PREFIX, 1, 6, OP4, B30 | DISPREG, DST, DISP16LIST, E}}}, \
{CODE, AV_H8SX, 0, NAME, {{INDEXW16, DST, E}}, {{PREFIX, 2, 6, OP4, B30 | DISPREG, DST, DISP16LIST, E}}}, \
{CODE, AV_H8SX, 0, NAME, {{INDEXL16, DST, E}}, {{PREFIX, 3, 6, OP4, B30 | DISPREG, DST, DISP16LIST, E}}}, \
@@ -1518,8 +1516,8 @@ struct h8_opcode h8_opcodes[] =
{O (O_MOV, SL), AV_H8SX, 0, "mov.l", {{RS32, DISP2DST, E}}, {{PREFIX_010, B30 | B20 | DISP2DST, 0x6, 0x9, B31 | DSTDISPREG, RS32, E}}},
{O (O_MOV, SL), AV_H8H, 6, "mov.l", {{RS32, DISP16DST, E}}, {{PREFIX_0100, 0x6, 0xf, B31 | DSTDISPREG, RS32, DSTDISP16LIST, E}}},
{O (O_MOV, SL), AV_H8SX, 6, "mov.l", {{RS32, DISP32DST, E}}, {{0x7, 0x8, B31 | DSTDISPREG, 0x0, 0x6, 0xb, 0xa, RS32, DSTDISP32LIST, E}}},
- {O (O_MOV, SL), AV_H8H, 6, "mov.l", {{RS32, DISP32DST, E}}, {{PREFIX_0100, 0x7, 0x8, B31 | DSTDISPREG, 0x0, 0x6, 0xb, 0xa, RS32, DSTDISP32LIST, E}}},
- {O (O_MOV, SL), AV_H8H, 6, "mov.l", {{RS32, DISP32DST, E}}, {{PREFIX_0100, 0x7, 0x8, DSTDISPREG, 0x0, 0x6, 0xb, 0xa, RS32, DSTDISP32LIST, E}}},
+ {O (O_MOV, SL), AV_H8H, 6, "mov.l", {{RS32, DISP32DST, E}}, {{PREFIX_0100, 0x7, 0x8, B31 | DSTDISPREG, 0x0, 0x6, 0xb, 0xa, RS32, MEMRELAX | DSTDISP32LIST, E}}},
+ {O (O_MOV, SL), AV_H8H, 6, "mov.l", {{RS32, DISP32DST, E}}, {{PREFIX_0100, 0x7, 0x8, DSTDISPREG, 0x0, 0x6, 0xb, 0xa, RS32, MEMRELAX | DSTDISP32LIST, E}}},
{O (O_MOV, SL), AV_H8SX, 0, "mov.l", {{RS32, INDEXB16D, E}}, {{PREFIX_0101, 0x6, 0xf, B31 | DSTDISPREG, RS32, DSTDISP16LIST, E}}},
{O (O_MOV, SL), AV_H8SX, 0, "mov.l", {{RS32, INDEXW16D, E}}, {{PREFIX_0102, 0x6, 0xf, B31 | DSTDISPREG, RS32, DSTDISP16LIST, E}}},
{O (O_MOV, SL), AV_H8SX, 0, "mov.l", {{RS32, INDEXL16D, E}}, {{PREFIX_0103, 0x6, 0xf, B31 | DSTDISPREG, RS32, DSTDISP16LIST, E}}},
@@ -1537,7 +1535,7 @@ struct h8_opcode h8_opcodes[] =
{O (O_MOV, SL), AV_H8SX, 0, "mov.l", {{DISP2SRC, RD32, E}}, {{PREFIX_010, B30 | B20 | DISP2SRC, 0x6, 0x9, B30 | DISPREG, RD32, E}}},
{O (O_MOV, SL), AV_H8H, 6, "mov.l", {{DISP16SRC, RD32, E}}, {{PREFIX_0100, 0x6, 0xf, B30 | DISPREG, RD32, SRC | DISP16LIST, E}}},
{O (O_MOV, SL), AV_H8SX, 6, "mov.l", {{DISP32SRC, RD32, E}}, {{0x7, 0x8, B31 | DISPREG, 0x0, 0x6, 0xb, 0x2, RD32, SRC | DISP32LIST, E}}},
- {O (O_MOV, SL), AV_H8H, 6, "mov.l", {{DISP32SRC, RD32, E}}, {{PREFIX_0100, 0x7, 0x8, B30 | DISPREG, 0x0, 0x6, 0xb, 0x2, RD32, SRC | DISP32LIST, E}}},
+ {O (O_MOV, SL), AV_H8H, 6, "mov.l", {{DISP32SRC, RD32, E}}, {{PREFIX_0100, 0x7, 0x8, B30 | DISPREG, 0x0, 0x6, 0xb, 0x2, RD32, MEMRELAX | SRC | DISP32LIST, E}}},
{O (O_MOV, SL), AV_H8SX, 0, "mov.l", {{INDEXB16, RD32, E}}, {{PREFIX_0101, 0x6, 0xf, B30 | DISPREG, RD32, SRC | DISP16LIST, E}}},
{O (O_MOV, SL), AV_H8SX, 0, "mov.l", {{INDEXW16, RD32, E}}, {{PREFIX_0102, 0x6, 0xf, B30 | DISPREG, RD32, SRC | DISP16LIST, E}}},
{O (O_MOV, SL), AV_H8SX, 0, "mov.l", {{INDEXL16, RD32, E}}, {{PREFIX_0103, 0x6, 0xf, B30 | DISPREG, RD32, SRC | DISP16LIST, E}}},
diff --git a/ld/ChangeLog b/ld/ChangeLog
index e733147..93a52dc 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,8 @@
+2013-03-21 Michael Schewe <michael.schewe@gmx.net>
+
+ * ld.texinfo (H8/300): Add description of relaxation of
+ mov @(disp:32,ERx) to mov @(disp:16,ERx).
+
2013-03-21 Kai Tietz <ktietz@redhat.com>
* pe-dll.c (process_def_file_and_drectve): Don't handle VC
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 1f8e34d..7fae2c2 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -6078,7 +6078,7 @@ respectively.
@cindex synthesizing on H8/300
@item synthesizing instructions
-@c FIXME: specifically mov.b, or any mov instructions really?
+@c FIXME: specifically mov.b, or any mov instructions really? -> mov.b only, at least on H8, H8H, H8S
@command{ld} finds all @code{mov.b} instructions which use the
sixteen-bit absolute address form, but refer to the top
page of memory, and changes them to use the eight-bit address form.
@@ -6086,6 +6086,14 @@ page of memory, and changes them to use the eight-bit address form.
@samp{mov.b @code{@@}@var{aa}:8} whenever the address @var{aa} is in the
top page of memory).
+@command{ld} finds all @code{mov} instructions which use the register
+indirect with 32-bit displacement addressing mode, but use a small
+displacement inside 16-bit displacement range, and changes them to use
+the 16-bit displacement form. (That is: the linker turns @samp{mov.b
+@code{@@}@var{d}:32,ERx} into @samp{mov.b @code{@@}@var{d}:16,ERx}
+whenever the displacement @var{d} is in the 16 bit signed integer
+range. Only implemented in ELF-format ld).
+
@item bit manipulation instructions
@command{ld} finds all bit manipulation instructions like @code{band, bclr,
biand, bild, bior, bist, bixor, bld, bnot, bor, bset, bst, btst, bxor}
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index c30e3cd..4c1cac7 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2013-02-02 Michael Schewe <michael.schewe@gmx.net>
+
+ * ld-h8300/h8300.exp: Add new relax-7 test on ELF.
+ * ld-h8300/relax-2.s: Add other direction and .w/.l variants of
+ mov insns.
+ * ld-h8300/relax-2.d: Update expected disassembly.
+ * ld-h8300/relax-7a.s: New: tests for mov @(disp:32,ERx) -> mov
+ @(disp:16,ERx).
+ * ld-h8300/relax-7b.s: New: Likewise.
+ * ld-h8300/relax-7.d: New: expected disassembly.
+
2013-03-20 Venkataramanan Kumar <venkataramanan.kumar@linaro.org>
* ld-elf/group8a.d (notarget): Remove aarch64*-*-*.
diff --git a/ld/testsuite/ld-h8300/h8300.exp b/ld/testsuite/ld-h8300/h8300.exp
index 3604dfa..240c7c3 100644
--- a/ld/testsuite/ld-h8300/h8300.exp
+++ b/ld/testsuite/ld-h8300/h8300.exp
@@ -1,5 +1,5 @@
# Expect script for ld-h8300 tests
-# Copyright 2002, 2003, 2004, 2005, 2007, 2010 Free Software Foundation, Inc.
+# Copyright 2002-2013 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
@@ -35,6 +35,7 @@ if [is_elf_format] {
run_dump_test relax-4
run_dump_test relax-5
run_dump_test relax-6
+ run_dump_test relax-7
run_dump_test gcsection
} else {
run_dump_test relax-3-coff
diff --git a/ld/testsuite/ld-h8300/relax-2.d b/ld/testsuite/ld-h8300/relax-2.d
index 963139d..b79f5c2 100644
--- a/ld/testsuite/ld-h8300/relax-2.d
+++ b/ld/testsuite/ld-h8300/relax-2.d
@@ -7,5 +7,15 @@
Disassembly of section .text:
00000100 <_start>:
- *100: mov.b @0x67:8,r0l
- *102: mov.b @0x4321:16,r0l
+ 100: mov.b @0x64:8,r0l
+ 102: mov.b r0l,@0x64:8
+ 104: mov.b @0x4320:16,r0l
+ 108: mov.b r0l,@0x4320:16
+ 10c: mov.w @0xff64:16,r0
+ 110: mov.w r0,@0xff64:16
+ 114: mov.w @0x4320:16,r0
+ 118: mov.w r0,@0x4320:16
+ 11c: mov.l @0xff64:16,er0
+ 122: mov.l er0,@0xff64:16
+ 128: mov.l @0x4320:16,er0
+ 12e: mov.l er0,@0x4320:16
diff --git a/ld/testsuite/ld-h8300/relax-2.s b/ld/testsuite/ld-h8300/relax-2.s
index aa82dba..8e096b8 100644
--- a/ld/testsuite/ld-h8300/relax-2.s
+++ b/ld/testsuite/ld-h8300/relax-2.s
@@ -2,7 +2,19 @@
.globl _start
_start:
mov.b @foo:16,r0l
+ mov.b r0l,@foo:16
mov.b @bar:32,r0l
+ mov.b r0l,@bar:32
- .equ foo,0xffff67
- .equ bar,0x4321
+ mov.w @foo:16,r0
+ mov.w r0,@foo:16
+ mov.w @bar:32,r0
+ mov.w r0,@bar:32
+
+ mov.l @foo:16,er0
+ mov.l er0,@foo:16
+ mov.l @bar:32,er0
+ mov.l er0,@bar:32
+
+ .equ foo,0xffff64
+ .equ bar,0x4320
diff --git a/ld/testsuite/ld-h8300/relax-7.d b/ld/testsuite/ld-h8300/relax-7.d
new file mode 100644
index 0000000..ecf1a10
--- /dev/null
+++ b/ld/testsuite/ld-h8300/relax-7.d
@@ -0,0 +1,81 @@
+# name: H8300 Relaxation Test 7
+# source: relax-7?.s
+# ld: --relax -m h8300self
+# objdump: -d -s --no-show-raw-insn
+
+.*: file format .*-h8300
+
+Contents of section .text:
+ 0100 1a801aa2 7a01ffff 80000100 6f2201d0 [^\000]*
+ 0110 59206e0a ff016e8a ff016e1a 00016e9a [^\000]*
+ 0120 00015470 6f02fff2 6f82fff2 6f120002 [^\000]*
+ 0130 6f920002 54700100 6f028004 01006f82 [^\000]*
+ 0140 80040100 6f120004 01006f92 00045470 [^\000]*
+ 0150 7a000100 78006b01 fff25470 78006a2a [^\000]*
+ 0160 ffff7ff1 78006aaa ffff7ff1 78106a2a [^\000]*
+ 0170 00008000 78106aaa 00008000 54707800 [^\000]*
+ 0180 6b22ffff 7ffa7800 6ba2ffff 7ffa7810 [^\000]*
+ 0190 6b220000 80007810 6ba20000 80005470 [^\000]*
+ 01a0 01007800 6b2200ff ff040100 78806ba2 [^\000]*
+ 01b0 00ffff04 01007810 6b220000 80000100 [^\000]*
+ 01c0 78906ba2 00008000 5470 [^\000]*
+Contents of section .rodata:
+ 01cc 00000112 00000124 00000136 0000015c [^\000]*
+ 01dc 0000017e 000001a0 00000150 01007800 [^\000]*
+ 01ec 6b200000 01e80000 [^\000]*
+
+Disassembly of section .text:
+
+00000100 <_start>:
+ 100: sub.l er0,er0
+ 102: sub.l er2,er2
+ 104: mov.l #0xffff8000,er1
+ 10a: mov.l @\(0x1d0:16,er2\),er2
+ 110: jmp @er2
+
+00000112 <.L20>:
+ 112: mov.b @\(0xff01:16,er0\),r2l
+ 116: mov.b r2l,@\(0xff01:16,er0\)
+ 11a: mov.b @\(0x1:16,er1\),r2l
+ 11e: mov.b r2l,@\(0x1:16,er1\)
+ 122: rts[\t]*
+
+00000124 <.L21>:
+ 124: mov.w @\(0xfff2:16,er0\),r2
+ 128: mov.w r2,@\(0xfff2:16,er0\)
+ 12c: mov.w @\(0x2:16,er1\),r2
+ 130: mov.w r2,@\(0x2:16,er1\)
+ 134: rts[\t]*
+
+00000136 <.L22>:
+ 136: mov.l @\(0x8004:16,er0\),er2
+ 13c: mov.l er2,@\(0x8004:16,er0\)
+ 142: mov.l @\(0x4:16,er1\),er2
+ 148: mov.l er2,@\(0x4:16,er1\)
+ 14e: rts[\t]*
+
+00000150 <.L100Relax>:
+ 150: mov.l #0x1007800,er0
+ 156: mov.w @0xfff2:16,r1
+ 15a: rts[\t]*
+
+0000015c <.L30noRelax>:
+ 15c: mov.b @\(0xffff7ff1:32,er0\),r2l
+ 164: mov.b r2l,@\(0xffff7ff1:32,er0\)
+ 16c: mov.b @\(0x8000:32,er1\),r2l
+ 174: mov.b r2l,@\(0x8000:32,er1\)
+ 17c: rts[\t]*
+
+0000017e <.L31noRelax>:
+ 17e: mov.w @\(0xffff7ffa:32,er0\),r2
+ 186: mov.w r2,@\(0xffff7ffa:32,er0\)
+ 18e: mov.w @\(0x8000:32,er1\),r2
+ 196: mov.w r2,@\(0x8000:32,er1\)
+ 19e: rts[\t]*
+
+000001a0 <.L32noRelax>:
+ 1a0: mov.l @\(0xffff04:32,er0\),er2
+ 1aa: mov.l er2,@\(0xffff04:32,er0\)
+ 1b4: mov.l @\(0x8000:32,er1\),er2
+ 1be: mov.l er2,@\(0x8000:32,er1\)
+ 1c8: rts[\t]*
diff --git a/ld/testsuite/ld-h8300/relax-7a.s b/ld/testsuite/ld-h8300/relax-7a.s
new file mode 100644
index 0000000..915fb79
--- /dev/null
+++ b/ld/testsuite/ld-h8300/relax-7a.s
@@ -0,0 +1,66 @@
+ .h8300s
+# relax expected
+ .global _start
+ .section .text.func1,"ax",@progbits
+ .align 1
+_start:
+ sub.l er0,er0
+ sub.l er2,er2
+ mov.l #var3,er1
+ mov.l @(table+4:32,er2),er2
+ jmp @er2
+ .section .rodata.tab,"a",@progbits
+ .align 2
+table:
+ .long .L20
+ .long .L21
+ .long .L22
+ .long .L30noRelax
+ .long .L31noRelax
+ .long .L32noRelax
+ .long .L100Relax
+ .section .text.func1
+.L20:
+ mov.b @(var1+1:32,er0), r2l
+ mov.b r2l,@(var1+1:32,er0)
+ mov.b @(1:32,er1), r2l
+ mov.b r2l,@(1:32,er1)
+ rts
+.L21:
+ mov.w @(var2+2:32,er0), r2
+ mov.w r2,@(var2+2:32,er0)
+ mov.w @(2:32,er1), r2
+ mov.w r2,@(2:32,er1)
+ rts
+.L22:
+ mov.l @(var3+4:32,er0), er2
+ mov.l er2,@(var3+4:32,er0)
+ mov.l @(4:32,er1), er2
+ mov.l er2,@(4:32,er1)
+ rts
+
+.L100Relax:
+ mov.l #0x01007800,er0
+# part of MOV.L @(d:24,ERs),ERd opcode
+ mov.w @var2+2:32,r1
+ rts
+
+# no relax allowed:
+.L30noRelax:
+ mov.b @(var4+1:32,er0), r2l
+ mov.b r2l,@(var4+1:32,er0)
+ mov.b @(0x8000:32,er1), r2l
+ mov.b r2l,@(0x8000:32,er1)
+ rts
+.L31noRelax:
+ mov.w @(var5+2:32,er0), r2
+ mov.w r2,@(var5+2:32,er0)
+ mov.w @(0x8000:32,er1), r2
+ mov.w r2,@(0x8000:32,er1)
+ rts
+.L32noRelax:
+ mov.l @(var6+4:32,er0), er2
+ mov.l er2,@(var6+4:32,er0)
+ mov.l @(0x8000:32,er1), er2
+ mov.l er2,@(0x8000:32,er1)
+ rts
diff --git a/ld/testsuite/ld-h8300/relax-7b.s b/ld/testsuite/ld-h8300/relax-7b.s
new file mode 100644
index 0000000..eea9cfd
--- /dev/null
+++ b/ld/testsuite/ld-h8300/relax-7b.s
@@ -0,0 +1,19 @@
+ .h8300s
+ .global var1,var2,var3,var4,var5,var6
+
+ .equ var1,0xffffff00
+ .equ var2,0xfffffff0
+ .equ var3,0xffff8000
+
+ .equ var4,0xffff7ff0
+ .equ var5,0xffff7ff8
+ .equ var6,0x00ffff00
+
+ .section .rodata.tab2,"a",@progbits
+ .align 2
+table2: # no relax in sections other than text expected:
+ .short 0x0100
+ # MOV.L @(d:24,ERs),ERd opcodes
+ .short 0x7800
+ .short 0x6b20
+ .long table2