Add support for the GBZ80 and Z80N variants of the Z80 architecture, and add DWARF debug info support to the Z80 assembler.

PR 25469
bfd	* archures.c: Add GBZ80 and Z80N machine values.
	* reloc.c: Add BFD_RELOC_Z80_16_BE.
	* coff-z80.c: Add support for new reloc.
	* coffcode.h: Add support for new machine values.
	* cpu-z80.c: Add support for new machine names.
	* elf32-z80.c: Add support for new reloc.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenerate.

binutils* readelf.c (get_machine_flags): Add support for Z80N machine
	number.

gas	* config/tc-z80.c: Add -gbz80 command line option to generate code
	for the GameBoy Z80.  Add support for generating DWARF.
	* config/tc-z80.h: Add support for DWARF debug information
	generation.
	* doc/c-z80.texi: Document new command line option.
	* testsuite/gas/z80/gbz80_all.d: New file.
	* testsuite/gas/z80/gbz80_all.s: New file.
	* testsuite/gas/z80/z80.exp: Run the new tests.
	* testsuite/gas/z80/z80n_all.d: New file.
	* testsuite/gas/z80/z80n_all.s: New file.
	* testsuite/gas/z80/z80n_reloc.d: New file.

include	* coff/internal.h (R_IMM16BE): Define.
	* elf/z80.h (EF_Z80_MACH_Z80N): Define.
	(R_Z80_16_BE): New reloc.

ld	* emulparams/elf32z80.sh: Use z80 emulation.
	* emultempl/z80.em: Make generic to both COFF and ELF Z80 emulations.
	* emultempl/z80elf.em: Delete.
	* testsuite/ld-elf/pr22450.d: Expect to fail for the Z80.
	* testsuite/ld-elf/sec64k.exp: Fix Z80 assembly.
	* testsuite/ld-unique/pr21529.s: Avoid register name conflict.
	* testsuite/ld-unique/unique.s: Likewise.
	* testsuite/ld-unique/unique_empty.s: Likewise.
	* testsuite/ld-unique/unique_shared.s: Likewise.
	* testsuite/ld-unique/unique.d: Updated expected output.
	* testsuite/ld-z80/arch_z80n.d: New file.
	* testsuite/ld-z80/comb_arch_z80_z80n.d: New file.
	* testsuite/ld-z80/labels.s: Add more labels.
	* testsuite/ld-z80/relocs.s: Add more reloc tests.
	* testsuite/ld-z80/relocs_f_z80n.d: New file

opcodes	* z80-dis.c: Add support for GBZ80 opcodes.
This commit is contained in:
Sergey Belyashov 2020-02-07 14:53:46 +00:00 committed by Nick Clifton
parent adb8754e48
commit 9fc0b501af
42 changed files with 4876 additions and 480 deletions

View File

@ -1,3 +1,15 @@
2020-02-07 Sergey Belyashov <sergey.belyashov@gmail.com>
PR 25469
* archures.c: Add GBZ80 and Z80N machine values.
* reloc.c: Add BFD_RELOC_Z80_16_BE.
* coff-z80.c: Add support for new reloc.
* coffcode.h: Add support for new machine values.
* cpu-z80.c: Add support for new machine names.
* elf32-z80.c: Add support for new reloc.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
2020-02-07 Nick Clifton <nickc@redhat.com>
PR 23932

View File

@ -504,14 +504,15 @@ DESCRIPTION
. bfd_arch_xtensa, {* Tensilica's Xtensa cores. *}
.#define bfd_mach_xtensa 1
. bfd_arch_z80,
.#define bfd_mach_gbz80 0 {* GameBoy Z80 (reduced instruction set) *}
.#define bfd_mach_z80strict 1 {* Z80 without undocumented opcodes. *}
.#define bfd_mach_z180 2 {* Z180: successor with additional instructions, but without halves of ix and iy *}
.#define bfd_mach_z80 3 {* Z80 with ixl, ixh, iyl, and iyh. *}
.#define bfd_mach_ez80_z80 4 {* eZ80 (successor of Z80 & Z180) in Z80 (16-bit address) mode *}
.#define bfd_mach_ez80_adl 5 {* eZ80 (successor of Z80 & Z180) in ADL (24-bit address) mode *}
.#define bfd_mach_z80full 7 {* Z80 with all undocumented instructions. *}
.#define bfd_mach_r800 11 {* R800: successor with multiplication. *}
.#define bfd_mach_z80strict 1 {* Zilog Z80 without undocumented opcodes. *}
.#define bfd_mach_z180 2 {* Zilog Z180: successor with additional instructions, but without halves of ix and iy *}
.#define bfd_mach_z80 3 {* Zilog Z80 with ixl, ixh, iyl, and iyh. *}
.#define bfd_mach_ez80_z80 4 {* Zilog eZ80 (successor of Z80 & Z180) in Z80 (16-bit address) mode *}
.#define bfd_mach_ez80_adl 5 {* Zilog eZ80 (successor of Z80 & Z180) in ADL (24-bit address) mode *}
.#define bfd_mach_z80n 6 {* Z80N *}
.#define bfd_mach_z80full 7 {* Zilog Z80 with all undocumented instructions. *}
.#define bfd_mach_gbz80 8 {* GameBoy Z80 (reduced instruction set) *}
.#define bfd_mach_r800 11 {* Ascii R800: successor with multiplication. *}
. bfd_arch_lm32, {* Lattice Mico32. *}
.#define bfd_mach_lm32 1
. bfd_arch_microblaze,{* Xilinx MicroBlaze. *}

View File

@ -1897,14 +1897,15 @@ enum bfd_architecture
bfd_arch_xtensa, /* Tensilica's Xtensa cores. */
#define bfd_mach_xtensa 1
bfd_arch_z80,
#define bfd_mach_gbz80 0 /* GameBoy Z80 (reduced instruction set) */
#define bfd_mach_z80strict 1 /* Z80 without undocumented opcodes. */
#define bfd_mach_z180 2 /* Z180: successor with additional instructions, but without halves of ix and iy */
#define bfd_mach_z80 3 /* Z80 with ixl, ixh, iyl, and iyh. */
#define bfd_mach_ez80_z80 4 /* eZ80 (successor of Z80 & Z180) in Z80 (16-bit address) mode */
#define bfd_mach_ez80_adl 5 /* eZ80 (successor of Z80 & Z180) in ADL (24-bit address) mode */
#define bfd_mach_z80full 7 /* Z80 with all undocumented instructions. */
#define bfd_mach_r800 11 /* R800: successor with multiplication. */
#define bfd_mach_z80strict 1 /* Zilog Z80 without undocumented opcodes. */
#define bfd_mach_z180 2 /* Zilog Z180: successor with additional instructions, but without halves of ix and iy */
#define bfd_mach_z80 3 /* Zilog Z80 with ixl, ixh, iyl, and iyh. */
#define bfd_mach_ez80_z80 4 /* Zilog eZ80 (successor of Z80 & Z180) in Z80 (16-bit address) mode */
#define bfd_mach_ez80_adl 5 /* Zilog eZ80 (successor of Z80 & Z180) in ADL (24-bit address) mode */
#define bfd_mach_z80n 6 /* Z80N */
#define bfd_mach_z80full 7 /* Zilog Z80 with all undocumented instructions. */
#define bfd_mach_gbz80 8 /* GameBoy Z80 (reduced instruction set) */
#define bfd_mach_r800 11 /*Ascii R800: Z80 successor with multiplication. */
bfd_arch_lm32, /* Lattice Mico32. */
#define bfd_mach_lm32 1
bfd_arch_microblaze,/* Xilinx MicroBlaze. */
@ -5301,6 +5302,9 @@ BFD_RELOC_XTENSA_ASM_EXPAND. */
/* Highest 16 bits of multibyte (32 or 24 bit) value. */
BFD_RELOC_Z80_WORD1,
/* 16 bit word big endian */
BFD_RELOC_Z80_16_BE,
/* DJNZ offset. */
BFD_RELOC_Z8K_DISP7,

View File

@ -221,6 +221,21 @@ static bfd_howto_type howto_table[] =
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
BFD_HOWTO (BFD_RELOC_Z80_16_BE,
R_IMM16BE, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
0, /* special_function */
"r_imm16be", /* name */
FALSE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
};
#define NUM_HOWTOS ARRAY_SIZE (howto_table)
@ -421,6 +436,17 @@ extra_case (bfd *in_abfd,
break;
}
case R_IMM16BE:
if (reloc->howto->partial_inplace)
val += (bfd_get_8 ( in_abfd, data+*src_ptr+0) * 0x100 +
bfd_get_8 ( in_abfd, data+*src_ptr+1)) & reloc->howto->src_mask;
bfd_put_8 (in_abfd, val >> 8, data + *dst_ptr+0);
bfd_put_8 (in_abfd, val, data + *dst_ptr+1);
(*dst_ptr) += 2;
(*src_ptr) += 2;
break;
default:
abort ();
}

View File

@ -2163,6 +2163,7 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr)
{
case bfd_mach_z80strict << 12:
case bfd_mach_z80 << 12:
case bfd_mach_z80n << 12:
case bfd_mach_z80full << 12:
case bfd_mach_r800 << 12:
case bfd_mach_gbz80 << 12:
@ -2655,6 +2656,7 @@ coff_set_flags (bfd * abfd,
{
case bfd_mach_z80strict:
case bfd_mach_z80:
case bfd_mach_z80n:
case bfd_mach_z80full:
case bfd_mach_r800:
case bfd_mach_gbz80:

View File

@ -54,7 +54,8 @@ static const bfd_arch_info_type arch_info_struct[] =
N (bfd_mach_r800, "r800", 16, FALSE, M(4)),
N (bfd_mach_gbz80, "gbz80", 16, FALSE, M(5)),
N (bfd_mach_z180, "z180", 16, FALSE, M(6)),
N (bfd_mach_ez80_z80, "ez80-z80", 16, FALSE, M(7)),
N (bfd_mach_z80n, "z80n", 16, FALSE, M(7)),
N (bfd_mach_ez80_z80, "ez80-z80", 16, FALSE, M(8)),
N (bfd_mach_ez80_adl, "ez80-adl", 24, FALSE, NULL)
};

View File

@ -30,12 +30,6 @@
/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
#define OCTETS_PER_BYTE(ABFD, SEC) 1
/* Relocation functions. */
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
(bfd *, bfd_reloc_code_real_type);
static bfd_boolean z80_info_to_howto_rel
(bfd *, arelent *, Elf_Internal_Rela *);
typedef struct {
bfd_reloc_code_real_type r_type;
reloc_howto_type howto;
@ -44,6 +38,11 @@ typedef struct {
#define BFD_EMPTY_HOWTO(rt,x) {rt, EMPTY_HOWTO(x)}
#define BFD_HOWTO(rt,a,b,c,d,e,f,g,h,i,j,k,l,m) {rt, HOWTO(a,b,c,d,e,f,g,h,i,j,k,l,m)}
static bfd_reloc_status_type
z80_elf_16_be_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
void *data, asection *input_section, bfd *output_bfd,
char **error_message);
static const
bfd_howto_type elf_z80_howto_table[] =
{
@ -253,11 +252,27 @@ bfd_howto_type elf_z80_howto_table[] =
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* An 16 bit big endian absolute relocation */
BFD_HOWTO (BFD_RELOC_Z80_16_BE,
R_Z80_16_BE, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
z80_elf_16_be_reloc, /* special_function */
"r_imm16be", /* name */
FALSE, /* partial_inplace */
0x00000000, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
};
static reloc_howto_type *
bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
bfd_reloc_code_real_type code)
z80_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
bfd_reloc_code_real_type code)
{
enum
{
@ -268,16 +283,16 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
for (i = 0; i < table_size; i++)
{
if (elf_z80_howto_table[i].r_type == code)
return &elf_z80_howto_table[i].howto;
return &elf_z80_howto_table[i].howto;
}
printf ("%s:%d Not found type %d\n", __FILE__, __LINE__, code);
printf ("%s:%d Not found BFD reloc type %d\n", __FILE__, __LINE__, code);
return NULL;
}
static reloc_howto_type *
bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
z80_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
{
enum
{
@ -288,82 +303,308 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
for (i = 0; i < table_size; i++)
{
if (elf_z80_howto_table[i].howto.name != NULL
&& strcasecmp (elf_z80_howto_table[i].howto.name, r_name) == 0)
return &elf_z80_howto_table[i].howto;
&& strcasecmp (elf_z80_howto_table[i].howto.name, r_name) == 0)
return &elf_z80_howto_table[i].howto;
}
printf ("%s:%d Not found ELF reloc name `%s'\n", __FILE__, __LINE__, r_name);
return NULL;
}
/* Set the howto pointer for an z80 ELF reloc. */
static bfd_boolean
z80_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
static reloc_howto_type *
z80_rtype_to_howto (bfd *abfd, unsigned r_type)
{
enum
{
table_size = sizeof (elf_z80_howto_table) / sizeof (elf_z80_howto_table[0])
};
unsigned int i;
unsigned int r_type = ELF32_R_TYPE (dst->r_info);
unsigned int i;
for (i = 0; i < table_size; i++)
{
if (elf_z80_howto_table[i].howto.type == r_type)
{
cache_ptr->howto = &elf_z80_howto_table[i].howto;
return TRUE;
}
return &elf_z80_howto_table[i].howto;
}
/* xgettext:c-format */
_bfd_error_handler (_("%pB: unsupported relocation type %#x"),
abfd, r_type);
abfd, r_type);
return NULL;
}
/* Set the howto pointer for an z80 ELF reloc. */
static bfd_boolean
z80_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
{
unsigned int r_type = ELF32_R_TYPE (dst->r_info);
reloc_howto_type *howto = z80_rtype_to_howto (abfd, r_type);
if (howto != NULL)
{
cache_ptr->howto = howto;
return TRUE;
}
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
static bfd_boolean
z80_elf_set_mach_from_flags (bfd *abfd)
static bfd_reloc_status_type
z80_elf_final_link_relocate (unsigned long r_type,
bfd *input_bfd,
bfd *output_bfd ATTRIBUTE_UNUSED,
asection *input_section ATTRIBUTE_UNUSED,
bfd_byte *contents,
bfd_vma offset,
bfd_vma value,
bfd_vma addend,
struct bfd_link_info *info ATTRIBUTE_UNUSED,
asection *sym_sec ATTRIBUTE_UNUSED,
int is_local ATTRIBUTE_UNUSED)
{
int mach;
switch (elf_elfheader (abfd)->e_flags)
bfd_boolean r;
reloc_howto_type *howto;
switch (r_type)
{
case EF_Z80_MACH_GBZ80:
mach = bfd_mach_gbz80;
break;
case EF_Z80_MACH_Z80:
mach = bfd_mach_z80;
break;
case EF_Z80_MACH_Z180:
mach = bfd_mach_z180;
break;
case EF_Z80_MACH_EZ80_Z80:
mach = bfd_mach_ez80_z80;
break;
case EF_Z80_MACH_EZ80_ADL:
mach = bfd_mach_ez80_adl;
break;
case EF_Z80_MACH_R800:
mach = bfd_mach_r800;
break;
default:
mach = bfd_mach_z80;
break;
case R_Z80_16_BE:
value += addend;
bfd_put_8 (input_bfd, value >> 8, contents + offset + 0);
bfd_put_8 (input_bfd, value >> 0, contents + offset + 1);
return bfd_reloc_ok;
}
howto = z80_rtype_to_howto (input_bfd, r_type);
if (howto == NULL)
return bfd_reloc_notsupported;
r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents,
offset, value, addend);
return r ? bfd_reloc_ok : bfd_reloc_notsupported;
}
static bfd_boolean
z80_elf_relocate_section (bfd *output_bfd,
struct bfd_link_info *info,
bfd *input_bfd,
asection *input_section,
bfd_byte *contents,
Elf_Internal_Rela *relocs,
Elf_Internal_Sym *local_syms,
asection **local_sections)
{
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
Elf_Internal_Rela *rel, *relend;
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
rel = relocs;
relend = relocs + input_section->reloc_count;
for (; rel < relend; rel++)
{
unsigned int r_type;
unsigned long r_symndx;
Elf_Internal_Sym *sym;
asection *sec;
struct elf_link_hash_entry *h;
bfd_vma relocation;
/* This is a final link. */
r_symndx = ELF32_R_SYM (rel->r_info);
r_type = ELF32_R_TYPE (rel->r_info);
h = NULL;
sym = NULL;
sec = NULL;
if (r_symndx < symtab_hdr->sh_info)
{
sym = local_syms + r_symndx;
sec = local_sections[r_symndx];
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
}
else
{
bfd_boolean unresolved_reloc, warned, ignored;
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
r_symndx, symtab_hdr, sym_hashes,
h, sec, relocation,
unresolved_reloc, warned, ignored);
}
if (sec != NULL && discarded_section (sec))
{
/* For relocs against symbols from removed linkonce sections,
or sections discarded by a linker script, we just want the
section contents cleared. Avoid any special processing. */
reloc_howto_type *howto;
howto = z80_rtype_to_howto (input_bfd, r_type);
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
rel, 1, relend, howto, 0, contents);
}
if (bfd_link_relocatable (info))
continue;
z80_elf_final_link_relocate (r_type, input_bfd, output_bfd,
input_section,
contents, rel->r_offset,
relocation, rel->r_addend,
info, sec, h == NULL);
}
bfd_default_set_arch_mach (abfd, bfd_arch_z80, mach);
return TRUE;
}
static int
z80_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
const char * name)
/* The final processing done just before writing out a Z80 ELF object
file. This gets the Z80 architecture right based on the machine
number. */
static bfd_boolean
z80_elf_final_write_processing (bfd *abfd)
{
return (name[0] == '.' && name[1] == 'L') ||
_bfd_elf_is_local_label_name (abfd, name);
unsigned long val = bfd_get_mach (abfd);
switch (val)
{
default:
_bfd_error_handler (_("%pB: unsupported bfd mach %#lx"),
abfd, val);
/* fall through */
case bfd_mach_z80:
case bfd_mach_z80full:
case bfd_mach_z80strict:
val = EF_Z80_MACH_Z80;
break;
case bfd_mach_gbz80:
val = EF_Z80_MACH_GBZ80;
break;
case bfd_mach_z80n:
val = EF_Z80_MACH_Z80N;
break;
case bfd_mach_z180:
val = EF_Z80_MACH_Z180;
break;
case bfd_mach_ez80_z80:
val = EF_Z80_MACH_EZ80_Z80;
break;
case bfd_mach_ez80_adl:
val = EF_Z80_MACH_EZ80_ADL;
break;
case bfd_mach_r800:
val = EF_Z80_MACH_R800;
break;
}
elf_elfheader (abfd)->e_machine = EM_Z80;
elf_elfheader (abfd)->e_flags &= ~EF_Z80_MACH_MSK;
elf_elfheader (abfd)->e_flags |= val;
return _bfd_elf_final_write_processing (abfd);
}
/* Set the right machine number. */
static bfd_boolean
z80_elf_object_p (bfd *abfd)
{
unsigned int mach;
if (elf_elfheader (abfd)->e_machine == EM_Z80)
{
int e_mach = elf_elfheader (abfd)->e_flags & EF_Z80_MACH_MSK;
switch (e_mach)
{
default:
_bfd_error_handler (_("%pB: unsupported mach %#x"),
abfd, e_mach);
/* fall through */
case EF_Z80_MACH_Z80:
mach = bfd_mach_z80;
break;
case EF_Z80_MACH_GBZ80:
mach = bfd_mach_gbz80;
break;
case EF_Z80_MACH_Z180:
mach = bfd_mach_z180;
break;
case EF_Z80_MACH_EZ80_Z80:
mach = bfd_mach_ez80_z80;
break;
case EF_Z80_MACH_EZ80_ADL:
mach = bfd_mach_ez80_adl;
break;
case EF_Z80_MACH_R800:
mach = bfd_mach_r800;
break;
case EF_Z80_MACH_Z80N:
mach = bfd_mach_z80n;
break;
}
}
else
{
_bfd_error_handler (_("%pB: unsupported arch %#x"),
abfd, elf_elfheader (abfd)->e_machine);
mach = bfd_mach_z80;
}
return bfd_default_set_arch_mach (abfd, bfd_arch_z80, mach);
}
static int
z80_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
const char * name)
{
return (name[0] == '.' && name[1] == 'L') ||
_bfd_elf_is_local_label_name (abfd, name);
}
static bfd_reloc_status_type
z80_elf_16_be_reloc (bfd *abfd,
arelent *reloc_entry,
asymbol *symbol,
void *data,
asection *input_section,
bfd *output_bfd,
char **error_message)
{
bfd_vma val;
long x;
bfd_size_type octets = (reloc_entry->address
* OCTETS_PER_BYTE (abfd, input_section));
/* If this is a relocatable link (output_bfd test tells us), just
call the generic function. Any adjustment will be done at final
link time. */
if (output_bfd != NULL)
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
/* Get symbol value. */
val = 0;
if (!bfd_is_com_section (symbol->section))
val = symbol->value;
val += symbol->section->output_offset + input_section->output_offset;
if (symbol->section->output_section)
val += symbol->section->output_section->vma;
val += reloc_entry->addend;
if (reloc_entry->howto->partial_inplace)
{
x = bfd_get_8 (abfd, (bfd_byte *) data + octets + 0) * 0x100;
x += bfd_get_8 (abfd, (bfd_byte *) data + octets + 1);
x &= ~reloc_entry->howto->src_mask;
}
else
x = 0;
x |= val & reloc_entry->howto->dst_mask;
if (x < -0x8000 || x >= 0x10000)
return bfd_reloc_outofrange;
bfd_put_8 (abfd, x >> 8, (bfd_byte *) data + octets + 0);
bfd_put_8 (abfd, x >> 0, (bfd_byte *) data + octets + 1);
return bfd_reloc_ok;
}
#define ELF_ARCH bfd_arch_z80
#define ELF_MACHINE_CODE EM_Z80
@ -372,9 +613,20 @@ z80_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
#define TARGET_LITTLE_SYM z80_elf32_vec
#define TARGET_LITTLE_NAME "elf32-z80"
#define elf_info_to_howto NULL
#define elf_info_to_howto_rel z80_info_to_howto_rel
#define elf_backend_object_p z80_elf_set_mach_from_flags
#define elf_backend_can_refcount 1
#define elf_backend_can_gc_sections 1
#define elf_backend_stack_align 1
#define elf_backend_rela_normal 1
#define elf_info_to_howto z80_info_to_howto_rela
#define elf_info_to_howto_rel z80_info_to_howto_rela
#define elf_backend_final_write_processing z80_elf_final_write_processing
#define elf_backend_object_p z80_elf_object_p
#define elf_backend_relocate_section z80_elf_relocate_section
#define bfd_elf32_bfd_reloc_type_lookup z80_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup z80_reloc_name_lookup
#define bfd_elf32_bfd_is_local_label_name z80_is_local_label_name
#include "elf32-target.h"

View File

@ -2875,6 +2875,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_Z80_BYTE3",
"BFD_RELOC_Z80_WORD0",
"BFD_RELOC_Z80_WORD1",
"BFD_RELOC_Z80_16_BE",
"BFD_RELOC_Z8K_DISP7",
"BFD_RELOC_Z8K_CALLR",
"BFD_RELOC_Z8K_IMM4L",

View File

@ -6697,6 +6697,10 @@ ENUM
BFD_RELOC_Z80_WORD1
ENUMDOC
Highest 16 bits of multibyte (32 or 24 bit) value.
ENUM
BFD_RELOC_Z80_16_BE
ENUMDOC
Like BFD_RELOC_16 but big-endian.
ENUM
BFD_RELOC_Z8K_DISP7

View File

@ -1,3 +1,9 @@
2020-02-07 Sergey Belyashov <sergey.belyashov@gmail.com>
PR 25469
* readelf.c (get_machine_flags): Add support for Z80N machine
number.
2020-02-07 Nick Clifton <nickc@redhat.com>
* dwarf.c (display_debug_lines_decoded): Force a NUL termination

View File

@ -3769,6 +3769,7 @@ get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
default:
strcat (buf, _(", unknown")); break;
}

View File

@ -1,3 +1,18 @@
2020-02-07 Sergey Belyashov <sergey.belyashov@gmail.com>
PR 25469
* config/tc-z80.c: Add -gbz80 command line option to generate code
for the GameBoy Z80. Add support for generating DWARF.
* config/tc-z80.h: Add support for DWARF debug information
generation.
* doc/c-z80.texi: Document new command line option.
* testsuite/gas/z80/gbz80_all.d: New file.
* testsuite/gas/z80/gbz80_all.s: New file.
* testsuite/gas/z80/z80.exp: Run the new tests.
* testsuite/gas/z80/z80n_all.d: New file.
* testsuite/gas/z80/z80n_all.s: New file.
* testsuite/gas/z80/z80n_reloc.d: New file.
2020-02-06 H.J. Lu <hongjiu.lu@intel.com>
PR gas/25381

View File

@ -24,6 +24,7 @@
#include "subsegs.h"
#include "elf/z80.h"
#include "dwarf2dbg.h"
#include "dw2gencfi.h"
/* Exported constants. */
const char comment_chars[] = ";\0";
@ -43,6 +44,7 @@ enum options
OPTION_MACH_EZ80_Z80,
OPTION_MACH_EZ80_ADL,
OPTION_MACH_GBZ80,
OPTION_MACH_Z80N,
OPTION_MACH_INST,
OPTION_MACH_NO_INST,
OPTION_MACH_IUD,
@ -63,6 +65,7 @@ enum options
#define INS_GBZ80 (1 << 2)
#define INS_Z180 (1 << 3)
#define INS_EZ80 (1 << 4)
#define INS_Z80N (1 << 5)
#define INS_MARCH_MASK 0xffff
#define INS_IDX_HALF (1 << 16)
@ -72,7 +75,7 @@ enum options
#define INS_ROT_II_LD (1 << 20) /* instructions like SLA (ii+d),r; which is: LD r,(ii+d); SLA r; LD (ii+d),r */
#define INS_TUNE_MASK 0xffff0000
#define INS_NOT_GBZ80 (INS_Z80 | INS_Z180 | INS_R800 | INS_EZ80)
#define INS_NOT_GBZ80 (INS_Z80 | INS_Z180 | INS_R800 | INS_EZ80 | INS_Z80N)
#define INS_ALL 0
#define INS_UNDOC (INS_IDX_HALF | INS_IN_F_C)
@ -85,6 +88,8 @@ struct option md_longopts[] =
{ "z180", no_argument, NULL, OPTION_MACH_Z180},
{ "ez80", no_argument, NULL, OPTION_MACH_EZ80_Z80},
{ "ez80-adl", no_argument, NULL, OPTION_MACH_EZ80_ADL},
{ "gbz80", no_argument, NULL, OPTION_MACH_GBZ80},
{ "z80n", no_argument, NULL, OPTION_MACH_Z80N},
{ "fp-s", required_argument, NULL, OPTION_FP_SINGLE_FORMAT},
{ "fp-d", required_argument, NULL, OPTION_FP_DOUBLE_FORMAT},
{ "strict", no_argument, NULL, OPTION_MACH_FUD},
@ -243,7 +248,7 @@ md_parse_option (int c, const char* arg)
ins_err = (ins_err & INS_MARCH_MASK) | (~INS_Z80 & INS_MARCH_MASK);
break;
case OPTION_MACH_R800:
ins_ok = INS_R800 | INS_IDX_HALF;
ins_ok = INS_R800 | INS_IDX_HALF | INS_IN_F_C;
ins_err = INS_UNPORT;
break;
case OPTION_MACH_Z180:
@ -251,12 +256,12 @@ md_parse_option (int c, const char* arg)
ins_err = INS_UNDOC | INS_UNPORT;
break;
case OPTION_MACH_EZ80_Z80:
ins_ok = INS_EZ80;
ins_ok = INS_EZ80 | INS_IDX_HALF;
ins_err = (INS_UNDOC | INS_UNPORT) & ~INS_IDX_HALF;
cpu_mode = 0;
break;
case OPTION_MACH_EZ80_ADL:
ins_ok = INS_EZ80;
ins_ok = INS_EZ80 | INS_IDX_HALF;
ins_err = (INS_UNDOC | INS_UNPORT) & ~INS_IDX_HALF;
cpu_mode = 1;
break;
@ -264,6 +269,10 @@ md_parse_option (int c, const char* arg)
ins_ok = INS_GBZ80;
ins_err = INS_UNDOC | INS_UNPORT;
break;
case OPTION_MACH_Z80N:
ins_ok = INS_Z80N | INS_UNPORT | INS_UNDOC;
ins_err = 0;
break;
case OPTION_FP_SINGLE_FORMAT:
str_to_float = get_str_to_float (arg);
break;
@ -325,11 +334,13 @@ md_show_usage (FILE * f)
{
fprintf (f, "\n\
CPU model options:\n\
-z80\t\t\t assemble for Z80\n\
-r800\t\t\t assemble for R800\n\
-z180\t\t\t assemble for Z180\n\
-ez80\t\t\t assemble for eZ80 in Z80 mode by default\n\
-ez80-adl\t\t assemble for eZ80 in ADL mode by default\n\
-z80\t\t\t assemble for Zilog Z80\n\
-r800\t\t\t assemble for Ascii R800\n\
-z180\t\t\t assemble for Zilog Z180\n\
-ez80\t\t\t assemble for Zilog eZ80 in Z80 mode by default\n\
-ez80-adl\t\t assemble for Zilog eZ80 in ADL mode by default\n\
-gbz80\t\t assemble for GameBoy Z80\n\
-z80n\t\t\t assemble for Z80N\n\
\n\
Compatibility options:\n\
-local-prefix=TEXT\t treat labels prefixed by TEXT as local\n\
@ -507,6 +518,9 @@ z80_md_end (void)
case INS_EZ80:
mach_type = cpu_mode ? bfd_mach_ez80_adl : bfd_mach_ez80_z80;
break;
case INS_Z80N:
mach_type = bfd_mach_z80n;
break;
default:
mach_type = 0;
}
@ -536,6 +550,9 @@ z80_elf_final_processing (void)
case INS_EZ80:
elf_flags = cpu_mode ? EF_Z80_MACH_EZ80_ADL : EF_Z80_MACH_EZ80_Z80;
break;
case INS_Z80N:
elf_flags = EF_Z80_MACH_Z80N;
break;
default:
elf_flags = 0;
}
@ -843,6 +860,22 @@ parse_exp_not_indexed (const char *s, expressionS *op)
}
op->X_md = indir = is_indir (p);
if (indir && (ins_ok & INS_GBZ80))
{ /* check for instructions like ld a,(hl+), ld (hl-),a */
p = skip_space (p+1);
if (!strncasecmp (p, "hl", 2))
{
p = skip_space(p+2);
if (*skip_space(p+1) == ')' && (*p == '+' || *p == '-'))
{
op->X_op = O_md1;
op->X_add_symbol = NULL;
op->X_add_number = (*p == '+') ? REG_HL : -REG_HL;
input_line_pointer = (char*)skip_space(p + 1) + 1;
return input_line_pointer;
}
}
}
input_line_pointer = (char*) s ;
expression (op);
switch (op->X_op)
@ -1122,7 +1155,6 @@ static void
emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
{
char *p;
int lo, hi;
if (r_type == BFD_RELOC_8)
{
@ -1141,15 +1173,12 @@ emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
}
else if (val->X_op == O_constant)
{
lo = -128;
hi = (BFD_RELOC_8 == r_type) ? 255 : 127;
if ((val->X_add_number < lo) || (val->X_add_number > hi))
if ((val->X_add_number < -128) || (val->X_add_number >= 128))
{
if (r_type == BFD_RELOC_Z80_DISP8)
as_bad (_("offset too large"));
as_bad (_("index overflow (%+ld)"), val->X_add_number);
else
as_warn (_("overflow"));
as_bad (_("offset overflow (%+ld)"), val->X_add_number);
}
}
else
@ -1339,6 +1368,51 @@ emit_s (char prefix, char opcode, const char *args)
return p;
}
static const char *
emit_sub (char prefix, char opcode, const char *args)
{
expressionS arg_s;
const char *p;
if (!(ins_ok & INS_GBZ80))
return emit_s (prefix, opcode, args);
p = parse_exp (args, & arg_s);
if (*p++ != ',')
{
error (_("bad instruction syntax"));
return p;
}
if (arg_s.X_md != 0 || arg_s.X_op != O_register || arg_s.X_add_number != REG_A)
ill_op ();
p = parse_exp (p, & arg_s);
emit_sx (prefix, opcode, & arg_s);
return p;
}
static const char *
emit_swap (char prefix, char opcode, const char *args)
{
expressionS reg;
const char *p;
char *q;
if (!(ins_ok & INS_Z80N))
return emit_mr (prefix, opcode, args);
/* check for alias swap a for swapnib of Z80N */
p = parse_exp (args, &reg);
if (reg.X_md != 0 || reg.X_op != O_register || reg.X_add_number != REG_A)
ill_op ();
q = frag_more (2);
*q++ = 0xED;
*q = 0x23;
return p;
}
static const char *
emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
{
@ -1425,6 +1499,12 @@ emit_jp (char prefix, char opcode, const char * args)
*q++ = (rnum & R_IX) ? 0xDD : 0xFD;
*q = prefix;
}
else if (addr.X_op == O_register && rnum == REG_C && (ins_ok & INS_Z80N))
{
q = frag_more (2);
*q++ = 0xED;
*q = 0x98;
}
else
ill_op ();
}
@ -1495,6 +1575,31 @@ emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
return p;
}
static const char *
emit_push (char prefix, char opcode, const char * args)
{
expressionS arg;
const char *p;
char *q;
p = parse_exp (args, & arg);
if (arg.X_op == O_register)
return emit_pop (prefix, opcode, args);
if (arg.X_md || arg.X_op == O_md1 || !(ins_ok & INS_Z80N))
ill_op ();
q = frag_more (2);
*q++ = 0xED;
*q = 0x8A;
q = frag_more (2);
fix_new_exp (frag_now, q - frag_now->fr_literal, 2, &arg, FALSE,
BFD_RELOC_Z80_16_BE);
return p;
}
static const char *
emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
{
@ -1571,19 +1676,38 @@ emit_add (char prefix, char opcode, const char * args)
if ((term.X_md) || (term.X_op != O_register))
ill_op ();
else
switch (term.X_add_number & ~R_INDEX)
switch (term.X_add_number)
{
case REG_A:
p = emit_s (0, prefix, p);
break;
case REG_SP:
p = parse_exp (p, &term);
if (!(ins_ok & INS_GBZ80) || term.X_md || term.X_op == O_register)
ill_op ();
q = frag_more (1);
*q = 0xE8;
emit_byte (&term, BFD_RELOC_Z80_DISP8);
break;
case REG_BC:
case REG_DE:
if (!(ins_ok & INS_Z80N))
{
ill_op ();
break;
}
/* Fall through. */
case REG_HL:
case REG_IX:
case REG_IY:
lhs = term.X_add_number;
p = parse_exp (p, &term);
if ((!term.X_md) && (term.X_op == O_register))
rhs = term.X_add_number;
if (term.X_md != 0 || term.X_op == O_md1)
ill_op ();
else if ((term.X_op == O_register) && (rhs & R_ARITH) && (rhs == lhs || (rhs & ~R_INDEX) != REG_HL))
{
rhs = term.X_add_number;
if ((rhs & R_ARITH)
&& ((rhs == lhs) || ((rhs & ~R_INDEX) != REG_HL)))
if (1)
{
q = frag_more ((lhs & R_INDEX) ? 2 : 1);
if (lhs & R_INDEX)
@ -1592,6 +1716,24 @@ emit_add (char prefix, char opcode, const char * args)
break;
}
}
else if (!(lhs & R_INDEX) && (ins_ok & INS_Z80N))
{
if (term.X_op == O_register && rhs == REG_A)
{ /* ADD BC/DE/HL,A */
q = frag_more (2);
*q++ = 0xED;
*q = 0x33 - (lhs & 3);
break;
}
else if (term.X_op != O_register && term.X_op != O_md1)
{ /* ADD BC/DE/HL,nn */
q = frag_more (2);
*q++ = 0xED;
*q = 0x36 - (lhs & 3);
emit_word (&term);
break;
}
}
/* Fall through. */
default:
ill_op ();
@ -1628,6 +1770,27 @@ emit_bit (char prefix, char opcode, const char * args)
return p;
}
/* BSLA DE,B; BSRA DE,B; BSRL DE,B; BSRF DE,B; BRLC DE,B (Z80N only) */
static const char *
emit_bshft (char prefix, char opcode, const char * args)
{
expressionS r1, r2;
const char *p;
char *q;
p = parse_exp (args, & r1);
if (*p++ != ',')
error (_("bad instruction syntax"));
p = parse_exp (p, & r2);
if (r1.X_md || r1.X_op != O_register || r1.X_add_number != REG_DE ||
r2.X_md || r2.X_op != O_register || r2.X_add_number != REG_B)
ill_op ();
q = frag_more (2);
*q++ = prefix;
*q = opcode;
return p;
}
static const char *
emit_jpcc (char prefix, char opcode, const char * args)
{
@ -1726,13 +1889,21 @@ emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
char *q;
p = parse_exp (args, &reg);
if (*p++ != ',')
{
error (_("bad instruction syntax"));
return p;
if (reg.X_md && reg.X_op == O_register && reg.X_add_number == REG_C)
{ /* permit instruction in (c) as alias for in f,(c) */
port = reg;
reg.X_md = 0;
reg.X_add_number = REG_F;
}
else
{
if (*p++ != ',')
{
error (_("bad instruction syntax"));
return p;
}
p = parse_exp (p, &port);
}
p = parse_exp (p, &port);
if (reg.X_md == 0
&& reg.X_op == O_register
&& (reg.X_add_number <= 7 || reg.X_add_number == REG_F)
@ -1958,7 +2129,15 @@ emit_ld_m_r (expressionS *dst, expressionS *src)
switch (dst->X_op)
{
case O_md1:
prefix = (dst->X_add_number == REG_IX) ? 0xDD : 0xFD;
if (ins_ok & INS_GBZ80)
{ /* LD (HL+),A or LD (HL-),A */
if (src->X_op != O_register || src->X_add_number != REG_A)
break;
*frag_more (1) = (dst->X_add_number == REG_HL) ? 0x22 : 0x32;
return;
}
else
prefix = (dst->X_add_number == REG_IX) ? 0xDD : 0xFD;
/* Fall through. */
case O_register:
switch (dst->X_add_number)
@ -1998,7 +2177,7 @@ emit_ld_m_r (expressionS *dst, expressionS *src)
if (src->X_add_number == REG_A)
{
q = frag_more (1);
*q = 0x32;
*q = (ins_ok & INS_GBZ80) ? 0xEA : 0x32;
emit_word (dst);
return;
}
@ -2112,6 +2291,15 @@ emit_ld_r_m (expressionS *dst, expressionS *src)
switch (src->X_op)
{
case O_md1:
if (ins_ok & INS_GBZ80)
{ /* LD A,(HL+) or LD A,(HL-) */
if (dst->X_op == O_register && dst->X_add_number == REG_A)
*frag_more (1) = (src->X_add_number == REG_HL) ? 0x2A : 0x3A;
else
ill_op ();
break;
}
/* Fall through. */
case O_register:
if (dst->X_add_number > 7)
ill_op ();
@ -2140,7 +2328,7 @@ emit_ld_r_m (expressionS *dst, expressionS *src)
if (dst->X_add_number == REG_A)
{
q = frag_more (1);
*q = 0x3A;
*q = (ins_ok & INS_GBZ80) ? 0xFA : 0x3A;
emit_word (src);
}
}
@ -2208,8 +2396,6 @@ emit_ld_r_r (expressionS *dst, expressionS *src)
default:
ill_op ();
}
if (ins_ok & INS_GBZ80)
ill_op ();
opcode = 0xF9;
break;
case REG_HL:
@ -2522,7 +2708,7 @@ emit_lddldi (char prefix, char opcode, const char * args)
p = parse_exp (args, & dst);
if (*p++ != ',')
error (_("bad instruction syntax"));
p = parse_exp (args, & src);
p = parse_exp (p, & src);
if (dst.X_op != O_register || src.X_op != O_register)
ill_op ();
@ -2568,12 +2754,18 @@ emit_ldh (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
&& dst.X_op == O_register
&& dst.X_add_number == REG_A
&& src.X_md != 0
&& src.X_op != O_md1
&& src.X_op != O_register)
&& src.X_op != O_md1)
{
q = frag_more (1);
*q = 0xF0;
emit_byte (& src, BFD_RELOC_8);
if (src.X_op != O_register)
{
q = frag_more (1);
*q = 0xF0;
emit_byte (& src, BFD_RELOC_8);
}
else if (src.X_add_number == REG_C)
*frag_more (1) = 0xF2;
else
ill_op ();
}
else if (dst.X_md != 0
&& dst.X_op != O_md1
@ -2604,6 +2796,29 @@ emit_ldh (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
return p;
}
static const char *
emit_ldhl (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
{
expressionS dst, src;
const char *p;
char *q;
p = parse_exp (args, & dst);
if (*p++ != ',')
{
error (_("bad instruction syntax"));
return p;
}
p = parse_exp (p, & src);
if (dst.X_md || dst.X_op != O_register || dst.X_add_number != REG_SP
|| src.X_md || src.X_op == O_register || src.X_op == O_md1)
ill_op ();
q = frag_more (1);
*q = opcode;
emit_byte (& src, BFD_RELOC_Z80_DISP8);
return p;
}
static const char *
parse_lea_pea_args (const char * args, expressionS *op)
{
@ -2700,12 +2915,75 @@ emit_mlt (char prefix, char opcode, const char * args)
ill_op ();
q = frag_more (2);
*q++ = prefix;
*q = opcode | ((arg.X_add_number & 3) << 4);
if (ins_ok & INS_Z80N)
{
if (arg.X_add_number != REG_DE)
ill_op ();
*q++ = 0xED;
*q = 0x30;
}
else
{
*q++ = prefix;
*q = opcode | ((arg.X_add_number & 3) << 4);
}
return p;
}
/* MUL D,E (Z80N only) */
static const char *
emit_mul (char prefix, char opcode, const char * args)
{
expressionS r1, r2;
const char *p;
char *q;
p = parse_exp (args, & r1);
if (*p++ != ',')
error (_("bad instruction syntax"));
p = parse_exp (p, & r2);
if (r1.X_md != 0 || r1.X_op != O_register || r1.X_add_number != REG_D ||
r2.X_md != 0 || r2.X_op != O_register || r2.X_add_number != REG_E)
ill_op ();
q = frag_more (2);
*q++ = prefix;
*q = opcode;
return p;
}
static const char *
emit_nextreg (char prefix, char opcode ATTRIBUTE_UNUSED, const char * args)
{
expressionS rr, nn;
const char *p;
char *q;
p = parse_exp (args, & rr);
if (*p++ != ',')
error (_("bad instruction syntax"));
p = parse_exp (p, & nn);
if (rr.X_md != 0 || rr.X_op == O_register || rr.X_op == O_md1 ||
nn.X_md != 0 || nn.X_op == O_md1)
ill_op ();
q = frag_more (2);
*q++ = prefix;
emit_byte (&rr, BFD_RELOC_8);
if (nn.X_op == O_register && nn.X_add_number == REG_A)
*q = 0x92;
else if (nn.X_op != O_register)
{
*q = 0x91;
emit_byte (&nn, BFD_RELOC_8);
}
else
ill_op ();
return p;
}
static const char *
emit_pea (char prefix, char opcode, const char * args)
{
@ -2783,15 +3061,23 @@ emit_tst (char prefix, char opcode, const char *args)
if (arg_s.X_md)
ill_op ();
q = frag_more (2);
*q++ = prefix;
*q = opcode | 0x60;
if (ins_ok & INS_Z80N)
{
*q++ = 0xED;
*q = 0x27;
}
else
{
*q++ = prefix;
*q = opcode | 0x60;
}
emit_byte (& arg_s, BFD_RELOC_8);
}
return p;
}
static const char *
emit_tstio (char prefix, char opcode, const char *args)
emit_insn_n (char prefix, char opcode, const char *args)
{
expressionS arg;
const char *p;
@ -3130,6 +3416,7 @@ const pseudo_typeS md_pseudo_table[] =
{ ".set", s_set, 0},
{ ".z180", set_inss, INS_Z180},
{ ".z80", set_inss, INS_Z80},
{ ".z80n", set_inss, INS_Z80N},
{ "db" , emit_data, 1},
{ "d24", z80_cons, 3},
{ "d32", z80_cons, 4},
@ -3152,6 +3439,11 @@ static table_t instab[] =
{ "add", 0x80, 0x09, emit_add, INS_ALL },
{ "and", 0x00, 0xA0, emit_s, INS_ALL },
{ "bit", 0xCB, 0x40, emit_bit, INS_ALL },
{ "brlc", 0xED, 0x2C, emit_bshft,INS_Z80N },
{ "bsla", 0xED, 0x28, emit_bshft,INS_Z80N },
{ "bsra", 0xED, 0x29, emit_bshft,INS_Z80N },
{ "bsrf", 0xED, 0x2B, emit_bshft,INS_Z80N },
{ "bsrl", 0xED, 0x2A, emit_bshft,INS_Z80N },
{ "call", 0xCD, 0xC4, emit_jpcc, INS_ALL },
{ "ccf", 0x00, 0x3F, emit_insn, INS_ALL },
{ "cp", 0x00, 0xB8, emit_s, INS_ALL },
@ -3191,15 +3483,24 @@ static table_t instab[] =
{ "ld", 0x00, 0x00, emit_ld, INS_ALL },
{ "ldd", 0xED, 0xA8, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */
{ "lddr", 0xED, 0xB8, emit_insn, INS_NOT_GBZ80 },
{ "lddrx",0xED, 0xBC, emit_insn, INS_Z80N },
{ "lddx", 0xED, 0xAC, emit_insn, INS_Z80N },
{ "ldh", 0xE0, 0x00, emit_ldh, INS_GBZ80 },
{ "ldhl", 0xE0, 0x00, emit_ldh, INS_GBZ80 },
{ "ldhl", 0x00, 0xF8, emit_ldhl, INS_GBZ80 },
{ "ldi", 0xED, 0xA0, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */
{ "ldir", 0xED, 0xB0, emit_insn, INS_NOT_GBZ80 },
{ "ldirx",0xED, 0xB4, emit_insn, INS_Z80N },
{ "ldix", 0xED, 0xA4, emit_insn, INS_Z80N },
{ "ldpirx",0xED,0xB7, emit_insn, INS_Z80N },
{ "ldws", 0xED, 0xA5, emit_insn, INS_Z80N },
{ "lea", 0xED, 0x02, emit_lea, INS_EZ80 },
{ "mlt", 0xED, 0x4C, emit_mlt, INS_Z180|INS_EZ80 },
{ "mirror",0xED,0x24, emit_insn, INS_Z80N },
{ "mlt", 0xED, 0x4C, emit_mlt, INS_Z180|INS_EZ80|INS_Z80N },
{ "mul", 0xED, 0x30, emit_mul, INS_Z80N },
{ "mulub",0xED, 0xC5, emit_mulub,INS_R800 },
{ "muluw",0xED, 0xC3, emit_muluw,INS_R800 },
{ "neg", 0xed, 0x44, emit_insn, INS_NOT_GBZ80 },
{ "neg", 0xED, 0x44, emit_insn, INS_NOT_GBZ80 },
{ "nextreg",0xED,0x91,emit_nextreg,INS_Z80N },
{ "nop", 0x00, 0x00, emit_insn, INS_ALL },
{ "or", 0x00, 0xB0, emit_s, INS_ALL },
{ "otd2r",0xED, 0xBC, emit_insn, INS_EZ80 },
@ -3218,9 +3519,12 @@ static table_t instab[] =
{ "outd2",0xED, 0xAC, emit_insn, INS_EZ80 },
{ "outi", 0xED, 0xA3, emit_insn, INS_NOT_GBZ80 },
{ "outi2",0xED, 0xA4, emit_insn, INS_EZ80 },
{ "outinb",0xED,0x90, emit_insn, INS_Z80N },
{ "pea", 0xED, 0x65, emit_pea, INS_EZ80 },
{ "pixelad",0xED,0x94,emit_insn, INS_Z80N },
{ "pixeldn",0xED,0x93,emit_insn, INS_Z80N },
{ "pop", 0x00, 0xC1, emit_pop, INS_ALL },
{ "push", 0x00, 0xC5, emit_pop, INS_ALL },
{ "push", 0x00, 0xC5, emit_push, INS_ALL },
{ "res", 0xCB, 0x80, emit_bit, INS_ALL },
{ "ret", 0xC9, 0xC0, emit_retcc,INS_ALL },
{ "reti", 0xED, 0x4D, emit_reti, INS_ALL }, /*GBZ80 has its own opcode for it*/
@ -3240,6 +3544,8 @@ static table_t instab[] =
{ "sbc", 0x98, 0x42, emit_adc, INS_ALL },
{ "scf", 0x00, 0x37, emit_insn, INS_ALL },
{ "set", 0xCB, 0xC0, emit_bit, INS_ALL },
{ "setae",0xED, 0x95, emit_insn, INS_Z80N },
{ "sl1", 0xCB, 0x30, emit_mr, INS_SLI },
{ "sla", 0xCB, 0x20, emit_mr, INS_ALL },
{ "sli", 0xCB, 0x30, emit_mr, INS_SLI },
{ "sll", 0xCB, 0x30, emit_mr, INS_SLI },
@ -3248,10 +3554,12 @@ static table_t instab[] =
{ "srl", 0xCB, 0x38, emit_mr, INS_ALL },
{ "stmix",0xED, 0x7D, emit_insn, INS_EZ80 },
{ "stop", 0x00, 0x10, emit_insn, INS_GBZ80 },
{ "sub", 0x00, 0x90, emit_s, INS_ALL },
{ "swap", 0xCB, 0x30, emit_mr, INS_GBZ80 },
{ "tst", 0xED, 0x04, emit_tst, INS_Z180|INS_EZ80 },
{ "tstio",0xED, 0x74, emit_tstio,INS_Z180|INS_EZ80 },
{ "sub", 0x00, 0x90, emit_sub, INS_ALL },
{ "swap", 0xCB, 0x30, emit_swap, INS_GBZ80|INS_Z80N },
{ "swapnib",0xED,0x23,emit_insn, INS_Z80N },
{ "test", 0xED, 0x27, emit_insn_n, INS_Z80N },
{ "tst", 0xED, 0x04, emit_tst, INS_Z180|INS_EZ80|INS_Z80N },
{ "tstio",0xED, 0x74, emit_insn_n,INS_Z180|INS_EZ80 },
{ "xor", 0x00, 0xA8, emit_s, INS_ALL },
} ;
@ -3294,139 +3602,146 @@ md_assemble (char *str)
insp = bsearch (&key, instab, ARRAY_SIZE (instab),
sizeof (instab[0]), key_cmp);
if (!insp || (insp->inss && !(insp->inss & ins_ok)))
{
as_bad (_("Unknown instruction '%s'"), buf);
*frag_more (1) = 0;
}
{
*frag_more (1) = 0;
as_bad (_("Unknown instruction `%s'"), buf);
}
else
{
p = insp->fp (insp->prefix, insp->opcode, p);
p = skip_space (p);
if ((!err_flag) && *p)
as_bad (_("junk at end of line, first unrecognized character is `%c'"),
*p);
if ((!err_flag) && *p)
as_bad (_("junk at end of line, "
"first unrecognized character is `%c'"), *p);
}
}
end:
input_line_pointer = old_ptr;
}
void
md_apply_fix (fixS * fixP, valueT* valP, segT seg ATTRIBUTE_UNUSED)
static int
is_overflow (long value, unsigned bitsize)
{
long val = * (long *) valP;
long fieldmask = (1 << bitsize) - 1;
long signmask = ~fieldmask;
long a = value & fieldmask;
long ss = a & signmask;
if (ss != 0 && ss != (signmask & fieldmask))
return 1;
return 0;
}
void
md_apply_fix (fixS * fixP, valueT* valP, segT seg)
{
long val = *valP;
char *p_lit = fixP->fx_where + fixP->fx_frag->fr_literal;
if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
else if (fixP->fx_pcrel)
{
segT s = S_GET_SEGMENT (fixP->fx_addsy);
if (s == seg || s == absolute_section)
{
val += S_GET_VALUE (fixP->fx_addsy);
fixP->fx_done = 1;
}
}
switch (fixP->fx_r_type)
{
case BFD_RELOC_8_PCREL:
if (fixP->fx_addsy)
{
fixP->fx_no_overflow = 1;
fixP->fx_done = 0;
}
else
{
fixP->fx_no_overflow = (-128 <= val && val < 128);
if (!fixP->fx_no_overflow)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("relative jump out of range"));
*p_lit++ = val;
fixP->fx_done = 1;
}
break;
case BFD_RELOC_Z80_DISP8:
if (fixP->fx_addsy)
{
fixP->fx_no_overflow = 1;
fixP->fx_done = 0;
}
else
{
fixP->fx_no_overflow = (-128 <= val && val < 128);
if (!fixP->fx_no_overflow)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("index offset out of range"));
*p_lit++ = val;
fixP->fx_done = 1;
}
case BFD_RELOC_8:
case BFD_RELOC_16:
case BFD_RELOC_24:
case BFD_RELOC_32:
case BFD_RELOC_Z80_16_BE:
fixP->fx_no_overflow = 0;
break;
default:
fixP->fx_no_overflow = 1;
break;
}
switch (fixP->fx_r_type)
{
case BFD_RELOC_8_PCREL:
case BFD_RELOC_Z80_DISP8:
if (fixP->fx_done && (val < -0x80 || val > 0x7f))
as_bad_where (fixP->fx_file, fixP->fx_line,
_("8-bit signed offset out of range (%+ld)"), val);
*p_lit++ = val;
break;
case BFD_RELOC_Z80_BYTE0:
*p_lit++ = val;
fixP->fx_no_overflow = 1;
if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
break;
case BFD_RELOC_Z80_BYTE1:
*p_lit++ = (val >> 8);
fixP->fx_no_overflow = 1;
if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
break;
case BFD_RELOC_Z80_BYTE2:
*p_lit++ = (val >> 16);
fixP->fx_no_overflow = 1;
if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
break;
case BFD_RELOC_Z80_BYTE3:
*p_lit++ = (val >> 24);
fixP->fx_no_overflow = 1;
if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
break;
case BFD_RELOC_8:
if (val > 255 || val < -128)
as_warn_where (fixP->fx_file, fixP->fx_line, _("overflow"));
if (fixP->fx_done && is_overflow(val, 8))
as_warn_where (fixP->fx_file, fixP->fx_line,
_("8-bit overflow (%+ld)"), val);
*p_lit++ = val;
fixP->fx_no_overflow = 1;
if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
break;
case BFD_RELOC_Z80_WORD1:
*p_lit++ = (val >> 16);
*p_lit++ = (val >> 24);
fixP->fx_no_overflow = 1;
if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
break;
case BFD_RELOC_Z80_WORD0:
case BFD_RELOC_16:
*p_lit++ = val;
*p_lit++ = (val >> 8);
fixP->fx_no_overflow = 1;
if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
break;
case BFD_RELOC_16:
if (fixP->fx_done && is_overflow(val, 16))
as_warn_where (fixP->fx_file, fixP->fx_line,
_("16-bit overflow (%+ld)"), val);
*p_lit++ = val;
*p_lit++ = (val >> 8);
break;
case BFD_RELOC_24: /* Def24 may produce this. */
if (fixP->fx_done && is_overflow(val, 24))
as_warn_where (fixP->fx_file, fixP->fx_line,
_("24-bit overflow (%+ld)"), val);
*p_lit++ = val;
*p_lit++ = (val >> 8);
*p_lit++ = (val >> 16);
fixP->fx_no_overflow = 1;
if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
break;
case BFD_RELOC_32: /* Def32 and .long may produce this. */
if (fixP->fx_done && is_overflow(val, 32))
as_warn_where (fixP->fx_file, fixP->fx_line,
_("32-bit overflow (%+ld)"), val);
*p_lit++ = val;
*p_lit++ = (val >> 8);
*p_lit++ = (val >> 16);
*p_lit++ = (val >> 24);
if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
break;
case BFD_RELOC_Z80_16_BE: /* Z80N PUSH nn instruction produce this. */
*p_lit++ = val >> 8;
*p_lit++ = val;
break;
default:
printf (_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
printf (_("md_apply_fix: unknown reloc type 0x%x\n"), fixP->fx_r_type);
abort ();
}
}
@ -3446,11 +3761,9 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
{
arelent *reloc;
if (! bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type))
if (fixp->fx_subsy != NULL)
{
as_bad_where (fixp->fx_file, fixp->fx_line,
_("reloc %d not supported by object file format"),
(int) fixp->fx_r_type);
as_bad_where (fixp->fx_file, fixp->fx_line, _("expression too complex"));
return NULL;
}
@ -3458,8 +3771,19 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
reloc->sym_ptr_ptr = XNEW (asymbol *);
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
reloc->addend = fixp->fx_offset;
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
if (reloc->howto == NULL)
{
as_bad_where (fixp->fx_file, fixp->fx_line,
_("reloc %d not supported by object file format"),
(int) fixp->fx_r_type);
return NULL;
}
if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|| fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
reloc->address = fixp->fx_offset;
return reloc;
}
@ -3712,3 +4036,49 @@ str_to_ieee754_d(char *litP, int *sizeP)
{
return ieee_md_atof ('d', litP, sizeP, FALSE);
}
#ifdef TARGET_USE_CFIPOP
/* Initialize the DWARF-2 unwind information for this procedure. */
void
z80_tc_frame_initial_instructions (void)
{
static int sp_regno = -1;
if (sp_regno < 0)
sp_regno = z80_tc_regname_to_dw2regnum ("sp");
cfi_add_CFA_def_cfa (sp_regno, 0);
}
int
z80_tc_regname_to_dw2regnum (const char *regname)
{
static const char *regs[] =
{ /* same registers as for GDB */
"af", "bc", "de", "hl",
"sp", "pc", "ix", "iy",
"af_", "bc_", "de_", "hl_",
"ir"
};
unsigned i;
for (i = 0; i < ARRAY_SIZE(regs); ++i)
if (!strcasecmp (regs[i], regname))
return i;
return -1;
}
#endif
/* Implement DWARF2_ADDR_SIZE. */
int
z80_dwarf2_addr_size (const bfd *abfd)
{
switch (bfd_get_mach (abfd))
{
case bfd_mach_ez80_adl:
return 3;
default:
return 2;
}
}

View File

@ -29,7 +29,6 @@
#endif
#define BFD_ARCH TARGET_ARCH
#define COFF_MAGIC 0x5A80
#define TARGET_MACH 0
#define TARGET_BYTES_BIG_ENDIAN 0
/* If you define this macro, GAS will warn about the
@ -116,4 +115,24 @@ extern int z80_tc_label_is_local (const char *name);
#define elf_tc_final_processing z80_elf_final_processing
extern void z80_elf_final_processing (void);
/* Define the column that represents the PC. */
#define DWARF2_DEFAULT_RETURN_COLUMN 5
/* The stack grows down, and is only byte aligned. */
#define DWARF2_CIE_DATA_ALIGNMENT -1
/* Z80 instructions are 1 or 4 bytes long. */
#define DWARF2_LINE_MIN_INSN_LENGTH 1
/* 16 bits addresses are used on Z80. */
#define DWARF2_ADDR_SIZE(bfd) z80_dwarf2_addr_size(bfd)
extern int z80_dwarf2_addr_size (const bfd *abfd);
/* CFI hooks. */
#define tc_cfi_frame_initial_instructions z80_tc_frame_initial_instructions
extern void z80_tc_frame_initial_instructions (void);
#define tc_regname_to_dw2regnum z80_tc_regname_to_dw2regnum
extern int z80_tc_regname_to_dw2regnum (const char *regname);
#endif

View File

@ -31,19 +31,19 @@
@table @gcctabopt
@cindex @code{-z80} command-line option, Z80
@item -z80
Produce code for the Z80 processor. By default accepted undocumented
operations with halves of index registers (@code{IXL}, @code{IXH}, @code{IYL}, @code{IYH}) and
instuction @code{IN F,(C)}. Other useful undocumented instructions produces
warnings. Undocumented instructions may not work on some CPUs, use
them on your own risk.
Produce code for the Zilog Z80 processor. By default accepted undocumented
operations with halves of index registers (@code{IXL}, @code{IXH}, @code{IYL},
@code{IYH}) and instuction @code{IN F,(C)}. Other useful undocumented
instructions produces warnings. Undocumented instructions may not work on some
CPUs, use them on your own risk.
@cindex @code{-r800} command-line option, Z80
@item -r800
Produce code for the R800 processor.
Produce code for the Ascii R800 processor.
@cindex @code{-z180} command-line option, Z80
@item -z180
Produce code for the Z180 processor.
Produce code for the Zilog Z180 processor.
@cindex @code{-ez80} command-line option, Z80
@item -ez80
@ -53,6 +53,14 @@ Produce code for the eZ80 processor in Z80 memory mode by default.
@item -ez80-adl
Produce code for the eZ80 processor in ADL memory mode by default.
@cindex @code{-gbz80} command-line option, Z80
@item -gbz80
Produce code for the GameBoy Z80 processor.
@cindex @code{-z80n} command-line option, Z80
@item -z80n
Produce code for the Z80N processor.
@cindex @code{-local-prefix} command-line option, Z80
@item -local-prefix=@var{prefix}
Mark all labels with specified prefix as local. But such label can be

View File

@ -0,0 +1,514 @@
#as: -gbz80
#objdump: -d
#name: GBZ80 instruction set
.*: .*
Disassembly of section .text:
0+ <.text>:
\s+[0-9a-f]+:\s+00\s+nop
\s+[0-9a-f]+:\s+01 af be\s+ld bc,0xbeaf
\s+[0-9a-f]+:\s+02\s+ld \(bc\),a
\s+[0-9a-f]+:\s+03\s+inc bc
\s+[0-9a-f]+:\s+04\s+inc b
\s+[0-9a-f]+:\s+05\s+dec b
\s+[0-9a-f]+:\s+06 fd\s+ld b,0xfd
\s+[0-9a-f]+:\s+07\s+rlca
\s+[0-9a-f]+:\s+08 af be\s+ld \(0xbeaf\),sp
\s+[0-9a-f]+:\s+09\s+add hl,bc
\s+[0-9a-f]+:\s+0a\s+ld a,\(bc\)
\s+[0-9a-f]+:\s+0b\s+dec bc
\s+[0-9a-f]+:\s+0c\s+inc c
\s+[0-9a-f]+:\s+0d\s+dec c
\s+[0-9a-f]+:\s+0e fd\s+ld c,0xfd
\s+[0-9a-f]+:\s+0f\s+rrca
\s+[0-9a-f]+:\s+10\s+stop
\s+[0-9a-f]+:\s+11 af be\s+ld de,0xbeaf
\s+[0-9a-f]+:\s+12\s+ld \(de\),a
\s+[0-9a-f]+:\s+13\s+inc de
\s+[0-9a-f]+:\s+14\s+inc d
\s+[0-9a-f]+:\s+15\s+dec d
\s+[0-9a-f]+:\s+16 fd\s+ld d,0xfd
\s+[0-9a-f]+:\s+17\s+rla
\s+[0-9a-f]+:\s+18 0a\s+jr 0x002d
\s+[0-9a-f]+:\s+19\s+add hl,de
\s+[0-9a-f]+:\s+1a\s+ld a,\(de\)
\s+[0-9a-f]+:\s+1b\s+dec de
\s+[0-9a-f]+:\s+1c\s+inc e
\s+[0-9a-f]+:\s+1d\s+dec e
\s+[0-9a-f]+:\s+1e fd\s+ld e,0xfd
\s+[0-9a-f]+:\s+1f\s+rra
\s+[0-9a-f]+:\s+20 0a\s+jr nz,0x0037
\s+[0-9a-f]+:\s+21 af be\s+ld hl,0xbeaf
\s+[0-9a-f]+:\s+22\s+ld \(hl\+\),a
\s+[0-9a-f]+:\s+22\s+ld \(hl\+\),a
\s+[0-9a-f]+:\s+23\s+inc hl
\s+[0-9a-f]+:\s+24\s+inc h
\s+[0-9a-f]+:\s+25\s+dec h
\s+[0-9a-f]+:\s+26 fd\s+ld h,0xfd
\s+[0-9a-f]+:\s+27\s+daa
\s+[0-9a-f]+:\s+28 0a\s+jr z,0x0044
\s+[0-9a-f]+:\s+29\s+add hl,hl
\s+[0-9a-f]+:\s+2a\s+ld a,\(hl\+\)
\s+[0-9a-f]+:\s+2a\s+ld a,\(hl\+\)
\s+[0-9a-f]+:\s+2b\s+dec hl
\s+[0-9a-f]+:\s+2c\s+inc l
\s+[0-9a-f]+:\s+2d\s+dec l
\s+[0-9a-f]+:\s+2e fd\s+ld l,0xfd
\s+[0-9a-f]+:\s+2f\s+cpl
\s+[0-9a-f]+:\s+30 0a\s+jr nc,0x004f
\s+[0-9a-f]+:\s+31 af be\s+ld sp,0xbeaf
\s+[0-9a-f]+:\s+32\s+ld \(hl-\),a
\s+[0-9a-f]+:\s+32\s+ld \(hl-\),a
\s+[0-9a-f]+:\s+33\s+inc sp
\s+[0-9a-f]+:\s+34\s+inc \(hl\)
\s+[0-9a-f]+:\s+35\s+dec \(hl\)
\s+[0-9a-f]+:\s+36 fd\s+ld \(hl\),0xfd
\s+[0-9a-f]+:\s+37\s+scf
\s+[0-9a-f]+:\s+38 0a\s+jr c,0x005c
\s+[0-9a-f]+:\s+39\s+add hl,sp
\s+[0-9a-f]+:\s+3a\s+ld a,\(hl-\)
\s+[0-9a-f]+:\s+3a\s+ld a,\(hl-\)
\s+[0-9a-f]+:\s+3b\s+dec sp
\s+[0-9a-f]+:\s+3c\s+inc a
\s+[0-9a-f]+:\s+3d\s+dec a
\s+[0-9a-f]+:\s+3e fd\s+ld a,0xfd
\s+[0-9a-f]+:\s+3f\s+ccf
\s+[0-9a-f]+:\s+40\s+ld b,b
\s+[0-9a-f]+:\s+41\s+ld b,c
\s+[0-9a-f]+:\s+42\s+ld b,d
\s+[0-9a-f]+:\s+43\s+ld b,e
\s+[0-9a-f]+:\s+44\s+ld b,h
\s+[0-9a-f]+:\s+45\s+ld b,l
\s+[0-9a-f]+:\s+46\s+ld b,\(hl\)
\s+[0-9a-f]+:\s+47\s+ld b,a
\s+[0-9a-f]+:\s+48\s+ld c,b
\s+[0-9a-f]+:\s+49\s+ld c,c
\s+[0-9a-f]+:\s+4a\s+ld c,d
\s+[0-9a-f]+:\s+4b\s+ld c,e
\s+[0-9a-f]+:\s+4c\s+ld c,h
\s+[0-9a-f]+:\s+4d\s+ld c,l
\s+[0-9a-f]+:\s+4e\s+ld c,\(hl\)
\s+[0-9a-f]+:\s+4f\s+ld c,a
\s+[0-9a-f]+:\s+50\s+ld d,b
\s+[0-9a-f]+:\s+51\s+ld d,c
\s+[0-9a-f]+:\s+52\s+ld d,d
\s+[0-9a-f]+:\s+53\s+ld d,e
\s+[0-9a-f]+:\s+54\s+ld d,h
\s+[0-9a-f]+:\s+55\s+ld d,l
\s+[0-9a-f]+:\s+56\s+ld d,\(hl\)
\s+[0-9a-f]+:\s+57\s+ld d,a
\s+[0-9a-f]+:\s+58\s+ld e,b
\s+[0-9a-f]+:\s+59\s+ld e,c
\s+[0-9a-f]+:\s+5a\s+ld e,d
\s+[0-9a-f]+:\s+5b\s+ld e,e
\s+[0-9a-f]+:\s+5c\s+ld e,h
\s+[0-9a-f]+:\s+5d\s+ld e,l
\s+[0-9a-f]+:\s+5e\s+ld e,\(hl\)
\s+[0-9a-f]+:\s+5f\s+ld e,a
\s+[0-9a-f]+:\s+60\s+ld h,b
\s+[0-9a-f]+:\s+61\s+ld h,c
\s+[0-9a-f]+:\s+62\s+ld h,d
\s+[0-9a-f]+:\s+63\s+ld h,e
\s+[0-9a-f]+:\s+64\s+ld h,h
\s+[0-9a-f]+:\s+65\s+ld h,l
\s+[0-9a-f]+:\s+66\s+ld h,\(hl\)
\s+[0-9a-f]+:\s+67\s+ld h,a
\s+[0-9a-f]+:\s+68\s+ld l,b
\s+[0-9a-f]+:\s+69\s+ld l,c
\s+[0-9a-f]+:\s+6a\s+ld l,d
\s+[0-9a-f]+:\s+6b\s+ld l,e
\s+[0-9a-f]+:\s+6c\s+ld l,h
\s+[0-9a-f]+:\s+6d\s+ld l,l
\s+[0-9a-f]+:\s+6e\s+ld l,\(hl\)
\s+[0-9a-f]+:\s+6f\s+ld l,a
\s+[0-9a-f]+:\s+70\s+ld \(hl\),b
\s+[0-9a-f]+:\s+71\s+ld \(hl\),c
\s+[0-9a-f]+:\s+72\s+ld \(hl\),d
\s+[0-9a-f]+:\s+73\s+ld \(hl\),e
\s+[0-9a-f]+:\s+74\s+ld \(hl\),h
\s+[0-9a-f]+:\s+75\s+ld \(hl\),l
\s+[0-9a-f]+:\s+76\s+halt
\s+[0-9a-f]+:\s+77\s+ld \(hl\),a
\s+[0-9a-f]+:\s+78\s+ld a,b
\s+[0-9a-f]+:\s+79\s+ld a,c
\s+[0-9a-f]+:\s+7a\s+ld a,d
\s+[0-9a-f]+:\s+7b\s+ld a,e
\s+[0-9a-f]+:\s+7c\s+ld a,h
\s+[0-9a-f]+:\s+7d\s+ld a,l
\s+[0-9a-f]+:\s+7e\s+ld a,\(hl\)
\s+[0-9a-f]+:\s+7f\s+ld a,a
\s+[0-9a-f]+:\s+80\s+add a,b
\s+[0-9a-f]+:\s+81\s+add a,c
\s+[0-9a-f]+:\s+82\s+add a,d
\s+[0-9a-f]+:\s+83\s+add a,e
\s+[0-9a-f]+:\s+84\s+add a,h
\s+[0-9a-f]+:\s+85\s+add a,l
\s+[0-9a-f]+:\s+86\s+add a,\(hl\)
\s+[0-9a-f]+:\s+87\s+add a,a
\s+[0-9a-f]+:\s+88\s+adc a,b
\s+[0-9a-f]+:\s+89\s+adc a,c
\s+[0-9a-f]+:\s+8a\s+adc a,d
\s+[0-9a-f]+:\s+8b\s+adc a,e
\s+[0-9a-f]+:\s+8c\s+adc a,h
\s+[0-9a-f]+:\s+8d\s+adc a,l
\s+[0-9a-f]+:\s+8e\s+adc a,\(hl\)
\s+[0-9a-f]+:\s+8f\s+adc a,a
\s+[0-9a-f]+:\s+90\s+sub a,b
\s+[0-9a-f]+:\s+91\s+sub a,c
\s+[0-9a-f]+:\s+92\s+sub a,d
\s+[0-9a-f]+:\s+93\s+sub a,e
\s+[0-9a-f]+:\s+94\s+sub a,h
\s+[0-9a-f]+:\s+95\s+sub a,l
\s+[0-9a-f]+:\s+96\s+sub a,\(hl\)
\s+[0-9a-f]+:\s+97\s+sub a,a
\s+[0-9a-f]+:\s+98\s+sbc a,b
\s+[0-9a-f]+:\s+99\s+sbc a,c
\s+[0-9a-f]+:\s+9a\s+sbc a,d
\s+[0-9a-f]+:\s+9b\s+sbc a,e
\s+[0-9a-f]+:\s+9c\s+sbc a,h
\s+[0-9a-f]+:\s+9d\s+sbc a,l
\s+[0-9a-f]+:\s+9e\s+sbc a,\(hl\)
\s+[0-9a-f]+:\s+9f\s+sbc a,a
\s+[0-9a-f]+:\s+a0\s+and b
\s+[0-9a-f]+:\s+a1\s+and c
\s+[0-9a-f]+:\s+a2\s+and d
\s+[0-9a-f]+:\s+a3\s+and e
\s+[0-9a-f]+:\s+a4\s+and h
\s+[0-9a-f]+:\s+a5\s+and l
\s+[0-9a-f]+:\s+a6\s+and \(hl\)
\s+[0-9a-f]+:\s+a7\s+and a
\s+[0-9a-f]+:\s+a8\s+xor b
\s+[0-9a-f]+:\s+a9\s+xor c
\s+[0-9a-f]+:\s+aa\s+xor d
\s+[0-9a-f]+:\s+ab\s+xor e
\s+[0-9a-f]+:\s+ac\s+xor h
\s+[0-9a-f]+:\s+ad\s+xor l
\s+[0-9a-f]+:\s+ae\s+xor \(hl\)
\s+[0-9a-f]+:\s+af\s+xor a
\s+[0-9a-f]+:\s+b0\s+or b
\s+[0-9a-f]+:\s+b1\s+or c
\s+[0-9a-f]+:\s+b2\s+or d
\s+[0-9a-f]+:\s+b3\s+or e
\s+[0-9a-f]+:\s+b4\s+or h
\s+[0-9a-f]+:\s+b5\s+or l
\s+[0-9a-f]+:\s+b6\s+or \(hl\)
\s+[0-9a-f]+:\s+b7\s+or a
\s+[0-9a-f]+:\s+b8\s+cp b
\s+[0-9a-f]+:\s+b9\s+cp c
\s+[0-9a-f]+:\s+ba\s+cp d
\s+[0-9a-f]+:\s+bb\s+cp e
\s+[0-9a-f]+:\s+bc\s+cp h
\s+[0-9a-f]+:\s+bd\s+cp l
\s+[0-9a-f]+:\s+be\s+cp \(hl\)
\s+[0-9a-f]+:\s+bf\s+cp a
\s+[0-9a-f]+:\s+c0\s+ret nz
\s+[0-9a-f]+:\s+c1\s+pop bc
\s+[0-9a-f]+:\s+c2 af be\s+jp nz,0xbeaf
\s+[0-9a-f]+:\s+c3 af be\s+jp 0xbeaf
\s+[0-9a-f]+:\s+c4 af be\s+call nz,0xbeaf
\s+[0-9a-f]+:\s+c5\s+push bc
\s+[0-9a-f]+:\s+c6 fd\s+add a,0xfd
\s+[0-9a-f]+:\s+c7\s+rst 0x00
\s+[0-9a-f]+:\s+c8\s+ret z
\s+[0-9a-f]+:\s+c9\s+ret
\s+[0-9a-f]+:\s+ca af be\s+jp z,0xbeaf
\s+[0-9a-f]+:\s+00\s+nop
\s+[0-9a-f]+:\s+cc af be\s+call z,0xbeaf
\s+[0-9a-f]+:\s+cd af be\s+call 0xbeaf
\s+[0-9a-f]+:\s+ce fd\s+adc a,0xfd
\s+[0-9a-f]+:\s+cf\s+rst 0x08
\s+[0-9a-f]+:\s+d0\s+ret nc
\s+[0-9a-f]+:\s+d1\s+pop de
\s+[0-9a-f]+:\s+d2 af be\s+jp nc,0xbeaf
\s+[0-9a-f]+:\s+d4 af be\s+call nc,0xbeaf
\s+[0-9a-f]+:\s+d5\s+push de
\s+[0-9a-f]+:\s+d6 fd\s+sub a,0xfd
\s+[0-9a-f]+:\s+d7\s+rst 0x10
\s+[0-9a-f]+:\s+d8\s+ret c
\s+[0-9a-f]+:\s+d9\s+reti
\s+[0-9a-f]+:\s+da af be\s+jp c,0xbeaf
\s+[0-9a-f]+:\s+dc af be\s+call c,0xbeaf
\s+[0-9a-f]+:\s+de fd\s+sbc a,0xfd
\s+[0-9a-f]+:\s+df\s+rst 0x18
\s+[0-9a-f]+:\s+e0 fd\s+ldh \(0xfd\),a
\s+[0-9a-f]+:\s+e1\s+pop hl
\s+[0-9a-f]+:\s+e2\s+ldh \(c\),a
\s+[0-9a-f]+:\s+e5\s+push hl
\s+[0-9a-f]+:\s+e6 fd\s+and 0xfd
\s+[0-9a-f]+:\s+e7\s+rst 0x20
\s+[0-9a-f]+:\s+e8 f4\s+add sp,-12
\s+[0-9a-f]+:\s+e9\s+jp \(hl\)
\s+[0-9a-f]+:\s+ea af be\s+ld \(0xbeaf\),a
\s+[0-9a-f]+:\s+ee fd\s+xor 0xfd
\s+[0-9a-f]+:\s+ef\s+rst 0x28
\s+[0-9a-f]+:\s+f0 fd\s+ldh a,\(0xfd\)
\s+[0-9a-f]+:\s+f1\s+pop af
\s+[0-9a-f]+:\s+f2\s+ldh a,\(c\)
\s+[0-9a-f]+:\s+f3\s+di
\s+[0-9a-f]+:\s+f5\s+push af
\s+[0-9a-f]+:\s+f6 fd\s+or 0xfd
\s+[0-9a-f]+:\s+f7\s+rst 0x30
\s+[0-9a-f]+:\s+f8 f4\s+ldhl sp,-12
\s+[0-9a-f]+:\s+f9\s+ld sp,hl
\s+[0-9a-f]+:\s+fa af be\s+ld a,\(0xbeaf\)
\s+[0-9a-f]+:\s+fb\s+ei
\s+[0-9a-f]+:\s+fe fd\s+cp 0xfd
\s+[0-9a-f]+:\s+ff\s+rst 0x38
\s+[0-9a-f]+:\s+cb 00\s+rlc b
\s+[0-9a-f]+:\s+cb 01\s+rlc c
\s+[0-9a-f]+:\s+cb 02\s+rlc d
\s+[0-9a-f]+:\s+cb 03\s+rlc e
\s+[0-9a-f]+:\s+cb 04\s+rlc h
\s+[0-9a-f]+:\s+cb 05\s+rlc l
\s+[0-9a-f]+:\s+cb 06\s+rlc \(hl\)
\s+[0-9a-f]+:\s+cb 07\s+rlc a
\s+[0-9a-f]+:\s+cb 08\s+rrc b
\s+[0-9a-f]+:\s+cb 09\s+rrc c
\s+[0-9a-f]+:\s+cb 0a\s+rrc d
\s+[0-9a-f]+:\s+cb 0b\s+rrc e
\s+[0-9a-f]+:\s+cb 0c\s+rrc h
\s+[0-9a-f]+:\s+cb 0d\s+rrc l
\s+[0-9a-f]+:\s+cb 0e\s+rrc \(hl\)
\s+[0-9a-f]+:\s+cb 0f\s+rrc a
\s+[0-9a-f]+:\s+cb 10\s+rl b
\s+[0-9a-f]+:\s+cb 11\s+rl c
\s+[0-9a-f]+:\s+cb 12\s+rl d
\s+[0-9a-f]+:\s+cb 13\s+rl e
\s+[0-9a-f]+:\s+cb 14\s+rl h
\s+[0-9a-f]+:\s+cb 15\s+rl l
\s+[0-9a-f]+:\s+cb 16\s+rl \(hl\)
\s+[0-9a-f]+:\s+cb 17\s+rl a
\s+[0-9a-f]+:\s+cb 18\s+rr b
\s+[0-9a-f]+:\s+cb 19\s+rr c
\s+[0-9a-f]+:\s+cb 1a\s+rr d
\s+[0-9a-f]+:\s+cb 1b\s+rr e
\s+[0-9a-f]+:\s+cb 1c\s+rr h
\s+[0-9a-f]+:\s+cb 1d\s+rr l
\s+[0-9a-f]+:\s+cb 1e\s+rr \(hl\)
\s+[0-9a-f]+:\s+cb 1f\s+rr a
\s+[0-9a-f]+:\s+cb 20\s+sla b
\s+[0-9a-f]+:\s+cb 21\s+sla c
\s+[0-9a-f]+:\s+cb 22\s+sla d
\s+[0-9a-f]+:\s+cb 23\s+sla e
\s+[0-9a-f]+:\s+cb 24\s+sla h
\s+[0-9a-f]+:\s+cb 25\s+sla l
\s+[0-9a-f]+:\s+cb 26\s+sla \(hl\)
\s+[0-9a-f]+:\s+cb 27\s+sla a
\s+[0-9a-f]+:\s+cb 28\s+sra b
\s+[0-9a-f]+:\s+cb 29\s+sra c
\s+[0-9a-f]+:\s+cb 2a\s+sra d
\s+[0-9a-f]+:\s+cb 2b\s+sra e
\s+[0-9a-f]+:\s+cb 2c\s+sra h
\s+[0-9a-f]+:\s+cb 2d\s+sra l
\s+[0-9a-f]+:\s+cb 2e\s+sra \(hl\)
\s+[0-9a-f]+:\s+cb 2f\s+sra a
\s+[0-9a-f]+:\s+cb 30\s+swap b
\s+[0-9a-f]+:\s+cb 31\s+swap c
\s+[0-9a-f]+:\s+cb 32\s+swap d
\s+[0-9a-f]+:\s+cb 33\s+swap e
\s+[0-9a-f]+:\s+cb 34\s+swap h
\s+[0-9a-f]+:\s+cb 35\s+swap l
\s+[0-9a-f]+:\s+cb 36\s+swap \(hl\)
\s+[0-9a-f]+:\s+cb 37\s+swap a
\s+[0-9a-f]+:\s+cb 38\s+srl b
\s+[0-9a-f]+:\s+cb 39\s+srl c
\s+[0-9a-f]+:\s+cb 3a\s+srl d
\s+[0-9a-f]+:\s+cb 3b\s+srl e
\s+[0-9a-f]+:\s+cb 3c\s+srl h
\s+[0-9a-f]+:\s+cb 3d\s+srl l
\s+[0-9a-f]+:\s+cb 3e\s+srl \(hl\)
\s+[0-9a-f]+:\s+cb 3f\s+srl a
\s+[0-9a-f]+:\s+cb 40\s+bit 0,b
\s+[0-9a-f]+:\s+cb 41\s+bit 0,c
\s+[0-9a-f]+:\s+cb 42\s+bit 0,d
\s+[0-9a-f]+:\s+cb 43\s+bit 0,e
\s+[0-9a-f]+:\s+cb 44\s+bit 0,h
\s+[0-9a-f]+:\s+cb 45\s+bit 0,l
\s+[0-9a-f]+:\s+cb 46\s+bit 0,\(hl\)
\s+[0-9a-f]+:\s+cb 47\s+bit 0,a
\s+[0-9a-f]+:\s+cb 48\s+bit 1,b
\s+[0-9a-f]+:\s+cb 49\s+bit 1,c
\s+[0-9a-f]+:\s+cb 4a\s+bit 1,d
\s+[0-9a-f]+:\s+cb 4b\s+bit 1,e
\s+[0-9a-f]+:\s+cb 4c\s+bit 1,h
\s+[0-9a-f]+:\s+cb 4d\s+bit 1,l
\s+[0-9a-f]+:\s+cb 4e\s+bit 1,\(hl\)
\s+[0-9a-f]+:\s+cb 4f\s+bit 1,a
\s+[0-9a-f]+:\s+cb 50\s+bit 2,b
\s+[0-9a-f]+:\s+cb 51\s+bit 2,c
\s+[0-9a-f]+:\s+cb 52\s+bit 2,d
\s+[0-9a-f]+:\s+cb 53\s+bit 2,e
\s+[0-9a-f]+:\s+cb 54\s+bit 2,h
\s+[0-9a-f]+:\s+cb 55\s+bit 2,l
\s+[0-9a-f]+:\s+cb 56\s+bit 2,\(hl\)
\s+[0-9a-f]+:\s+cb 57\s+bit 2,a
\s+[0-9a-f]+:\s+cb 58\s+bit 3,b
\s+[0-9a-f]+:\s+cb 59\s+bit 3,c
\s+[0-9a-f]+:\s+cb 5a\s+bit 3,d
\s+[0-9a-f]+:\s+cb 5b\s+bit 3,e
\s+[0-9a-f]+:\s+cb 5c\s+bit 3,h
\s+[0-9a-f]+:\s+cb 5d\s+bit 3,l
\s+[0-9a-f]+:\s+cb 5e\s+bit 3,\(hl\)
\s+[0-9a-f]+:\s+cb 5f\s+bit 3,a
\s+[0-9a-f]+:\s+cb 60\s+bit 4,b
\s+[0-9a-f]+:\s+cb 61\s+bit 4,c
\s+[0-9a-f]+:\s+cb 62\s+bit 4,d
\s+[0-9a-f]+:\s+cb 63\s+bit 4,e
\s+[0-9a-f]+:\s+cb 64\s+bit 4,h
\s+[0-9a-f]+:\s+cb 65\s+bit 4,l
\s+[0-9a-f]+:\s+cb 66\s+bit 4,\(hl\)
\s+[0-9a-f]+:\s+cb 67\s+bit 4,a
\s+[0-9a-f]+:\s+cb 68\s+bit 5,b
\s+[0-9a-f]+:\s+cb 69\s+bit 5,c
\s+[0-9a-f]+:\s+cb 6a\s+bit 5,d
\s+[0-9a-f]+:\s+cb 6b\s+bit 5,e
\s+[0-9a-f]+:\s+cb 6c\s+bit 5,h
\s+[0-9a-f]+:\s+cb 6d\s+bit 5,l
\s+[0-9a-f]+:\s+cb 6e\s+bit 5,\(hl\)
\s+[0-9a-f]+:\s+cb 6f\s+bit 5,a
\s+[0-9a-f]+:\s+cb 70\s+bit 6,b
\s+[0-9a-f]+:\s+cb 71\s+bit 6,c
\s+[0-9a-f]+:\s+cb 72\s+bit 6,d
\s+[0-9a-f]+:\s+cb 73\s+bit 6,e
\s+[0-9a-f]+:\s+cb 74\s+bit 6,h
\s+[0-9a-f]+:\s+cb 75\s+bit 6,l
\s+[0-9a-f]+:\s+cb 76\s+bit 6,\(hl\)
\s+[0-9a-f]+:\s+cb 77\s+bit 6,a
\s+[0-9a-f]+:\s+cb 78\s+bit 7,b
\s+[0-9a-f]+:\s+cb 79\s+bit 7,c
\s+[0-9a-f]+:\s+cb 7a\s+bit 7,d
\s+[0-9a-f]+:\s+cb 7b\s+bit 7,e
\s+[0-9a-f]+:\s+cb 7c\s+bit 7,h
\s+[0-9a-f]+:\s+cb 7d\s+bit 7,l
\s+[0-9a-f]+:\s+cb 7e\s+bit 7,\(hl\)
\s+[0-9a-f]+:\s+cb 7f\s+bit 7,a
\s+[0-9a-f]+:\s+cb 80\s+res 0,b
\s+[0-9a-f]+:\s+cb 81\s+res 0,c
\s+[0-9a-f]+:\s+cb 82\s+res 0,d
\s+[0-9a-f]+:\s+cb 83\s+res 0,e
\s+[0-9a-f]+:\s+cb 84\s+res 0,h
\s+[0-9a-f]+:\s+cb 85\s+res 0,l
\s+[0-9a-f]+:\s+cb 86\s+res 0,\(hl\)
\s+[0-9a-f]+:\s+cb 87\s+res 0,a
\s+[0-9a-f]+:\s+cb 88\s+res 1,b
\s+[0-9a-f]+:\s+cb 89\s+res 1,c
\s+[0-9a-f]+:\s+cb 8a\s+res 1,d
\s+[0-9a-f]+:\s+cb 8b\s+res 1,e
\s+[0-9a-f]+:\s+cb 8c\s+res 1,h
\s+[0-9a-f]+:\s+cb 8d\s+res 1,l
\s+[0-9a-f]+:\s+cb 8e\s+res 1,\(hl\)
\s+[0-9a-f]+:\s+cb 8f\s+res 1,a
\s+[0-9a-f]+:\s+cb 90\s+res 2,b
\s+[0-9a-f]+:\s+cb 91\s+res 2,c
\s+[0-9a-f]+:\s+cb 92\s+res 2,d
\s+[0-9a-f]+:\s+cb 93\s+res 2,e
\s+[0-9a-f]+:\s+cb 94\s+res 2,h
\s+[0-9a-f]+:\s+cb 95\s+res 2,l
\s+[0-9a-f]+:\s+cb 96\s+res 2,\(hl\)
\s+[0-9a-f]+:\s+cb 97\s+res 2,a
\s+[0-9a-f]+:\s+cb 98\s+res 3,b
\s+[0-9a-f]+:\s+cb 99\s+res 3,c
\s+[0-9a-f]+:\s+cb 9a\s+res 3,d
\s+[0-9a-f]+:\s+cb 9b\s+res 3,e
\s+[0-9a-f]+:\s+cb 9c\s+res 3,h
\s+[0-9a-f]+:\s+cb 9d\s+res 3,l
\s+[0-9a-f]+:\s+cb 9e\s+res 3,\(hl\)
\s+[0-9a-f]+:\s+cb 9f\s+res 3,a
\s+[0-9a-f]+:\s+cb a0\s+res 4,b
\s+[0-9a-f]+:\s+cb a1\s+res 4,c
\s+[0-9a-f]+:\s+cb a2\s+res 4,d
\s+[0-9a-f]+:\s+cb a3\s+res 4,e
\s+[0-9a-f]+:\s+cb a4\s+res 4,h
\s+[0-9a-f]+:\s+cb a5\s+res 4,l
\s+[0-9a-f]+:\s+cb a6\s+res 4,\(hl\)
\s+[0-9a-f]+:\s+cb a7\s+res 4,a
\s+[0-9a-f]+:\s+cb a8\s+res 5,b
\s+[0-9a-f]+:\s+cb a9\s+res 5,c
\s+[0-9a-f]+:\s+cb aa\s+res 5,d
\s+[0-9a-f]+:\s+cb ab\s+res 5,e
\s+[0-9a-f]+:\s+cb ac\s+res 5,h
\s+[0-9a-f]+:\s+cb ad\s+res 5,l
\s+[0-9a-f]+:\s+cb ae\s+res 5,\(hl\)
\s+[0-9a-f]+:\s+cb af\s+res 5,a
\s+[0-9a-f]+:\s+cb b0\s+res 6,b
\s+[0-9a-f]+:\s+cb b1\s+res 6,c
\s+[0-9a-f]+:\s+cb b2\s+res 6,d
\s+[0-9a-f]+:\s+cb b3\s+res 6,e
\s+[0-9a-f]+:\s+cb b4\s+res 6,h
\s+[0-9a-f]+:\s+cb b5\s+res 6,l
\s+[0-9a-f]+:\s+cb b6\s+res 6,\(hl\)
\s+[0-9a-f]+:\s+cb b7\s+res 6,a
\s+[0-9a-f]+:\s+cb b8\s+res 7,b
\s+[0-9a-f]+:\s+cb b9\s+res 7,c
\s+[0-9a-f]+:\s+cb ba\s+res 7,d
\s+[0-9a-f]+:\s+cb bb\s+res 7,e
\s+[0-9a-f]+:\s+cb bc\s+res 7,h
\s+[0-9a-f]+:\s+cb bd\s+res 7,l
\s+[0-9a-f]+:\s+cb be\s+res 7,\(hl\)
\s+[0-9a-f]+:\s+cb bf\s+res 7,a
\s+[0-9a-f]+:\s+cb c0\s+set 0,b
\s+[0-9a-f]+:\s+cb c1\s+set 0,c
\s+[0-9a-f]+:\s+cb c2\s+set 0,d
\s+[0-9a-f]+:\s+cb c3\s+set 0,e
\s+[0-9a-f]+:\s+cb c4\s+set 0,h
\s+[0-9a-f]+:\s+cb c5\s+set 0,l
\s+[0-9a-f]+:\s+cb c6\s+set 0,\(hl\)
\s+[0-9a-f]+:\s+cb c7\s+set 0,a
\s+[0-9a-f]+:\s+cb c8\s+set 1,b
\s+[0-9a-f]+:\s+cb c9\s+set 1,c
\s+[0-9a-f]+:\s+cb ca\s+set 1,d
\s+[0-9a-f]+:\s+cb cb\s+set 1,e
\s+[0-9a-f]+:\s+cb cc\s+set 1,h
\s+[0-9a-f]+:\s+cb cd\s+set 1,l
\s+[0-9a-f]+:\s+cb ce\s+set 1,\(hl\)
\s+[0-9a-f]+:\s+cb cf\s+set 1,a
\s+[0-9a-f]+:\s+cb d0\s+set 2,b
\s+[0-9a-f]+:\s+cb d1\s+set 2,c
\s+[0-9a-f]+:\s+cb d2\s+set 2,d
\s+[0-9a-f]+:\s+cb d3\s+set 2,e
\s+[0-9a-f]+:\s+cb d4\s+set 2,h
\s+[0-9a-f]+:\s+cb d5\s+set 2,l
\s+[0-9a-f]+:\s+cb d6\s+set 2,\(hl\)
\s+[0-9a-f]+:\s+cb d7\s+set 2,a
\s+[0-9a-f]+:\s+cb d8\s+set 3,b
\s+[0-9a-f]+:\s+cb d9\s+set 3,c
\s+[0-9a-f]+:\s+cb da\s+set 3,d
\s+[0-9a-f]+:\s+cb db\s+set 3,e
\s+[0-9a-f]+:\s+cb dc\s+set 3,h
\s+[0-9a-f]+:\s+cb dd\s+set 3,l
\s+[0-9a-f]+:\s+cb de\s+set 3,\(hl\)
\s+[0-9a-f]+:\s+cb df\s+set 3,a
\s+[0-9a-f]+:\s+cb e0\s+set 4,b
\s+[0-9a-f]+:\s+cb e1\s+set 4,c
\s+[0-9a-f]+:\s+cb e2\s+set 4,d
\s+[0-9a-f]+:\s+cb e3\s+set 4,e
\s+[0-9a-f]+:\s+cb e4\s+set 4,h
\s+[0-9a-f]+:\s+cb e5\s+set 4,l
\s+[0-9a-f]+:\s+cb e6\s+set 4,\(hl\)
\s+[0-9a-f]+:\s+cb e7\s+set 4,a
\s+[0-9a-f]+:\s+cb e8\s+set 5,b
\s+[0-9a-f]+:\s+cb e9\s+set 5,c
\s+[0-9a-f]+:\s+cb ea\s+set 5,d
\s+[0-9a-f]+:\s+cb eb\s+set 5,e
\s+[0-9a-f]+:\s+cb ec\s+set 5,h
\s+[0-9a-f]+:\s+cb ed\s+set 5,l
\s+[0-9a-f]+:\s+cb ee\s+set 5,\(hl\)
\s+[0-9a-f]+:\s+cb ef\s+set 5,a
\s+[0-9a-f]+:\s+cb f0\s+set 6,b
\s+[0-9a-f]+:\s+cb f1\s+set 6,c
\s+[0-9a-f]+:\s+cb f2\s+set 6,d
\s+[0-9a-f]+:\s+cb f3\s+set 6,e
\s+[0-9a-f]+:\s+cb f4\s+set 6,h
\s+[0-9a-f]+:\s+cb f5\s+set 6,l
\s+[0-9a-f]+:\s+cb f6\s+set 6,\(hl\)
\s+[0-9a-f]+:\s+cb f7\s+set 6,a
\s+[0-9a-f]+:\s+cb f8\s+set 7,b
\s+[0-9a-f]+:\s+cb f9\s+set 7,c
\s+[0-9a-f]+:\s+cb fa\s+set 7,d
\s+[0-9a-f]+:\s+cb fb\s+set 7,e
\s+[0-9a-f]+:\s+cb fc\s+set 7,h
\s+[0-9a-f]+:\s+cb fd\s+set 7,l
\s+[0-9a-f]+:\s+cb fe\s+set 7,\(hl\)
\s+[0-9a-f]+:\s+cb ff\s+set 7,a

View File

@ -0,0 +1,519 @@
.text
.org 0
;; Game Boy Z80 opcode test
nop
ld bc,0xbeaf
ld (bc),a
inc bc
inc b
dec b
ld b,0xfd
rlca
ld (0xbeaf),sp
add hl,bc
ld a,(bc)
dec bc
inc c
dec c
ld c,0xfd
rrca
stop
ld de,0xbeaf
ld (de),a
inc de
inc d
dec d
ld d,0xfd
rla
jr .+12
add hl,de
ld a,(de)
dec de
inc e
dec e
ld e,0xfd
rra
jr nz,.+12
ld hl,0xbeaf
ldi (hl),a
ld (hl+),a
inc hl
inc h
dec h
ld h,0xfd
daa
jr z,.+12
add hl,hl
ldi a,(hl)
ld a,(hl+)
dec hl
inc l
dec l
ld l,0xfd
cpl
jr nc,.+12
ld sp,0xbeaf
ldd (hl),a
ld (hl-),a
inc sp
inc (hl)
dec (hl)
ld (hl),0xfd
scf
jr c,.+12
add hl,sp
ldd a,(hl)
ld a,(hl-)
dec sp
inc a
dec a
ld a,0xfd
ccf
ld b,b
ld b,c
ld b,d
ld b,e
ld b,h
ld b,l
ld b,(hl)
ld b,a
ld c,b
ld c,c
ld c,d
ld c,e
ld c,h
ld c,l
ld c,(hl)
ld c,a
ld d,b
ld d,c
ld d,d
ld d,e
ld d,h
ld d,l
ld d,(hl)
ld d,a
ld e,b
ld e,c
ld e,d
ld e,e
ld e,h
ld e,l
ld e,(hl)
ld e,a
ld h,b
ld h,c
ld h,d
ld h,e
ld h,h
ld h,l
ld h,(hl)
ld h,a
ld l,b
ld l,c
ld l,d
ld l,e
ld l,h
ld l,l
ld l,(hl)
ld l,a
ld (hl),b
ld (hl),c
ld (hl),d
ld (hl),e
ld (hl),h
ld (hl),l
halt
ld (hl),a
ld a,b
ld a,c
ld a,d
ld a,e
ld a,h
ld a,l
ld a,(hl)
ld a,a
add a,b
add a,c
add a,d
add a,e
add a,h
add a,l
add a,(hl)
add a,a
adc a,b
adc a,c
adc a,d
adc a,e
adc a,h
adc a,l
adc a,(hl)
adc a,a
sub a,b
sub a,c
sub a,d
sub a,e
sub a,h
sub a,l
sub a,(hl)
sub a,a
sbc a,b
sbc a,c
sbc a,d
sbc a,e
sbc a,h
sbc a,l
sbc a,(hl)
sbc a,a
and b
and c
and d
and e
and h
and l
and (hl)
and a
xor b
xor c
xor d
xor e
xor h
xor l
xor (hl)
xor a
or b
or c
or d
or e
or h
or l
or (hl)
or a
cp b
cp c
cp d
cp e
cp h
cp l
cp (hl)
cp a
ret nz
pop bc
jp nz,0xbeaf
jp 0xbeaf
call nz,0xbeaf
push bc
add a,0xfd
rst 0
ret z
ret
jp z,0xbeaf
nop ;CB prefix
call z,0xbeaf
call 0xbeaf
adc a,0xfd
rst 0x08
ret nc
pop de
jp nc,0xbeaf
;xx
call nc,0xbeaf
push de
sub a,0xfd
rst 0x10
ret c
reti
jp c,0xbeaf
;xx
call c,0xbeaf
;xx
sbc a,0xfd
rst 0x18
ldh (0xfd),a
pop hl
ldh (c),a
;xx
;xx
push hl
and 0xfd
rst 0x20
add sp,-12
jp (hl)
ld (0xbeaf),a
;xx
;xx
;xx
xor 0xfd
rst 0x28
ldh a,(0xfd)
pop af
ldh a,(c)
di
;xx
push af
or 0xfd
rst 0x30
ldhl sp,-12
ld sp,hl
ld a,(0xbeaf)
ei
;xx
;xx
cp 0xfd
rst 0x38
rlc b
rlc c
rlc d
rlc e
rlc h
rlc l
rlc (hl)
rlc a
rrc b
rrc c
rrc d
rrc e
rrc h
rrc l
rrc (hl)
rrc a
rl b
rl c
rl d
rl e
rl h
rl l
rl (hl)
rl a
rr b
rr c
rr d
rr e
rr h
rr l
rr (hl)
rr a
sla b
sla c
sla d
sla e
sla h
sla l
sla (hl)
sla a
sra b
sra c
sra d
sra e
sra h
sra l
sra (hl)
sra a
swap b
swap c
swap d
swap e
swap h
swap l
swap (hl)
swap a
srl b
srl c
srl d
srl e
srl h
srl l
srl (hl)
srl a
bit 0,b
bit 0,c
bit 0,d
bit 0,e
bit 0,h
bit 0,l
bit 0,(hl)
bit 0,a
bit 1,b
bit 1,c
bit 1,d
bit 1,e
bit 1,h
bit 1,l
bit 1,(hl)
bit 1,a
bit 2,b
bit 2,c
bit 2,d
bit 2,e
bit 2,h
bit 2,l
bit 2,(hl)
bit 2,a
bit 3,b
bit 3,c
bit 3,d
bit 3,e
bit 3,h
bit 3,l
bit 3,(hl)
bit 3,a
bit 4,b
bit 4,c
bit 4,d
bit 4,e
bit 4,h
bit 4,l
bit 4,(hl)
bit 4,a
bit 5,b
bit 5,c
bit 5,d
bit 5,e
bit 5,h
bit 5,l
bit 5,(hl)
bit 5,a
bit 6,b
bit 6,c
bit 6,d
bit 6,e
bit 6,h
bit 6,l
bit 6,(hl)
bit 6,a
bit 7,b
bit 7,c
bit 7,d
bit 7,e
bit 7,h
bit 7,l
bit 7,(hl)
bit 7,a
res 0,b
res 0,c
res 0,d
res 0,e
res 0,h
res 0,l
res 0,(hl)
res 0,a
res 1,b
res 1,c
res 1,d
res 1,e
res 1,h
res 1,l
res 1,(hl)
res 1,a
res 2,b
res 2,c
res 2,d
res 2,e
res 2,h
res 2,l
res 2,(hl)
res 2,a
res 3,b
res 3,c
res 3,d
res 3,e
res 3,h
res 3,l
res 3,(hl)
res 3,a
res 4,b
res 4,c
res 4,d
res 4,e
res 4,h
res 4,l
res 4,(hl)
res 4,a
res 5,b
res 5,c
res 5,d
res 5,e
res 5,h
res 5,l
res 5,(hl)
res 5,a
res 6,b
res 6,c
res 6,d
res 6,e
res 6,h
res 6,l
res 6,(hl)
res 6,a
res 7,b
res 7,c
res 7,d
res 7,e
res 7,h
res 7,l
res 7,(hl)
res 7,a
set 0,b
set 0,c
set 0,d
set 0,e
set 0,h
set 0,l
set 0,(hl)
set 0,a
set 1,b
set 1,c
set 1,d
set 1,e
set 1,h
set 1,l
set 1,(hl)
set 1,a
set 2,b
set 2,c
set 2,d
set 2,e
set 2,h
set 2,l
set 2,(hl)
set 2,a
set 3,b
set 3,c
set 3,d
set 3,e
set 3,h
set 3,l
set 3,(hl)
set 3,a
set 4,b
set 4,c
set 4,d
set 4,e
set 4,h
set 4,l
set 4,(hl)
set 4,a
set 5,b
set 5,c
set 5,d
set 5,e
set 5,h
set 5,l
set 5,(hl)
set 5,a
set 6,b
set 6,c
set 6,d
set 6,e
set 6,h
set 6,l
set 6,(hl)
set 6,a
set 7,b
set 7,c
set 7,d
set 7,e
set 7,h
set 7,l
set 7,(hl)
set 7,a

View File

@ -92,6 +92,12 @@ if [istarget z80-*-*] then {
run_dump_test "ez80_adl_suf"
#test for eZ80 opcode prefixes as multiple bytes before instruction
run_dump_test "ez80_pref_dis"
#test for GBZ80 instruction set
run_dump_test "gbz80_all"
#test for Z80N instruction set
run_dump_test "z80n_all"
#test for Z80N push nn relocation test
run_dump_test "z80n_reloc"
# test for SDCC compatibility mode
run_dump_test "sdcc"
# test for colonless labels

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
#as: -z80n
#source: z80n_all.s
#objdump: -r
#name: Z80N big-endian relocation
.*:[ ]+file format (coff|elf32)\-z80
RELOCATION RECORDS FOR \[\.text\]:
OFFSET[ ]+TYPE[ ]+VALUE\s*
0*c2a[ ]+r_imm16be[ ]+push_value\s*

View File

@ -1,3 +1,10 @@
2020-02-07 Sergey Belyashov <sergey.belyashov@gmail.com>
PR 25469
* coff/internal.h (R_IMM16BE): Define.
* elf/z80.h (EF_Z80_MACH_Z80N): Define.
(R_Z80_16_BE): New reloc.
2020-02-04 Alan Modra <amodra@gmail.com>
* opcode/d30v.h (struct pd_reg): Make value field unsigned.

View File

@ -812,6 +812,7 @@ struct internal_reloc
/* Z80 modes */
#define R_OFF8 0x32 /* 8 bit signed abs, for (i[xy]+d) */
#define R_IMM24 0x33 /* 24 bit abs */
#define R_IMM16BE 0x3A /* 16 bit abs, big endian */
/* R_JR, R_IMM8, R_IMM16, R_IMM32 - as for Z8k */
#define R_BYTE0 0x34 /* first (lowest) 8 bits of multibyte value */
#define R_BYTE1 0x35 /* second 8 bits of multibyte value */

View File

@ -30,6 +30,7 @@
#define EF_Z80_MACH_EZ80_Z80 0x04
#define EF_Z80_MACH_EZ80_ADL 0x84
#define EF_Z80_MACH_GBZ80 0x05
#define EF_Z80_MACH_Z80N 0x06
#define EF_Z80_MACH_MSK 0xff
/* Relocations. */
@ -47,6 +48,7 @@ START_RELOC_NUMBERS (elf_z80_reloc_type)
RELOC_NUMBER (R_Z80_BYTE3, 10)
RELOC_NUMBER (R_Z80_WORD0, 11)
RELOC_NUMBER (R_Z80_WORD1, 12)
RELOC_NUMBER (R_Z80_16_BE, 13)
END_RELOC_NUMBERS (R_Z80_max)
#endif /* _ELF_Z80_H */

View File

@ -1,3 +1,22 @@
2020-02-07 Sergey Belyashov <sergey.belyashov@gmail.com>
PR 25469
* emulparams/elf32z80.sh: Use z80 emulation.
* emultempl/z80.em: Make generic to both COFF and ELF Z80 emulations.
* emultempl/z80elf.em: Delete.
* testsuite/ld-elf/pr22450.d: Expect to fail for the Z80.
* testsuite/ld-elf/sec64k.exp: Fix Z80 assembly.
* testsuite/ld-unique/pr21529.s: Avoid register name conflict.
* testsuite/ld-unique/unique.s: Likewise.
* testsuite/ld-unique/unique_empty.s: Likewise.
* testsuite/ld-unique/unique_shared.s: Likewise.
* testsuite/ld-unique/unique.d: Updated expected output.
* testsuite/ld-z80/arch_z80n.d: New file.
* testsuite/ld-z80/comb_arch_z80_z80n.d: New file.
* testsuite/ld-z80/labels.s: Add more labels.
* testsuite/ld-z80/relocs.s: Add more reloc tests.
* testsuite/ld-z80/relocs_f_z80n.d: New file
2020-02-07 H.J. Lu <hongjiu.lu@intel.com>
PR ld/25022

View File

@ -11,7 +11,7 @@ TEXT_START_ADDR=0x100
#TEXT_LENGTH=0
#DATA_ORIGIN=0
#DATA_LENGTH=0
EXTRA_EM_FILE=z80elf
EXTRA_EM_FILE=z80
#FUSE_NAME=fuse

View File

@ -19,129 +19,136 @@
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
LDEMUL_BEFORE_PARSE=gldz80_before_parse
LDEMUL_RECOGNIZED_FILE=gldz80_recognized_file
LDEMUL_AFTER_OPEN=gldz80_after_open
fragment <<EOF
/* --- \begin{z80.em} */
/* Codes for machine types, bitwise or gives the code to use for the
output. */
#define M_Z80STRICT 0x01
#define M_Z80 0x03
#define M_Z80FULL 0x07
#define M_R800 0x10
#define M_Z80ANY 0x0f
#define M_GBZ80 0x20
#define M_Z180 0x40
#define M_EZ80_Z80 0x80
#define M_EZ80_ADL 0x100
#define M_ARCH_MASK 0xFF0
/* Bitwise or of the machine types seen so far. */
static int result_mach_type;
#include "elf/z80.h"
static void
${LDEMUL_BEFORE_PARSE} (void)
gld${EMULATION_NAME}_after_open (void);
static int result_mach_type;
struct z80_mach_info
{
#ifndef TARGET_ /* I.e., if not generic. */
ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown);
#endif /* not TARGET_ */
result_mach_type = 0;
unsigned eflags;
unsigned bfd_mach;
const int *compat; /* back compatible machines */
};
static const int
back_compat_z80[] = {bfd_mach_z80, -1};
static const int
back_compat_z180[] = {bfd_mach_z180, bfd_mach_z80, -1};
static const int
back_compat_ez80[] = {bfd_mach_ez80_z80, bfd_mach_z180, bfd_mach_z80, -1};
static const struct z80_mach_info
z80_mach_info[] =
{
{ EF_Z80_MACH_Z80, bfd_mach_z80, NULL },
{ EF_Z80_MACH_Z80, bfd_mach_z80strict, back_compat_z80 },
{ EF_Z80_MACH_Z80, bfd_mach_z80full, back_compat_z80 },
{ EF_Z80_MACH_Z180, bfd_mach_z180, back_compat_z80 },
{ EF_Z80_MACH_EZ80_Z80, bfd_mach_ez80_z80, back_compat_z180 },
{ EF_Z80_MACH_EZ80_ADL, bfd_mach_ez80_adl, back_compat_ez80 },
{ EF_Z80_MACH_Z80N, bfd_mach_z80n, back_compat_z80 },
{ EF_Z80_MACH_GBZ80, bfd_mach_gbz80, NULL },
{ EF_Z80_MACH_R800, bfd_mach_r800, back_compat_z80 }
};
/*
static const struct z80_mach_info *
z80_mach_info_by_eflags (unsigned int eflags)
{
const struct z80_mach_info *p;
const struct z80_mach_info *e;
eflags &= EF_Z80_MACH_MSK;
p = &z80_mach_info[0];
e = &z80_mach_info[sizeof(z80_mach_info)/sizeof(*z80_mach_info)];
for (; p != e; ++p)
if (eflags == p->eflags)
return p;
return NULL;
}*/
static const struct z80_mach_info *
z80_mach_info_by_mach (unsigned int bfd_mach)
{
const struct z80_mach_info *p;
const struct z80_mach_info *e;
p = &z80_mach_info[0];
e = &z80_mach_info[sizeof(z80_mach_info)/sizeof(*z80_mach_info)];
for (; p != e; ++p)
if (bfd_mach == p->bfd_mach)
return p;
return NULL;
}
/* Update result_mach_type. */
static bfd_boolean
${LDEMUL_RECOGNIZED_FILE} (lang_input_statement_type *entry)
static const struct z80_mach_info *
z80_combine_mach (const struct z80_mach_info *m1,
const struct z80_mach_info *m2)
{
unsigned long mach_type;
mach_type = bfd_get_mach (entry->the_bfd);
switch (mach_type)
{
case bfd_mach_z80strict:
result_mach_type |= M_Z80STRICT;
break;
case bfd_mach_z80:
result_mach_type |= M_Z80;
break;
case bfd_mach_z80full:
result_mach_type |= M_Z80FULL;
break;
case bfd_mach_r800:
result_mach_type |= M_R800;
break;
case bfd_mach_gbz80:
result_mach_type |= M_GBZ80;
break;
case bfd_mach_z180:
result_mach_type |= M_Z180;
break;
case bfd_mach_ez80_z80:
result_mach_type |= M_EZ80_Z80;
break;
case bfd_mach_ez80_adl:
result_mach_type |= M_EZ80_ADL;
break;
default:
einfo (_("%P: warning: unknown machine type %u"), (unsigned)mach_type);
result_mach_type |= M_Z80ANY;
}
return FALSE;
int i;
int mach;
if (m1->compat != NULL)
for (i = 0; (mach = m1->compat[i]) >= 0; ++i)
if ((unsigned)mach == m2->bfd_mach)
return m1;
if (m2->compat != NULL)
for (i = 0; (mach = m2->compat[i]) >= 0; ++i)
if ((unsigned)mach == m1->bfd_mach)
return m2;
/* incompatible mach */
return NULL;
}
/* Set the machine type of the output file based on result_mach_type. */
static void
gldz80_after_open (void)
z80_after_open (void)
{
unsigned long mach_type;
const struct z80_mach_info *mach = NULL;
bfd *abfd;
after_open_default ();
switch (result_mach_type & M_ARCH_MASK)
/* For now, make sure all object files are of the same architecture.
We may try to merge object files with different architecture together. */
for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
{
case M_Z80 & M_ARCH_MASK:
case M_R800:
case M_Z180:
case M_GBZ80:
case M_EZ80_Z80:
case M_EZ80_ADL:
case M_EZ80_Z80 | M_Z180:
/* valid combination */
break;
case M_EZ80_Z80 | M_EZ80_ADL:
case M_EZ80_Z80 | M_EZ80_ADL | M_Z180:
case M_EZ80_ADL | M_Z180:
/* combination may cause invalid objdump output */
/* but it is possible for mixed ADL/Z80 code */
einfo (_("%P: warning: mixing ADL and Z80 mode binaries, objdump may generate invalid output"));
break;
default:
/* invalid combination: for example Z180 + R800 */
einfo (_("%P: warning: incompatible object files linked, result code might not work"));
const struct z80_mach_info *new_mach;
/*new_mach = z80_mach_info_by_eflags (elf_elfheader (abfd)->e_flags);*/
new_mach = z80_mach_info_by_mach(bfd_get_mach (abfd));
if (mach == NULL)
mach = new_mach;
else if (mach != new_mach)
mach = z80_combine_mach (mach, new_mach);
if (mach == NULL)
einfo (_("%F%P: %pB: Instruction sets of object files incompatible\n"),
abfd);
}
if (mach != NULL)
{
bfd_set_arch_mach (link_info.output_bfd, bfd_arch_z80, mach->bfd_mach);
result_mach_type = mach->bfd_mach;
}
if ((result_mach_type & M_EZ80_ADL) == M_EZ80_ADL)
mach_type = bfd_mach_ez80_adl;
else if ((result_mach_type & M_EZ80_Z80) == M_EZ80_Z80)
mach_type = bfd_mach_ez80_z80;
else if ((result_mach_type & M_Z180) == M_Z180)
mach_type = bfd_mach_z180;
else if ((result_mach_type & M_R800) == M_R800)
mach_type = bfd_mach_r800;
else if ((result_mach_type & M_GBZ80) == M_GBZ80)
mach_type = bfd_mach_gbz80;
else if ((result_mach_type & M_Z80FULL) == M_Z80FULL)
mach_type = bfd_mach_z80full; /* TODO: remove it */
else if ((result_mach_type & M_Z80) == M_Z80)
mach_type = bfd_mach_z80;
else if ((result_mach_type & M_Z80STRICT) == M_Z80STRICT)
mach_type = bfd_mach_z80strict; /* TODO: remove this */
else
mach_type = bfd_arch_unknown;
einfo (_("%F%P: %pB: Unknown machine type\n"),
abfd);
bfd_set_arch_mach (link_info.output_bfd, bfd_arch_z80, mach_type);
/* Call the standard elf routine. */
gld${EMULATION_NAME}_after_open ();
}
#ifndef TARGET_IS_elf32z80
static void
gld${EMULATION_NAME}_after_open (void)
{
}
#endif
/* --- \end{z80.em} */
EOF
LDEMUL_AFTER_OPEN=z80_after_open

View File

@ -1,133 +0,0 @@
# This shell script emits C code -*- C -*-
# to keep track of the machine type of Z80 object files
# It does some substitutions.
# Copyright (C) 2005-2019 Free Software Foundation, Inc.
# This file is part of the GNU Binutils.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
fragment <<EOF
/* --- \begin{z80.em} */
#include "elf/z80.h"
static void
gld${EMULATION_NAME}_after_open (void);
static int result_mach_type;
/* Set the machine type of the output file based on result_mach_type. */
static void
z80_elf_after_open (void)
{
unsigned int mach = 0;
bfd *abfd;
/* For now, make sure all object files are of the same architecture.
We may try to merge object files with different architecture together. */
for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
{
unsigned long new_mach;
new_mach = elf_elfheader (abfd)->e_flags & 0xff;
if (!mach)
mach = new_mach;
else if (mach != new_mach)
{
if ((new_mach == EF_Z80_MACH_R800 || mach == EF_Z80_MACH_R800) ||
(new_mach == EF_Z80_MACH_GBZ80 || mach == EF_Z80_MACH_GBZ80))
einfo (_("%F%P: %pB: Instruction set of object files mismatched\n"),
abfd);
else if (mach < new_mach)
mach = new_mach;
}
}
switch (mach & 0xff)
{
case EF_Z80_MACH_Z80:
mach = bfd_mach_z80;
break;
case EF_Z80_MACH_Z180:
mach = bfd_mach_z180;
break;
case EF_Z80_MACH_R800:
mach = bfd_mach_r800;
break;
case EF_Z80_MACH_EZ80_Z80:
mach = bfd_mach_ez80_z80;
break;
case EF_Z80_MACH_EZ80_ADL:
mach = bfd_mach_ez80_adl;
break;
case EF_Z80_MACH_GBZ80:
mach = bfd_mach_gbz80;
break;
default:
mach = (unsigned)-1;
}
bfd_set_arch_mach (link_info.output_bfd, bfd_arch_z80, mach);
result_mach_type = mach;
/* Call the standard elf routine. */
gld${EMULATION_NAME}_after_open ();
}
static void
z80_elf_finish (void)
{
bfd *abfd;
abfd = link_info.output_bfd;
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
{
unsigned e_flags;
switch (result_mach_type)
{
case bfd_mach_z80strict:
case bfd_mach_z80:
case bfd_mach_z80full:
e_flags = EF_Z80_MACH_Z80;
break;
case bfd_mach_r800:
e_flags = EF_Z80_MACH_R800;
break;
case bfd_mach_gbz80:
e_flags = EF_Z80_MACH_GBZ80;
break;
case bfd_mach_z180:
e_flags = EF_Z80_MACH_Z180;
break;
case bfd_mach_ez80_z80:
e_flags = EF_Z80_MACH_EZ80_Z80;
break;
case bfd_mach_ez80_adl:
e_flags = EF_Z80_MACH_EZ80_ADL;
break;
default:
e_flags = ~0;
}
elf_elfheader (abfd)->e_flags = (elf_elfheader (abfd)->e_flags & ~0xff) | e_flags;
}
finish_default ();
}
/* --- \end{z80.em} */
EOF
LDEMUL_AFTER_OPEN=z80_elf_after_open
LDEMUL_FINISH=z80_elf_finish

View File

@ -1,6 +1,7 @@
#source: pr22450.s
#readelf: --notes --wide
#ld: -r
#xfail: z80-*-*
# Fails on H8300 because it does not generate the correct relocs for the size fields.
# Fails on AVR, IP2K, M68HC11, XC16C because the assembler does not calculate the correct values for the differences of local symbols.
# Fails on CRX because readelf does not know how to apply CRX reloc number 20 (R_CRX_SWITCH32).

View File

@ -130,6 +130,10 @@ if { ![istarget "m32r-*-*"] } then {
foreach sfile [lrange $sfiles 0 [expr [llength $sfiles] / 2]] {
puts $ofd "#source: $sfile"
}
#force z80 target to compile for eZ80 in ADL mode
if { [istarget "z80-*-*"] } then {
puts $ofd "#as: -ez80-adl"
}
puts $ofd "#ld: -r"
puts $ofd "#readelf: -W -Ss"
puts $ofd "There are 680.. section headers.*:"
@ -180,6 +184,10 @@ if { ![istarget "d10v-*-*"]
} else {
puts $ofd "#ld:"
}
#force z80 target to compile for eZ80 in ADL mode
if { [istarget "z80-*-*"] } then {
puts $ofd "#as: -ez80-adl"
}
puts $ofd "#readelf: -W -Ss"
puts $ofd "There are 660.. section headers.*:"
puts $ofd "#..."

View File

@ -1,8 +1,8 @@
.type a, %gnu_unique_object
a: .long 0
.size a, .-a
.type a_val, %gnu_unique_object
a_val: .long 0
.size a_val, .-a_val
.type main,"function"
.global main
main:
.dc.a a
.dc.a a_val

View File

@ -5,5 +5,5 @@
#...
*OS/ABI: +UNIX - GNU
#...
*[0-9]+: +[0-9a-f]+ +[0-9]+ +OBJECT +UNIQUE +DEFAULT +[0-9]+ a
*[0-9]+: +[0-9a-f]+ +[0-9]+ +OBJECT +UNIQUE +DEFAULT +[0-9]+ a_val
#pass

View File

@ -1,6 +1,6 @@
.type a, %gnu_unique_object
a: .long 0
.size a, .-a
.type a_val, %gnu_unique_object
a_val: .long 0
.size a_val, .-a_val
.type main,"function"
.global main

View File

@ -1,4 +1,4 @@
.type main,"function"
.global main
main:
.dc.a b
.dc.a b_val

View File

@ -1,3 +1,3 @@
.type b, %gnu_unique_object
b: .long 0
.size b, .-b
.type b_val, %gnu_unique_object
b_val: .long 0
.size b_val, .-b_val

View File

@ -0,0 +1,11 @@
#name: Z80N arch test
#source: dummy1.s -z80n
#source: dummy2.s -z80n
#ld: -e 0
#objdump: -f
.*:[ ]+file format (coff|elf32)\-z80
architecture: z80n, flags 0x[0-9a-fA-F]+:
.*
.*

View File

@ -0,0 +1,11 @@
#name: Z80/Z80N arch combination test
#source: dummy1.s -z80
#source: dummy2.s -z80n
#ld: -e 0
#objdump: -f
.*:[ ]+file format (coff|elf32)\-z80
architecture: z80n, flags 0x[0-9a-fA-F]+:
.*
.*

View File

@ -9,6 +9,9 @@
.globl label8
.globl label9
.globl value8
.globl value8_1
.globl value8_2
.globl value8_3
.globl value16
.globl value24
.globl value32
@ -35,6 +38,9 @@ label9:
cpl
value8 .equ 0x12
value8_1 .equ 0xab
value8_2 .equ 0xcd
value8_3 .equ 0xef
value16 .equ 0x1234
value24 .equ 0x123456
value32 .equ 0x12345678

View File

@ -12,6 +12,9 @@
.globl label9
.globl value8
.globl value8_1
.globl value8_2
.globl value8_3
.globl value16
.globl value24
.globl value32
@ -74,6 +77,14 @@ field_0_1 .equ field_0+90
ld h,(value32 + 0x12345678) >> 8
ld l,(value32 + 0x12345678) >> 0
.ifdef Z80N
push label1
push value16
nextreg value8_1,value8_2
nextreg value8_3,a
ld a,a
.endif
.data
.db value8
.dw value16

View File

@ -0,0 +1,86 @@
#name: Z80N forward relocation
#as: -z80n --defsym Z80N=1
#source: relocs.s
#source: labels.s
#ld: -e 0 -Ttext 0x100 -Tdata 0x200
#objdump: -d
.*:[ ]+file format (coff|elf32)\-z80
.* \.text:
0+100 <.*>:
[ ]+100:[ ]+cd 7d 01[ ]+call 0x017d
[ ]+103:[ ]+c4 7e 01[ ]+call nz,0x017e
[ ]+106:[ ]+cc 7f 01[ ]+call z,0x017f
[ ]+109:[ ]+d4 80 01[ ]+call nc,0x0180
[ ]+10c:[ ]+dc 81 01[ ]+call c,0x0181
[ ]+10f:[ ]+e4 82 01[ ]+call po,0x0182
[ ]+112:[ ]+ec 83 01[ ]+call pe,0x0183
[ ]+115:[ ]+f4 84 01[ ]+call p,0x0184
[ ]+118:[ ]+fc 85 01[ ]+call m,0x0185
[ ]+11b:[ ]+c3 7d 01[ ]+jp 0x017d
[ ]+11e:[ ]+c2 7e 01[ ]+jp nz,0x017e
[ ]+121:[ ]+ca 7f 01[ ]+jp z,0x017f
[ ]+124:[ ]+d2 80 01[ ]+jp nc,0x0180
[ ]+127:[ ]+da 81 01[ ]+jp c,0x0181
[ ]+12a:[ ]+e2 82 01[ ]+jp po,0x0182
[ ]+12d:[ ]+ea 83 01[ ]+jp pe,0x0183
[ ]+130:[ ]+f2 84 01[ ]+jp p,0x0184
[ ]+133:[ ]+fa 85 01[ ]+jp m,0x0185
[ ]+136:[ ]+dd 6e 05[ ]+ld l,\(ix\+5\)
[ ]+139:[ ]+dd 7e 03[ ]+ld a,\(ix\+3\)
[ ]+13c:[ ]+dd 4e fa[ ]+ld c,\(ix\-6\)
[ ]+13f:[ ]+dd 46 f9[ ]+ld b,\(ix\-7\)
[ ]+142:[ ]+fd 75 fb[ ]+ld \(iy\-5\),l
[ ]+145:[ ]+fd 77 03[ ]+ld \(iy\+3\),a
[ ]+148:[ ]+fd 71 0e[ ]+ld \(iy\+14\),c
[ ]+14b:[ ]+fd 70 0f[ ]+ld \(iy\+15\),b
[ ]+14e:[ ]+fd 66 5d[ ]+ld h,\(iy\+93\)
[ ]+151:[ ]+11 34 12[ ]+ld de,0x1234
[ ]+154:[ ]+21 78 56[ ]+ld hl,0x5678
[ ]+157:[ ]+11 68 24[ ]+ld de,0x2468
[ ]+15a:[ ]+21 f0 ac[ ]+ld hl,0xacf0
[ ]+15d:[ ]+16 12[ ]+ld d,0x12
[ ]+15f:[ ]+1e 34[ ]+ld e,0x34
[ ]+161:[ ]+26 56[ ]+ld h,0x56
[ ]+163:[ ]+2e 78[ ]+ld l,0x78
[ ]+165:[ ]+16 24[ ]+ld d,0x24
[ ]+167:[ ]+1e 68[ ]+ld e,0x68
[ ]+169:[ ]+26 ac[ ]+ld h,0xac
[ ]+16b:[ ]+2e f0[ ]+ld l,0xf0
[ ]+16d:[ ]+ed 8a 01 7d[ ]+push 0x017d
[ ]+171:[ ]+ed 8a 12 34[ ]+push 0x1234
[ ]+175:[ ]+ed 91 ab cd[ ]+nextreg 0xab,0xcd
[ ]+179:[ ]+ed 92 ef[ ]+nextreg 0xef,a
[ ]+17c:[ ]+7f[ ]+ld a,a
0+17d <label1>:
[ ]+17d:[ ]+78[ ]+ld a,b
0+17e <label2>:
[ ]+17e:[ ]+79[ ]+ld a,c
0+17f <label3>:
[ ]+17f:[ ]+7a[ ]+ld a,d
0+180 <label4>:
[ ]+180:[ ]+7b[ ]+ld a,e
0+181 <label5>:
[ ]+181:[ ]+7c[ ]+ld a,h
0+182 <label6>:
[ ]+182:[ ]+7d[ ]+ld a,l
0+183 <label7>:
[ ]+183:[ ]+7e[ ]+ld a,\(hl\)
0+184 <label8>:
[ ]+184:[ ]+7f[ ]+ld a,a
0+185 <label9>:
[ ]+185:[ ]+2f[ ]+cpl
#pass

View File

@ -1,3 +1,8 @@
2020-02-07 Sergey Belyashov <sergey.belyashov@gmail.com>
PR 25469
* z80-dis.c: Add support for GBZ80 opcodes.
2020-02-04 Alan Modra <amodra@gmail.com>
* d30v-dis.c (print_insn): Make "val" and "opnum" unsigned.

View File

@ -52,6 +52,7 @@ struct tab_elt
#define INSS_EZ80_Z80 (1 << bfd_mach_ez80_z80)
#define INSS_EZ80_ADL (1 << bfd_mach_ez80_adl)
#define INSS_EZ80 (INSS_EZ80_ADL | INSS_EZ80_Z80)
#define INSS_Z80N (1 << bfd_mach_z80n)
#define TXTSIZ 24
/* Names of 16-bit registers. */
@ -65,6 +66,10 @@ static const char * arit_str[] =
{
"add a,", "adc a,", "sub ", "sbc a,", "and ", "xor ", "or ", "cp "
} ;
static const char * arit_str_gbz80[] =
{
"add a,", "adc a,", "sub a,", "sbc a,", "and ", "xor ", "or ", "cp "
} ;
static const char * arit_str_ez80[] =
{
"add a,", "adc a,", "sub a,", "sbc a,", "and a,", "xor a,", "or a,", "cp a,"
@ -72,7 +77,7 @@ static const char * arit_str_ez80[] =
static int
mach_inst (struct buffer *buf, struct tab_elt *p)
mach_inst (struct buffer *buf, const struct tab_elt *p)
{
return !p->inss || (p->inss & buf->inss);
}
@ -191,6 +196,27 @@ prt_n (struct buffer *buf, disassemble_info * info, const char *txt)
return buf->n_used;
}
static int
prt_n_n (struct buffer *buf, disassemble_info * info, const char *txt)
{
char mytxt[TXTSIZ];
int n;
unsigned char *p;
p = (unsigned char*) buf->data + buf->n_fetch;
if (fetch_data (buf, info, 1))
{
n = p[0];
snprintf (mytxt, TXTSIZ, txt, n);
buf->n_used = buf->n_fetch;
}
else
buf->n_used = -1;
return prt_n (buf, info, mytxt);
}
static int
prt_r_n (struct buffer *buf, disassemble_info * info, const char *txt)
{
@ -268,7 +294,14 @@ static int
arit_r (struct buffer *buf, disassemble_info * info, const char *txt)
{
const char * const *arit;
arit = (buf->inss & INSS_EZ80) ? arit_str_ez80 : arit_str;
if (buf->inss & INSS_EZ80)
arit = arit_str_ez80;
else if (buf->inss & INSS_GBZ80)
arit = arit_str_gbz80;
else
arit = arit_str;
info->fprintf_func (info->stream, txt,
arit[(buf->data[buf->n_fetch - 1] >> 3) & 7],
r_str[buf->data[buf->n_fetch - 1] & 7]);
@ -313,7 +346,13 @@ arit_n (struct buffer *buf, disassemble_info * info, const char *txt)
char mytxt[TXTSIZ];
const char * const *arit;
arit = (buf->inss & INSS_EZ80) ? arit_str_ez80 : arit_str;
if (buf->inss & INSS_EZ80)
arit = arit_str_ez80;
else if (buf->inss & INSS_GBZ80)
arit = arit_str_gbz80;
else
arit = arit_str;
snprintf (mytxt,TXTSIZ, txt, arit[(buf->data[0] >> 3) & 7]);
return prt_n (buf, info, mytxt);
}
@ -326,7 +365,7 @@ rst (struct buffer *buf, disassemble_info * info, const char *txt)
return buf->n_used;
}
static int
cis (struct buffer *buf, disassemble_info * info, const char *txt ATTRIBUTE_UNUSED)
{
@ -391,11 +430,13 @@ dump (struct buffer *buf, disassemble_info * info, const char *txt)
buf->n_used = i;
return buf->n_used;
}
/* Table to disassemble machine codes with prefix 0xED. */
struct tab_elt opc_ed[] =
{
{ 0x30, 0xFE, dump, "xx", INSS_ALL },
{ 0x30, 0xFF, prt, "mul d,e", INSS_Z80N },
{ 0x31, 0xFF, prt, "add hl,a", INSS_Z80N },
{ 0x30, 0xFE, dump, "xx", INSS_ALL }, /* do not move this line */
{ 0x00, 0xC7, prt_r_n, "in0 %s,(0x%%02x)", INSS_Z180|INSS_EZ80 },
{ 0x01, 0xC7, prt_r_n, "out0 (0x%%02x),%s", INSS_Z180|INSS_EZ80 },
{ 0x32, 0xFF, prt_d, "lea ix,ix%+d", INSS_EZ80 },
@ -407,17 +448,30 @@ struct tab_elt opc_ed[] =
{ 0x07, 0xFF, prt, "ld bc,(hl)", INSS_EZ80 },
{ 0x0F, 0xCF, prt_rr, "ld (hl),", INSS_EZ80 },
{ 0x17, 0xFF, prt, "ld de,(hl)", INSS_EZ80 },
{ 0x23, 0xFF, prt, "swapnib", INSS_Z80N },
{ 0x24, 0xFF, prt, "mirror", INSS_Z80N },
{ 0x27, 0xFF, prt, "ld hl,(hl)", INSS_EZ80 },
{ 0x27, 0xFF, prt_n, "test 0x%02x", INSS_Z80N },
{ 0x28, 0xFF, prt, "bsla de,b", INSS_Z80N },
{ 0x29, 0xFF, prt, "bsra de,b", INSS_Z80N },
{ 0x2A, 0xFF, prt, "bsrl de,b", INSS_Z80N },
{ 0x2B, 0xFF, prt, "bsrf de,b", INSS_Z80N },
{ 0x2C, 0xFF, prt, "bslc de,b", INSS_Z80N },
{ 0x32, 0xFF, prt, "add de,a", INSS_Z80N },
{ 0x33, 0xFF, prt, "add bc,a", INSS_Z80N },
{ 0x34, 0xFF, prt_nn, "add hl,0x%04x", INSS_Z80N },
{ 0x35, 0xFF, prt_nn, "add de,0x%04x", INSS_Z80N },
{ 0x36, 0xFF, prt_nn, "add bc,0x%04x", INSS_Z80N },
{ 0x36, 0xFF, prt, "ld iy,(hl)", INSS_EZ80 },
{ 0x37, 0xFF, prt, "ld ix,(hl)", INSS_EZ80 },
{ 0x3E, 0xFF, prt, "ld (hl),iy", INSS_EZ80 },
{ 0x3F, 0xFF, prt, "ld (hl),ix", INSS_EZ80 },
{ 0x70, 0xFF, prt, "in f,(c)", INSS_Z80 | INSS_R800 },
{ 0x70, 0xFF, prt, "in f,(c)", INSS_Z80 | INSS_R800 | INSS_Z80N },
{ 0x70, 0xFF, dump, "xx", INSS_ALL },
{ 0x40, 0xC7, prt_r, "in %s,(bc)", INSS_EZ80 },
{ 0x40, 0xC7, prt_r, "in %s,(c)", INSS_ALL },
{ 0x71, 0xFF, prt, "out (c),0", INSS_Z80 },
{ 0x70, 0xFF, dump, "xx", INSS_ALL },
{ 0x71, 0xFF, prt, "out (c),0", INSS_Z80 | INSS_Z80N },
{ 0x71, 0xFF, dump, "xx", INSS_ALL },
{ 0x41, 0xC7, prt_r, "out (bc),%s", INSS_EZ80 },
{ 0x41, 0xC7, prt_r, "out (c),%s", INSS_ALL },
{ 0x42, 0xCF, prt_rr, "sbc hl,", INSS_ALL },
@ -442,24 +496,38 @@ struct tab_elt opc_ed[] =
{ 0x65, 0xFF, prt_d, "pea ix%+d", INSS_EZ80 },
{ 0x66, 0xFF, prt_d, "pea iy%+d", INSS_EZ80 },
{ 0x67, 0xFF, prt, "rrd", INSS_ALL },
{ 0x6D, 0xFF, prt, "ld mb,a", INSS_EZ80 },
{ 0x6E, 0xFF, prt, "ld a,mb", INSS_EZ80 },
{ 0x6F, 0xFF, prt, "rld", INSS_ALL },
{ 0x74, 0xFF, prt_n, "tstio 0x%02x", INSS_Z180|INSS_EZ80 },
{ 0x76, 0xFF, prt, "slp", INSS_Z180|INSS_EZ80 },
{ 0x82, 0xE6, cism, "", INSS_Z180|INSS_EZ80 },
{ 0x84, 0xC7, cis2, "", INSS_EZ80 },
{ 0xA0, 0xE4, cis, "", INSS_ALL },
{ 0x7D, 0xFF, prt, "stmix", INSS_EZ80 },
{ 0x7E, 0xFF, prt, "rsmix", INSS_EZ80 },
{ 0x6D, 0xFF, prt, "ld mb,a", INSS_EZ80 },
{ 0x6E, 0xFF, prt, "ld a,mb", INSS_EZ80 },
{ 0xC7, 0xFF, prt, "ld i,hl", INSS_EZ80 },
{ 0xD7, 0xFF, prt, "ld hl,i", INSS_EZ80 },
{ 0x82, 0xE6, cism, "", INSS_Z180|INSS_EZ80 },
{ 0x84, 0xC7, cis2, "", INSS_EZ80 },
{ 0x8A, 0xFF, prt_n_n, "push 0x%02x%%02x", INSS_Z80N },
{ 0x90, 0xFF, prt, "outinb", INSS_Z80N },
{ 0x91, 0xFF, prt_n_n, "nextreg 0x%02x,0x%%02x", INSS_Z80N },
{ 0x92, 0xFF, prt_n, "nextreg 0x%02x,a", INSS_Z80N },
{ 0x93, 0xFF, prt, "pixeldn", INSS_Z80N },
{ 0x94, 0xFF, prt, "pixelad", INSS_Z80N },
{ 0x95, 0xFF, prt, "setae", INSS_Z80N },
{ 0x98, 0xFF, prt, "jp (c)", INSS_Z80N },
{ 0xA0, 0xE4, cis, "", INSS_ALL },
{ 0xA4, 0xFF, prt, "ldix", INSS_Z80N },
{ 0xAC, 0xFF, prt, "lddx", INSS_Z80N },
{ 0xA5, 0xFF, prt, "ldws", INSS_Z80N },
{ 0xB4, 0xFF, prt, "ldirx", INSS_Z80N },
{ 0xB7, 0xFF, prt, "ldpirx", INSS_Z80N },
{ 0xBC, 0xFF, prt, "lddrx", INSS_Z80N },
{ 0xC2, 0xFF, prt, "inirx", INSS_EZ80 },
{ 0xC3, 0xFF, prt, "otirx", INSS_EZ80 },
{ 0xC7, 0xFF, prt, "ld i,hl", INSS_EZ80 },
{ 0xCA, 0xFF, prt, "indrx", INSS_EZ80 },
{ 0xCB, 0xFF, prt, "otdrx", INSS_EZ80 },
{ 0xC3, 0xFF, prt, "muluw hl,bc", INSS_R800 },
{ 0xC5, 0xE7, prt_r, "mulub a,%s", INSS_R800 },
{ 0xD7, 0xFF, prt, "ld hl,i", INSS_EZ80 },
{ 0xF3, 0xFF, prt, "muluw hl,sp", INSS_R800 },
{ 0x00, 0x00, dump, "xx", INSS_ALL }
};
@ -521,7 +589,7 @@ pref_cb (struct buffer *buf, disassemble_info *info,
return buf->n_used;
}
static int
addvv (struct buffer * buf, disassemble_info * info, const char *txt)
{
@ -767,7 +835,8 @@ suffix (struct buffer *buf, disassemble_info *info, const char *txt)
}
/* Table to disassemble machine codes without prefix. */
static struct tab_elt opc_main[] =
static const struct tab_elt
opc_main[] =
{
{ 0x00, 0xFF, prt, "nop", INSS_ALL },
{ 0x01, 0xCF, prt_rr_nn, "ld %s,0x%%04x", INSS_ALL },
@ -829,12 +898,74 @@ static struct tab_elt opc_main[] =
{ 0xEB, 0xFF, prt, "ex de,hl", ~INSS_GBZ80 },
{ 0xED, 0xFF, pref_ed, "", ~INSS_GBZ80 },
{ 0xF3, 0xFF, prt, "di", INSS_ALL },
{ 0xF9, 0xFF, prt, "ld sp,hl", ~INSS_GBZ80 },
{ 0xF9, 0xFF, prt, "ld sp,hl", INSS_ALL },
{ 0xFB, 0xFF, prt, "ei", INSS_ALL },
{ 0xFD, 0xFF, pref_ind, "iy", ~INSS_GBZ80 },
{ 0x00, 0x00, prt, "????", INSS_ALL },
} ;
/* Separate GBZ80 main opcode table due to many differences */
static const struct tab_elt
opc_main_gbz80[] =
{
{ 0x00, 0xFF, prt,"nop", INSS_ALL },
{ 0x01, 0xCF, prt_rr_nn, "ld %s,0x%%04x", INSS_ALL },
{ 0x02, 0xFF, prt, "ld (bc),a", INSS_ALL },
{ 0x03, 0xCF, prt_rr, "inc ", INSS_ALL },
{ 0x04, 0xC7, prt_r, "inc %s", INSS_ALL },
{ 0x05, 0xC7, prt_r, "dec %s", INSS_ALL },
{ 0x06, 0xC7, ld_r_n, "ld %s,0x%%02x", INSS_ALL },
{ 0x07, 0xFF, prt, "rlca", INSS_ALL },
{ 0x08, 0xFF, prt_nn, "ld (0x%04x),sp", INSS_GBZ80 },
{ 0x09, 0xCF, prt_rr, "add hl,", INSS_ALL },
{ 0x0A, 0xFF, prt, "ld a,(bc)", INSS_ALL },
{ 0x0B, 0xCF, prt_rr, "dec ", INSS_ALL },
{ 0x0F, 0xFF, prt, "rrca", INSS_ALL },
{ 0x10, 0xFF, prt, "stop", INSS_GBZ80 },
{ 0x12, 0xFF, prt, "ld (de),a", INSS_ALL },
{ 0x17, 0xFF, prt, "rla", INSS_ALL },
{ 0x18, 0xFF, prt_e, "jr ", INSS_ALL },
{ 0x1A, 0xFF, prt, "ld a,(de)", INSS_ALL },
{ 0x1F, 0xFF, prt, "rra", INSS_ALL },
{ 0x20, 0xE7, jr_cc, "jr %s,", INSS_ALL },
{ 0x22, 0xFF, prt, "ld (hl+),a", INSS_GBZ80 },
{ 0x27, 0xFF, prt, "daa", INSS_ALL },
{ 0x2A, 0xFF, prt, "ld a,(hl+)", INSS_GBZ80 },
{ 0x2F, 0xFF, prt, "cpl", INSS_ALL },
{ 0x32, 0xFF, prt, "ld (hl-),a", INSS_GBZ80 },
{ 0x37, 0xFF, prt, "scf", INSS_ALL },
{ 0x3A, 0xFF, prt, "ld a,(hl-)", INSS_GBZ80 },
{ 0x3F, 0xFF, prt, "ccf", INSS_ALL },
{ 0x76, 0xFF, prt, "halt", INSS_ALL },
{ 0x40, 0xC0, ld_r_r, "ld %s,%s", INSS_ALL},
{ 0x80, 0xC0, arit_r, "%s%s", INSS_ALL },
{ 0xC0, 0xE7, prt_cc, "ret ", INSS_ALL },
{ 0xC1, 0xCF, pop_rr, "pop", INSS_ALL },
{ 0xC2, 0xE7, jp_cc_nn, "jp ", INSS_ALL },
{ 0xC3, 0xFF, prt_nn, "jp 0x%04x", INSS_ALL },
{ 0xC4, 0xE7, jp_cc_nn, "call ", INSS_ALL },
{ 0xC5, 0xCF, pop_rr, "push", INSS_ALL },
{ 0xC6, 0xC7, arit_n, "%s0x%%02x", INSS_ALL },
{ 0xC7, 0xC7, rst, "rst 0x%02x", INSS_ALL },
{ 0xC9, 0xFF, prt, "ret", INSS_ALL },
{ 0xCB, 0xFF, pref_cb, "", INSS_ALL },
{ 0xCD, 0xFF, prt_nn, "call 0x%04x", INSS_ALL },
{ 0xD9, 0xFF, prt, "reti", INSS_GBZ80 },
{ 0xE0, 0xFF, prt_n, "ldh (0x%02x),a", INSS_GBZ80 },
{ 0xE2, 0xFF, prt, "ldh (c),a", INSS_GBZ80 },
{ 0xE8, 0xFF, prt_d, "add sp,%d", INSS_GBZ80 },
{ 0xE9, 0xFF, prt, "jp (hl)", INSS_ALL },
{ 0xEA, 0xFF, prt_nn, "ld (0x%04x),a", INSS_GBZ80 },
{ 0xF0, 0xFF, prt_n, "ldh a,(0x%02x)", INSS_GBZ80 },
{ 0xF2, 0xFF, prt, "ldh a,(c)", INSS_GBZ80 },
{ 0xF3, 0xFF, prt, "di", INSS_ALL },
{ 0xF8, 0xFF, prt_d, "ldhl sp,%d", INSS_GBZ80 },
{ 0xF9, 0xFF, prt, "ld sp,hl", INSS_ALL },
{ 0xFA, 0xFF, prt_nn, "ld a,(0x%04x)", INSS_GBZ80 },
{ 0xFB, 0xFF, prt, "ei", INSS_ALL },
{ 0x00, 0x00, dump, "?", INSS_ALL },
} ;
int
print_insn_z80 (bfd_vma addr, disassemble_info * info)
{
@ -851,14 +982,16 @@ print_insn_z80 (bfd_vma addr, disassemble_info * info)
static int
print_insn_z80_buf (struct buffer *buf, disassemble_info *info)
{
struct tab_elt *p;
const struct tab_elt *p;
buf->n_fetch = 0;
buf->n_used = 0;
if (! fetch_data (buf, info, 1))
return -1;
for (p = opc_main; p->val != (buf->data[0] & p->mask) || !mach_inst (buf, p); ++p)
p = (buf->inss & INSS_GBZ80) ? opc_main_gbz80 : opc_main;
for (; p->val != (buf->data[0] & p->mask) || !mach_inst (buf, p); ++p)
;
p->fp (buf, info, p->text);