From 81f5558e3d93654ed79b6ea28850a4798ea1404f Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 21 Mar 2013 16:08:07 +0000 Subject: [PATCH] * 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. --- bfd/ChangeLog | 10 ++ bfd/bfd-in2.h | 1 + bfd/elf32-h8300.c | 212 ++++++++++++++++++++++++++++++--------- bfd/elflink.c | 1 + bfd/libbfd.h | 1 + bfd/reloc.c | 7 +- gas/ChangeLog | 7 ++ gas/config/tc-h8300.c | 33 ++++-- gas/config/tc-h8300.h | 6 +- include/elf/ChangeLog | 5 + include/elf/h8.h | 5 +- include/opcode/ChangeLog | 5 + include/opcode/h8300.h | 14 ++- ld/ChangeLog | 5 + ld/ld.texinfo | 10 +- ld/testsuite/ChangeLog | 11 ++ ld/testsuite/ld-h8300/h8300.exp | 3 +- ld/testsuite/ld-h8300/relax-2.d | 14 ++- ld/testsuite/ld-h8300/relax-2.s | 16 ++- ld/testsuite/ld-h8300/relax-7.d | 81 +++++++++++++++ ld/testsuite/ld-h8300/relax-7a.s | 66 ++++++++++++ ld/testsuite/ld-h8300/relax-7b.s | 19 ++++ 22 files changed, 449 insertions(+), 83 deletions(-) create mode 100644 ld/testsuite/ld-h8300/relax-7.d create mode 100644 ld/testsuite/ld-h8300/relax-7a.s create mode 100644 ld/testsuite/ld-h8300/relax-7b.s 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 + + * 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 * 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 + + * 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 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 + + * 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 * 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 + + * 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 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 . 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 + + * ld.texinfo (H8/300): Add description of relaxation of + mov @(disp:32,ERx) to mov @(disp:16,ERx). + 2013-03-21 Kai Tietz * 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 + + * 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 * 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 -- 2.7.4