Browse Source

Add support for the Z80 processor family

readline_5_1-import-branch
Nick Clifton 21 years ago
parent
commit
3c9b82baee
  1. 17
      bfd/ChangeLog
  2. 10
      bfd/Makefile.am
  3. 10
      bfd/Makefile.in
  4. 7
      bfd/archures.c
  5. 8
      bfd/bfd-in2.h
  6. 244
      bfd/coff-z80.c
  7. 35
      bfd/coffcode.h
  8. 6
      bfd/config.bfd
  9. 1
      bfd/configure
  10. 1
      bfd/configure.in
  11. 57
      bfd/cpu-z80.c
  12. 1
      bfd/libbfd.h
  13. 5
      bfd/reloc.c
  14. 2
      bfd/targets.c
  15. 17
      gas/ChangeLog
  16. 3
      gas/Makefile.am
  17. 3
      gas/Makefile.in
  18. 54
      gas/app.c
  19. 5
      gas/config/obj-coff.h
  20. 2061
      gas/config/tc-z80.c
  21. 103
      gas/config/tc-z80.h
  22. 4
      gas/configure.tgt
  23. 1
      gas/doc/Makefile.am
  24. 7
      gas/doc/Makefile.in
  25. 1
      gas/doc/all.texi
  26. 64
      gas/doc/as.texinfo
  27. 248
      gas/doc/c-z80.texi
  28. 13
      gas/testsuite/ChangeLog
  29. 26
      gas/testsuite/gas/all/gas.exp
  30. 2
      gas/testsuite/gas/macros/macros.exp
  31. 9
      gas/testsuite/gas/z80/quotes.d
  32. 11
      gas/testsuite/gas/z80/quotes.s
  33. 8
      gas/testsuite/gas/z80/redef.d
  34. 11
      gas/testsuite/gas/z80/redef.s
  35. 10
      gas/testsuite/gas/z80/z80.exp
  36. 6
      include/ChangeLog
  37. 5
      include/coff/ChangeLog
  38. 6
      include/coff/internal.h
  39. 51
      include/coff/z80.h
  40. 1
      include/dis-asm.h
  41. 5
      include/elf/ChangeLog
  42. 4
      include/opcode/ChangeLog
  43. 10
      ld/ChangeLog
  44. 5
      ld/Makefile.am
  45. 5
      ld/Makefile.in
  46. 2
      ld/NEWS
  47. 2
      ld/configure.tgt
  48. 6
      ld/emulparams/z80.sh
  49. 85
      ld/emultempl/z80.em
  50. 35
      ld/scripttempl/z80.sc
  51. 1
      ld/testsuite/ld-checks/checks.exp
  52. 4
      ld/testsuite/ld-scripts/align.exp
  53. 8
      opcodes/ChangeLog
  54. 4
      opcodes/Makefile.am
  55. 4
      opcodes/Makefile.in
  56. 1
      opcodes/configure
  57. 1
      opcodes/configure.in
  58. 6
      opcodes/disassemble.c
  59. 620
      opcodes/z80-dis.c

17
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

10
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 \

10
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 \

7
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

8
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,

244
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)

35
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;

6
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

1
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

1
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

57
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));

1
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",

5
bfd/reloc.c

@ -4574,6 +4574,11 @@ ENUMDOC
internally by the linker after analysis of a
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

2
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 */

17
gas/ChangeLog

@ -1,3 +1,20 @@
2005-10-25 Arnold Metselaar <arnold.metselaar@planet.nl>
* Makefile.am: Add Z80 cpu.
* Makefile.in: Regenerated.
* app.c (do_scrub_chars)<TC_Z80>: Correctly scrub "ex af,af'"
and disallow newlines in quoted strings.
* configure.tgt: Add z80-*-coff.
* config/obj-coff.h: Add format "coff-z80".
* doc/Makefile.am: Add c-z80.texi.
* doc/Makefile.in: Regenerated.
* doc/all.texi: Add Z80.
* doc/c-z80.texi: New file
* doc/as.texinfo: Add z80 options and some z80-related remarks.
* config/tc-z80.c: New file
* config/tc-z80.h: New file
* NEWS: Mention new support.
2005-10-25 H.J. Lu <hongjiu.lu@intel.com>
* write.c (adjust_reloc_syms): Undo the change made on

3
gas/Makefile.am

@ -88,6 +88,7 @@ CPU_TYPES = \
v850 \
xstormy16 \
xtensa \
z80 \
z8k
# Object format types. This is only used for dependency information.
@ -270,6 +271,7 @@ TARGET_CPU_CFILES = \
config/tc-v850.c \
config/tc-xstormy16.c \
config/tc-xtensa.c \
config/tc-z80.c \
config/tc-z8k.c
TARGET_CPU_HFILES = \
@ -319,6 +321,7 @@ TARGET_CPU_HFILES = \
config/tc-v850.h \
config/tc-xstormy16.h \
config/tc-xtensa.h \
config/tc-z80.h \
config/tc-z8k.h
# OBJ files in config

3
gas/Makefile.in

@ -318,6 +318,7 @@ CPU_TYPES = \
v850 \
xstormy16 \
xtensa \
z80 \
z8k
@ -498,6 +499,7 @@ TARGET_CPU_CFILES = \
config/tc-v850.c \
config/tc-xstormy16.c \
config/tc-xtensa.c \
config/tc-z80.c \
config/tc-z8k.c
TARGET_CPU_HFILES = \
@ -547,6 +549,7 @@ TARGET_CPU_HFILES = \
config/tc-v850.h \
config/tc-xstormy16.h \
config/tc-xtensa.h \
config/tc-z80.h \
config/tc-z8k.h

54
gas/app.c

@ -375,6 +375,10 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
predicate.
15: After seeing a `(' at state 1, looking for a `)' as
predicate.
#endif
#ifdef TC_Z80
16: After seeing an 'a' or an 'A' at the start of a symbol
17: After seeing an 'f' or an 'F' in state 16
#endif
*/
@ -664,6 +668,32 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
state = 1;
PUT ('|');
continue;
#endif
#ifdef TC_Z80
case 16:
/* We have seen an 'a' at the start of a symbol, look for an 'f'. */
ch = GET ();
if (ch == 'f' || ch == 'F')
{
state = 17;
PUT (ch);
}
else
{
state = 9;
break;
}
case 17:
/* We have seen "af" at the start of a symbol,
a ' here is a part of that symbol. */
ch = GET ();
state = 9;
if (ch == '\'')
/* Change to avoid warning about unclosed string. */
PUT ('`');
else
UNGET (ch);
break;
#endif
}
@ -1242,6 +1272,30 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
break;
}
#ifdef TC_Z80
/* "af'" is a symbol containing '\''. */
if (state == 3 && (ch == 'a' || ch == 'A'))
{
state = 16;
PUT (ch);
ch = GET ();
if (ch == 'f' || ch == 'F')
{
state = 17;
PUT (ch);
break;
}
else
{
state = 9;
if (!IS_SYMBOL_COMPONENT (ch))
{
UNGET (ch);
break;
}
}
}
#endif
if (state == 3)
state = 9;

5
gas/config/obj-coff.h

@ -85,6 +85,11 @@
#define TARGET_FORMAT "coff-Intel-little"
#endif
#ifdef TC_Z80
#include "coff/z80.h"
#define TARGET_FORMAT "coff-z80"
#endif
#ifdef TC_Z8K
#include "coff/z8k.h"
#define TARGET_FORMAT "coff-z8k"

2061
gas/config/tc-z80.c

File diff suppressed because it is too large

103
gas/config/tc-z80.h

@ -0,0 +1,103 @@
/* this is tc-z80.h
Copyright 2005 Free Software Foundation, Inc.
Contributed by Arnold Metselaar <arnold_m@operamail.com>
This file is part of GAS, the GNU Assembler.
GAS 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, or (at your option)
any later version.
GAS 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 GAS; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
#ifndef TC_Z80
#define TC_Z80
#define TARGET_ARCH bfd_arch_z80
#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
use of nonstandard escape sequences in a string. */
#define ONLY_STANDARD_ESCAPES
/* GAS will call this function for any expression that can not be
recognized. When the function is called, `input_line_pointer'
will point to the start of the expression. */
#define md_operand(x)
/* This should just call either `number_to_chars_bigendian' or
`number_to_chars_littleendian', whichever is appropriate. On
targets like the MIPS which support options to change the
endianness, which function to call is a runtime decision. On
other targets, `md_number_to_chars' can be a simple macro. */
#define md_number_to_chars number_to_chars_littleendian
#define TC_COUNT_RELOC(x) 1
#define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype (fixP)
#define md_convert_frag(b,s,f) as_fatal ("convert_frag called\n")
#define md_estimate_size_before_relax(f,s) \
(as_fatal (_("estimate_size_before_relax called")), 1)
/* Define some functions to be called by generic code. */
#define md_end z80_md_end
#define md_start_line_hook() { if (z80_start_line_hook ()) continue; }
#define md_optimize_expr z80_optimize_expr
extern void z80_md_end (void);
extern int z80_start_line_hook (void);
extern int z80_optimize_expr (expressionS *, operatorT, expressionS *);
#define WORKING_DOT_WORD
/* If you define this macro, it means that `tc_gen_reloc' may return
multiple relocation entries for a single fixup. In this case, the
return value of `tc_gen_reloc' is a pointer to a null terminated
array. */
#undef RELOC_EXPANSION_POSSIBLE
/* No shared lib support, so we don't need to ensure
externally visible symbols can be overridden. */
#define EXTERN_FORCE_RELOC 0
/* Values passed to md_apply_fix3 don't include the symbol value. */
#define MD_APPLY_SYM_VALUE(FIX) 0
#define LISTING_WORD_SIZE 2
/* A '$' is used to refer to the current location or as a hex. prefix. */
#define DOLLAR_DOT
#define DOLLAR_AMBIGU 1
#define SINGLE_EQ_COMPARES
#define LOCAL_LABELS_FB 1
#define LITERAL_PREFIXPERCENT_BIN
#define NUMBERS_WITH_SUFFIX 1
#define NO_PSEUDO_DOT 1
/* We allow single quotes to delimit character constants as
well, but it is cleaner to handle that in tc-z80.c. */
#define SINGLE_QUOTE_STRINGS
#define NO_STRING_ESCAPES
/* An `.lcomm' directive with no explicit alignment parameter will
use this macro to set P2VAR to the alignment that a request for
SIZE bytes will have. The alignment is expressed as a power of
two. If no alignment should take place, the macro definition
should do nothing. Some targets define a `.bss' directive that is
also affected by this macro. The default definition will set
P2VAR to the truncated power of two of sizes up to eight bytes. */
#define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) (P2VAR) = 0
#endif

4
gas/configure.tgt

@ -375,6 +375,8 @@ case ${generic_target} in
xtensa-*-*) fmt=elf ;;
z80-*-coff) fmt=coff ;;
z8k-*-coff | z8k-*-sim) fmt=coff ;;
*-*-aout | *-*-scout) fmt=aout ;;
@ -390,7 +392,7 @@ case ${generic_target} in
esac
case ${cpu_type} in
alpha | arm | i386 | ia64 | mips | ns32k | pdp11 | ppc | sparc | z8k)
alpha | arm | i386 | ia64 | mips | ns32k | pdp11 | ppc | sparc | z80 | z8k)
bfd_gas=yes
;;
esac

1
gas/doc/Makefile.am

@ -55,6 +55,7 @@ CPU_DOCS = \
c-vax.texi \
c-v850.texi \
c-xtensa.texi \
c-z80.texi \
c-z8k.texi
gasver.texi: $(srcdir)/../../bfd/configure

7
gas/doc/Makefile.in

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.9.2 from Makefile.am.
# Makefile.in generated by automake 1.9.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@ -246,6 +246,7 @@ CPU_DOCS = \
c-vax.texi \
c-v850.texi \
c-xtensa.texi \
c-z80.texi \
c-z8k.texi
@ -347,7 +348,7 @@ as.html: as.texinfo
$(DVIPS) -o $@ $<
uninstall-info-am:
$(PRE_UNINSTALL)
@$(PRE_UNINSTALL)
@if (install-info --version && \
install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
list='$(INFO_DEPS)'; \
@ -363,7 +364,7 @@ uninstall-info-am:
relfile=`echo "$$file" | sed 's|^.*/||'`; \
relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
(if cd "$(DESTDIR)$(infodir)"; then \
echo " rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9])"; \
echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
else :; fi); \
done

1
gas/doc/all.texi

@ -58,6 +58,7 @@
@set V850
@set VAX
@set XTENSA
@set Z80
@set Z8000
@c Does this version of the assembler use the difference-table kluge?

64
gas/doc/as.texinfo

@ -420,6 +420,19 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{-mcpu=54[123589]}|@b{-mcpu=54[56]lp}] [@b{-mfar-mode}|@b{-mf}]
[@b{-merrors-to-file} @var{<filename>}|@b{-me} @var{<filename>}]
@end ifset
@ifset Z80
@emph{Target Z80 options:}
[@b{-z80}] [@b{-r800}]
[@b{ -ignore-undocumented-instructions}] [@b{-Wnud}]
[@b{ -ignore-unportable-instructions}] [@b{-Wnup}]
[@b{ -warn-undocumented-instructions}] [@b{-Wud}]
[@b{ -warn-unportable-instructions}] [@b{-Wup}]
[@b{ -forbid-undocumented-instructions}] [@b{-Fud}]
[@b{ -forbid-unportable-instructions}] [@b{-Fup}]
@end ifset
@ifset Z8000
@c Z8000 has no machine-dependent assembler options
@end ifset
@ -1138,6 +1151,35 @@ instructions must be exactly as specified in the assembly source.
@end table
@end ifset
@ifset Z80
The following options are available when @value{AS} is configured for
a Z80 family processor.
@table @gcctabopt
@item -z80
Assemble for Z80 processor.
@item -r800
Assemble for R800 processor.
@item -ignore-undocumented-instructions
@itemx -Wnud
Assemble undocumented Z80 instructions that also work on R800 without warning.
@item -ignore-unportable-instructions
@itemx -Wnup
Assemble all undocumented Z80 instructions without warning.
@item -warn-undocumented-instructions
@itemx -Wud
Issue a warning for undocumented Z80 instructions that also work on R800.
@item -warn-unportable-instructions
@itemx -Wup
Issue a warning for undocumented Z80 instructions that do notwork on R800.
@item -forbid-undocumented-instructions
@itemx -Fud
Treat all undocumented instructions as errors.
@item -forbid-unportable-instructions
@itemx -Fup
Treat undocumented Z80 intructions that do notwork on R800 as errors.
@end table
@end ifset
@c man end
@menu
@ -2130,6 +2172,9 @@ is considered a comment and is ignored. The line comment character is
@ifset VAX
@samp{#} on the Vax;
@end ifset
@ifset Z80
@samp{;} for the Z80;
@end ifset
@ifset Z8000
@samp{!} for the Z8000;
@end ifset
@ -4272,6 +4317,13 @@ The syntax for @code{equ} on the HPPA is
@samp{@var{symbol} .equ @var{expression}}.
@end ifset
@ifset Z80
The syntax for @code{equ} on the Z80 is
@samp{@var{symbol} equ @var{expression}}.
On the Z80 it is an eror if @var{symbol} is already defined,
compare @xref{Equiv}.
@end ifset
@node Equiv
@section @code{.equiv @var{symbol}, @var{expression}}
@cindex @code{equiv} directive
@ -5512,6 +5564,11 @@ The syntax for @code{set} on the HPPA is
@samp{@var{symbol} .set @var{expression}}.
@end ifset
@ifset Z80
On Z80 @code{set} is a real instruction, use
@samp{@var{symbol} defl @var{expression}} instead.
@end ifset
@node Short
@section @code{.short @var{expressions}}
@ -6196,6 +6253,9 @@ subject, see the hardware manufacturer's manual.
@ifset XTENSA
* Xtensa-Dependent:: Xtensa Dependent Features
@end ifset
@ifset Z80
* Z80-Dependent:: Z80 Dependent Features
@end ifset
@ifset Z8000
* Z8000-Dependent:: Z8000 Dependent Features
@end ifset
@ -6350,6 +6410,10 @@ family.
@include c-tic54x.texi
@end ifset
@ifset Z80
@include c-z80.texi
@end ifset
@ifset Z8000
@include c-z8k.texi
@end ifset

248
gas/doc/c-z80.texi

@ -0,0 +1,248 @@
@c This is part of the GAS manual.
@c For copying conditions, see the file as.texinfo.
@ifset GENERIC
@page
@node Z80-Dependent
@chapter Z80 Dependent Features
@end ifset
@c DO-NOT-COMMIT
@ifclear GENERIC
@node Machine Dependencies
@chapter Z80 Dependent Features
@end ifclear
@cindex Z80 support
@menu
* Z80 Options:: Options
* Z80 Syntax:: Syntax
* Z80 Floating Point:: Floating Point
* Z80 Directives:: Z80 Machine Directives
* Z80 Opcodes:: Opcodes
@end menu
@node Z80 Options
@section Options
@cindex Z80 options
@cindex options for Z80
The Zilog Z80 and Ascii R800 version of @code{@value{AS}} have a few machine
dependent options.
@table @option
@cindex @code{-z80} command line option, Z80
@item -z80
Produce code for the Z80 processor. There are additional options to
request warnings and error messages for undocumented instructions.
@item -ignore-undocumented-instructions
@itemx -Wnud
Silently assemble undocumented Z80-instructions that have been adopted
as documented R800-instructions.
@item -ignore-unportable-instructions
@itemx -Wnup
Silently assemble all undocumented Z80-instructions.
@item -warn-undocumented-instructions
@itemx -Wud
Issue warnings for undocumented Z80-instructions that work on R800, do
not assemble other undocumented instructions without warning.
@item -warn-unportable-instructions
@itemx -Wup
Issue warnings for other undocumented Z80-instructions, do not treat any
undocumented instructions as errors.
@item -forbid-undocumented-instructions
@itemx -Fud
Treat all undocumented z80-instructions as errors.
@item -forbid-unportable-instructions
@itemx -Fup
Treat undocumented z80-instructions that do not work on R800 as errors.
@cindex @code{-r800} command line option, Z80
@item -r800
Produce code for the R800 processor. The assembler does not support
undocumented instructions for the R800.
In line with common practice, @code{@value{AS}} uses Z80 instriction names
for the R800 processor, as far as they exist.
@end table
@cindex Z80 Syntax
@node Z80 Syntax
@section Syntax
The assembler syntax closely follows the 'Z80 family CPU User Manual' by
Zilog.
In expressions a single @samp{=} may be used as ``is equal to''
comparison operator.
Suffices can be used to indicate the radix of integer constants;
@samp{H} or @samp{h} for hexadecimal, @samp{D} or @samp{d} for decimal,
@samp{Q}, @samp{O}, @samp{q} or @samp{o} for octal, and @samp{B} for
binary.
The suffix @samp{b} denotes a backreference to local label.
@menu
* Z80-Chars:: Special Characters
* Z80-Regs:: Register Names
* Z80-Case:: Case Sensitivity
@end menu
@node Z80-Chars
@subsection Special Characters
@cindex line comment character, Z80
@cindex Z80 line comment character
The semicolon @samp{;} is the line comment character;
@cindex location counter, Z80
@cindex hexadecimal prefix, Z80
@cindex Z80 $
The dollar sign @samp{$} can be used as a prefix for hexadecimal numbers
and as a symbol denoting the current location counter.
@cindex character escapes, Z80
@cindex Z80, \
A backslash @samp{\} is an ordinary character for the Z80 assembler.
@cindex character constant, Z80
@cindex single quote, Z80
@cindex Z80 '
The single quote @samp{'} must be followed by a closing quote. If there
is one character inbetween, it is a character constant, otherwise it is
a string constant.
@node Z80-Regs
@subsection Register Names
@cindex Z80 registers
@cindex register names, Z80
The registers are referred to with the letters assigned to them by
Zilog. In addition @command{@value{AS}} recognises @samp{ixl} and
@samp{ixh} as the least and most significant octet in @samp{ix}, and
similarly @samp{iyl} and @samp{iyh} as parts of @samp{iy}.
@c The @samp{'} in @samp{ex af,af'} may be omitted.
@node Z80-Case
@subsection Case Sensitivity
@cindex Z80, case sensitivity
@cindex case sensitivity, Z80
Upper and lower case are equivalent in register names, opcodes,
condition codes and assembler directives.
The case of letters is significant in labels and symbol names. The case
is also important to distinguish the suffix @samp{b} for a backward reference
to a local label from the suffix @samp{B} for a number in binary notation.
@node Z80 Floating Point
@section Floating Point
@cindex floating point, Z80
@cindex Z80 floating point
Floating-point numbers are not supported.
@node Z80 Directives
@section Z80 Assembler Directives
@command{@value{AS}} for the Z80 supports some additional directives for
compatibility with other assemblers.
@cindex Z80-only directives
These are the additional directives in @code{@value{AS}} for the Z80:
@table @code
@item db @var{expression}|@var{string}[,@var{expression}|@var{string}...]
@itemx defb @var{expression}|@var{string}[,@var{expression}|@var{string}...]
For each @var{string} the characters are copied to the object file, for
each other @var{expression} the value is stored in one byte, ignoring
overflow.
@item dw @var{expression}[,@var{expression}...]
@itemx defw @var{expression}[,@var{expression}...]
For each @var{expression} the value is stored in two bytes, ignoring
overflow.
@item ds @var{count}[, @var{value}]
@itemx defs @var{count}[, @var{value}]
@c Synonyms for @code{ds.b},
@c which should have been described elsewhre
Fill @var{count} bytes in the object file with @var{value}, if
@var{value} is omitted it defaults to zero.
@item @var{symbol} equ @var{expression}
@itemx @var{symbol} defl @var{expression}
These directives set the value of @var{symbol} to @var{expression}. To
keep code portable to other assemblers it is best to use @samp{equ} for
the first definition and @samp{defl} for redefinitions.
@item set
This is a normal instruction on Z80, and not an assembler directive.
@item psect @var{name}
A synonym for @xref{Section}, no second argument should be given.
@ignore
The following attributes will possibly be recognised in the future
@table @code
@item abs
The section is to be absolute. @code{@value{AS}} will issue an error
message because it can not produce an absolute section.
@item global
The section is to be concatenated with other sections of the same name
by the linker, this is the default.
@item local
The section is not global. @code{@value{AS}} will issue a warning if
object file format is not soff.
@item ovrld
The section is to be overlapped with other sections of the same name by
the linker. @code{@value{AS}} will issue an error message
because it can not mark a section as such.
@item pure
The section is marked as read only.
@end table
@end ignore
@end table
@node Z80 Opcodes
@section Opcodes
In line with commmon practice Z80 mnonics are used for both the Z80 and
the R800.
In many instructions it is possible to use one of the half index
registers (@samp{ixl},@samp{ixh},@samp{iyl},@samp{iyh}) in stead of an
8-bit general purpose register. This yields instructions that are
documented on the R800 and undocumented on the Z80.
Similarly @code{in f,(c)} is documented on the R800 and undocumented on
the Z80.
The assembler also supports the following undocumented Z80-instructions,
that have not been adopted in the R800 instruction set:
@table @code
@item out (c),0
Sends zero to the port pointed to by register c.
@item sli @var{m}
Equivalent to @code{@var{m} = (@var{m}<<1)+1}, the operand @var{m} can
be any operand that is valid for @samp{sla}. One can use @samp{sll} as a
synonym for @samp{sli}.
@item @var{op} (ix+@var{d}), @var{r}
This is equivalent to
@example
ld @var{r}, (ix+@var{d})
@var{opc} @var{r}
ld (ix+@var{d}), @var{r}
@end example
The operation @samp{@var{opc}} may be any of @samp{res @var{b},},
@samp{set @var{b},}, @samp{rl}, @samp{rlc}, @samp{rr}, @samp{rrc},
@samp{sla}, @samp{sli}, @samp{sra} and @samp{srl}, and the register
@samp{@var{r}} may be any of @samp{a}, @samp{b}, @samp{c}, @samp{d},
@samp{e}, @samp{h} and @samp{l}.
@item @var{opc} (iy+@var{d}), @var{r}
As above, but with @samp{iy} instead of @samp{ix}.
@end table
The web site at @uref{http://www.z80.info} is a good starting place to
find more information on programming the Z80.

13
gas/testsuite/ChangeLog

@ -1,3 +1,16 @@
2005-10-25 Arnold Metselaar <arnold.metselaar@planet.nl>
* gas/all/gas.exp: Exclude Z80-*-* from floating point, string,
and cofftag test.
* gas/macros/macros.exp: Expect z80-*-* to fail the strings test
because it has no string escapes.
* gas/z80/quotes.d: New file
* gas/z80/quotes.d: New file
* gas/z80/quotes.s: New file
* gas/z80/redef.d: New file
* gas/z80/redef.s: New file
* gas/z80/z80.exp: New file
2005-10-24 Bernd Schmidt <bernd.schmidt@analog.com>
* gas/bfin/flow2.d: Match changed assembler behaviour.

26
gas/testsuite/gas/all/gas.exp

@ -23,8 +23,9 @@ if { [istarget hppa*-*-*] || [istarget *c54x*-*-*] } then {
gas_test "p1480.s" "" "-a>" "simplifiable double subtraction"
}
# No floating point support in assembly code for CRIS.
if { ![istarget cris-*-*] && ![istarget crisv32-*-*] } then {
# No floating point support in assembly code for CRIS and Z80.
if { ![istarget cris-*-*] && ![istarget crisv32-*-*]
&& ![istarget z80-*-*] } then {
gas_test "float.s" "" "" "simple FP constants"
}
@ -78,6 +79,7 @@ case $target_triplet in {
{ iq2000*-*-* } { }
{ mips*-*-* } { }
{ *c54x*-*-* } { }
{ z80-*-* } { }
default {
setup_xfail "*c30*-*-*" "*c4x*-*-*" "pdp11-*-*"
run_dump_test redef
@ -189,7 +191,8 @@ case $target_triplet in {
# We omit the ARM toolchains because they define locals to
# start with '.', which eliminates .eos, .text etc from the output.
# Omit c54x, since .tag and .def mean something different on that target
if { ([istarget *-*-coff*] && ![istarget *arm*-*-coff] && ![istarget thumb*-*-coff] && ![istarget xscale-*-coff] && ![istarget *c4x*-*-coff] && ![istarget *c54x*-*-coff]) \
# Omit Z80, since octal numbers need a suffix on that target
if { ([istarget *-*-coff*] && ![istarget *arm*-*-coff] && ![istarget thumb*-*-coff] && ![istarget xscale-*-coff] && ![istarget *c4x*-*-coff] && ![istarget *c54x*-*-coff] && ![istarget z80-*-coff]) \
||([istarget *-*-pe*] && ![istarget arm*-*-pe*] && ![istarget thumb*-*-pe*]) \
|| [istarget i*86-*-aix*] \
|| [istarget i*86-*-sco*] \
@ -250,11 +253,18 @@ if { ![istarget "i960-*-*"] } {
run_dump_test quad
}
run_dump_test weakref1
run_dump_test weakref1g
run_dump_test weakref1l
run_dump_test weakref1u
run_dump_test weakref1w
# .set works differently on some targets.
case $target_triplet in {
{ z80-*-* } { }
default {
run_dump_test weakref1
run_dump_test weakref1g
run_dump_test weakref1l
run_dump_test weakref1u
run_dump_test weakref1w
}
}
gas_test_error "weakref2.s" "" "e: would close weakref loop: e => a => b => c => d => e"
gas_test_error "weakref3.s" "" "a: would close weakref loop: a => b => c => d => e => a"

2
gas/testsuite/gas/macros/macros.exp

@ -56,6 +56,7 @@ if { ![istarget hppa*-*-*] || [istarget *-*-linux*] } {
setup_xfail "powerpc*-*-aix*" "powerpc*-*-beos*" "powerpc*-*-macos*"
setup_xfail "powerpc*-*-pe" "powerpc*-*-*win*"
setup_xfail "rs6000-*-*"
setup_xfail "z80-*-*"
# FIXME: Due to difference in what "consecutive octets" means.
setup_xfail "*c4x*-*-*" "*c54x*-*"
@ -75,6 +76,7 @@ case $target_triplet in {
{ m68*-*-* } { }
{ m88*-*-* } { }
{ mmix-* } { }
{ z80-* } { }
default { run_list_test dot "-alm" }
}
run_list_test end ""

9
gas/testsuite/gas/z80/quotes.d

@ -0,0 +1,9 @@
#objdump: -s -j .data
#name: quotes
.*:.*
Contents of section .data:
0000 73696e67 6c653a27 646f7562 6c653a22[ ]+................
0010 00657363 6170653a 5c5c08fe 3a[ ]+................
#pass

11
gas/testsuite/gas/z80/quotes.s

@ -0,0 +1,11 @@
;; test the parsing of strings and character constants
section .data
laf:
defb "single:'"
defb 'double:"',laf
defb 'escape:\\'
ex af,af'
af0:
cp '9'+1

8
gas/testsuite/gas/z80/redef.d

@ -0,0 +1,8 @@
#objdump: -s -j .data
#name: .equ redefinitions
.*: .*
Contents of section .data:
0000 00000000 0[04]00000[04] 0[08]00000[08] 0[0c]00000[0c][ ]+................[ ]*
#pass

11
gas/testsuite/gas/z80/redef.s

@ -0,0 +1,11 @@
.data
_start:
x: defl .-_start
.long x
.balign 4
x: defl .-_start
.long x
x: defl .-_start
.long x
x: defl .-_start
.long x

10
gas/testsuite/gas/z80/z80.exp

@ -0,0 +1,10 @@
# run targets for target Z80.
if [istarget z80-*-*] then
{
# test redefinitions
run_dump_test "redef"
# test parsing of " and '
run_dump_test "quotes"
}

6
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>

5
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.

6
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 */

51
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

1
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 *);

5
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.

4
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

10
ld/ChangeLog

@ -1,3 +1,13 @@
2005-10-25 Arnold Metselaar <arnold.metselaar@planet.nl>
* Makefile.am: Add support for Z80
* Makefile.in: Regenerated
* configure.tgt: Add z80-*-coff
* emulparams/z80.sh: New file.
* emultempl/z80.em: New file.
* scripttempl/z80.sc New file.
* NEWS: Mention this new support.
2005-10-25 Alan Modra <amodra@bigpond.net.au>
* po/ld.pot: Regenerate.

5
ld/Makefile.am

@ -372,6 +372,7 @@ ALL_EMULATIONS = \
ew65.o \
ez8001.o \
eelf32frvfd.o \
ez80.o \
ez8002.o
ALL_64_EMULATIONS = \
@ -1537,6 +1538,10 @@ ev850.c: $(srcdir)/emulparams/v850.sh \
ew65.c: $(srcdir)/emulparams/w65.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/w65.sc ${GEN_DEPENDS}
${GENSCRIPTS} w65 "$(tdir_w65)"
ez80.c: $(srcdir)/emulparams/z80.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/emultempl/z80.em \
$(srcdir)/scripttempl/z80.sc ${GEN_DEPENDS}
${GENSCRIPTS} z80 "$(tdir_z80)"
ez8001.c: $(srcdir)/emulparams/z8001.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/z8000.sc ${GEN_DEPENDS}
${GENSCRIPTS} z8001 "$(tdir_z8001)"

5
ld/Makefile.in

@ -595,6 +595,7 @@ ALL_EMULATIONS = \
ew65.o \
ez8001.o \
eelf32frvfd.o \
ez80.o \
ez8002.o
ALL_64_EMULATIONS = \
@ -2341,6 +2342,10 @@ ev850.c: $(srcdir)/emulparams/v850.sh \
ew65.c: $(srcdir)/emulparams/w65.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/w65.sc ${GEN_DEPENDS}
${GENSCRIPTS} w65 "$(tdir_w65)"
ez80.c: $(srcdir)/emulparams/z80.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/emultempl/z80.em \
$(srcdir)/scripttempl/z80.sc ${GEN_DEPENDS}
${GENSCRIPTS} z80 "$(tdir_z80)"
ez8001.c: $(srcdir)/emulparams/z8001.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/z8000.sc ${GEN_DEPENDS}
${GENSCRIPTS} z8001 "$(tdir_z8001)"

2
ld/NEWS

@ -1,5 +1,7 @@
-*- text -*-
* Support for the Z80 processor family has been added.
* Add support for the "@<file>" syntax to the command line, so that extra
switches can be read from <file>.

2
ld/configure.tgt

@ -555,6 +555,8 @@ xstormy16-*-*) targ_emul=elf32xstormy16
;;
xtensa-*-*) targ_emul=elf32xtensa
;;
z80-*-coff) targ_emul=z80
;;
z8k-*-coff) targ_emul=z8002; targ_extra_emuls=z8001
;;
*-*-ieee*) targ_emul=vanilla

6
ld/emulparams/z80.sh

@ -0,0 +1,6 @@
SCRIPT_NAME=z80
OUTPUT_FORMAT="coff-z80"
OUTPUT_ARCH="z80"
TEXT_START_ADDR=0x100
EXTRA_EM_FILE=z80
ARCH=z80

85
ld/emultempl/z80.em

@ -0,0 +1,85 @@
# This shell script emits C code -*- C -*-
# to keep track of the machine type of Z80 object files
# It does some substitutions.
LDEMUL_BEFORE_PARSE=gldz80_before_parse
LDEMUL_RECOGNIZED_FILE=gldz80_recognized_file
LDEMUL_AFTER_OPEN=gldz80_after_open
cat >>e${EMULATION_NAME}.c <<EOF
/* --- \begin{z80.em} */
/* Codes for machine types, bitwise or gives the code to use for the
output. */
#define M_Z80STRICT 1
#define M_Z80 3
#define M_Z80FULL 7
#define M_R800 11
#define M_Z80ANY 15
/* Bitwise or of the machine types seen so far. */
static int result_mach_type;
static void
${LDEMUL_BEFORE_PARSE} (void)
{
#ifndef TARGET_ /* I.e., if not generic. */
ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown);
#endif /* not TARGET_ */
result_mach_type = M_Z80STRICT;
}
/* Update result_mach_type. */
static bfd_boolean
${LDEMUL_RECOGNIZED_FILE} (lang_input_statement_type *entry)
{
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;
default:
result_mach_type |= M_Z80ANY;
}
return FALSE;
}
/* Set the machine type of the output file based on result_mach_type. */
static void
gldz80_after_open (void)
{
unsigned long mach_type;
switch (result_mach_type)
{
case M_Z80STRICT:
mach_type = bfd_mach_z80strict;
break;
case M_Z80:
mach_type = bfd_mach_z80;
break;
case M_Z80FULL:
mach_type = bfd_mach_z80full;
break;
case M_R800:
mach_type = bfd_mach_r800;
break;
default:
mach_type = 0;
}
bfd_set_arch_mach (output_bfd, bfd_arch_z80, mach_type);
}
/* --- \end{z80.em} */
EOF

35
ld/scripttempl/z80.sc

@ -0,0 +1,35 @@
if [ x${LD_FLAG} = x ]
then
cat << EOF
/* Create a cp/m executable; load and execute at 0x100. */
OUTPUT_FORMAT("binary")
. = 0x100;
__Ltext = .;
ENTRY (__Ltext)
EOF
else
echo "OUTPUT_FORMAT(\"${OUTPUT_FORMAT}\")"
fi
cat <<EOF
OUTPUT_ARCH("${OUTPUT_ARCH}")
SECTIONS
{
.text : {
*(.text)
*(text)
${RELOCATING+ __Htext = .;}
}
.data : {
${RELOCATING+ __Ldata = .;}
*(.data)
*(data)
${RELOCATING+ __Hdata = .;}
}
.bss : {
${RELOCATING+ __Lbss = .;}
*(.bss)
*(bss)
${RELOCATING+ __Hbss = .;}
}
}
EOF

1
ld/testsuite/ld-checks/checks.exp

@ -54,6 +54,7 @@ proc section_check {} {
# Perform the equivalent of invoking ld_simple_link
# except that we need to massage the output futher.
verbose -log "$ld -o tmpdir/asm.x $ldflags tmpdir/asm.o"
catch "exec $ld -o tmpdir/asm.x $ldflags tmpdir/asm.o" exec_output
set exec_output [prune_warnings $exec_output]

4
ld/testsuite/ld-scripts/align.exp

@ -42,7 +42,11 @@ if ![ld_simple_link $ld tmpdir/align "-T $srcdir/$subdir/align.t tmpdir/align.o"
}
if ![is_aout_format] {
# The z80-coff port defaults to a "binary" like output
# file format which does not include a data section.
setup_xfail "z80-*-coff"
run_dump_test align2a
setup_xfail "z80-*-coff"
run_dump_test align2b
}
run_dump_test align2c

8
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.

4
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

4
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

1
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" ;;
"") ;;

1
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" ;;
"") ;;

6
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)

620
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;
}
Loading…
Cancel
Save