summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog17
-rw-r--r--bfd/Makefile.am10
-rw-r--r--bfd/Makefile.in10
-rw-r--r--bfd/archures.c7
-rw-r--r--bfd/bfd-in2.h8
-rw-r--r--bfd/coff-z80.c244
-rw-r--r--bfd/coffcode.h35
-rw-r--r--bfd/config.bfd6
-rwxr-xr-xbfd/configure1
-rw-r--r--bfd/configure.in1
-rw-r--r--bfd/cpu-z80.c57
-rw-r--r--bfd/libbfd.h1
-rw-r--r--bfd/reloc.c5
-rw-r--r--bfd/targets.c2
-rw-r--r--include/ChangeLog6
-rw-r--r--include/coff/ChangeLog5
-rw-r--r--include/coff/internal.h6
-rw-r--r--include/coff/z80.h51
-rw-r--r--include/dis-asm.h1
-rw-r--r--include/elf/ChangeLog5
-rw-r--r--include/opcode/ChangeLog4
-rw-r--r--opcodes/ChangeLog8
-rw-r--r--opcodes/Makefile.am4
-rw-r--r--opcodes/Makefile.in4
-rwxr-xr-xopcodes/configure1
-rw-r--r--opcodes/configure.in1
-rw-r--r--opcodes/disassemble.c6
-rw-r--r--opcodes/z80-dis.c620
28 files changed, 1123 insertions, 3 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9e6dec8a185..c12c6ace830 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,20 @@
+2005-10-25 Arnold Metselaar <arnold.metselaar@planet.nl>
+
+ * Makefile.am: Add rules for coff-z80 and cpu-z80.
+ * Makefile.in: Regenerated.
+ * archures.c: Add bfd_arch_z80 and support for it.
+ * coffcode.h(coff_set_arch_mach_hook): Add case Z80MAGIC.
+ (coff_set_flags): Add case bfd_arch_z80.
+ * config.bfd: Add z80coff_vec.
+ * configure.in: Add z80coff_vec.
+ * reloc.c: Add BFD_RELOC_Z80_DISP8
+ * targets.c: Add z80coff_vec.
+ * coff-z80.c: New file
+ * cpu-z80.c: New file
+ * configure: Regenerated.
+ * libbfd.h: Regenerated.
+ * bfd-in2.h: Regenerated.
+
2005-10-26 Alan Modra <amodra@bigpond.net.au>
PR ld/1540
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index d090ad3a039..46978a57f43 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -111,6 +111,7 @@ ALL_MACHINES = \
cpu-w65.lo \
cpu-xstormy16.lo \
cpu-xtensa.lo \
+ cpu-z80.lo \
cpu-z8k.lo
ALL_MACHINES_CFILES = \
@@ -171,6 +172,7 @@ ALL_MACHINES_CFILES = \
cpu-w65.c \
cpu-xstormy16.c \
cpu-xtensa.c \
+ cpu-z80.c \
cpu-z8k.c
# The .o files needed by all of the 32 bit vectors that are configured into
@@ -214,6 +216,7 @@ BFD32_BACKENDS = \
coff-u68k.lo \
coff-we32k.lo \
coff-w65.lo \
+ coff-z80.lo \
coff-z8k.lo \
cofflink.lo \
dwarf1.lo \
@@ -384,6 +387,7 @@ BFD32_BACKENDS_CFILES = \
coff-u68k.c \
coff-we32k.c \
coff-w65.c \
+ coff-z80.c \
coff-z8k.c \
cofflink.c \
dwarf1.c \
@@ -1084,6 +1088,8 @@ cpu-xstormy16.lo: cpu-xstormy16.c ./bfd.h ./config.h \
$(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-xtensa.lo: cpu-xtensa.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h
+cpu-z80.lo: cpu-z80.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
+ $(INCDIR)/hashtab.h
cpu-z8k.lo: cpu-z8k.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h
aout-adobe.lo: aout-adobe.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
@@ -1241,6 +1247,10 @@ coff-w65.lo: coff-w65.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h $(INCDIR)/bfdlink.h $(INCDIR)/coff/w65.h \
$(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
libcoff.h coffcode.h coffswap.h
+coff-z80.lo: coff-z80.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
+ $(INCDIR)/hashtab.h $(INCDIR)/bfdlink.h $(INCDIR)/coff/z80.h \
+ $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
+ libcoff.h coffcode.h coffswap.h
coff-z8k.lo: coff-z8k.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h $(INCDIR)/bfdlink.h $(INCDIR)/coff/z8k.h \
$(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 6c3f5980e45..ba368427ce9 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -348,6 +348,7 @@ ALL_MACHINES = \
cpu-w65.lo \
cpu-xstormy16.lo \
cpu-xtensa.lo \
+ cpu-z80.lo \
cpu-z8k.lo
ALL_MACHINES_CFILES = \
@@ -408,6 +409,7 @@ ALL_MACHINES_CFILES = \
cpu-w65.c \
cpu-xstormy16.c \
cpu-xtensa.c \
+ cpu-z80.c \
cpu-z8k.c
@@ -452,6 +454,7 @@ BFD32_BACKENDS = \
coff-u68k.lo \
coff-we32k.lo \
coff-w65.lo \
+ coff-z80.lo \
coff-z8k.lo \
cofflink.lo \
dwarf1.lo \
@@ -622,6 +625,7 @@ BFD32_BACKENDS_CFILES = \
coff-u68k.c \
coff-we32k.c \
coff-w65.c \
+ coff-z80.c \
coff-z8k.c \
cofflink.c \
dwarf1.c \
@@ -1651,6 +1655,8 @@ cpu-xstormy16.lo: cpu-xstormy16.c ./bfd.h ./config.h \
$(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-xtensa.lo: cpu-xtensa.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h
+cpu-z80.lo: cpu-z80.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
+ $(INCDIR)/hashtab.h
cpu-z8k.lo: cpu-z8k.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h
aout-adobe.lo: aout-adobe.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
@@ -1808,6 +1814,10 @@ coff-w65.lo: coff-w65.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h $(INCDIR)/bfdlink.h $(INCDIR)/coff/w65.h \
$(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
libcoff.h coffcode.h coffswap.h
+coff-z80.lo: coff-z80.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
+ $(INCDIR)/hashtab.h $(INCDIR)/bfdlink.h $(INCDIR)/coff/z80.h \
+ $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
+ libcoff.h coffcode.h coffswap.h
coff-z8k.lo: coff-z8k.c ./bfd.h ./config.h $(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h $(INCDIR)/bfdlink.h $(INCDIR)/coff/z8k.h \
$(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
diff --git a/bfd/archures.c b/bfd/archures.c
index 74d2b712ed5..a96771cf8da 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -365,6 +365,11 @@ DESCRIPTION
. bfd_arch_maxq, {* Dallas MAXQ 10/20 *}
.#define bfd_mach_maxq10 10
.#define bfd_mach_maxq20 20
+. bfd_arch_z80,
+.#define bfd_mach_z80strict 1 {* No undocumented opcodes. *}
+.#define bfd_mach_z80 3 {* With ixl, ixh, iyl, and iyh. *}
+.#define bfd_mach_z80full 7 {* All undocumented instructions. *}
+.#define bfd_mach_r800 11 {* R800: successor with multiplication. *}
. bfd_arch_last
. };
*/
@@ -461,6 +466,7 @@ extern const bfd_arch_info_type bfd_we32k_arch;
extern const bfd_arch_info_type bfd_w65_arch;
extern const bfd_arch_info_type bfd_xstormy16_arch;
extern const bfd_arch_info_type bfd_xtensa_arch;
+extern const bfd_arch_info_type bfd_z80_arch;
extern const bfd_arch_info_type bfd_z8k_arch;
static const bfd_arch_info_type * const bfd_archures_list[] =
@@ -524,6 +530,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
&bfd_we32k_arch,
&bfd_xstormy16_arch,
&bfd_xtensa_arch,
+ &bfd_z80_arch,
&bfd_z8k_arch,
#endif
0
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 6cf7e3c955c..7afe43725a7 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1953,6 +1953,11 @@ enum bfd_architecture
bfd_arch_maxq, /* Dallas MAXQ 10/20 */
#define bfd_mach_maxq10 10
#define bfd_mach_maxq20 20
+ bfd_arch_z80,
+#define bfd_mach_z80strict 1 /* No undocumented opcodes. */
+#define bfd_mach_z80 3 /* With ixl, ixh, iyl, and iyh. */
+#define bfd_mach_z80full 7 /* All undocumented instructions. */
+#define bfd_mach_r800 11 /* R800: successor with multiplication. */
bfd_arch_last
};
@@ -4058,6 +4063,9 @@ internally by the linker after analysis of a
BFD_RELOC_XTENSA_ASM_EXPAND. */
BFD_RELOC_XTENSA_ASM_SIMPLIFY,
+/* 8 bit signed offset in (ix+d) or (iy+d). */
+ BFD_RELOC_Z80_DISP8,
+
/* DJNZ offset. */
BFD_RELOC_Z8K_DISP7,
diff --git a/bfd/coff-z80.c b/bfd/coff-z80.c
new file mode 100644
index 00000000000..fe401d77b86
--- /dev/null
+++ b/bfd/coff-z80.c
@@ -0,0 +1,244 @@
+/* BFD back-end for Zilog Z80 COFF binaries.
+ Copyright 2005 Free Software Foundation, Inc.
+ Contributed by Arnold Metselaar <arnold_m@operamail.com>
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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 2 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. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "coff/z80.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 0
+
+static reloc_howto_type r_imm32 =
+HOWTO (R_IMM32, 0, 1, 32, FALSE, 0,
+ complain_overflow_dont, 0, "r_imm32", TRUE, 0xffffffff, 0xffffffff,
+ FALSE);
+
+static reloc_howto_type r_imm16 =
+HOWTO (R_IMM16, 0, 1, 16, FALSE, 0,
+ complain_overflow_dont, 0, "r_imm16", TRUE, 0x0000ffff, 0x0000ffff,
+ FALSE);
+
+static reloc_howto_type r_imm8 =
+HOWTO (R_IMM8, 0, 0, 8, FALSE, 0,
+ complain_overflow_bitfield, 0, "r_imm8", TRUE, 0x000000ff, 0x000000ff,
+ FALSE);
+
+static reloc_howto_type r_jr =
+HOWTO (R_JR, 0, 0, 8, TRUE, 0,
+ complain_overflow_signed, 0, "r_jr", FALSE, 0, 0xFF,
+ FALSE);
+
+static reloc_howto_type r_off8 =
+HOWTO (R_OFF8, 0, 0, 8, FALSE, 0,
+ complain_overflow_signed, 0,"r_off8", FALSE, 0, 0xff,
+ FALSE);
+
+
+#define BADMAG(x) Z80BADMAG(x)
+#define Z80 1 /* Customize coffcode.h. */
+#define __A_MAGIC_SET__
+
+/* Code to swap in the reloc. */
+
+#define SWAP_IN_RELOC_OFFSET H_GET_32
+#define SWAP_OUT_RELOC_OFFSET H_PUT_32
+
+#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
+ dst->r_stuff[0] = 'S'; \
+ dst->r_stuff[1] = 'C';
+
+/* Code to turn a r_type into a howto ptr, uses the above howto table. */
+
+static void
+rtype2howto (arelent *internal, struct internal_reloc *dst)
+{
+ switch (dst->r_type)
+ {
+ default:
+ abort ();
+ break;
+ case R_IMM8:
+ internal->howto = &r_imm8;
+ break;
+ case R_IMM16:
+ internal->howto = &r_imm16;
+ break;
+ case R_IMM32:
+ internal->howto = &r_imm32;
+ break;
+ case R_JR:
+ internal->howto = &r_jr;
+ break;
+ case R_OFF8:
+ internal->howto = &r_off8;
+ break;
+ }
+}
+
+#define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry)
+
+static reloc_howto_type *
+coff_z80_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_8: return & r_imm8;
+ case BFD_RELOC_16: return & r_imm16;
+ case BFD_RELOC_32: return & r_imm32;
+ case BFD_RELOC_8_PCREL: return & r_jr;
+ case BFD_RELOC_Z80_DISP8: return & r_off8;
+ default: BFD_FAIL ();
+ return NULL;
+ }
+}
+
+/* Perform any necessary magic to the addend in a reloc entry. */
+
+#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
+ cache_ptr->addend = ext_reloc.r_offset;
+
+#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
+ reloc_processing(relent, reloc, symbols, abfd, section)
+
+static void
+reloc_processing (arelent *relent,
+ struct internal_reloc *reloc,
+ asymbol **symbols,
+ bfd *abfd,
+ asection *section)
+{
+ relent->address = reloc->r_vaddr;
+ rtype2howto (relent, reloc);
+
+ if (reloc->r_symndx > 0)
+ relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
+ else
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+
+ relent->addend = reloc->r_offset;
+ relent->address -= section->vma;
+}
+
+static void
+extra_case (bfd *in_abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ arelent *reloc,
+ bfd_byte *data,
+ unsigned int *src_ptr,
+ unsigned int *dst_ptr)
+{
+ asection * input_section = link_order->u.indirect.section;
+ int val;
+
+ switch (reloc->howto->type)
+ {
+ case R_OFF8:
+ val = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ if (val>127 || val<-128) /* Test for overflow. */
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+ bfd_put_8 (in_abfd, val, data + *dst_ptr);
+ (*dst_ptr) += 1;
+ (*src_ptr) += 1;
+ break;
+
+ case R_IMM8:
+ val = bfd_get_16 ( in_abfd, data+*src_ptr)
+ + bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+ bfd_put_8 (in_abfd, val, data + *dst_ptr);
+ (*dst_ptr) += 1;
+ (*src_ptr) += 1;
+ break;
+
+ case R_IMM16:
+ val = bfd_get_16 ( in_abfd, data+*src_ptr)
+ + bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+ bfd_put_16 (in_abfd, val, data + *dst_ptr);
+ (*dst_ptr) += 2;
+ (*src_ptr) += 2;
+ break;
+
+ case R_IMM32:
+ val = bfd_get_32 ( in_abfd, data+*src_ptr)
+ + bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+ bfd_put_32 (in_abfd, val, data + *dst_ptr);
+ (*dst_ptr) += 4;
+ (*src_ptr) += 4;
+ break;
+
+ case R_JR:
+ {
+ bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = (link_order->offset
+ + *dst_ptr
+ + input_section->output_section->vma);
+ int gap = dst - dot - 1; /* -1, Since the offset is relative
+ to the value of PC after reading
+ the offset. */
+
+ if (gap >= 128 || gap < -128)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+ bfd_put_8 (in_abfd, gap, data + *dst_ptr);
+ (*dst_ptr)++;
+ (*src_ptr)++;
+ break;
+ }
+
+ default:
+ abort ();
+ }
+}
+
+#define coff_reloc16_extra_cases extra_case
+#define coff_bfd_reloc_type_lookup coff_z80_reloc_type_lookup
+
+#include "coffcode.h"
+
+#undef coff_bfd_get_relocated_section_contents
+#define coff_bfd_get_relocated_section_contents \
+ bfd_coff_reloc16_get_relocated_section_contents
+
+#undef coff_bfd_relax_section
+#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
+
+CREATE_LITTLE_COFF_TARGET_VEC (z80coff_vec, "coff-z80", 0, 0, '\0', NULL,
+ COFF_SWAP_TABLE)
+
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 3b94dff431a..aaf79c10325 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -1955,6 +1955,23 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr)
machine = 88100;
break;
#endif
+#ifdef Z80MAGIC
+ case Z80MAGIC:
+ arch = bfd_arch_z80;
+ switch (internal_f->f_flags & F_MACHMASK)
+ {
+ case 0:
+ case bfd_mach_z80strict << 12:
+ case bfd_mach_z80 << 12:
+ case bfd_mach_z80full << 12:
+ case bfd_mach_r800 << 12:
+ machine = ((unsigned)internal_f->f_flags & F_MACHMASK) >> 12;
+ break;
+ default:
+ return FALSE;
+ }
+ break;
+#endif
#ifdef Z8KMAGIC
case Z8KMAGIC:
arch = bfd_arch_z8k;
@@ -2555,6 +2572,24 @@ coff_set_flags (bfd * abfd,
{
switch (bfd_get_arch (abfd))
{
+#ifdef Z80MAGIC
+ case bfd_arch_z80:
+ *magicp = Z80MAGIC;
+ switch (bfd_get_mach (abfd))
+ {
+ case 0:
+ case bfd_mach_z80strict:
+ case bfd_mach_z80:
+ case bfd_mach_z80full:
+ case bfd_mach_r800:
+ *flagsp = bfd_get_mach (abfd) << 12;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+#endif
+
#ifdef Z8KMAGIC
case bfd_arch_z8k:
*magicp = Z8KMAGIC;
diff --git a/bfd/config.bfd b/bfd/config.bfd
index aec10e18233..ab47fa3cc25 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -101,6 +101,7 @@ v850*) targ_archs=bfd_v850_arch ;;
x86_64) targ_archs=bfd_i386_arch ;;
xscale*) targ_archs=bfd_arm_arch ;;
xtensa*) targ_archs=bfd_xtensa_arch ;;
+z80|r800) targ_archs=bfd_z80_arch ;;
z8k*) targ_archs=bfd_z8k_arch ;;
am33_2.0) targ_archs=bfd_mn10300_arch ;;
*) targ_archs=bfd_${targ_cpu}_arch ;;
@@ -1366,6 +1367,11 @@ case "${targ}" in
targ_selvecs=bfd_elf32_xtensa_be_vec
;;
+ z80-*-*)
+ targ_defvec=z80coff_vec
+ targ_underscore=no
+ ;;
+
z8k*-*-*)
targ_defvec=z8kcoff_vec
targ_underscore=yes
diff --git a/bfd/configure b/bfd/configure
index 179967607f6..d7f01e6c440 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -13190,6 +13190,7 @@ do
vms_vax_vec) tb="$tb vms.lo vms-hdr.lo vms-gsd.lo vms-tir.lo vms-misc.lo" ;;
w65_vec) tb="$tb coff-w65.lo reloc16.lo" ;;
we32kcoff_vec) tb="$tb coff-we32k.lo" ;;
+ z80coff_vec) tb="$tb coff-z80.lo reloc16.lo" ;;
z8kcoff_vec) tb="$tb coff-z8k.lo reloc16.lo cofflink.lo" ;;
# These appear out of order in targets.c
diff --git a/bfd/configure.in b/bfd/configure.in
index 7ace2196d06..1a7dc84de5b 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -811,6 +811,7 @@ do
vms_vax_vec) tb="$tb vms.lo vms-hdr.lo vms-gsd.lo vms-tir.lo vms-misc.lo" ;;
w65_vec) tb="$tb coff-w65.lo reloc16.lo" ;;
we32kcoff_vec) tb="$tb coff-we32k.lo" ;;
+ z80coff_vec) tb="$tb coff-z80.lo reloc16.lo" ;;
z8kcoff_vec) tb="$tb coff-z8k.lo reloc16.lo cofflink.lo" ;;
# These appear out of order in targets.c
diff --git a/bfd/cpu-z80.c b/bfd/cpu-z80.c
new file mode 100644
index 00000000000..3fd6fd48176
--- /dev/null
+++ b/bfd/cpu-z80.c
@@ -0,0 +1,57 @@
+/* BFD library support routines for the Z80 architecture.
+ Copyright 2005 Free Software Foundation, Inc.
+ Contributed by Arnold Metselaar <arnold_m@operamail.com>
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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 2 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. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_z80_arch;
+
+/* This routine is provided two arch_infos and
+ returns whether they'd be compatible. */
+
+static const bfd_arch_info_type *
+compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
+{
+ if (a->arch != b->arch)
+ return NULL;
+
+ if (a->mach == b->mach)
+ return a;
+
+ return (a->arch == bfd_arch_z80) ? & bfd_z80_arch : NULL;
+}
+
+#define N(name,print,default,next) \
+{ 16, 16, 8, bfd_arch_z80, name, "z80", print, 0, default, \
+ compatible, bfd_default_scan, next }
+
+#define M(n) &arch_info_struct[n]
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N (bfd_mach_z80strict, "z80-strict", FALSE, M(1)),
+ N (bfd_mach_z80, "z80", FALSE, M(2)),
+ N (bfd_mach_z80full, "z80-full", FALSE, M(3)),
+ N (bfd_mach_r800, "r800", FALSE, NULL)
+};
+
+const bfd_arch_info_type bfd_z80_arch = N (0, "z80-any", TRUE, M(0));
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 9125663515b..91f6f8bdea3 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1830,6 +1830,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_XTENSA_OP2",
"BFD_RELOC_XTENSA_ASM_EXPAND",
"BFD_RELOC_XTENSA_ASM_SIMPLIFY",
+ "BFD_RELOC_Z80_DISP8",
"BFD_RELOC_Z8K_DISP7",
"BFD_RELOC_Z8K_CALLR",
"BFD_RELOC_Z8K_IMM4L",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index ba8e14c7a42..ea73d137372 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -4575,6 +4575,11 @@ ENUMDOC
BFD_RELOC_XTENSA_ASM_EXPAND.
ENUM
+ BFD_RELOC_Z80_DISP8
+ENUMDOC
+ 8 bit signed offset in (ix+d) or (iy+d).
+
+ENUM
BFD_RELOC_Z8K_DISP7
ENUMDOC
DJNZ offset.
diff --git a/bfd/targets.c b/bfd/targets.c
index 78449711c02..8f5795c24a4 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -782,6 +782,7 @@ extern const bfd_target vms_alpha_vec;
extern const bfd_target vms_vax_vec;
extern const bfd_target w65_vec;
extern const bfd_target we32kcoff_vec;
+extern const bfd_target z80coff_vec;
extern const bfd_target z8kcoff_vec;
/* These are always included. */
@@ -1134,6 +1135,7 @@ static const bfd_target * const _bfd_target_vector[] = {
&vms_vax_vec,
&w65_vec,
&we32kcoff_vec,
+ &z80coff_vec,
&z8kcoff_vec,
&bfd_elf32_am33lin_vec,
#endif /* not SELECT_VECS */
diff --git a/include/ChangeLog b/include/ChangeLog
index 8f00e91ab37..a958dd25fc7 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,8 +1,10 @@
+2005-10-25 Arnold Metselaar <arnold.metselaar@planet.nl>
+
+ disasm.h: Add declaration for print_insn_z80
+
2005-09-30 Catherine Moore <clm@cm00re.com>
* dis-asm.h (print_insn_bfin): Declare.
- * elf/bfin.h: New file.
- * elf/common.h (EM_BLACKFIN): Define.
* opcode/bfin.h: New file.
2005-09-26 Mark Mitchell <mark@codesourcery.com>
diff --git a/include/coff/ChangeLog b/include/coff/ChangeLog
index ca201a12a63..a8b66cce2af 100644
--- a/include/coff/ChangeLog
+++ b/include/coff/ChangeLog
@@ -1,3 +1,8 @@
+2005-10-25 Arnold Metselaar <arnold.metselaar@planet.nl>
+
+ * internal.h: Add relocation number for Z80
+ * z80.h: New file.
+
2005-08-18 Alan Modra <amodra@bigpond.net.au>
* a29k.h: Delete.
diff --git a/include/coff/internal.h b/include/coff/internal.h
index 20e06c215ec..d7a83815aea 100644
--- a/include/coff/internal.h
+++ b/include/coff/internal.h
@@ -1,7 +1,7 @@
/* Internal format of COFF object file data structures, for GNU BFD.
This file is part of BFD, the Binary File Descriptor library.
- Copyright 1999, 2000, 2001, 2002, 2003, 2004
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004. 2005
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -715,6 +715,10 @@ struct internal_reloc
#define R_IMM4H 0x24 /* high nibble */
#define R_DISP7 0x25 /* djnz displacement */
+/* Z80 modes */
+#define R_OFF8 0x32 /* 8 bit signed abs, for (i[xy]+d) */
+/* R_JR, R_IMM8, R_IMM16, R_IMM32 - as for Z8k */
+
/* H8500 modes */
#define R_H8500_IMM8 1 /* 8 bit immediate */
diff --git a/include/coff/z80.h b/include/coff/z80.h
new file mode 100644
index 00000000000..3c72c10dd9e
--- /dev/null
+++ b/include/coff/z80.h
@@ -0,0 +1,51 @@
+/* coff information for Zilog Z80
+ Copyright 2005 Free Software Foundation, Inc.
+ Contributed by Arnold Metselaar <arnold_m@operamail.com>
+
+ 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 2 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, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define L_LNNO_SIZE 4
+#include "coff/external.h"
+
+/* z80 backend does not use dots in section names. */
+#undef _TEXT
+#define _TEXT "text"
+#undef _DATA
+#define _DATA "data"
+#undef _BSS
+#define _BSS "bss"
+
+/* Type of cpu is stored in flags. */
+#define F_MACHMASK 0xF000
+
+#define Z80MAGIC 0x805A
+
+#define Z80BADMAG(x) (((x).f_magic != Z80MAGIC))
+
+/* Relocation directives. */
+
+/* This format actually has more bits than we need. */
+
+struct external_reloc
+{
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_offset[4];
+ char r_type[2];
+ char r_stuff[2];
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 16
diff --git a/include/dis-asm.h b/include/dis-asm.h
index dd4e86e913c..8a02a245fbc 100644
--- a/include/dis-asm.h
+++ b/include/dis-asm.h
@@ -208,6 +208,7 @@ extern int print_insn_i370 (bfd_vma, disassemble_info *);
extern int print_insn_m68hc11 (bfd_vma, disassemble_info *);
extern int print_insn_m68hc12 (bfd_vma, disassemble_info *);
extern int print_insn_m68k (bfd_vma, disassemble_info *);
+extern int print_insn_z80 (bfd_vma, disassemble_info *);
extern int print_insn_z8001 (bfd_vma, disassemble_info *);
extern int print_insn_z8002 (bfd_vma, disassemble_info *);
extern int print_insn_h8300 (bfd_vma, disassemble_info *);
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
index cf4b57805b0..485a78e32a8 100644
--- a/include/elf/ChangeLog
+++ b/include/elf/ChangeLog
@@ -1,3 +1,8 @@
+2005-09-30 Catherine Moore <clm@cm00re.com>
+
+ * bfin.h: New file.
+ * common.h (EM_BLACKFIN): Define.
+
2005-10-08 Paul Brook <paul@codesourcery.com>
* arm.h: Add prototypes for BFD object attribute routines.
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index 740eb32f31d..1f50c5f6aa3 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -1,3 +1,7 @@
+2005-09-30 Catherine Moore <clm@cm00re.com>
+
+ * bfin.h: New file.
+
2005-10-24 Jan Beulich <jbeulich@novell.com>
* ia64.h (enum ia64_opnd): Move memory operand out of set of
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index b81339f7904..2234e02eedb 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,11 @@
+2005-10-25 Arnold Metselaar <arnold.metselaar@planet.nl>
+
+ * configure.in: Add target architecture bfd_arch_z80.
+ * configure: Regenerated.
+ * disassemble.c (disassembler)<ARCH_z80>: Add case
+ bfd_arch_z80.
+ * z80-dis.c: New file.
+
2005-10-25 Alan Modra <amodra@bigpond.net.au>
* po/POTFILES.in: Regenerate.
diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
index 5ac0ffe2b84..d8b928ecaef 100644
--- a/opcodes/Makefile.am
+++ b/opcodes/Makefile.am
@@ -178,6 +178,7 @@ CFILES = \
xstormy16-ibld.c \
xstormy16-opc.c \
xtensa-dis.c \
+ z80-dis.c \
z8k-dis.c \
z8kgen.c
@@ -302,6 +303,7 @@ ALL_MACHINES = \
xstormy16-ibld.lo \
xstormy16-opc.lo \
xtensa-dis.lo \
+ z80-dis.lo \
z8k-dis.lo
OFILES = @BFD_MACHINES@
@@ -1028,6 +1030,8 @@ xtensa-dis.lo: xtensa-dis.c $(INCDIR)/xtensa-isa.h \
$(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
sysdep.h ./config.h $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h \
$(INCDIR)/symcat.h
+z80-dis.lo: z80-dis.c sysdep.h ./config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h
z8k-dis.lo: z8k-dis.c sysdep.h ./config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h \
z8k-opc.h
diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in
index f2e8ccddbf5..5d082b77224 100644
--- a/opcodes/Makefile.in
+++ b/opcodes/Makefile.in
@@ -400,6 +400,7 @@ CFILES = \
xstormy16-ibld.c \
xstormy16-opc.c \
xtensa-dis.c \
+ z80-dis.c \
z8k-dis.c \
z8kgen.c
@@ -524,6 +525,7 @@ ALL_MACHINES = \
xstormy16-ibld.lo \
xstormy16-opc.lo \
xtensa-dis.lo \
+ z80-dis.lo \
z8k-dis.lo
OFILES = @BFD_MACHINES@
@@ -1570,6 +1572,8 @@ xtensa-dis.lo: xtensa-dis.c $(INCDIR)/xtensa-isa.h \
$(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
sysdep.h ./config.h $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h \
$(INCDIR)/symcat.h
+z80-dis.lo: z80-dis.c sysdep.h ./config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h
z8k-dis.lo: z8k-dis.c sysdep.h ./config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h \
z8k-opc.h
diff --git a/opcodes/configure b/opcodes/configure
index a9c0ac64569..34c9ced1d03 100755
--- a/opcodes/configure
+++ b/opcodes/configure
@@ -8769,6 +8769,7 @@ if test x${all_targets} = xfalse ; then
bfd_we32k_arch) ;;
bfd_xstormy16_arch) ta="$ta xstormy16-asm.lo xstormy16-desc.lo xstormy16-dis.lo xstormy16-ibld.lo xstormy16-opc.lo" using_cgen=yes ;;
bfd_xtensa_arch) ta="$ta xtensa-dis.lo" ;;
+ bfd_z80_arch) ta="$ta z80-dis.lo" ;;
bfd_z8k_arch) ta="$ta z8k-dis.lo" ;;
"") ;;
diff --git a/opcodes/configure.in b/opcodes/configure.in
index 5156685e8cb..ad02c3e3d16 100644
--- a/opcodes/configure.in
+++ b/opcodes/configure.in
@@ -229,6 +229,7 @@ if test x${all_targets} = xfalse ; then
bfd_we32k_arch) ;;
bfd_xstormy16_arch) ta="$ta xstormy16-asm.lo xstormy16-desc.lo xstormy16-dis.lo xstormy16-ibld.lo xstormy16-opc.lo" using_cgen=yes ;;
bfd_xtensa_arch) ta="$ta xtensa-dis.lo" ;;
+ bfd_z80_arch) ta="$ta z80-dis.lo" ;;
bfd_z8k_arch) ta="$ta z8k-dis.lo" ;;
"") ;;
diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c
index 9304e083806..507606807f9 100644
--- a/opcodes/disassemble.c
+++ b/opcodes/disassemble.c
@@ -75,6 +75,7 @@
#define ARCH_w65
#define ARCH_xstormy16
#define ARCH_xtensa
+#define ARCH_z80
#define ARCH_z8k
#define INCLUDE_SHMEDIA
#endif
@@ -374,6 +375,11 @@ disassembler (abfd)
disassemble = print_insn_xtensa;
break;
#endif
+#ifdef ARCH_z80
+ case bfd_arch_z80:
+ disassemble = print_insn_z80;
+ break;
+#endif
#ifdef ARCH_z8k
case bfd_arch_z8k:
if (bfd_get_mach(abfd) == bfd_mach_z8001)
diff --git a/opcodes/z80-dis.c b/opcodes/z80-dis.c
new file mode 100644
index 00000000000..38ce4d11809
--- /dev/null
+++ b/opcodes/z80-dis.c
@@ -0,0 +1,620 @@
+/* Print Z80 and R800 instructions
+ Copyright 2005 Free Software Foundation, Inc.
+ Contributed by Arnold Metselaar <arnold_m@operamail.com>
+
+ This file 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 2 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. */
+
+#include "sysdep.h"
+#include "dis-asm.h"
+#include <stdio.h>
+
+struct buffer
+{
+ bfd_vma base;
+ int n_fetch;
+ int n_used;
+ char data[4];
+} ;
+
+typedef int (*func)(struct buffer *, disassemble_info *, char *);
+
+struct tab_elt
+{
+ unsigned char val;
+ unsigned char mask;
+ func fp;
+ char * text;
+} ;
+
+#define TXTSIZ 16
+/* Names of 16-bit registers. */
+static char * rr_str[] = { "bc", "de", "hl", "sp" };
+/* Names of 8-bit registers. */
+static char * r_str[] = { "b", "c", "d", "e", "h", "l", "(hl)", "a" };
+/* Texts for condition codes. */
+static char * cc_str[] = { "nz", "z", "nc", "c", "po", "pe", "p", "m" };
+/* Instruction names for 8-bit arithmetic, operand "a" is often implicit */
+static char * arit_str[] =
+{
+ "add a,", "adc a,", "sub ", "sbc a,", "and ", "xor ", "or ", "cp "
+} ;
+
+static int
+fetch_data (struct buffer *buf, disassemble_info * info, int n)
+{
+ int r;
+
+ if (buf->n_fetch + n > 4)
+ abort ();
+
+ r = info->read_memory_func (buf->base + buf->n_fetch,
+ buf->data + buf->n_fetch,
+ n, info);
+ if (r == 0)
+ buf->n_fetch += n;
+ return !r;
+}
+
+static int
+prt (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ info->fprintf_func (info->stream, "%s", txt);
+ buf->n_used = buf->n_fetch;
+ return 1;
+}
+
+static int
+prt_e (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ char e;
+ int target_addr;
+
+ if (fetch_data (buf, info, 1))
+ {
+ e = buf->data[1];
+ target_addr = (buf->base + 2 + e) & 0xffff;
+ buf->n_used = buf->n_fetch;
+ info->fprintf_func (info->stream, "%s0x%04x", txt, target_addr);
+ }
+ else
+ buf->n_used = -1;
+
+ return buf->n_used;
+}
+
+static int
+jr_cc (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ char mytxt[TXTSIZ];
+
+ snprintf (mytxt, TXTSIZ, txt, cc_str[(buf->data[0] >> 3) & 3]);
+ return prt_e (buf, info, mytxt);
+}
+
+static int
+prt_nn (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ int nn;
+ unsigned char *p;
+
+ p = (unsigned char*) buf->data + buf->n_fetch;
+ if (fetch_data (buf, info, 2))
+ {
+ nn = p[0] + (p[1] << 8);
+ info->fprintf_func (info->stream, txt, nn);
+ buf->n_used = buf->n_fetch;
+ }
+ else
+ buf->n_used = -1;
+ return buf->n_used;
+}
+
+static int
+prt_rr_nn (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ char mytxt[TXTSIZ];
+
+ snprintf (mytxt, TXTSIZ, txt, rr_str[(buf->data[0] >> 4) & 3]);
+ return prt_nn (buf, info, mytxt);
+}
+
+static int
+prt_rr (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ info->fprintf_func (info->stream, "%s%s", txt,
+ rr_str[(buf->data[buf->n_fetch - 1] >> 4) & 3]);
+ buf->n_used = buf->n_fetch;
+ return buf->n_used;
+}
+
+static int
+prt_n (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ int n;
+ unsigned char *p;
+
+ p = (unsigned char*) buf->data + buf->n_fetch;
+
+ if (fetch_data (buf, info, 1))
+ {
+ n = p[0];
+ info->fprintf_func (info->stream, txt, n);
+ buf->n_used = buf->n_fetch;
+ }
+ else
+ buf->n_used = -1;
+
+ return buf->n_used;
+}
+
+static int
+ld_r_n (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ char mytxt[TXTSIZ];
+
+ snprintf (mytxt, TXTSIZ, txt, r_str[(buf->data[0] >> 3) & 7]);
+ return prt_n (buf, info, mytxt);
+}
+
+static int
+prt_r (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ info->fprintf_func (info->stream, txt,
+ r_str[(buf->data[buf->n_fetch - 1] >> 3) & 7]);
+ buf->n_used = buf->n_fetch;
+ return buf->n_used;
+}
+
+static int
+ld_r_r (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ info->fprintf_func (info->stream, txt,
+ r_str[(buf->data[buf->n_fetch - 1] >> 3) & 7],
+ r_str[buf->data[buf->n_fetch - 1] & 7]);
+ buf->n_used = buf->n_fetch;
+ return buf->n_used;
+}
+
+static int
+arit_r (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ info->fprintf_func (info->stream, txt,
+ arit_str[(buf->data[buf->n_fetch - 1] >> 3) & 7],
+ r_str[buf->data[buf->n_fetch - 1] & 7]);
+ buf->n_used = buf->n_fetch;
+ return buf->n_used;
+}
+
+static int
+prt_cc (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ info->fprintf_func (info->stream, "%s%s", txt,
+ cc_str[(buf->data[0] >> 3) & 7]);
+ buf->n_used = buf->n_fetch;
+ return buf->n_used;
+}
+
+static int
+pop_rr (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ static char *rr_stack[] = { "bc","de","hl","af"};
+
+ info->fprintf_func (info->stream, "%s %s", txt,
+ rr_stack[(buf->data[0] >> 4) & 3]);
+ buf->n_used = buf->n_fetch;
+ return buf->n_used;
+}
+
+
+static int
+jp_cc_nn (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ char mytxt[TXTSIZ];
+
+ snprintf (mytxt,TXTSIZ,
+ "%s%s,0x%%04x", txt, cc_str[(buf->data[0] >> 3) & 7]);
+ return prt_nn (buf, info, mytxt);
+}
+
+static int
+arit_n (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ char mytxt[TXTSIZ];
+
+ snprintf (mytxt,TXTSIZ, txt, arit_str[(buf->data[0] >> 3) & 7]);
+ return prt_n (buf, info, mytxt);
+}
+
+static int
+rst (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ info->fprintf_func (info->stream, txt, buf->data[0] & 0x38);
+ buf->n_used = buf->n_fetch;
+ return buf->n_used;
+}
+
+
+static int
+cis (struct buffer *buf, disassemble_info * info, char *txt ATTRIBUTE_UNUSED)
+{
+ static char * opar[] = { "ld", "cp", "in", "out" };
+ char * op;
+ char c;
+
+ c = buf->data[1];
+ op = ((0x13 & c) == 0x13) ? "ot" : (opar[c & 3]);
+ info->fprintf_func (info->stream,
+ "%s%c%s", op,
+ (c & 0x08) ? 'd' : 'i',
+ (c & 0x10) ? "r" : "");
+ buf->n_used = 2;
+ return buf->n_used;
+}
+
+static int
+dump (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ int i;
+
+ info->fprintf_func (info->stream, "defb ");
+ for (i = 0; txt[i]; ++i)
+ info->fprintf_func (info->stream, i ? ", 0x%02x" : "0x%02x",
+ (unsigned char) buf->data[i]);
+ buf->n_used = i;
+ return buf->n_used;
+}
+
+/* Table to disassemble machine codes with prefix 0xED. */
+struct tab_elt opc_ed[] =
+{
+ { 0x70, 0xFF, prt, "in f,(c)" },
+ { 0x70, 0xFF, dump, "xx" },
+ { 0x40, 0xC7, prt_r, "in %s,(c)" },
+ { 0x71, 0xFF, prt, "out (c),0" },
+ { 0x70, 0xFF, dump, "xx" },
+ { 0x41, 0xC7, prt_r, "out (c),%s" },
+ { 0x42, 0xCF, prt_rr, "sbc hl," },
+ { 0x43, 0xCF, prt_rr_nn, "ld (0x%%04x),%s" },
+ { 0x44, 0xFF, prt, "neg" },
+ { 0x45, 0xFF, prt, "retn" },
+ { 0x46, 0xFF, prt, "im 0" },
+ { 0x47, 0xFF, prt, "ld i,a" },
+ { 0x4A, 0xCF, prt_rr, "adc hl," },
+ { 0x4B, 0xCF, prt_rr_nn, "ld %s,(0x%%04x)" },
+ { 0x4D, 0xFF, prt, "reti" },
+ { 0x56, 0xFF, prt, "im 1" },
+ { 0x57, 0xFF, prt, "ld a,i" },
+ { 0x5E, 0xFF, prt, "im 2" },
+ { 0x67, 0xFF, prt, "rrd" },
+ { 0x6F, 0xFF, prt, "rld" },
+ { 0xA0, 0xE4, cis, "" },
+ { 0xC3, 0xFF, prt, "muluw hl,bc" },
+ { 0xC5, 0xE7, prt_r, "mulub a,%s" },
+ { 0xF3, 0xFF, prt, "muluw hl,sp" },
+ { 0x00, 0x00, dump, "xx" }
+};
+
+static int
+pref_ed (struct buffer * buf, disassemble_info * info,
+ char* txt ATTRIBUTE_UNUSED)
+{
+ struct tab_elt *p;
+
+ if (fetch_data(buf, info, 1))
+ {
+ for (p = opc_ed; p->val != (buf->data[1] & p->mask); ++p)
+ ;
+ p->fp (buf, info, p->text);
+ }
+ else
+ buf->n_used = -1;
+
+ return buf->n_used;
+}
+
+/* Instruction names for the instructions addressing single bits. */
+static char *cb1_str[] = { "", "bit", "res", "set"};
+/* Instruction names for shifts and rotates. */
+static char *cb2_str[] =
+{
+ "rlc", "rrc", "rl", "rr", "sla", "sra", "sli", "srl"
+};
+
+static int
+pref_cb (struct buffer * buf, disassemble_info * info,
+ char* txt ATTRIBUTE_UNUSED)
+{
+ if (fetch_data (buf, info, 1))
+ {
+ buf->n_used = 2;
+ if ((buf->data[1] & 0xc0) == 0)
+ info->fprintf_func (info->stream, "%s %s",
+ cb2_str[(buf->data[1] >> 3) & 7],
+ r_str[buf->data[1] & 7]);
+ else
+ info->fprintf_func (info->stream, "%s %d,%s",
+ cb1_str[(buf->data[1] >> 6) & 3],
+ (buf->data[1] >> 3) & 7,
+ r_str[buf->data[1] & 7]);
+ }
+ else
+ buf->n_used = -1;
+
+ return buf->n_used;
+}
+
+static int
+addvv (struct buffer * buf, disassemble_info * info, char* txt)
+{
+ info->fprintf_func (info->stream, "add %s,%s", txt, txt);
+
+ return buf->n_used = buf->n_fetch;
+}
+
+static int
+ld_v_v (struct buffer * buf, disassemble_info * info, char* txt)
+{
+ char mytxt[TXTSIZ];
+
+ snprintf (mytxt, TXTSIZ, "ld %s%%s,%s%%s", txt, txt);
+ return ld_r_r (buf, info, mytxt);
+}
+
+static int
+prt_d (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ int d;
+ signed char *p;
+
+ p = (unsigned char*) buf->data + buf->n_fetch;
+
+ if (fetch_data (buf, info, 1))
+ {
+ d = p[0];
+ info->fprintf_func (info->stream, txt, d);
+ buf->n_used = buf->n_fetch;
+ }
+ else
+ buf->n_used = -1;
+
+ return buf->n_used;
+}
+
+static int
+prt_d_n (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ char mytxt[TXTSIZ];
+ int d;
+ signed char *p;
+
+ p = (unsigned char*) buf->data + buf->n_fetch;
+
+ if (fetch_data (buf, info, 1))
+ {
+ d = p[0];
+ snprintf (mytxt, TXTSIZ, txt, d);
+ return prt_n (buf, info, mytxt);
+ }
+ else
+ buf->n_used = -1;
+
+ return buf->n_used;
+}
+
+static int
+arit_d (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ char mytxt[TXTSIZ];
+ unsigned char c;
+
+ c = buf->data[buf->n_fetch - 1];
+ snprintf (mytxt, TXTSIZ, txt, arit_str[(c >> 3) & 7]);
+ return prt_d (buf, info, mytxt);
+}
+
+static int
+ld_r_d (struct buffer *buf, disassemble_info * info, char *txt)
+{
+ char mytxt[TXTSIZ];
+ unsigned char c;
+
+ c = buf->data[buf->n_fetch - 1];
+ snprintf (mytxt, TXTSIZ, txt, r_str[(c >> 3) & 7]);
+ return prt_d (buf, info, mytxt);
+}
+
+static int
+ld_d_r(struct buffer *buf, disassemble_info * info, char *txt)
+{
+ char mytxt[TXTSIZ];
+ unsigned char c;
+
+ c = buf->data[buf->n_fetch - 1];
+ snprintf (mytxt, TXTSIZ, txt, r_str[c & 7]);
+ return prt_d (buf, info, mytxt);
+}
+
+static int
+pref_xd_cb (struct buffer * buf, disassemble_info * info, char* txt)
+{
+ if (fetch_data (buf, info, 2))
+ {
+ int d;
+ char arg[TXTSIZ];
+ signed char *p;
+
+ buf->n_used = 4;
+ p = buf->data;
+ d = p[2];
+
+ if (((p[3] & 0xC0) == 0x40) || ((p[3] & 7) == 0x06))
+ snprintf (arg, TXTSIZ, "(%s+%d)", txt, d);
+ else
+ snprintf (arg, TXTSIZ, "(%s+%d),%s", txt, d, r_str[p[3] & 7]);
+
+ if ((p[3] & 0xc0) == 0)
+ info->fprintf_func (info->stream, "%s %s",
+ cb2_str[(buf->data[3] >> 3) & 7],
+ arg);
+ else
+ info->fprintf_func (info->stream, "%s %d,%s",
+ cb1_str[(buf->data[3] >> 6) & 3],
+ (buf->data[3] >> 3) & 7,
+ arg);
+ }
+ else
+ buf->n_used = -1;
+
+ return buf->n_used;
+}
+
+/* Table to disassemble machine codes with prefix 0xDD or 0xFD. */
+static struct tab_elt opc_ind[] =
+{
+ { 0x24, 0xF7, prt_r, "inc %s%%s" },
+ { 0x25, 0xF7, prt_r, "dec %s%%s" },
+ { 0x26, 0xF7, ld_r_n, "ld %s%%s,0x%%%%02x" },
+ { 0x21, 0xFF, prt_nn, "ld %s,0x%%04x" },
+ { 0x22, 0xFF, prt_nn, "ld (0x%%04x),%s" },
+ { 0x2A, 0xFF, prt_nn, "ld %s,(0x%%04x)" },
+ { 0x23, 0xFF, prt, "inc %s" },
+ { 0x2B, 0xFF, prt, "dec %s" },
+ { 0x29, 0xFF, addvv, "%s" },
+ { 0x09, 0xCF, prt_rr, "add %s," },
+ { 0x34, 0xFF, prt_d, "inc (%s+%%d)" },
+ { 0x35, 0xFF, prt_d, "dec (%s+%%d)" },
+ { 0x36, 0xFF, prt_d_n, "ld (%s+%%d),0x%%02x" },
+
+ { 0x76, 0xFF, dump, "h" },
+ { 0x46, 0xC7, ld_r_d, "ld %%s,(%s+%%%%d)" },
+ { 0x70, 0xF8, ld_d_r, "ld (%s+%%%%d),%%s" },
+ { 0x64, 0xF6, ld_v_v, "%s" },
+ { 0x60, 0xF0, ld_r_r, "ld %s%%s,%%s" },
+ { 0x44, 0xC6, ld_r_r, "ld %%s,%s%%s" },
+
+ { 0x86, 0xC7, arit_d, "%%s(%s+%%%%d)" },
+ { 0x84, 0xC6, arit_r, "%%s%s%%s" },
+
+ { 0xE1, 0xFF, prt, "pop %s" },
+ { 0xE5, 0xFF, prt, "push %s" },
+ { 0xCB, 0xFF, pref_xd_cb, "%s" },
+ { 0xE3, 0xFF, prt, "ex (sp),%s" },
+ { 0xE9, 0xFF, prt, "jp (%s)" },
+ { 0xF9, 0xFF, prt, "ld sp,%s" },
+ { 0x00, 0x00, dump, "?" },
+} ;
+
+static int
+pref_ind (struct buffer * buf, disassemble_info * info, char* txt)
+{
+ if (fetch_data (buf, info, 1))
+ {
+ char mytxt[TXTSIZ];
+ struct tab_elt *p;
+
+ for (p = opc_ind; p->val != (buf->data[1] & p->mask); ++p)
+ ;
+ snprintf (mytxt, TXTSIZ, p->text, txt);
+ p->fp (buf, info, mytxt);
+ }
+ else
+ buf->n_used = -1;
+
+ return buf->n_used;
+}
+
+/* Table to disassemble machine codes without prefix. */
+static struct tab_elt opc_main[] =
+{
+ { 0x00, 0xFF, prt, "nop" },
+ { 0x01, 0xCF, prt_rr_nn, "ld %s,0x%%04x" },
+ { 0x02, 0xFF, prt, "ld (bc),a" },
+ { 0x03, 0xCF, prt_rr, "inc " },
+ { 0x04, 0xC7, prt_r, "inc %s" },
+ { 0x05, 0xC7, prt_r, "dec %s" },
+ { 0x06, 0xC7, ld_r_n, "ld %s,0x%%02x" },
+ { 0x07, 0xFF, prt, "rlca" },
+ { 0x08, 0xFF, prt, "ex af,af'" },
+ { 0x09, 0xCF, prt_rr, "add hl," },
+ { 0x0A, 0xFF, prt, "ld a,(bc)" },
+ { 0x0B, 0xCF, prt_rr, "dec " },
+ { 0x0F, 0xFF, prt, "rrca" },
+ { 0x10, 0xFF, prt_e, "djnz " },
+ { 0x12, 0xFF, prt, "ld (de),a" },
+ { 0x17, 0xFF, prt, "rla" },
+ { 0x18, 0xFF, prt_e, "jr "},
+ { 0x1A, 0xFF, prt, "ld a,(de)" },
+ { 0x1F, 0xFF, prt, "rra" },
+ { 0x20, 0xE7, jr_cc, "jr %s,"},
+ { 0x22, 0xFF, prt_nn, "ld (0x%04x),hl" },
+ { 0x27, 0xFF, prt, "daa"},
+ { 0x2A, 0xFF, prt_nn, "ld hl,(0x%04x)" },
+ { 0x2F, 0xFF, prt, "cpl" },
+ { 0x32, 0xFF, prt_nn, "ld (0x%04x),a" },
+ { 0x37, 0xFF, prt, "scf" },
+ { 0x3A, 0xFF, prt_nn, "ld a,(0x%04x)" },
+ { 0x3F, 0xFF, prt, "ccf" },
+
+ { 0x76, 0xFF, prt, "halt" },
+ { 0x40, 0xC0, ld_r_r, "ld %s,%s"},
+
+ { 0x80, 0xC0, arit_r, "%s%s" },
+
+ { 0xC0, 0xC7, prt_cc, "ret " },
+ { 0xC1, 0xCF, pop_rr, "pop" },
+ { 0xC2, 0xC7, jp_cc_nn, "jp " },
+ { 0xC3, 0xFF, prt_nn, "jp 0x%04x" },
+ { 0xC4, 0xC7, jp_cc_nn, "call " },
+ { 0xC5, 0xCF, pop_rr, "push" },
+ { 0xC6, 0xC7, arit_n, "%s0x%%02x" },
+ { 0xC7, 0xC7, rst, "rst 0x%02x" },
+ { 0xC9, 0xFF, prt, "ret" },
+ { 0xCB, 0xFF, pref_cb, "" },
+ { 0xCD, 0xFF, prt_nn, "call 0x%04x" },
+ { 0xD3, 0xFF, prt_n, "out (0x%02x),a" },
+ { 0xD9, 0xFF, prt, "exx" },
+ { 0xDB, 0xFF, prt_n, "in a,(0x%02x)" },
+ { 0xDD, 0xFF, pref_ind, "ix" },
+ { 0xE3, 0xFF, prt, "ex (sp),hl" },
+ { 0xE9, 0xFF, prt, "jp (hl)" },
+ { 0xEB, 0xFF, prt, "ex de,hl" },
+ { 0xED, 0xFF, pref_ed, ""},
+ { 0xF3, 0xFF, prt, "di" },
+ { 0xF9, 0xFF, prt, "ld sp,hl" },
+ { 0xFB, 0xFF, prt, "ei" },
+ { 0xFD, 0xFF, pref_ind, "iy" },
+ { 0x00, 0x00, prt, "????" },
+} ;
+
+int
+print_insn_z80 (bfd_vma addr, disassemble_info * info)
+{
+ struct buffer buf;
+ struct tab_elt *p;
+
+ buf.base = addr;
+ 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); ++p)
+ ;
+ p->fp (& buf, info, p->text);
+
+ return buf.n_used;
+}