From: John Darrington Date: Fri, 18 May 2018 14:26:18 +0000 (+0100) Subject: Add support for the Freescale s12z processor. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7b4ae824289504c173a597e86a00ceab452095b7;p=binutils-gdb.git Add support for the Freescale s12z processor. bfd * Makefile.am: Add s12z files. * Makefile.in: Regenerate. * archures.c: Add bfd_s12z_arch. * bfd-in.h: Add exports of bfd_putb24 and bfd_putl24. * bfd-in2.h: Regenerate. * config.bfd: Add s12z target. * configure.ac: Add s12z target. * configure: Regenerate. * cpu-s12z.c: New file. * elf32-s12z.c: New file. * libbfd.c (bfd_putb24): New function. (bfd_putl24): New function. * libbfd.h: Regenerate. * reloc.c: Add s12z relocations. (bfd_get_reloc_size): Handle size 5 relocs. * targets.c: Add s12z_elf32_vec. opcodes * Makefile.am: Add support for s12z architecture. * configure.ac: Likewise. * disassemble.c: Likewise. * disassemble.h: Likewise. * Makefile.in: Regenerate. * configure: Regenerate. * s12z-dis.c: New file. * s12z.h: New file. include * elf/s12z.h: New header. ld * Makefile.am: Add support for s12z architecture. * configure.tgt: Likewise. * Makefile.in: Regenerate. * emulparams/m9s12zelf.sh: New file. * scripttempl/elfm9s12z.sc: New file. * testsuite/ld-discard/static.d: Expect to fail for the s12z target. * testsuite/ld-elf/endsym.d: Likewise. * testsuite/ld-elf/merge.d: Likewise. * testsuite/ld-elf/pr14926.d: Skip for the s12z target. * testsuite/ld-elf/sec64k.exp: Likewise. * testsuite/ld-s12z: New directory. * testsuite/ld-s12z/opr-linking.d: New file. * testsuite/ld-s12z/opr-linking.s: New file. * testsuite/ld-s12z/relative-linking.d: New file. * testsuite/ld-s12z/relative-linking.s: New file. * testsuite/ld-s12z/z12s.exp: New file. gas * Makefile.am: Add support for s12z target. * Makefile.in: Regenerate. * NEWS: Mention the new support. * config/tc-s12z.c: New file. * config/tc-s12z.h: New file. * configure.tgt: Add s12z support. * doc/Makefile.am: Likewise. * doc/Makefile.in: Regenerate. * doc/all.texi: Add s12z documentation. * doc/as.textinfo: Likewise. * doc/c-s12z.texi: New file. * testsuite/gas/s12z: New directory. * testsuite/gas/s12z/abs.d: New file. * testsuite/gas/s12z/abs.s: New file. * testsuite/gas/s12z/adc-imm.d: New file. * testsuite/gas/s12z/adc-imm.s: New file. * testsuite/gas/s12z/adc-opr.d: New file. * testsuite/gas/s12z/adc-opr.s: New file. * testsuite/gas/s12z/add-imm.d: New file. * testsuite/gas/s12z/add-imm.s: New file. * testsuite/gas/s12z/add-opr.d: New file. * testsuite/gas/s12z/add-opr.s: New file. * testsuite/gas/s12z/and-imm.d: New file. * testsuite/gas/s12z/and-imm.s: New file. * testsuite/gas/s12z/and-opr.d: New file. * testsuite/gas/s12z/and-opr.s: New file. * testsuite/gas/s12z/and-or-cc.d: New file. * testsuite/gas/s12z/and-or-cc.s: New file. * testsuite/gas/s12z/bfext-special.d: New file. * testsuite/gas/s12z/bfext-special.s: New file. * testsuite/gas/s12z/bfext.d: New file. * testsuite/gas/s12z/bfext.s: New file. * testsuite/gas/s12z/bit-manip.d: New file. * testsuite/gas/s12z/bit-manip.s: New file. * testsuite/gas/s12z/bit.d: New file. * testsuite/gas/s12z/bit.s: New file. * testsuite/gas/s12z/bra-expression-defined.d: New file. * testsuite/gas/s12z/bra-expression-defined.s: New file. * testsuite/gas/s12z/bra-expression-undef.d: New file. * testsuite/gas/s12z/bra-expression-undef.s: New file. * testsuite/gas/s12z/bra.d: New file. * testsuite/gas/s12z/bra.s: New file. * testsuite/gas/s12z/brclr-symbols.d: New file. * testsuite/gas/s12z/brclr-symbols.s: New file. * testsuite/gas/s12z/brset-clr-opr-imm-rel.d: New file. * testsuite/gas/s12z/brset-clr-opr-imm-rel.s: New file. * testsuite/gas/s12z/brset-clr-opr-reg-rel.d: New file. * testsuite/gas/s12z/brset-clr-opr-reg-rel.s: New file. * testsuite/gas/s12z/brset-clr-reg-imm-rel.d: New file. * testsuite/gas/s12z/brset-clr-reg-imm-rel.s: New file. * testsuite/gas/s12z/brset-clr-reg-reg-rel.d: New file. * testsuite/gas/s12z/brset-clr-reg-reg-rel.s: New file. * testsuite/gas/s12z/clb.d: New file. * testsuite/gas/s12z/clb.s: New file. * testsuite/gas/s12z/clr-opr.d: New file. * testsuite/gas/s12z/clr-opr.s: New file. * testsuite/gas/s12z/clr.d: New file. * testsuite/gas/s12z/clr.s: New file. * testsuite/gas/s12z/cmp-imm.d: New file. * testsuite/gas/s12z/cmp-imm.s: New file. * testsuite/gas/s12z/cmp-opr-inc.d: New file. * testsuite/gas/s12z/cmp-opr-inc.s: New file. * testsuite/gas/s12z/cmp-opr-rdirect.d: New file. * testsuite/gas/s12z/cmp-opr-rdirect.s: New file. * testsuite/gas/s12z/cmp-opr-reg.d: New file. * testsuite/gas/s12z/cmp-opr-reg.s: New file. * testsuite/gas/s12z/cmp-opr-rindirect.d: New file. * testsuite/gas/s12z/cmp-opr-rindirect.s: New file. * testsuite/gas/s12z/cmp-opr-sxe4.d: New file. * testsuite/gas/s12z/cmp-opr-sxe4.s: New file. * testsuite/gas/s12z/cmp-opr-xys.d: New file. * testsuite/gas/s12z/cmp-opr-xys.s: New file. * testsuite/gas/s12z/cmp-s-imm.d: New file. * testsuite/gas/s12z/cmp-s-imm.s: New file. * testsuite/gas/s12z/cmp-s-opr.d: New file. * testsuite/gas/s12z/cmp-s-opr.s: New file. * testsuite/gas/s12z/cmp-xy.d: New file. * testsuite/gas/s12z/cmp-xy.s: New file. * testsuite/gas/s12z/com-opr.d: New file. * testsuite/gas/s12z/com-opr.s: New file. * testsuite/gas/s12z/complex-shifts.d: New file. * testsuite/gas/s12z/complex-shifts.s: New file. * testsuite/gas/s12z/db-tb-cc-opr.d: New file. * testsuite/gas/s12z/db-tb-cc-opr.s: New file. * testsuite/gas/s12z/db-tb-cc-reg.d: New file. * testsuite/gas/s12z/db-tb-cc-reg.s: New file. * testsuite/gas/s12z/dbCC.d: New file. * testsuite/gas/s12z/dbCC.s: New file. * testsuite/gas/s12z/dec-opr.d: New file. * testsuite/gas/s12z/dec-opr.s: New file. * testsuite/gas/s12z/dec.d: New file. * testsuite/gas/s12z/dec.s: New file. * testsuite/gas/s12z/div.d: New file. * testsuite/gas/s12z/div.s: New file. * testsuite/gas/s12z/eor.d: New file. * testsuite/gas/s12z/eor.s: New file. * testsuite/gas/s12z/exg.d: New file. * testsuite/gas/s12z/exg.s: New file. * testsuite/gas/s12z/ext24-ld-xy.d: New file. * testsuite/gas/s12z/ext24-ld-xy.s: New file. * testsuite/gas/s12z/inc-opr.d: New file. * testsuite/gas/s12z/inc-opr.s: New file. * testsuite/gas/s12z/inc.d: New file. * testsuite/gas/s12z/inc.s: New file. * testsuite/gas/s12z/inh.d: New file. * testsuite/gas/s12z/inh.s: New file. * testsuite/gas/s12z/jmp.d: New file. * testsuite/gas/s12z/jmp.s: New file. * testsuite/gas/s12z/jsr.d: New file. * testsuite/gas/s12z/jsr.s: New file. * testsuite/gas/s12z/ld-imm-page2.d: New file. * testsuite/gas/s12z/ld-imm-page2.s: New file. * testsuite/gas/s12z/ld-imm.d: New file. * testsuite/gas/s12z/ld-imm.s: New file. * testsuite/gas/s12z/ld-immu18.d: New file. * testsuite/gas/s12z/ld-immu18.s: New file. * testsuite/gas/s12z/ld-large-direct.d: New file. * testsuite/gas/s12z/ld-large-direct.s: New file. * testsuite/gas/s12z/ld-opr.d: New file. * testsuite/gas/s12z/ld-opr.s: New file. * testsuite/gas/s12z/ld-s-opr.d: New file. * testsuite/gas/s12z/ld-s-opr.s: New file. * testsuite/gas/s12z/ld-small-direct.d: New file. * testsuite/gas/s12z/ld-small-direct.s: New file. * testsuite/gas/s12z/lea-immu18.d: New file. * testsuite/gas/s12z/lea-immu18.s: New file. * testsuite/gas/s12z/lea.d: New file. * testsuite/gas/s12z/lea.s: New file. * testsuite/gas/s12z/mac.d: New file. * testsuite/gas/s12z/mac.s: New file. * testsuite/gas/s12z/min-max.d: New file. * testsuite/gas/s12z/min-max.s: New file. * testsuite/gas/s12z/mod.d: New file. * testsuite/gas/s12z/mod.s: New file. * testsuite/gas/s12z/mov.d: New file. * testsuite/gas/s12z/mov.s: New file. * testsuite/gas/s12z/mul-imm.d: New file. * testsuite/gas/s12z/mul-imm.s: New file. * testsuite/gas/s12z/mul-opr-opr.d: New file. * testsuite/gas/s12z/mul-opr-opr.s: New file. * testsuite/gas/s12z/mul-opr.d: New file. * testsuite/gas/s12z/mul-opr.s: New file. * testsuite/gas/s12z/mul-reg.d: New file. * testsuite/gas/s12z/mul-reg.s: New file. * testsuite/gas/s12z/mul.d: New file. * testsuite/gas/s12z/mul.s: New file. * testsuite/gas/s12z/neg-opr.d: New file. * testsuite/gas/s12z/neg-opr.s: New file. * testsuite/gas/s12z/not-so-simple-shifts.d: New file. * testsuite/gas/s12z/not-so-simple-shifts.s: New file. * testsuite/gas/s12z/opr-18u.d: New file. * testsuite/gas/s12z/opr-18u.s: New file. * testsuite/gas/s12z/opr-expr.d: New file. * testsuite/gas/s12z/opr-expr.s: New file. * testsuite/gas/s12z/opr-ext-18.d: New file. * testsuite/gas/s12z/opr-ext-18.s: New file. * testsuite/gas/s12z/opr-idx-24-reg.d: New file. * testsuite/gas/s12z/opr-idx-24-reg.s: New file. * testsuite/gas/s12z/opr-idx3-reg.d: New file. * testsuite/gas/s12z/opr-idx3-reg.s: New file. * testsuite/gas/s12z/opr-idx3-xysp-24.d: New file. * testsuite/gas/s12z/opr-idx3-xysp-24.s: New file. * testsuite/gas/s12z/opr-indirect-expr.d: New file. * testsuite/gas/s12z/opr-indirect-expr.s: New file. * testsuite/gas/s12z/opr-symbol.d: New file. * testsuite/gas/s12z/opr-symbol.s: New file. * testsuite/gas/s12z/or-imm.d: New file. * testsuite/gas/s12z/or-imm.s: New file. * testsuite/gas/s12z/or-opr.d: New file. * testsuite/gas/s12z/or-opr.s: New file. * testsuite/gas/s12z/p2-mul.d: New file. * testsuite/gas/s12z/p2-mul.s: New file. * testsuite/gas/s12z/page2-inh.d: New file. * testsuite/gas/s12z/page2-inh.s: New file. * testsuite/gas/s12z/psh-pul.d: New file. * testsuite/gas/s12z/psh-pul.s: New file. * testsuite/gas/s12z/qmul.d: New file. * testsuite/gas/s12z/qmul.s: New file. * testsuite/gas/s12z/rotate.d: New file. * testsuite/gas/s12z/rotate.s: New file. * testsuite/gas/s12z/s12z.exp: New file. * testsuite/gas/s12z/sat.d: New file. * testsuite/gas/s12z/sat.s: New file. * testsuite/gas/s12z/sbc-imm.d: New file. * testsuite/gas/s12z/sbc-imm.s: New file. * testsuite/gas/s12z/sbc-opr.d: New file. * testsuite/gas/s12z/sbc-opr.s: New file. * testsuite/gas/s12z/shift.d: New file. * testsuite/gas/s12z/shift.s: New file. * testsuite/gas/s12z/simple-shift.d: New file. * testsuite/gas/s12z/simple-shift.s: New file. * testsuite/gas/s12z/single-ops.d: New file. * testsuite/gas/s12z/single-ops.s: New file. * testsuite/gas/s12z/specd6.d: New file. * testsuite/gas/s12z/specd6.s: New file. * testsuite/gas/s12z/st-large-direct.d: New file. * testsuite/gas/s12z/st-large-direct.s: New file. * testsuite/gas/s12z/st-opr.d: New file. * testsuite/gas/s12z/st-opr.s: New file. * testsuite/gas/s12z/st-s-opr.d: New file. * testsuite/gas/s12z/st-s-opr.s: New file. * testsuite/gas/s12z/st-small-direct.d: New file. * testsuite/gas/s12z/st-small-direct.s: New file. * testsuite/gas/s12z/st-xy.d: New file. * testsuite/gas/s12z/st-xy.s: New file. * testsuite/gas/s12z/sub-imm.d: New file. * testsuite/gas/s12z/sub-imm.s: New file. * testsuite/gas/s12z/sub-opr.d: New file. * testsuite/gas/s12z/sub-opr.s: New file. * testsuite/gas/s12z/tfr.d: New file. * testsuite/gas/s12z/tfr.s: New file. * testsuite/gas/s12z/trap.d: New file. * testsuite/gas/s12z/trap.s: New file. binutils* readelf.c: Add support for s12z architecture. * testsuite/lib/binutils-common.exp (is_elf_format): Excluse s12z targets. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a9248e64d50..0319fa7f6db 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,22 @@ +2018-05-18 John Darrington + + * Makefile.am: Add s12z files. + * Makefile.in: Regenerate. + * archures.c: Add bfd_s12z_arch. + * bfd-in.h: Add exports of bfd_putb24 and bfd_putl24. + * bfd-in2.h: Regenerate. + * config.bfd: Add s12z target. + * configure.ac: Add s12z target. + * configure: Regenerate. + * cpu-s12z.c: New file. + * elf32-s12z.c: New file. + * libbfd.c (bfd_putb24): New function. + (bfd_putl24): New function. + * libbfd.h: Regenerate. + * reloc.c: Add s12z relocations. + (bfd_get_reloc_size): Handle size 5 relocs. + * targets.c: Add s12z_elf32_vec. + 2018-05-18 H.J. Lu PR ld/23189 diff --git a/bfd/Makefile.am b/bfd/Makefile.am index 8500a4fa74a..8374bbda209 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -123,6 +123,7 @@ ALL_MACHINES = \ cpu-m68hc11.lo \ cpu-m68hc12.lo \ cpu-m9s12x.lo \ + cpu-s12z.lo \ cpu-m9s12xg.lo \ cpu-m68k.lo \ cpu-mcore.lo \ @@ -207,6 +208,7 @@ ALL_MACHINES_CFILES = \ cpu-m68hc11.c \ cpu-m68hc12.c \ cpu-m9s12x.c \ + cpu-s12z.c \ cpu-m9s12xg.c \ cpu-m68k.c \ cpu-mcore.c \ @@ -322,6 +324,7 @@ BFD32_BACKENDS = \ elf32-m68hc12.lo \ elf32-m68hc1x.lo \ elf32-m68k.lo \ + elf32-s12z.lo \ elf32-mcore.lo \ elf32-mep.lo \ elf32-metag.lo \ @@ -458,6 +461,7 @@ BFD32_BACKENDS_CFILES = \ elf32-m68hc12.c \ elf32-m68hc1x.c \ elf32-m68k.c \ + elf32-s12z.c \ elf32-mcore.c \ elf32-mep.c \ elf32-metag.c \ diff --git a/bfd/Makefile.in b/bfd/Makefile.in index ccd9ce1201b..88b6b8ebd56 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -456,6 +456,7 @@ ALL_MACHINES = \ cpu-m68hc11.lo \ cpu-m68hc12.lo \ cpu-m9s12x.lo \ + cpu-s12z.lo \ cpu-m9s12xg.lo \ cpu-m68k.lo \ cpu-mcore.lo \ @@ -540,6 +541,7 @@ ALL_MACHINES_CFILES = \ cpu-m68hc11.c \ cpu-m68hc12.c \ cpu-m9s12x.c \ + cpu-s12z.c \ cpu-m9s12xg.c \ cpu-m68k.c \ cpu-mcore.c \ @@ -656,6 +658,7 @@ BFD32_BACKENDS = \ elf32-m68hc12.lo \ elf32-m68hc1x.lo \ elf32-m68k.lo \ + elf32-s12z.lo \ elf32-mcore.lo \ elf32-mep.lo \ elf32-metag.lo \ @@ -792,6 +795,7 @@ BFD32_BACKENDS_CFILES = \ elf32-m68hc12.c \ elf32-m68hc1x.c \ elf32-m68k.c \ + elf32-s12z.c \ elf32-mcore.c \ elf32-mep.c \ elf32-metag.c \ @@ -1253,6 +1257,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m68k.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m9s12x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m9s12xg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-s12z.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-mcore.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-mep.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-metag.Plo@am__quote@ @@ -1344,6 +1349,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-m68hc12.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-m68hc1x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-m68k.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-s12z.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-mcore.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-mep.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-metag.Plo@am__quote@ diff --git a/bfd/archures.c b/bfd/archures.c index 4c206642571..3af7ddd19a2 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -281,6 +281,8 @@ DESCRIPTION .#define bfd_mach_m6812s 2 . bfd_arch_m9s12x, {* Freescale S12X. *} . bfd_arch_m9s12xg, {* Freescale XGATE. *} +. bfd_arch_s12z, {* Freescale S12Z. *} +.#define bfd_mach_s12z_default 0 . bfd_arch_z8k, {* Zilog Z8000. *} .#define bfd_mach_z8001 1 .#define bfd_mach_z8002 2 @@ -590,6 +592,7 @@ extern const bfd_arch_info_type bfd_m68hc11_arch; extern const bfd_arch_info_type bfd_m68hc12_arch; extern const bfd_arch_info_type bfd_m9s12x_arch; extern const bfd_arch_info_type bfd_m9s12xg_arch; +extern const bfd_arch_info_type bfd_s12z_arch; extern const bfd_arch_info_type bfd_m68k_arch; extern const bfd_arch_info_type bfd_mcore_arch; extern const bfd_arch_info_type bfd_mep_arch; @@ -679,6 +682,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] = &bfd_m68hc12_arch, &bfd_m9s12x_arch, &bfd_m9s12xg_arch, + &bfd_s12z_arch, &bfd_m68k_arch, &bfd_mcore_arch, &bfd_mep_arch, diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 50a8b52e96f..481587e458f 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -581,6 +581,8 @@ void bfd_putb64 (bfd_uint64_t, void *); void bfd_putl64 (bfd_uint64_t, void *); void bfd_putb32 (bfd_vma, void *); void bfd_putl32 (bfd_vma, void *); +void bfd_putb24 (bfd_vma, void *); +void bfd_putl24 (bfd_vma, void *); void bfd_putb16 (bfd_vma, void *); void bfd_putl16 (bfd_vma, void *); diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 5f7ecd35dba..c64eee1fe1e 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -588,6 +588,8 @@ void bfd_putb64 (bfd_uint64_t, void *); void bfd_putl64 (bfd_uint64_t, void *); void bfd_putb32 (bfd_vma, void *); void bfd_putl32 (bfd_vma, void *); +void bfd_putb24 (bfd_vma, void *); +void bfd_putl24 (bfd_vma, void *); void bfd_putb16 (bfd_vma, void *); void bfd_putl16 (bfd_vma, void *); @@ -2149,6 +2151,8 @@ enum bfd_architecture #define bfd_mach_m6812s 2 bfd_arch_m9s12x, /* Freescale S12X. */ bfd_arch_m9s12xg, /* Freescale XGATE. */ + bfd_arch_s12z, /* Freescale S12Z. */ +#define bfd_mach_s12z_default 0 bfd_arch_z8k, /* Zilog Z8000. */ #define bfd_mach_z8001 1 #define bfd_mach_z8002 2 @@ -5253,6 +5257,11 @@ This is the 8 bit high part of an absolute address and immediately follows a matching LO8XG part. */ BFD_RELOC_M68HC12_HI8XG, +/* Freescale S12Z reloc. +This is a 15 bit relative address. If the most significant bits are all zero +then it may be truncated to 8 bits. */ + BFD_RELOC_S12Z_15_PCREL, + /* NS CR16C Relocations. */ BFD_RELOC_16C_NUM08, BFD_RELOC_16C_NUM08_C, diff --git a/bfd/config.bfd b/bfd/config.bfd index bbd41941539..0db8ed4562b 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -179,6 +179,7 @@ lm32) targ_archs=bfd_lm32_arch ;; m6811*|m68hc11*) targ_archs="bfd_m68hc11_arch bfd_m68hc12_arch bfd_m9s12x_arch bfd_m9s12xg_arch" ;; m6812*|m68hc12*) targ_archs="bfd_m68hc12_arch bfd_m68hc11_arch bfd_m9s12x_arch bfd_m9s12xg_arch" ;; m68*) targ_archs=bfd_m68k_arch ;; +s12z*) targ_archs=bfd_s12z_arch ;; microblaze*) targ_archs=bfd_microblaze_arch ;; mips*) targ_archs=bfd_mips_arch ;; nds32*) targ_archs=bfd_nds32_arch ;; @@ -814,6 +815,9 @@ case "${targ}" in targ_defvec=m68k_elf32_vec ;; + s12z-*-*) + targ_defvec=s12z_elf32_vec + ;; mcore-*-elf) targ_defvec=mcore_elf32_be_vec targ_selvecs="mcore_elf32_be_vec mcore_elf32_le_vec" diff --git a/bfd/configure b/bfd/configure index edc1de9bced..2f3dbe7de3b 100755 --- a/bfd/configure +++ b/bfd/configure @@ -14465,6 +14465,7 @@ do m68hc11_elf32_vec) tb="$tb elf32-m68hc11.lo elf32-m68hc1x.lo elf32.lo $elf" ;; m68hc12_elf32_vec) tb="$tb elf32-m68hc12.lo elf32-m68hc1x.lo elf32.lo $elf" ;; m68k_elf32_vec) tb="$tb elf32-m68k.lo elf32.lo $elf" ;; + s12z_elf32_vec) tb="$tb elf32-s12z.lo elf32.lo $elf" ;; mach_o_be_vec) tb="$tb mach-o.lo dwarf2.lo" ;; mach_o_le_vec) tb="$tb mach-o.lo dwarf2.lo" ;; mach_o_fat_vec) tb="$tb mach-o.lo dwarf2.lo" ;; diff --git a/bfd/configure.ac b/bfd/configure.ac index 12974691ad0..b320828fbb2 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -520,6 +520,7 @@ do m68hc11_elf32_vec) tb="$tb elf32-m68hc11.lo elf32-m68hc1x.lo elf32.lo $elf" ;; m68hc12_elf32_vec) tb="$tb elf32-m68hc12.lo elf32-m68hc1x.lo elf32.lo $elf" ;; m68k_elf32_vec) tb="$tb elf32-m68k.lo elf32.lo $elf" ;; + s12z_elf32_vec) tb="$tb elf32-s12z.lo elf32.lo $elf" ;; mach_o_be_vec) tb="$tb mach-o.lo dwarf2.lo" ;; mach_o_le_vec) tb="$tb mach-o.lo dwarf2.lo" ;; mach_o_fat_vec) tb="$tb mach-o.lo dwarf2.lo" ;; diff --git a/bfd/cpu-s12z.c b/bfd/cpu-s12z.c new file mode 100644 index 00000000000..07bcb49a696 --- /dev/null +++ b/bfd/cpu-s12z.c @@ -0,0 +1,41 @@ +/* BFD support for the Freescale 9S12Z processor + Copyright (C) 2008-2018 Free Software Foundation, Inc. + + 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" + +const bfd_arch_info_type bfd_s12z_arch = +{ + 16, /* 16 bits in a word. */ + 24, /* 24 bits in an address. */ + 8, /* 8 bits in a byte. */ + bfd_arch_s12z, + 0, + "s12z", + "s12z", + 4, /* Section alignment power. */ + TRUE, + bfd_default_compatible, + bfd_default_scan, + bfd_arch_default_fill, + 0, +}; + diff --git a/bfd/elf32-s12z.c b/bfd/elf32-s12z.c new file mode 100644 index 00000000000..4b638e635cd --- /dev/null +++ b/bfd/elf32-s12z.c @@ -0,0 +1,270 @@ +/* Freescale S12Z-specific support for 32-bit ELF + Copyright (C) 1999-2018 Free Software Foundation, Inc. + (Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" +#include "bfdlink.h" +#include "libbfd.h" +#include "elf-bfd.h" + +#include "elf/s12z.h" + +/* Relocation functions. */ +static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup + (bfd *, bfd_reloc_code_real_type); +static bfd_boolean s12z_info_to_howto_rel + (bfd *, arelent *, Elf_Internal_Rela *); + +static bfd_reloc_status_type +shift_addend_reloc (bfd *abfd, arelent *reloc_entry, struct bfd_symbol *symbol ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED, asection *input_section ATTRIBUTE_UNUSED, + bfd *output ATTRIBUTE_UNUSED, char **msg ATTRIBUTE_UNUSED) +{ + /* This is a really peculiar reloc, which is done for compatibility + with the Freescale toolchain. + + That toolchain appears to (ab)use the lowest 15 bits of the addend for + the purpose of holding flags. The purpose of these flags are unknown. + So in this function, when writing the bfd we left shift the addend by + 15, and when reading we right shift it by 15 (discarding the lower bits). + + This allows the linker to work with object files generated by Freescale, + as well as by Gas. */ + + if (abfd->is_linker_input) + reloc_entry->addend >>= 15; + else + reloc_entry->addend <<= 15; + + return bfd_reloc_continue; +} + +#define USE_REL 0 + +static reloc_howto_type elf_s12z_howto_table[] = +{ + /* This reloc does nothing. */ + HOWTO (R_S12Z_NONE, /* type */ + 0, /* rightshift */ + 3, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_S12Z_NONE", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A 24 bit absolute relocation emitted by the OPR mode operands */ + HOWTO (R_S12Z_OPR, /* type */ + 0, /* rightshift */ + 5, /* size (0 = byte, 1 = short, 2 = long) */ + 24, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + shift_addend_reloc, + "R_S12Z_OPR", /* name */ + FALSE, /* partial_inplace */ + 0x00ffffff, /* src_mask */ + 0x00ffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* The purpose of this reloc is not known */ + HOWTO (R_S12Z_UKNWN_2, /* type */ + 0, /* rightshift */ + 3, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_S12Z_UKNWN_2", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A 15 bit PC-rel relocation */ + HOWTO (R_S12Z_PCREL_7_15, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 15, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + shift_addend_reloc, + "R_S12Z_PCREL_7_15", /* name */ + FALSE, /* partial_inplace */ + 0x00, /* src_mask */ + 0x007fff, /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* A 24 bit absolute relocation emitted by EXT24 mode operands */ + HOWTO (R_S12Z_EXT24, /* type */ + 0, /* rightshift */ + 5, /* size (0 = byte, 1 = short, 2 = long) */ + 24, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_S12Z_EXT24", /* name */ + FALSE, /* partial_inplace */ + 0x00ffffff, /* src_mask */ + 0x00ffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* The purpose of this reloc is not known */ + HOWTO (R_S12Z_UKNWN_3, /* type */ + 0, /* rightshift */ + 3, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_S12Z_UKNWN_3", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A 32 bit absolute relocation */ + HOWTO (R_S12Z_EXT32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_S12Z_EXT32", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ +}; + +/* Map BFD reloc types to S12Z ELF reloc types. */ + +struct s12z_reloc_map +{ + bfd_reloc_code_real_type bfd_reloc_val; + unsigned char elf_reloc_val; +}; + +static const struct s12z_reloc_map s12z_reloc_map[] = +{ + /* bfd reloc val */ /* elf reloc val */ + {BFD_RELOC_NONE, R_S12Z_NONE}, + {BFD_RELOC_32, R_S12Z_EXT32}, + {BFD_RELOC_24, R_S12Z_EXT24}, + {BFD_RELOC_16_PCREL, R_S12Z_PCREL_7_15} +}; + +static reloc_howto_type * +bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) +{ + unsigned int i; + + for (i = 0; + i < sizeof (s12z_reloc_map) / sizeof (struct s12z_reloc_map); + i++) + { + if (s12z_reloc_map[i].bfd_reloc_val == code) + { + return &elf_s12z_howto_table[s12z_reloc_map[i].elf_reloc_val]; + } + } + + printf ("%s:%d Not found type %d\n", __FILE__, __LINE__, code); + + return NULL; +} + +static reloc_howto_type * +bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + printf ("%s:%d Looking up %s\n", __FILE__, __LINE__, r_name); + + for (i = 0; + i < (sizeof (elf_s12z_howto_table) + / sizeof (elf_s12z_howto_table[0])); + i++) + if (elf_s12z_howto_table[i].name != NULL + && strcasecmp (elf_s12z_howto_table[i].name, r_name) == 0) + return &elf_s12z_howto_table[i]; + + return NULL; +} + +/* Set the howto pointer for an S12Z ELF reloc. */ + +static bfd_boolean +s12z_info_to_howto_rel (bfd *abfd, + arelent *cache_ptr, Elf_Internal_Rela *dst) +{ + unsigned int r_type = ELF32_R_TYPE (dst->r_info); + + if (r_type >= (unsigned int) R_S12Z_max) + { + /* xgettext:c-format */ + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), + abfd, r_type); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + + cache_ptr->howto = &elf_s12z_howto_table[r_type]; + return TRUE; +} + +static bfd_boolean +s12z_elf_set_mach_from_flags (bfd *abfd) +{ + bfd_default_set_arch_mach (abfd, bfd_arch_s12z, 0); // bfd_mach_s12z); + + return TRUE; +} + +#define ELF_ARCH bfd_arch_s12z +#define ELF_TARGET_ID 0 +#define ELF_MACHINE_CODE EM_S12Z +#define ELF_MAXPAGESIZE 0x1000 + +#define TARGET_BIG_SYM s12z_elf32_vec +#define TARGET_BIG_NAME "elf32-s12z" + +#define elf_info_to_howto NULL +#define elf_info_to_howto_rel s12z_info_to_howto_rel +#define elf_backend_object_p s12z_elf_set_mach_from_flags +#define elf_backend_final_write_processing NULL +#define elf_backend_can_gc_sections 1 + +#include "elf32-target.h" diff --git a/bfd/libbfd.c b/bfd/libbfd.c index c581238515c..971be4f3dec 100644 --- a/bfd/libbfd.c +++ b/bfd/libbfd.c @@ -613,6 +613,27 @@ bfd_putl16 (bfd_vma data, void *p) addr[1] = (data >> 8) & 0xff; } + +void +bfd_putb24 (bfd_vma data, void *p) +{ + bfd_byte *addr = (bfd_byte *) p; + addr[0] = (data >> 16) & 0xff; + addr[1] = (data >> 8) & 0xff; + addr[2] = data & 0xff; +} + + +void +bfd_putl24 (bfd_vma data, void *p) +{ + bfd_byte *addr = (bfd_byte *) p; + addr[0] = data & 0xff; + addr[1] = (data >> 8) & 0xff; + addr[2] = (data >> 16) & 0xff; +} + + bfd_vma bfd_getb32 (const void *p) { diff --git a/bfd/libbfd.h b/bfd/libbfd.h index e8c0fd86755..b810c40c405 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -2513,6 +2513,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_M68HC12_10_PCREL", "BFD_RELOC_M68HC12_LO8XG", "BFD_RELOC_M68HC12_HI8XG", + "BFD_RELOC_S12Z_15_PCREL", "BFD_RELOC_16C_NUM08", "BFD_RELOC_16C_NUM08_C", "BFD_RELOC_16C_NUM16", diff --git a/bfd/reloc.c b/bfd/reloc.c index f7e34a993ae..411f998f540 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -431,6 +431,7 @@ bfd_get_reloc_size (reloc_howto_type *howto) { switch (howto->size) { + case 5: return 3; case 0: return 1; case 1: return 2; case 2: return 4; @@ -917,6 +918,16 @@ space consuming. For each target: switch (howto->size) { + case 5: + { + long x = bfd_get_32 (abfd, (bfd_byte *) data + octets); + x >>= 8; + DOIT (x); + bfd_put_16 (abfd, (bfd_vma) (x >> 8), (bfd_byte *) data + octets); + bfd_put_8 (abfd, (x & 0xFF), (unsigned char *) data + 2 + octets); + } + break; + case 0: { char x = bfd_get_8 (abfd, (char *) data + octets); @@ -5948,6 +5959,12 @@ ENUMDOC Motorola 68HC12/XGATE reloc. This is the 8 bit high part of an absolute address and immediately follows a matching LO8XG part. +ENUM + BFD_RELOC_S12Z_15_PCREL +ENUMDOC + Freescale S12Z reloc. + This is a 15 bit relative address. If the most significant bits are all zero + then it may be truncated to 8 bits. ENUM BFD_RELOC_16C_NUM08 ENUMX diff --git a/bfd/targets.c b/bfd/targets.c index 5d78f574512..5a2a684bc82 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -684,6 +684,7 @@ extern const bfd_target m32r_elf32_linux_le_vec; extern const bfd_target m68hc11_elf32_vec; extern const bfd_target m68hc12_elf32_vec; extern const bfd_target m68k_elf32_vec; +extern const bfd_target s12z_elf32_vec; extern const bfd_target mach_o_be_vec; extern const bfd_target mach_o_le_vec; extern const bfd_target mach_o_fat_vec; @@ -1044,6 +1045,8 @@ static const bfd_target * const _bfd_target_vector[] = &m68k_elf32_vec, + &s12z_elf32_vec, + &mach_o_be_vec, &mach_o_le_vec, &mach_o_fat_vec, diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 3d90103aba0..fd77f44fbea 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2018-05-18 John Darrington + + * readelf.c: Add support for s12z architecture. + * testsuite/lib/binutils-common.exp (is_elf_format): Excluse s12z + targets. + 2018-05-15 Tamar Christina PR binutils/21446 diff --git a/binutils/readelf.c b/binutils/readelf.c index 6a9c51d4bb7..6a9319f5dbf 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -119,6 +119,7 @@ #include "elf/m32r.h" #include "elf/m68k.h" #include "elf/m68hc11.h" +#include "elf/s12z.h" #include "elf/mcore.h" #include "elf/mep.h" #include "elf/metag.h" @@ -1274,6 +1275,10 @@ dump_relocations (Filedata * filedata, rtype = elf_m68hc11_reloc_type (type); break; + case EM_S12Z: + rtype = elf_s12z_reloc_type (type); + break; + case EM_68K: rtype = elf_m68k_reloc_type (type); break; @@ -12309,6 +12314,8 @@ is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type) case EM_68HC11: case EM_68HC12: return reloc_type == 6; /* R_M68HC11_32. */ + case EM_S12Z: + return reloc_type == 6; /* R_S12Z_EXT32. */ case EM_MCORE: return reloc_type == 1; /* R_MCORE_ADDR32. */ case EM_CYGNUS_MEP: diff --git a/binutils/testsuite/binutils-all/dw2-1.S b/binutils/testsuite/binutils-all/dw2-1.S index 06cb593a2e2..6342a0e8f83 100644 --- a/binutils/testsuite/binutils-all/dw2-1.S +++ b/binutils/testsuite/binutils-all/dw2-1.S @@ -27,6 +27,8 @@ _start: func_cu1: .Lbegin_func_cu1: .4byte 0 + .global func_cu1_end +func_cu1_end: .Lend_func_cu1: .size func_cu1, .-func_cu1 .Lend_text1: diff --git a/binutils/testsuite/lib/binutils-common.exp b/binutils/testsuite/lib/binutils-common.exp index 9fc9a18dae2..dcaab847d24 100644 --- a/binutils/testsuite/lib/binutils-common.exp +++ b/binutils/testsuite/lib/binutils-common.exp @@ -23,7 +23,7 @@ proc is_elf_format {} { # config.sub for these targets curiously transforms a target doublet # ending in -elf to -none. eg. m68hc12-elf to m68hc12-unknown-none # They are always elf. - if { [istarget m68hc1*-*] || [istarget xgate-*] } { + if { [istarget m68hc1*-*] || [istarget s12z*-*] || [istarget xgate-*] } { return 1; } # vxworks (and windiss) excluded due to number of ELF tests that need diff --git a/gas/ChangeLog b/gas/ChangeLog index c2a5659143b..39c51b23a06 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,219 @@ +2018-05-18 John Darrington + + * Makefile.am: Add support for s12z target. + * Makefile.in: Regenerate. + * NEWS: Mention the new support. + * config/tc-s12z.c: New file. + * config/tc-s12z.h: New file. + * configure.tgt: Add s12z support. + * doc/Makefile.am: Likewise. + * doc/Makefile.in: Regenerate. + * doc/all.texi: Add s12z documentation. + * doc/as.textinfo: Likewise. + * doc/c-s12z.texi: New file. + * testsuite/gas/s12z: New directory. + * testsuite/gas/s12z/abs.d: New file. + * testsuite/gas/s12z/abs.s: New file. + * testsuite/gas/s12z/adc-imm.d: New file. + * testsuite/gas/s12z/adc-imm.s: New file. + * testsuite/gas/s12z/adc-opr.d: New file. + * testsuite/gas/s12z/adc-opr.s: New file. + * testsuite/gas/s12z/add-imm.d: New file. + * testsuite/gas/s12z/add-imm.s: New file. + * testsuite/gas/s12z/add-opr.d: New file. + * testsuite/gas/s12z/add-opr.s: New file. + * testsuite/gas/s12z/and-imm.d: New file. + * testsuite/gas/s12z/and-imm.s: New file. + * testsuite/gas/s12z/and-opr.d: New file. + * testsuite/gas/s12z/and-opr.s: New file. + * testsuite/gas/s12z/and-or-cc.d: New file. + * testsuite/gas/s12z/and-or-cc.s: New file. + * testsuite/gas/s12z/bfext-special.d: New file. + * testsuite/gas/s12z/bfext-special.s: New file. + * testsuite/gas/s12z/bfext.d: New file. + * testsuite/gas/s12z/bfext.s: New file. + * testsuite/gas/s12z/bit-manip.d: New file. + * testsuite/gas/s12z/bit-manip.s: New file. + * testsuite/gas/s12z/bit.d: New file. + * testsuite/gas/s12z/bit.s: New file. + * testsuite/gas/s12z/bra-expression-defined.d: New file. + * testsuite/gas/s12z/bra-expression-defined.s: New file. + * testsuite/gas/s12z/bra-expression-undef.d: New file. + * testsuite/gas/s12z/bra-expression-undef.s: New file. + * testsuite/gas/s12z/bra.d: New file. + * testsuite/gas/s12z/bra.s: New file. + * testsuite/gas/s12z/brclr-symbols.d: New file. + * testsuite/gas/s12z/brclr-symbols.s: New file. + * testsuite/gas/s12z/brset-clr-opr-imm-rel.d: New file. + * testsuite/gas/s12z/brset-clr-opr-imm-rel.s: New file. + * testsuite/gas/s12z/brset-clr-opr-reg-rel.d: New file. + * testsuite/gas/s12z/brset-clr-opr-reg-rel.s: New file. + * testsuite/gas/s12z/brset-clr-reg-imm-rel.d: New file. + * testsuite/gas/s12z/brset-clr-reg-imm-rel.s: New file. + * testsuite/gas/s12z/brset-clr-reg-reg-rel.d: New file. + * testsuite/gas/s12z/brset-clr-reg-reg-rel.s: New file. + * testsuite/gas/s12z/clb.d: New file. + * testsuite/gas/s12z/clb.s: New file. + * testsuite/gas/s12z/clr-opr.d: New file. + * testsuite/gas/s12z/clr-opr.s: New file. + * testsuite/gas/s12z/clr.d: New file. + * testsuite/gas/s12z/clr.s: New file. + * testsuite/gas/s12z/cmp-imm.d: New file. + * testsuite/gas/s12z/cmp-imm.s: New file. + * testsuite/gas/s12z/cmp-opr-inc.d: New file. + * testsuite/gas/s12z/cmp-opr-inc.s: New file. + * testsuite/gas/s12z/cmp-opr-rdirect.d: New file. + * testsuite/gas/s12z/cmp-opr-rdirect.s: New file. + * testsuite/gas/s12z/cmp-opr-reg.d: New file. + * testsuite/gas/s12z/cmp-opr-reg.s: New file. + * testsuite/gas/s12z/cmp-opr-rindirect.d: New file. + * testsuite/gas/s12z/cmp-opr-rindirect.s: New file. + * testsuite/gas/s12z/cmp-opr-sxe4.d: New file. + * testsuite/gas/s12z/cmp-opr-sxe4.s: New file. + * testsuite/gas/s12z/cmp-opr-xys.d: New file. + * testsuite/gas/s12z/cmp-opr-xys.s: New file. + * testsuite/gas/s12z/cmp-s-imm.d: New file. + * testsuite/gas/s12z/cmp-s-imm.s: New file. + * testsuite/gas/s12z/cmp-s-opr.d: New file. + * testsuite/gas/s12z/cmp-s-opr.s: New file. + * testsuite/gas/s12z/cmp-xy.d: New file. + * testsuite/gas/s12z/cmp-xy.s: New file. + * testsuite/gas/s12z/com-opr.d: New file. + * testsuite/gas/s12z/com-opr.s: New file. + * testsuite/gas/s12z/complex-shifts.d: New file. + * testsuite/gas/s12z/complex-shifts.s: New file. + * testsuite/gas/s12z/db-tb-cc-opr.d: New file. + * testsuite/gas/s12z/db-tb-cc-opr.s: New file. + * testsuite/gas/s12z/db-tb-cc-reg.d: New file. + * testsuite/gas/s12z/db-tb-cc-reg.s: New file. + * testsuite/gas/s12z/dbCC.d: New file. + * testsuite/gas/s12z/dbCC.s: New file. + * testsuite/gas/s12z/dec-opr.d: New file. + * testsuite/gas/s12z/dec-opr.s: New file. + * testsuite/gas/s12z/dec.d: New file. + * testsuite/gas/s12z/dec.s: New file. + * testsuite/gas/s12z/div.d: New file. + * testsuite/gas/s12z/div.s: New file. + * testsuite/gas/s12z/eor.d: New file. + * testsuite/gas/s12z/eor.s: New file. + * testsuite/gas/s12z/exg.d: New file. + * testsuite/gas/s12z/exg.s: New file. + * testsuite/gas/s12z/ext24-ld-xy.d: New file. + * testsuite/gas/s12z/ext24-ld-xy.s: New file. + * testsuite/gas/s12z/inc-opr.d: New file. + * testsuite/gas/s12z/inc-opr.s: New file. + * testsuite/gas/s12z/inc.d: New file. + * testsuite/gas/s12z/inc.s: New file. + * testsuite/gas/s12z/inh.d: New file. + * testsuite/gas/s12z/inh.s: New file. + * testsuite/gas/s12z/jmp.d: New file. + * testsuite/gas/s12z/jmp.s: New file. + * testsuite/gas/s12z/jsr.d: New file. + * testsuite/gas/s12z/jsr.s: New file. + * testsuite/gas/s12z/ld-imm-page2.d: New file. + * testsuite/gas/s12z/ld-imm-page2.s: New file. + * testsuite/gas/s12z/ld-imm.d: New file. + * testsuite/gas/s12z/ld-imm.s: New file. + * testsuite/gas/s12z/ld-immu18.d: New file. + * testsuite/gas/s12z/ld-immu18.s: New file. + * testsuite/gas/s12z/ld-large-direct.d: New file. + * testsuite/gas/s12z/ld-large-direct.s: New file. + * testsuite/gas/s12z/ld-opr.d: New file. + * testsuite/gas/s12z/ld-opr.s: New file. + * testsuite/gas/s12z/ld-s-opr.d: New file. + * testsuite/gas/s12z/ld-s-opr.s: New file. + * testsuite/gas/s12z/ld-small-direct.d: New file. + * testsuite/gas/s12z/ld-small-direct.s: New file. + * testsuite/gas/s12z/lea-immu18.d: New file. + * testsuite/gas/s12z/lea-immu18.s: New file. + * testsuite/gas/s12z/lea.d: New file. + * testsuite/gas/s12z/lea.s: New file. + * testsuite/gas/s12z/mac.d: New file. + * testsuite/gas/s12z/mac.s: New file. + * testsuite/gas/s12z/min-max.d: New file. + * testsuite/gas/s12z/min-max.s: New file. + * testsuite/gas/s12z/mod.d: New file. + * testsuite/gas/s12z/mod.s: New file. + * testsuite/gas/s12z/mov.d: New file. + * testsuite/gas/s12z/mov.s: New file. + * testsuite/gas/s12z/mul-imm.d: New file. + * testsuite/gas/s12z/mul-imm.s: New file. + * testsuite/gas/s12z/mul-opr-opr.d: New file. + * testsuite/gas/s12z/mul-opr-opr.s: New file. + * testsuite/gas/s12z/mul-opr.d: New file. + * testsuite/gas/s12z/mul-opr.s: New file. + * testsuite/gas/s12z/mul-reg.d: New file. + * testsuite/gas/s12z/mul-reg.s: New file. + * testsuite/gas/s12z/mul.d: New file. + * testsuite/gas/s12z/mul.s: New file. + * testsuite/gas/s12z/neg-opr.d: New file. + * testsuite/gas/s12z/neg-opr.s: New file. + * testsuite/gas/s12z/not-so-simple-shifts.d: New file. + * testsuite/gas/s12z/not-so-simple-shifts.s: New file. + * testsuite/gas/s12z/opr-18u.d: New file. + * testsuite/gas/s12z/opr-18u.s: New file. + * testsuite/gas/s12z/opr-expr.d: New file. + * testsuite/gas/s12z/opr-expr.s: New file. + * testsuite/gas/s12z/opr-ext-18.d: New file. + * testsuite/gas/s12z/opr-ext-18.s: New file. + * testsuite/gas/s12z/opr-idx-24-reg.d: New file. + * testsuite/gas/s12z/opr-idx-24-reg.s: New file. + * testsuite/gas/s12z/opr-idx3-reg.d: New file. + * testsuite/gas/s12z/opr-idx3-reg.s: New file. + * testsuite/gas/s12z/opr-idx3-xysp-24.d: New file. + * testsuite/gas/s12z/opr-idx3-xysp-24.s: New file. + * testsuite/gas/s12z/opr-indirect-expr.d: New file. + * testsuite/gas/s12z/opr-indirect-expr.s: New file. + * testsuite/gas/s12z/opr-symbol.d: New file. + * testsuite/gas/s12z/opr-symbol.s: New file. + * testsuite/gas/s12z/or-imm.d: New file. + * testsuite/gas/s12z/or-imm.s: New file. + * testsuite/gas/s12z/or-opr.d: New file. + * testsuite/gas/s12z/or-opr.s: New file. + * testsuite/gas/s12z/p2-mul.d: New file. + * testsuite/gas/s12z/p2-mul.s: New file. + * testsuite/gas/s12z/page2-inh.d: New file. + * testsuite/gas/s12z/page2-inh.s: New file. + * testsuite/gas/s12z/psh-pul.d: New file. + * testsuite/gas/s12z/psh-pul.s: New file. + * testsuite/gas/s12z/qmul.d: New file. + * testsuite/gas/s12z/qmul.s: New file. + * testsuite/gas/s12z/rotate.d: New file. + * testsuite/gas/s12z/rotate.s: New file. + * testsuite/gas/s12z/s12z.exp: New file. + * testsuite/gas/s12z/sat.d: New file. + * testsuite/gas/s12z/sat.s: New file. + * testsuite/gas/s12z/sbc-imm.d: New file. + * testsuite/gas/s12z/sbc-imm.s: New file. + * testsuite/gas/s12z/sbc-opr.d: New file. + * testsuite/gas/s12z/sbc-opr.s: New file. + * testsuite/gas/s12z/shift.d: New file. + * testsuite/gas/s12z/shift.s: New file. + * testsuite/gas/s12z/simple-shift.d: New file. + * testsuite/gas/s12z/simple-shift.s: New file. + * testsuite/gas/s12z/single-ops.d: New file. + * testsuite/gas/s12z/single-ops.s: New file. + * testsuite/gas/s12z/specd6.d: New file. + * testsuite/gas/s12z/specd6.s: New file. + * testsuite/gas/s12z/st-large-direct.d: New file. + * testsuite/gas/s12z/st-large-direct.s: New file. + * testsuite/gas/s12z/st-opr.d: New file. + * testsuite/gas/s12z/st-opr.s: New file. + * testsuite/gas/s12z/st-s-opr.d: New file. + * testsuite/gas/s12z/st-s-opr.s: New file. + * testsuite/gas/s12z/st-small-direct.d: New file. + * testsuite/gas/s12z/st-small-direct.s: New file. + * testsuite/gas/s12z/st-xy.d: New file. + * testsuite/gas/s12z/st-xy.s: New file. + * testsuite/gas/s12z/sub-imm.d: New file. + * testsuite/gas/s12z/sub-imm.s: New file. + * testsuite/gas/s12z/sub-opr.d: New file. + * testsuite/gas/s12z/sub-opr.s: New file. + * testsuite/gas/s12z/tfr.d: New file. + * testsuite/gas/s12z/tfr.s: New file. + * testsuite/gas/s12z/trap.d: New file. + * testsuite/gas/s12z/trap.s: New file. + 2018-05-16 Maciej W. Rozycki * tc-nds32.c (md_assemble): Rename `expr' local variable to diff --git a/gas/Makefile.am b/gas/Makefile.am index 952377093d0..ff46b0dfefc 100644 --- a/gas/Makefile.am +++ b/gas/Makefile.am @@ -156,6 +156,7 @@ TARGET_CPU_CFILES = \ config/tc-m32r.c \ config/tc-m68hc11.c \ config/tc-m68k.c \ + config/tc-s12z.c \ config/tc-mcore.c \ config/tc-mep.c \ config/tc-metag.c \ @@ -229,6 +230,7 @@ TARGET_CPU_HFILES = \ config/tc-m32r.h \ config/tc-m68hc11.h \ config/tc-m68k.h \ + config/tc-s12z.h \ config/tc-mcore.h \ config/tc-mep.h \ config/tc-metag.h \ diff --git a/gas/Makefile.in b/gas/Makefile.in index 4feabb3432e..c127d3606f4 100644 --- a/gas/Makefile.in +++ b/gas/Makefile.in @@ -452,6 +452,7 @@ TARGET_CPU_CFILES = \ config/tc-m32r.c \ config/tc-m68hc11.c \ config/tc-m68k.c \ + config/tc-s12z.c \ config/tc-mcore.c \ config/tc-mep.c \ config/tc-metag.c \ @@ -525,6 +526,7 @@ TARGET_CPU_HFILES = \ config/tc-m32r.h \ config/tc-m68hc11.h \ config/tc-m68k.h \ + config/tc-s12z.h \ config/tc-mcore.h \ config/tc-mep.h \ config/tc-metag.h \ @@ -872,6 +874,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-m32r.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-m68hc11.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-m68k.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-s12z.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-mcore.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-mep.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-metag.Po@am__quote@ @@ -1318,6 +1321,20 @@ tc-m68k.obj: config/tc-m68k.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-m68k.obj `if test -f 'config/tc-m68k.c'; then $(CYGPATH_W) 'config/tc-m68k.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-m68k.c'; fi` +tc-s12z.o: config/tc-s12z.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-s12z.o -MD -MP -MF $(DEPDIR)/tc-s12z.Tpo -c -o tc-s12z.o `test -f 'config/tc-s12z.c' || echo '$(srcdir)/'`config/tc-s12z.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-s12z.Tpo $(DEPDIR)/tc-s12z.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-s12z.c' object='tc-s12z.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-s12z.o `test -f 'config/tc-s12z.c' || echo '$(srcdir)/'`config/tc-s12z.c + +tc-s12z.obj: config/tc-s12z.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-s12z.obj -MD -MP -MF $(DEPDIR)/tc-s12z.Tpo -c -o tc-s12z.obj `if test -f 'config/tc-s12z.c'; then $(CYGPATH_W) 'config/tc-s12z.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-s12z.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-s12z.Tpo $(DEPDIR)/tc-s12z.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-s12z.c' object='tc-s12z.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-s12z.obj `if test -f 'config/tc-s12z.c'; then $(CYGPATH_W) 'config/tc-s12z.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-s12z.c'; fi` + tc-mcore.o: config/tc-mcore.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-mcore.o -MD -MP -MF $(DEPDIR)/tc-mcore.Tpo -c -o tc-mcore.o `test -f 'config/tc-mcore.c' || echo '$(srcdir)/'`config/tc-mcore.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-mcore.Tpo $(DEPDIR)/tc-mcore.Po diff --git a/gas/NEWS b/gas/NEWS index ec1ba78a66a..a05b703d9c8 100644 --- a/gas/NEWS +++ b/gas/NEWS @@ -1,5 +1,7 @@ -*- text -*- +* Add support for the Freescale S12Z architecture. + * Add --generate-missing-build-notes=[yes|no] option to create (or not) GNU Build Attribute notes if none are present in the input sources. Add a --enable-generate-build-notes=[yes|no] configure time option to set the diff --git a/gas/config/tc-s12z.c b/gas/config/tc-s12z.c new file mode 100644 index 00000000000..e024e7298b3 --- /dev/null +++ b/gas/config/tc-s12z.c @@ -0,0 +1,3840 @@ +/* tc-s12z.c -- Assembler code for the Freescale S12Z + Copyright (C) 2018 Free Software Foundation, Inc. + + 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 3, 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. */ + +#include "as.h" +#include "safe-ctype.h" +#include "subsegs.h" +#include "dwarf2dbg.h" +#include "opcodes/s12z.h" +#include +#include +#include + +const char comment_chars[] = ";"; + +const char line_comment_chars[] = "#*"; +const char line_separator_chars[] = ""; + +const char EXP_CHARS[] = "eE"; +const char FLT_CHARS[] = "dD"; + +static char *fail_line_pointer; + + +/* Options and initialization. */ + +const char *md_shortopts = "Sm:"; + +struct option md_longopts[] = + { + }; + +size_t md_longopts_size = sizeof (md_longopts); + + +relax_typeS md_relax_table[] = + { + + }; + +/* This table describes all the machine specific pseudo-ops the assembler + has to support. The fields are: + pseudo-op name without dot + function to call to execute this pseudo-op + Integer arg to pass to the function. */ +const pseudo_typeS md_pseudo_table[] = + { + {0, 0, 0} + }; + + +/* Get the target cpu for the assembler. */ +const char * +s12z_arch_format (void) +{ + return "elf32-s12z"; +} + +enum bfd_architecture +s12z_arch (void) +{ + return bfd_arch_s12z; +} + +int +s12z_mach (void) +{ + return 0; +} + +/* Listing header selected according to cpu. */ +const char * +s12z_listing_header (void) +{ + return "S12Z GAS "; +} + +void +md_show_usage (FILE *stream ATTRIBUTE_UNUSED) +{ +} + +void +s12z_print_statistics (FILE *file ATTRIBUTE_UNUSED) +{ +} + +int +md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED) +{ + return 0; +} + +symbolS * +md_undefined_symbol (char *name ATTRIBUTE_UNUSED) +{ + return 0; +} + +const char * +md_atof (int type, char *litP, int *sizeP) +{ + return ieee_md_atof (type, litP, sizeP, TRUE); +} + +valueT +md_section_align (asection *seg, valueT addr) +{ + int align = bfd_get_section_alignment (stdoutput, seg); + return ((addr + (1 << align) - 1) & -(1 << align)); +} + +void +md_begin (void) +{ +} + +void +s12z_init_after_args (void) +{ +} + +/* Builtin help. */ + + +static char * +skip_whites (char *p) +{ + while (*p == ' ' || *p == '\t') + p++; + + return p; +} + + + +/* Start a new insn that contains at least 'size' bytes. Record the + line information of that insn in the dwarf2 debug sections. */ +static char * +s12z_new_insn (int size) +{ + char *f = frag_more (size); + + dwarf2_emit_insn (size); + + return f; +} + + + +static int lex_reg_name (uint16_t which, int *reg); + +static int +lex_constant (long *v) +{ + char *end = NULL; + char *p = input_line_pointer; + + /* A constant may not have the same value as a register + eg: "d6" */ + int dummy; + if (lex_reg_name (~0, &dummy)) + { + input_line_pointer = p; + return 0; + } + + errno = 0; + *v = strtol (p, &end, 0); + if (errno == 0 && end != p) + { + input_line_pointer = end; + return 1; + } + + return 0; +} + +static int +lex_match (char x) +{ + char *p = input_line_pointer; + if (*p != x) + return 0; + + input_line_pointer++; + return 1; +} + + +static int +lex_expression (expressionS *exp) +{ + char *ilp = input_line_pointer; + int dummy; + exp->X_op = O_absent; + + if (lex_match ('#')) + goto fail; + + if (lex_reg_name (~0, &dummy)) + goto fail; + + expression (exp); + if (exp->X_op != O_absent) + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +/* immediate operand */ +static int +lex_imm (long *v) +{ + char *ilp = input_line_pointer; + + if (*input_line_pointer != '#') + goto fail; + + input_line_pointer++; + expressionS exp; + if (!lex_expression (&exp)) + goto fail; + + if (exp.X_op != O_constant) + goto fail; + + *v = exp.X_add_number; + return 1; + +fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +/* Short mmediate operand */ +static int +lex_imm_e4 (long *val) +{ + char *ilp = input_line_pointer; + if ((lex_imm (val))) + { + if ((*val == -1) || (*val > 0 && *val <= 15)) + { + return 1; + } + } + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +static int +lex_match_string (const char *s) +{ + char *p = input_line_pointer; + while (p != 0 && *p != '\t' && *p != ' ' && *p != '\0') + { + p++; + } + + size_t len = p - input_line_pointer; + if (len != strlen (s)) + return 0; + + if (0 == strncasecmp (s, input_line_pointer, len)) + { + input_line_pointer = p; + return 1; + } + + return 0; +} + +/* Parse a register name. + WHICH is a ORwise combination of the registers which are accepted. + ~0 accepts all. + On success, REG will be filled with the index of the register which + was successfully scanned. +*/ +static int +lex_reg_name (uint16_t which, int *reg) +{ + char *p = input_line_pointer; + while (p != 0 && + ((*p >= 'a' && *p <='z') || (*p >= '0' && *p <= '9') || (*p >= 'A' && *p <='Z'))) + { + p++; + } + + int len = p - input_line_pointer; + + if (len <= 0) + return 0; + + int i; + for (i = 0; i < S12Z_N_REGISTERS; ++i) + { + gas_assert (registers[i].name); + + if (0 == strncasecmp (registers[i].name, input_line_pointer, len)) + { + if ((0x1U << i) & which) + { + input_line_pointer = p; + *reg = i; + return 1; + } + } + } + + return 0; +} + +static int +lex_force_match (char x) +{ + char *p = input_line_pointer; + if (*p != x) + { + as_bad (_("Expecting '%c'"), x); + return 0; + } + + input_line_pointer++; + return 1; +} + +static int +lex_opr (uint8_t *buffer, int *n_bytes, expressionS *exp) +{ + char *ilp = input_line_pointer; + uint8_t *xb = buffer; + int reg; + long imm; + exp->X_op = O_absent; + *n_bytes = 0; + *xb = 0; + if (lex_imm_e4 (&imm)) + { + if (imm > 0) + *xb = imm; + else + *xb = 0; + *xb |= 0x70; + *n_bytes = 1; + return 1; + } + else if (lex_reg_name (REG_BIT_Dn, ®)) + { + *xb = reg; + *xb |= 0xb8; + *n_bytes = 1; + return 1; + } + else if (lex_match ('[')) + { + if (lex_expression (exp)) + { + long c = exp->X_add_number; + if (lex_match (',')) + { + if (lex_reg_name (REG_BIT_XYSP, ®)) + { + int i; + if (c <= 255 && c >= -256) + { + *n_bytes = 2; + *xb |= 0xc4; + } + else + { + *n_bytes = 4; + *xb |= 0xc6; + } + *xb |= (reg - REG_X) << 4; + + if (c < 0) + *xb |= 0x01; + for (i = 1; i < *n_bytes ; ++i) + { + buffer[i] = c >> (8 * (*n_bytes - i - 1)); + } + } + else + { + as_bad (_("Bad operand for constant offset")); + goto fail; + } + } + else + { + *xb = 0xfe; + *n_bytes = 4; + buffer[1] = c >> 16; + buffer[2] = c >> 8; + buffer[3] = c; + } + } + else if (lex_reg_name (REG_BIT_Dn, ®)) + { + if (!lex_force_match (',')) + goto fail; + + int reg2; + if (lex_reg_name (REG_BIT_XY, ®2)) + { + *n_bytes = 1; + *xb = reg; + *xb |= (reg2 - REG_X) << 4; + *xb |= 0xc8; + } + else + { + as_bad (_("Invalid operand for register offset")); + goto fail; + } + } + else + { + goto fail; + } + if (!lex_force_match (']')) + goto fail; + return 1; + } + else if (lex_match ('(')) + { + long c; + if (lex_constant (&c)) + { + if (!lex_force_match (',')) + goto fail; + int reg2; + if (lex_reg_name (REG_BIT_XYSP, ®2)) + { + if (reg2 != REG_P && c >= 0 && c <= 15) + { + *n_bytes = 1; + *xb = 0x40; + *xb |= (reg2 - REG_X) << 4; + *xb |= c; + } + else if (c >= -256 && c <= 255) + { + *n_bytes = 2; + *xb = 0xc0; + *xb |= (reg2 - REG_X) << 4; + if (c < 0) + *xb |= 0x01; + buffer[1] = c; + } + else + { + *n_bytes = 4; + *xb = 0xc2; + *xb |= (reg2 - REG_X) << 4; + buffer[1] = c >> 16; + buffer[2] = c >> 8; + buffer[3] = c; + } + } + else if (lex_reg_name (REG_BIT_Dn, ®2)) + { + if (c >= -1 * (long) (0x1u << 17) + && + c < (long) (0x1u << 17) - 1) + { + *n_bytes = 3; + *xb = 0x80; + *xb |= reg2; + *xb |= ((c >> 16) & 0x03) << 4; + buffer[1] = c >> 8; + buffer[2] = c; + } + else + { + *n_bytes = 4; + *xb = 0xe8; + *xb |= reg2; + buffer[1] = c >> 16; + buffer[2] = c >> 8; + buffer[3] = c; + } + } + else + { + as_bad (_("Bad operand for constant offset")); + goto fail; + } + } + else if (lex_reg_name (REG_BIT_Dn, ®)) + { + if (lex_match (',')) + { + int reg2; + if (lex_reg_name (REG_BIT_XYS, ®2)) + { + *n_bytes = 1; + *xb = 0x88; + *xb |= (reg2 - REG_X) << 4; + *xb |= reg; + } + else + { + as_bad (_("Invalid operand for register offset")); + goto fail; + } + } + else + { + goto fail; + } + } + else if (lex_reg_name (REG_BIT_XYS, ®)) + { + if (lex_match ('-')) + { + if (reg == REG_S) + { + as_bad (_("Invalid register for postdecrement operation")); + goto fail; + } + *n_bytes = 1; + if (reg == REG_X) + *xb = 0xc7; + else if (reg == REG_Y) + *xb = 0xd7; + } + else if (lex_match ('+')) + { + *n_bytes = 1; + if (reg == REG_X) + *xb = 0xe7; + else if (reg == REG_Y) + *xb = 0xf7; + else if (reg == REG_S) + *xb = 0xff; + } + else + { + goto fail; + } + } + else if (lex_match ('+')) + { + if (lex_reg_name (REG_BIT_XY, ®)) + { + *n_bytes = 1; + if (reg == REG_X) + *xb = 0xe3; + else if (reg == REG_Y) + *xb = 0xf3; + } + else + { + as_bad (_("Invalid register for preincrement operation")); + goto fail; + } + } + else if (lex_match ('-')) + { + if (lex_reg_name (REG_BIT_XYS, ®)) + { + *n_bytes = 1; + if (reg == REG_X) + *xb = 0xc3; + else if (reg == REG_Y) + *xb = 0xd3; + else if (reg == REG_S) + *xb = 0xfb; + } + else + { + as_bad (_("Invalid register for predecrement operation")); + goto fail; + } + } + else + { + goto fail; + } + + if (! lex_match (')')) + goto fail; + return 1; + } + else if (lex_expression (exp)) + { + *xb = 0xfa; + *n_bytes = 4; + buffer[1] = 0; + buffer[2] = 0; + buffer[3] = 0; + if (exp->X_op == O_constant) + { + if (exp->X_add_number < (0x1U << 14)) + { + *xb = 0x00; + *n_bytes = 2; + *xb |= exp->X_add_number >> 8; + buffer[1] = exp->X_add_number; + } + else if (exp->X_add_number < (0x1U << 19)) + { + *xb = 0xf8; + if (exp->X_add_number & (0x1U << 17)) + *xb |= 0x04; + if (exp->X_add_number & (0x1U << 16)) + *xb |= 0x01; + *n_bytes = 3; + buffer[1] = exp->X_add_number >> 8; + buffer[2] = exp->X_add_number; + } + else + { + *xb = 0xfa; + *n_bytes = 4; + buffer[1] = exp->X_add_number >> 16; + buffer[2] = exp->X_add_number >> 8; + buffer[3] = exp->X_add_number; + } + } + return 1; + } + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +static int +lex_offset (long *val) +{ + char *end = NULL; + char *p = input_line_pointer; + + if (*p++ != '*') + return 0; + + if (*p != '+' && *p != '-') + return 0; + + bool negative = (*p == '-'); + p++; + + errno = 0; + *val = strtol (p, &end, 0); + if (errno == 0) + { + if (negative) + *val *= -1; + input_line_pointer = end; + return 1; + } + + return 0; +} + + + +struct instruction; + +typedef int (*parse_operand_func) (const struct instruction *); + +struct instruction +{ + const char *name; + + /* The "page" to which the instruction belongs. + This is also only a hint. Some instructions might have modes in both + pages... */ + char page; + + /* This is a hint - and only a hint - about the opcode of the instruction. + The parse_operand_func is free to ignore it. + */ + uint8_t opc; + + parse_operand_func parse_operands; + + /* Some instructions can be encoded with a different opcode */ + uint8_t alt_opc; +}; + +static int +no_operands (const struct instruction *insn) +{ + if (*input_line_pointer != '\0') + { + as_bad (_("Garbage at end of instruction")); + return 0; + } + + char *f = s12z_new_insn (insn->page); + if (insn->page == 2) + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + + number_to_chars_bigendian (f++, insn->opc, 1); + + return 1; +} + +/* Emit the code for an OPR address mode operand */ +static char * +emit_opr (char *f, const uint8_t *buffer, int n_bytes, expressionS *exp) +{ + int i; + number_to_chars_bigendian (f++, buffer[0], 1); + if (exp->X_op != O_absent && exp->X_op != O_constant) + { + fix_new_exp (frag_now, + f - frag_now->fr_literal, + 3, + exp, + FALSE, + BFD_RELOC_24); + } + for (i = 1; i < n_bytes; ++i) + number_to_chars_bigendian (f++, buffer[i], 1); + + return f; +} + +/* Emit the code for a 24 bit direct address operand */ +static char * +emit_ext24 (char *f, long v) +{ + number_to_chars_bigendian (f, v, 3); + + return f + 3; +} + +static int +opr (const struct instruction *insn) +{ + uint8_t buffer[4]; + int n_bytes; + expressionS exp; + if (lex_opr (buffer, &n_bytes, &exp)) + { + /* Large constant direct values are more efficiently encoded as ext24 mode. + Otherwise a decision has to be deferred to a relax. */ + if (exp.X_op == O_constant + && buffer[0] == 0xFA + && insn->alt_opc != 0) + { + char *f = s12z_new_insn (4); + + /* I don't think there are any instances of page 2 opcodes in this case */ + gas_assert (insn->page == 1); + + number_to_chars_bigendian (f++, insn->alt_opc, 1); + + emit_ext24 (f, exp.X_add_number); + } + else + { + char *f = s12z_new_insn (n_bytes + 1); + number_to_chars_bigendian (f++, insn->opc, 1); + + emit_opr (f, buffer, n_bytes, &exp); + } + return 1; + } + + return 0; +} + +/* Parse a 15 bit offset, as an expression. + LONG_DISPLACEMENT will be set to true if the offset is wider than 7 bits. + */ +static int +lex_15_bit_offset (bool *long_displacement, expressionS *exp) +{ + char *ilp = input_line_pointer; + + long val; + if (lex_offset (&val)) + { + exp->X_op = O_absent; + exp->X_add_number = val; + } + else if (lex_expression (exp)) + { + if (exp->X_op == O_constant) + { + val = exp->X_add_number; + } + else + { + /* If a symbol was parsed we don't know the displacement. + We have to assume it is long, and relax it later if possible. */ + *long_displacement = true; + return 1; + } + } + else + { + exp->X_op = O_absent; + goto fail; + } + + if (val > 0x3FFF || val < -0x4000) + { + as_fatal (_("Offset is outside of 15 bit range")); + return 0; + } + + *long_displacement = (val > 63 || val < -64); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +static void +emit_15_bit_offset (char *f, int where, expressionS *exp) +{ + gas_assert (exp); + if (exp->X_op != O_absent && exp->X_op != O_constant) + { + exp->X_add_number += where; + fixS *fix = fix_new_exp (frag_now, + f - frag_now->fr_literal, + 2, + exp, + TRUE, + BFD_RELOC_16_PCREL); + fix->fx_addnumber = where - 2; + } + else + { + long val = exp->X_add_number; + bool long_displacement = (val > 63 || val < -64); + if (long_displacement) + val |= 0x8000; + else + val &= 0x7F; + + number_to_chars_bigendian (f++, val, long_displacement ? 2 : 1); + } +} + +static int +rel (const struct instruction *insn) +{ + bool long_displacement; + + expressionS exp; + if (! lex_15_bit_offset (&long_displacement, &exp)) + return 0; + + char *f = s12z_new_insn (long_displacement ? 3 : 2); + number_to_chars_bigendian (f++, insn->opc, 1); + emit_15_bit_offset (f, 3, &exp); + return 1; +} + +static int +reg_inh (const struct instruction *insn) +{ + int reg; + if (lex_reg_name (REG_BIT_Dn, ®)) + { + char *f = s12z_new_insn (insn->page); + if (insn->page == 2) + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + + number_to_chars_bigendian (f++, insn->opc + reg, 1); + return 1; + } + + return 0; +} + + +/* Special case for CLR X and CLR Y */ +static int +clr_xy (const struct instruction *insn ATTRIBUTE_UNUSED) +{ + int reg; + if (lex_reg_name (REG_BIT_XY, ®)) + { + char *f = s12z_new_insn (1); + number_to_chars_bigendian (f, 0x9a + reg - REG_X, 1); + return 1; + } + + return 0; +} + +/* Some instructions have a suffix like ".l", ".b", ".w" etc + which indicates the size of the operands. */ +static int +size_from_suffix (const struct instruction *insn, int idx) +{ + const char *dot = strchr (insn->name, '.'); + + if (dot == NULL) + return -3; + + int size = -2; + switch (dot[1 + idx]) + { + case 'b': + size = 1; + break; + case 'w': + size = 2; + break; + case 'p': + size = 3; + break; + case 'l': + size = 4; + break; + default: + as_fatal (_("Bad size")); + }; + + return size; +} + +static int +mul_reg_reg_reg (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + int Dd; + if (!lex_reg_name (REG_BIT_Dn, &Dd)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int Dj; + if (!lex_reg_name (REG_BIT_Dn, &Dj)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int Dk; + if (!lex_reg_name (REG_BIT_Dn, &Dk)) + goto fail; + + char *f = s12z_new_insn (insn->page + 1); + if (insn->page == 2) + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + + number_to_chars_bigendian (f++, insn->opc + Dd, 1); + const char *dot = strchrnul (insn->name, '.'); + uint8_t mb ; + switch (dot[-1]) + { + case 's': + mb = 0x80; + break; + case 'u': + mb = 0x00; + break; + default: + as_fatal (_("BAD MUL")); + break; + } + + mb |= Dj << 3; + mb |= Dk; + + number_to_chars_bigendian (f++, mb, 1); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + +static int +mul_reg_reg_imm (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + int Dd; + if (!lex_reg_name (REG_BIT_Dn, &Dd)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int Dj; + if (!lex_reg_name (REG_BIT_Dn, &Dj)) + goto fail; + + if (!lex_match (',')) + goto fail; + + long imm; + if (!lex_imm (&imm)) + goto fail; + + + int size = size_from_suffix (insn, 0); + + char *f = s12z_new_insn (insn->page + 1 + size); + if (insn->page == 2) + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + + number_to_chars_bigendian (f++, insn->opc + Dd, 1); + uint8_t mb = 0x44; + const char *dot = strchrnul (insn->name, '.'); + switch (dot[-1]) + { + case 's': + mb |= 0x80; + break; + case 'u': + mb |= 0x00; + break; + default: + as_fatal (_("BAD MUL")); + break; + } + + mb |= Dj << 3; + mb |= size - 1; + + number_to_chars_bigendian (f++, mb, 1); + number_to_chars_bigendian (f++, imm, size); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + +static int +mul_reg_reg_opr (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + int Dd; + if (!lex_reg_name (REG_BIT_Dn, &Dd)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int Dj; + if (!lex_reg_name (REG_BIT_Dn, &Dj)) + goto fail; + + if (!lex_match (',')) + goto fail; + + uint8_t buffer[4]; + int n_bytes; + expressionS exp; + if (!lex_opr (buffer, &n_bytes, &exp)) + goto fail; + + int size = size_from_suffix (insn, 0); + + char *f = s12z_new_insn (insn->page + 1 + n_bytes); + if (insn->page == 2) + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + + number_to_chars_bigendian (f++, insn->opc + Dd, 1); + uint8_t mb = 0x40; + const char *dot = strchrnul (insn->name, '.'); + switch (dot[-1]) + { + case 's': + mb |= 0x80; + break; + case 'u': + mb |= 0x00; + break; + default: + as_fatal (_("BAD MUL")); + break; + } + + mb |= Dj << 3; + mb |= size - 1; + + number_to_chars_bigendian (f++, mb, 1); + + emit_opr (f, buffer, n_bytes, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +static int +mul_reg_opr_opr (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + int Dd; + if (!lex_reg_name (REG_BIT_Dn, &Dd)) + goto fail; + + if (!lex_match (',')) + goto fail; + + uint8_t buffer1[4]; + int n_bytes1; + expressionS exp1; + if (!lex_opr (buffer1, &n_bytes1, &exp1)) + goto fail; + + if (!lex_match (',')) + goto fail; + + uint8_t buffer2[4]; + int n_bytes2; + expressionS exp2; + if (!lex_opr (buffer2, &n_bytes2, &exp2)) + goto fail; + + int size1 = size_from_suffix (insn, 0); + int size2 = size_from_suffix (insn, 1); + + char *f = s12z_new_insn (insn->page + 1 + n_bytes1 + n_bytes2); + if (insn->page == 2) + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + + number_to_chars_bigendian (f++, insn->opc + Dd, 1); + uint8_t mb = 0x42; + const char *dot = strchrnul (insn->name, '.'); + switch (dot[-1]) + { + case 's': + mb |= 0x80; + break; + case 'u': + mb |= 0x00; + break; + default: + as_fatal (_("BAD MUL")); + break; + } + + mb |= (size1 - 1) << 4; + mb |= (size2 - 1) << 2; + number_to_chars_bigendian (f++, mb, 1); + + f = emit_opr (f, buffer1, n_bytes1, &exp1); + f = emit_opr (f, buffer2, n_bytes2, &exp2); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + +#define REG_BIT_GRP0 \ + ((0x1U << REG_D2) | \ + (0x1U << REG_D3) | \ + (0x1U << REG_CCH) | \ + (0x1U << REG_CCL) | \ + (0x1U << REG_D0) | \ + (0x1U << REG_D1)) + +#define REG_BIT_GRP1 \ + ((0x1U << REG_D4) | \ + (0x1U << REG_D5) | \ + (0x1U << REG_D6) | \ + (0x1U << REG_D7) | \ + (0x1U << REG_X) | \ + (0x1U << REG_Y)) + +static const uint8_t reg_map [] = + { + 0x02, // D2 + 0x01, // D3 + 0x20, + 0x10, // D5 + 0x08, // D0 + 0x04, // D1 + 0x08, // D6 + 0x04, // D7 + 0x02, + 0x01, // Y + 0x00, + 0x00, + 0x20, // CCH + 0x10, // CCL + 0x00 + }; + +static int +lex_reg_list (uint16_t grp, uint16_t *reg_bits) +{ + if (lex_match (',')) + { + int reg; + if (!lex_reg_name (grp, ®)) + return 0; + *reg_bits |= 0x1u << reg; + lex_reg_list (grp, reg_bits); + } + + /* Empty list */ + return 1; +} + +static int +psh_pull (const struct instruction *insn) +{ + uint8_t pb = + (0 == strcmp ("pul", insn->name)) ? 0x80: 0x00; + + if (lex_match_string ("all16b")) + { + pb |= 0x40; + } + else if (lex_match_string ("all")) + { + /* Nothing to do */ + } + else + { + int reg1; + if (!lex_reg_name (REG_BIT_GRP1 | REG_BIT_GRP0, ®1)) + goto fail; + uint16_t admitted_group = 0; + + if ((0x1U << reg1) & REG_BIT_GRP1) + admitted_group = REG_BIT_GRP1; + else if ((0x1U << reg1) & REG_BIT_GRP0) + admitted_group = REG_BIT_GRP0; + + uint16_t reg_bits = 0x1 << reg1; + if (!lex_reg_list (admitted_group, ®_bits)) + goto fail; + + if (reg_bits & REG_BIT_GRP1) + pb |= 0x40; + + int i; + for (i = 0; i < 16; ++i) + { + if (reg_bits & (0x1u << i)) + pb |= reg_map[i]; + } + } + + char *f = s12z_new_insn (2); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, pb, 1); + return 1; + + fail: + fail_line_pointer = input_line_pointer; + return 0; +} + + +static int +tfr (const struct instruction *insn) +{ + int reg1; + if (!lex_reg_name (~0, ®1)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int reg2; + if (!lex_reg_name (~0, ®2)) + goto fail; + + if ((0 == strcasecmp ("sex", insn->name)) + || (0 == strcasecmp ("zex", insn->name))) + { + if (registers[reg1].bytes >= registers[reg2].bytes) + { + as_bad (_("Source register for %s must be smaller that the destination register"), + insn->name); + goto fail; + } + } + + char *f = s12z_new_insn (1 + insn->page); + if (insn->page == 2) + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, reg1 << 4 | reg2, 1); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + return 0; +} + +static int +imm8 (const struct instruction *insn) +{ + long imm; + if (! lex_imm (&imm)) + return 0; + if (imm > 127 || imm < -128) + { + as_bad (_("Immediate value %ld is out of range for instruction %s"), + imm, insn->name); + } + + char *f = s12z_new_insn (2); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, imm, 1); + + return 1; +} + +static int +reg_imm (const struct instruction *insn, int allowed_reg) +{ + char *ilp = input_line_pointer; + int reg; + if (lex_reg_name (allowed_reg, ®)) + { + if (!lex_force_match (',')) + goto fail; + long imm; + if (! lex_imm (&imm)) + goto fail; + + short size = registers[reg].bytes; + char *f = s12z_new_insn (insn->page + size); + if (insn->page == 2) + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + + number_to_chars_bigendian (f++, insn->opc + reg, 1); + number_to_chars_bigendian (f++, imm, size); + return 1; + } + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + +static int +regd_imm (const struct instruction *insn) +{ + return reg_imm (insn, REG_BIT_Dn); +} + +static int +regdxy_imm (const struct instruction *insn) +{ + return reg_imm (insn, REG_BIT_Dn | REG_BIT_XY); +} + + +static int +regs_imm (const struct instruction *insn) +{ + return reg_imm (insn, 0x1U << REG_S); +} + +static int +trap_imm (const struct instruction *insn ATTRIBUTE_UNUSED) +{ + long imm = -1; + if (! lex_imm (&imm)) + goto fail; + + if (imm < 0x92 || imm > 0xFF || + (imm >= 0xA0 && imm <= 0xA7) || + (imm >= 0xB0 && imm <= 0xB7)) + { + as_bad (_("trap value %ld is not valid"), imm); + return 0; + } + else + { + char *f = s12z_new_insn (2); + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + number_to_chars_bigendian (f++, imm & 0xFF, 1); + return 1; + } + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + return 0; +} + + + +/* Special one byte instruction CMP X, Y */ +static int +regx_regy (const struct instruction *insn) +{ + int reg; + if (lex_reg_name (0x1U << REG_X, ®)) + { + if (lex_force_match (',')) + { + if (lex_reg_name (0x1U << REG_Y, ®)) + { + char *f = s12z_new_insn (1); + number_to_chars_bigendian (f, insn->opc, 1); + return 1; + } + } + } + return 0; +} + +/* Special one byte instruction SUB D6, X, Y */ +static int +regd6_regx_regy (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + int reg; + if (!lex_reg_name (0x1U << REG_D6, ®)) + goto fail; + + if (!lex_match (',')) + goto fail; + + if (!lex_reg_name (0x1U << REG_X, ®)) + goto fail; + + if (!lex_match (',')) + goto fail; + + if (!lex_reg_name (0x1U << REG_Y, ®)) + goto fail; + + char *f = s12z_new_insn (1); + number_to_chars_bigendian (f, insn->opc, 1); + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +/* Special one byte instruction SUB D6, Y, X */ +static int +regd6_regy_regx (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + int reg; + if (!lex_reg_name (0x1U << REG_D6, ®)) + goto fail; + + if (!lex_match (',')) + goto fail; + + if (!lex_reg_name (0x1U << REG_Y, ®)) + goto fail; + + if (!lex_match (',')) + goto fail; + + if (!lex_reg_name (0x1U << REG_X, ®)) + goto fail; + + char *f = s12z_new_insn (1); + number_to_chars_bigendian (f, insn->opc, 1); + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +static int +reg_opr (const struct instruction *insn, int allowed_regs) +{ + char *ilp = input_line_pointer; + int reg; + if (lex_reg_name (allowed_regs, ®)) + { + if (!lex_force_match (',')) + goto fail; + + uint8_t buffer[4]; + int n_bytes; + expressionS exp; + if (lex_opr (buffer, &n_bytes, &exp)) + { + /* Large constant direct values are more efficiently encoded as ext24 mode. + Otherwise a decision has to be deferred to a relax. */ + if (exp.X_op == O_constant + && buffer[0] == 0xFA + && insn->alt_opc != 0) + { + char *f = s12z_new_insn (4); + + /* I don't think there are any instances of page 2 opcodes in this case */ + gas_assert (insn->page == 1); + + number_to_chars_bigendian (f++, insn->alt_opc + reg, 1); + + emit_ext24 (f, exp.X_add_number); + } + else + { + char *f = s12z_new_insn (n_bytes + insn->page); + + if (insn->page == 2) + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + + number_to_chars_bigendian (f++, insn->opc + reg, 1); + + emit_opr (f, buffer, n_bytes, &exp); + } + + return 1; + } + } + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + +static int +regdxy_opr (const struct instruction *insn) +{ + return reg_opr (insn, REG_BIT_Dn | REG_BIT_XY); +} + +static int +regd_opr (const struct instruction *insn) +{ + return reg_opr (insn, REG_BIT_Dn); +} + + +static int +regs_opr (const struct instruction *insn) +{ + return reg_opr (insn, 0x1U << REG_S); +} + +static int +imm_opr (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + long imm; + if (!lex_imm (&imm)) + goto fail; + + if (!lex_match (',')) + goto fail; + + uint8_t buffer[4]; + int n_bytes; + expressionS exp; + if (!lex_opr (buffer, &n_bytes, &exp)) + goto fail; + + int size = size_from_suffix (insn, 0); + char *f = s12z_new_insn (1 + n_bytes + size); + number_to_chars_bigendian (f++, insn->opc, 1); + + int i; + for (i = 0; i < size; ++i) + number_to_chars_bigendian (f++, imm >> (CHAR_BIT * (size - i - 1)), 1); + + emit_opr (f, buffer, n_bytes, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +static int +opr_opr (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + uint8_t buffer1[4]; + int n_bytes1; + expressionS exp1; + if (!lex_opr (buffer1, &n_bytes1, &exp1)) + goto fail; + + + if (!lex_match (',')) + goto fail; + + uint8_t buffer2[4]; + int n_bytes2; + expressionS exp2; + if (!lex_opr (buffer2, &n_bytes2, &exp2)) + goto fail; + + char *f = s12z_new_insn (1 + n_bytes1 + n_bytes2); + number_to_chars_bigendian (f++, insn->opc, 1); + + f = emit_opr (f, buffer1, n_bytes1, &exp1); + f = emit_opr (f, buffer2, n_bytes2, &exp2); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +static int +reg67sxy_opr (const struct instruction *insn) +{ + int reg; + if (!lex_reg_name (REG_BIT_XYS | (0x1U << REG_D6) | (0x1U << REG_D7), ®)) + return 0; + + if (!lex_match (',')) + return 0; + + uint8_t buffer[4]; + int n_bytes; + expressionS exp; + if (!lex_opr (buffer, &n_bytes, &exp)) + return 0; + + char *f = s12z_new_insn (1 + n_bytes); + number_to_chars_bigendian (f++, insn->opc + reg - REG_D6, 1); + emit_opr (f, buffer, n_bytes, &exp); + + return 1; +} + +static int +rotate (const struct instruction *insn, short dir) +{ + uint8_t buffer[4]; + int n_bytes; + expressionS exp; + if (lex_opr (buffer, &n_bytes, &exp)) + { + char *f = s12z_new_insn (n_bytes + 2); + number_to_chars_bigendian (f++, insn->opc, 1); + int size = size_from_suffix (insn, 0); + if (size < 0) + size = 1; + uint8_t sb = 0x24; + sb |= size - 1; + if (dir) + sb |= 0x40; + number_to_chars_bigendian (f++, sb, 1); + emit_opr (f, buffer, n_bytes, &exp); + + return 1; + } + + return 0; +} + +static int +rol (const struct instruction *insn) +{ + return rotate (insn, 1); +} + +static int +ror (const struct instruction *insn) +{ + return rotate (insn, 0); +} + + +/* Shift instruction with a register operand and an immediate #1 or #2 + left = 1; right = 0; + logical = 0; arithmetic = 1; +*/ +static int +lex_shift_reg_imm1 (const struct instruction *insn, short type, short dir) +{ + /* + This function is highly unusual and a bit wierd! + It first matches the input against a register {d0, d1, ... d7} followed by an immediate + {#1, #2}. + Then, it rewinds the input and parses it again as a OPR. + */ + char *ilp = input_line_pointer; + + int Dd; + if (!lex_reg_name (REG_BIT_Dn, &Dd)) + { + goto fail; + } + + if (!lex_match (',')) + goto fail; + + long imm = -1; + if (!lex_imm (&imm)) + goto fail; + + if (imm != 1 && imm != 2) + goto fail; + input_line_pointer = ilp; + + /* Now parse the first operand again */ + + uint8_t buffer[4]; + int n_bytes; + + expressionS exp; + if (!lex_opr (buffer, &n_bytes, &exp)) + goto fail; + + gas_assert (n_bytes == 1); + + uint8_t sb = 0x34; + sb |= dir << 6; + sb |= type << 7; + if (imm == 2) + sb |= 0x08; + + char *f = s12z_new_insn (3); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, sb, 1); + emit_opr (f, buffer, n_bytes, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +/* Shift instruction with a register operand. + left = 1; right = 0; + logical = 0; arithmetic = 1; */ +static int +lex_shift_reg (const struct instruction *insn, short type, short dir) +{ + int Dd, Ds, Dn; + if (!lex_reg_name (REG_BIT_Dn, &Dd)) + { + goto fail; + } + + if (!lex_match (',')) + goto fail; + + if (!lex_reg_name (REG_BIT_Dn, &Ds)) + { + goto fail; + } + + if (!lex_match (',')) + goto fail; + + uint8_t sb = 0x10; + sb |= Ds; + sb |= dir << 6; + sb |= type << 7; + long imm; + if (lex_reg_name (REG_BIT_Dn, &Dn)) + { + char *f = s12z_new_insn (3); + number_to_chars_bigendian (f++, insn->opc | Dd, 1); + number_to_chars_bigendian (f++, sb, 1); + uint8_t xb = 0xb8; + xb |= Dn; + number_to_chars_bigendian (f++, xb, 1); + + return 1; + } + else if (lex_imm (&imm)) + { + if (imm < 0 || imm > 31) + { + as_bad (_("Shift value should be in the range [0,31]")); + goto fail; + } + + int n_bytes = 3; + if (imm == 1 || imm == 2) + { + n_bytes = 2; + sb &= ~0x10; + } + else + { + sb |= (imm & 0x01) << 3; + } + + char *f = s12z_new_insn (n_bytes); + number_to_chars_bigendian (f++, insn->opc | Dd, 1); + number_to_chars_bigendian (f++, sb, 1); + if (n_bytes > 2) + { + uint8_t xb = 0x70; + xb |= imm >> 1; + number_to_chars_bigendian (f++, xb, 1); + } + + return 1; + } + + fail: + fail_line_pointer = input_line_pointer; + return 0; +} + +static void +impute_shift_dir_and_type (const struct instruction *insn, short *type, short *dir) +{ + *dir = -1; + *type = -1; + switch (insn->name[0]) + { + case 'l': + *type = 0; + break; + case 'a': + *type = 1; + break; + default: + as_fatal (_("Bad shift mode")); + break; + } + + switch (insn->name[2]) + { + case 'l': + *dir = 1; + break; + case 'r': + *dir = 0; + break; + default: + as_fatal (_("Bad shift *direction")); + break; + } +} + +/* Shift instruction with a OPR operand */ +static int +shift_two_operand (const struct instruction *insn) +{ + uint8_t sb = 0x34; + char *ilp = input_line_pointer; + + short dir = -1; + short type = -1; + impute_shift_dir_and_type (insn, &type, &dir); + sb |= dir << 6; + sb |= type << 7; + + int size = size_from_suffix (insn, 0); + sb |= size - 1; + + uint8_t buffer[4]; + int n_opr_bytes; + expressionS exp; + if (!lex_opr (buffer, &n_opr_bytes, &exp)) + goto fail; + + if (!lex_match (',')) + goto fail; + + long imm = -1; + if (!lex_imm (&imm)) + goto fail; + + if (imm != 1 && imm != 2) + goto fail; + + if (imm == 2) + sb |= 0x08; + + char *f = s12z_new_insn (2 + n_opr_bytes); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, sb, 1); + emit_opr (f, buffer, n_opr_bytes, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +/* Shift instruction with a OPR operand */ +static int +shift_opr_imm (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + short dir = -1; + short type = -1; + impute_shift_dir_and_type (insn, &type, &dir); + + int Dd = 0; + if (!lex_reg_name (REG_BIT_Dn, &Dd)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int n_bytes = 2; + + uint8_t buffer1[4]; + int n_opr_bytes1; + + expressionS exp1; + if (!lex_opr (buffer1, &n_opr_bytes1, &exp1)) + goto fail; + + n_bytes += n_opr_bytes1; + if (!lex_match (',')) + goto fail; + + uint8_t buffer2[4]; + int n_opr_bytes2 = 0; + expressionS exp2; + long imm; + bool immediate = false; + if (lex_imm (&imm)) + { + immediate = true; + } + else if (!lex_opr (buffer2, &n_opr_bytes2, &exp2)) + goto fail; + + uint8_t sb = 0x20; + + int size = size_from_suffix (insn, 0); + + if (size != -1) + sb |= size - 1; + + sb |= dir << 6; + sb |= type << 7; + + if (immediate) + { + if (imm == 2 || imm == 1) + { + if (imm == 2) + sb |= 0x08; + } + else + { + n_bytes++; + sb |= 0x10; + if (imm % 2) + sb |= 0x08; + } + } + else + { + n_bytes += n_opr_bytes2; + sb |= 0x10; + } + + char *f = s12z_new_insn (n_bytes); + number_to_chars_bigendian (f++, insn->opc | Dd, 1); + number_to_chars_bigendian (f++, sb, 1); + f = emit_opr (f, buffer1, n_opr_bytes1, &exp1); + if (immediate) + { + if (imm != 1 && imm != 2) + { + number_to_chars_bigendian (f++, 0x70 | (imm >> 1), 1); + } + } + else + { + f = emit_opr (f, buffer2, n_opr_bytes2, &exp2); + } + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +/* Shift instruction with a register operand */ +static int +shift_reg (const struct instruction *insn) +{ + short dir = -1; + short type = -1; + impute_shift_dir_and_type (insn, &type, &dir); + + if (lex_shift_reg_imm1 (insn, type, dir)) + return 1; + + return lex_shift_reg (insn, type, dir); +} + +static int +bm_regd_imm (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + int Di = 0; + if (!lex_reg_name (REG_BIT_Dn, &Di)) + goto fail; + + if (!lex_match (',')) + goto fail; + + long imm; + if (!lex_imm (&imm)) + goto fail; + + + uint8_t bm = imm << 3; + bm |= Di; + + char *f = s12z_new_insn (2); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, bm, 1); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +static int +bm_opr_reg (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + uint8_t buffer[4]; + int n_opr_bytes; + + expressionS exp; + if (!lex_opr (buffer, &n_opr_bytes, &exp)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int Dn = 0; + if (!lex_reg_name (REG_BIT_Dn, &Dn)) + goto fail; + + uint8_t bm = Dn << 4; + int size = size_from_suffix (insn, 0); + bm |= (size - 1) << 2; + bm |= 0x81; + + char *f = s12z_new_insn (2 + n_opr_bytes); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, bm, 1); + + emit_opr (f, buffer, n_opr_bytes, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + +static int +bm_opr_imm (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + uint8_t buffer[4]; + int n_opr_bytes; + + expressionS exp; + if (!lex_opr (buffer, &n_opr_bytes, &exp)) + goto fail; + + if (!lex_match (',')) + goto fail; + + + long imm; + if (!lex_imm (&imm)) + goto fail; + + int size = size_from_suffix (insn, 0); + + if (imm < 0 || imm >= size * 8) + { + as_bad (_("Immediate operand %ld is inappropriate for size of instruction"), imm); + goto fail; + } + + uint8_t bm = 0x80; + if (size == 2) + bm |= 0x02; + else if (size == 4) + bm |= 0x08; + bm |= (imm & 0x07) << 4; + bm |= (imm >> 3); + + + char *f = s12z_new_insn (2 + n_opr_bytes); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, bm, 1); + emit_opr (f, buffer, n_opr_bytes, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + +static int +bm_regd_reg (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + int Di = 0; + if (!lex_reg_name (REG_BIT_Dn, &Di)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int Dn = 0; + if (!lex_reg_name (REG_BIT_Dn, &Dn)) + goto fail; + + uint8_t bm = Dn << 4; + bm |= 0x81; + + uint8_t xb = Di | 0xb8; + + char *f = s12z_new_insn (3); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, bm, 1); + number_to_chars_bigendian (f++, xb, 1); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + + + + +static int +bf_reg_opr_imm (const struct instruction *insn, short ie) +{ + char *ilp = input_line_pointer; + int Dd = 0; + if (!lex_reg_name (REG_BIT_Dn, &Dd)) + goto fail; + + if (!lex_match (',')) + goto fail; + + uint8_t buffer[4]; + int n_bytes; + + expressionS exp; + if (!lex_opr (buffer, &n_bytes, &exp)) + goto fail; + + if (!lex_match (',')) + goto fail; + + long width; + if (!lex_imm (&width)) + goto fail; + + if (width < 0 || width > 31) + { + as_bad (_("Invalid width value for %s"), insn->name); + goto fail; + } + + if (!lex_match (':')) + goto fail; + + long offset; + if (!lex_constant (&offset)) + goto fail; + + if (offset < 0 || offset > 31) + { + as_bad (_("Invalid offset value for %s"), insn->name); + goto fail; + } + + uint8_t i1 = width << 5; + i1 |= offset; + + int size = size_from_suffix (insn, 0); + uint8_t bb = ie ? 0x80 : 0x00; + bb |= 0x60; + bb |= (size - 1) << 2; + bb |= width >> 3; + + char *f = s12z_new_insn (4 + n_bytes); + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + number_to_chars_bigendian (f++, 0x08 | Dd, 1); + number_to_chars_bigendian (f++, bb, 1); + number_to_chars_bigendian (f++, i1, 1); + + emit_opr (f, buffer, n_bytes, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + +static int +bf_opr_reg_imm (const struct instruction *insn, short ie) +{ + char *ilp = input_line_pointer; + uint8_t buffer[4]; + int n_bytes; + expressionS exp; + if (!lex_opr (buffer, &n_bytes, &exp)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int Ds = 0; + if (!lex_reg_name (REG_BIT_Dn, &Ds)) + goto fail; + + if (!lex_match (',')) + goto fail; + + long width; + if (!lex_imm (&width)) + goto fail; + + if (width < 0 || width > 31) + { + as_bad (_("Invalid width value for %s"), insn->name); + goto fail; + } + + if (!lex_match (':')) + goto fail; + + long offset; + if (!lex_constant (&offset)) + goto fail; + + if (offset < 0 || offset > 31) + { + as_bad (_("Invalid offset value for %s"), insn->name); + goto fail; + } + + uint8_t i1 = width << 5; + i1 |= offset; + + int size = size_from_suffix (insn, 0); + uint8_t bb = ie ? 0x80 : 0x00; + bb |= 0x70; + bb |= (size - 1) << 2; + bb |= width >> 3; + + char *f = s12z_new_insn (4 + n_bytes); + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + number_to_chars_bigendian (f++, 0x08 | Ds, 1); + number_to_chars_bigendian (f++, bb, 1); + number_to_chars_bigendian (f++, i1, 1); + + emit_opr (f, buffer, n_bytes, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + + +static int +bf_reg_reg_imm (const struct instruction *insn, short ie) +{ + char *ilp = input_line_pointer; + int Dd = 0; + if (!lex_reg_name (REG_BIT_Dn, &Dd)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int Ds = 0; + if (!lex_reg_name (REG_BIT_Dn, &Ds)) + goto fail; + + if (!lex_match (',')) + goto fail; + + long width; + if (!lex_imm (&width)) + goto fail; + + if (width < 0 || width > 31) + { + as_bad (_("Invalid width value for %s"), insn->name); + goto fail; + } + + if (!lex_match (':')) + goto fail; + + long offset; + if (!lex_constant (&offset)) + goto fail; + + if (offset < 0 || offset > 31) + { + as_bad (_("Invalid offset value for %s"), insn->name); + goto fail; + } + + uint8_t bb = ie ? 0x80 : 0x00; + bb |= 0x20; + bb |= Ds << 2; + bb |= width >> 3; + + uint8_t i1 = width << 5; + i1 |= offset; + + char *f = s12z_new_insn (4); + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + number_to_chars_bigendian (f++, 0x08 | Dd, 1); + number_to_chars_bigendian (f++, bb, 1); + number_to_chars_bigendian (f++, i1, 1); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +static int +bf_reg_reg_reg (const struct instruction *insn ATTRIBUTE_UNUSED, short ie) +{ + char *ilp = input_line_pointer; + int Dd = 0; + if (!lex_reg_name (REG_BIT_Dn, &Dd)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int Ds = 0; + if (!lex_reg_name (REG_BIT_Dn, &Ds)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int Dp = 0; + if (!lex_reg_name ((0x01u << REG_D2) | + (0x01u << REG_D3) | + (0x01u << REG_D4) | + (0x01u << REG_D5), + &Dp)) + goto fail; + + uint8_t bb = ie ? 0x80 : 0x00; + bb |= Ds << 2; + bb |= Dp; + + char *f = s12z_new_insn (3); + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + number_to_chars_bigendian (f++, 0x08 | Dd, 1); + number_to_chars_bigendian (f++, bb , 1); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +static int +bf_opr_reg_reg (const struct instruction *insn, short ie) +{ + char *ilp = input_line_pointer; + + uint8_t buffer[4]; + int n_bytes; + expressionS exp; + if (!lex_opr (buffer, &n_bytes, &exp)) + goto fail; + + if (!lex_match (',')) + goto fail; + + + int Ds = 0; + if (!lex_reg_name (REG_BIT_Dn, &Ds)) + goto fail; + + if (!lex_match (',')) + goto fail; + + + int Dp = 0; + if (!lex_reg_name ((0x01u << REG_D2) | + (0x01u << REG_D3) | + (0x01u << REG_D4) | + (0x01u << REG_D5), + &Dp)) + goto fail; + + int size = size_from_suffix (insn, 0); + uint8_t bb = ie ? 0x80 : 0x00; + bb |= 0x50; + bb |= Dp; + bb |= (size - 1) << 2; + + char *f = s12z_new_insn (3 + n_bytes); + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + number_to_chars_bigendian (f++, 0x08 | Ds, 1); + number_to_chars_bigendian (f++, bb , 1); + + emit_opr (f, buffer, n_bytes, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + +static int +bf_reg_opr_reg (const struct instruction *insn, short ie) +{ + char *ilp = input_line_pointer; + int Dd = 0; + if (!lex_reg_name (REG_BIT_Dn, &Dd)) + goto fail; + + if (!lex_match (',')) + goto fail; + + + uint8_t buffer[4]; + int n_bytes; + expressionS exp; + if (!lex_opr (buffer, &n_bytes, &exp)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int Dp = 0; + if (!lex_reg_name ((0x01u << REG_D2) | + (0x01u << REG_D3) | + (0x01u << REG_D4) | + (0x01u << REG_D5), + &Dp)) + goto fail; + + int size = size_from_suffix (insn, 0); + uint8_t bb = ie ? 0x80 : 0x00; + bb |= 0x40; + bb |= Dp; + bb |= (size - 1) << 2; + + char *f = s12z_new_insn (3 + n_bytes); + number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1); + number_to_chars_bigendian (f++, 0x08 | Dd, 1); + number_to_chars_bigendian (f++, bb , 1); + + emit_opr (f, buffer, n_bytes, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + + +static int +bfe_reg_reg_reg (const struct instruction *insn) +{ + return bf_reg_reg_reg (insn, 0); +} + +static int +bfi_reg_reg_reg (const struct instruction *insn) +{ + return bf_reg_reg_reg (insn, 1); +} + +static int +bfe_reg_reg_imm (const struct instruction *insn) +{ + return bf_reg_reg_imm (insn, 0); +} + +static int +bfi_reg_reg_imm (const struct instruction *insn) +{ + return bf_reg_reg_imm (insn, 1); +} + + +static int +bfe_reg_opr_reg (const struct instruction *insn) +{ + return bf_reg_opr_reg (insn, 0); +} + +static int +bfi_reg_opr_reg (const struct instruction *insn) +{ + return bf_reg_opr_reg (insn, 1); +} + + +static int +bfe_opr_reg_reg (const struct instruction *insn) +{ + return bf_opr_reg_reg (insn, 0); +} + +static int +bfi_opr_reg_reg (const struct instruction *insn) +{ + return bf_opr_reg_reg (insn, 1); +} + +static int +bfe_reg_opr_imm (const struct instruction *insn) +{ + return bf_reg_opr_imm (insn, 0); +} + +static int +bfi_reg_opr_imm (const struct instruction *insn) +{ + return bf_reg_opr_imm (insn, 1); +} + +static int +bfe_opr_reg_imm (const struct instruction *insn) +{ + return bf_opr_reg_imm (insn, 0); +} + +static int +bfi_opr_reg_imm (const struct instruction *insn) +{ + return bf_opr_reg_imm (insn, 1); +} + + + + +static int +tb_reg_rel (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + int reg; + if (!lex_reg_name (REG_BIT_Dn | REG_BIT_XY, ®)) + goto fail; + + if (!lex_match (',')) + goto fail; + + bool long_displacement; + expressionS exp; + if (! lex_15_bit_offset (&long_displacement, &exp)) + goto fail; + + uint8_t lb = 0x00; + if (reg == REG_X || reg == REG_Y) + { + lb |= 0x08; + } + else + { + lb |= reg; + } + if (reg == REG_Y) + lb |= 0x01; + + if (0 == strncmp (insn->name + 2, "ne", 2)) + lb |= 0x00 << 4; + else if (0 == strncmp (insn->name + 2, "eq", 2)) + lb |= 0x01 << 4; + else if (0 == strncmp (insn->name + 2, "pl", 2)) + lb |= 0x02 << 4; + else if (0 == strncmp (insn->name + 2, "mi", 2)) + lb |= 0x03 << 4; + else if (0 == strncmp (insn->name + 2, "gt", 2)) + lb |= 0x04 << 4; + else if (0 == strncmp (insn->name + 2, "le", 2)) + lb |= 0x05 << 4; + + switch (insn->name[0]) + { + case 'd': + lb |= 0x80; + break; + case 't': + break; + default: + gas_assert (0); + break; + }; + + char *f = s12z_new_insn (long_displacement ? 4 : 3); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, lb, 1); + + emit_15_bit_offset (f, 4, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + +static int +tb_opr_rel (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + uint8_t buffer[4]; + int n_bytes; + expressionS exp; + if (!lex_opr (buffer, &n_bytes, &exp)) + goto fail; + + if (!lex_match (',')) + goto fail; + + bool long_displacement; + expressionS exp2; + if (! lex_15_bit_offset (&long_displacement, &exp2)) + goto fail; + + uint8_t lb = 0x0C; + + if (0 == strncmp (insn->name + 2, "ne", 2)) + lb |= 0x00 << 4; + else if (0 == strncmp (insn->name + 2, "eq", 2)) + lb |= 0x01 << 4; + else if (0 == strncmp (insn->name + 2, "pl", 2)) + lb |= 0x02 << 4; + else if (0 == strncmp (insn->name + 2, "mi", 2)) + lb |= 0x03 << 4; + else if (0 == strncmp (insn->name + 2, "gt", 2)) + lb |= 0x04 << 4; + else if (0 == strncmp (insn->name + 2, "le", 2)) + lb |= 0x05 << 4; + + switch (insn->name[0]) + { + case 'd': + lb |= 0x80; + break; + case 't': + break; + default: + gas_assert (0); + break; + }; + + int size = size_from_suffix (insn, 0); + + lb |= size -1; + + char *f = s12z_new_insn (n_bytes + (long_displacement ? 4 : 3)); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, lb, 1); + f = emit_opr (f, buffer, n_bytes, &exp); + + emit_15_bit_offset (f, n_bytes + 4, &exp2); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + + + +static int +test_br_reg_reg_rel (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + int Di = 0; + if (!lex_reg_name (REG_BIT_Dn, &Di)) + goto fail; + + if (!lex_match (',')) + goto fail; + + + int Dn = 0; + if (!lex_reg_name (REG_BIT_Dn, &Dn)) + goto fail; + + if (!lex_match (',')) + goto fail; + + + bool long_displacement; + expressionS exp; + if (! lex_15_bit_offset (&long_displacement, &exp)) + goto fail; + + uint8_t bm = 0x81; + uint8_t xb = 0xb8; + + bm |= Dn << 4; + xb |= Di; + + char *f = s12z_new_insn (long_displacement ? 5 : 4); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, bm, 1); + number_to_chars_bigendian (f++, xb, 1); + + emit_15_bit_offset (f, 5, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + +static int +test_br_opr_reg_rel (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + uint8_t buffer[4]; + int n_bytes; + expressionS exp; + if (!lex_opr (buffer, &n_bytes, &exp)) + goto fail; + + if (!lex_match (',')) + goto fail; + + int Dn = 0; + if (!lex_reg_name (REG_BIT_Dn, &Dn)) + goto fail; + + if (!lex_match (',')) + goto fail; + + uint8_t bm = 0x81; + bm |= Dn << 4; + int size = size_from_suffix (insn, 0); + bm |= (size -1) << 2; + + bool long_displacement; + + expressionS exp2; + if (! lex_15_bit_offset (&long_displacement, &exp2)) + goto fail; + + int n = n_bytes + (long_displacement ? 4 : 3); + char *f = s12z_new_insn (n); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, bm, 1); + f = emit_opr (f, buffer, n_bytes, &exp); + + emit_15_bit_offset (f, n, &exp2); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + +static int +test_br_opr_imm_rel (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + uint8_t buffer[4]; + int n_bytes; + expressionS exp; + if (!lex_opr (buffer, &n_bytes, &exp)) + goto fail; + + if (!lex_match (',')) + goto fail; + + long imm; + if (!lex_imm (&imm)) + goto fail; + + if (imm < 0 || imm > 31) + goto fail; + + if (!lex_match (',')) + goto fail; + + bool long_displacement; + expressionS exp2; + if (! lex_15_bit_offset (&long_displacement, &exp2)) + goto fail; + + int size = size_from_suffix (insn, 0); + + uint8_t bm = 0x80; + bm |= (imm & 0x07) << 4; + bm |= (imm >> 3) & 0x03; + if (size == 4) + bm |= 0x08; + else if (size == 2) + bm |= 0x02; + + char *f = s12z_new_insn (n_bytes + (long_displacement ? 4 : 3)); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, bm, 1); + f = emit_opr (f, buffer, n_bytes, &exp); + + emit_15_bit_offset (f, n_bytes + 4, &exp2); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + +static int +test_br_reg_imm_rel (const struct instruction *insn) +{ + char *ilp = input_line_pointer; + + int Di = 0; + if (!lex_reg_name (REG_BIT_Dn, &Di)) + goto fail; + + if (!lex_match (',')) + goto fail; + + long imm; + if (!lex_imm (&imm)) + goto fail; + + if (imm < 0 || imm > 31) + goto fail; + + + if (!lex_match (',')) + goto fail; + + bool long_displacement; + expressionS exp; + if (! lex_15_bit_offset (&long_displacement, &exp)) + goto fail; + + uint8_t bm = Di; + bm |= imm << 3; + + char *f = s12z_new_insn (long_displacement ? 4 : 3); + number_to_chars_bigendian (f++, insn->opc, 1); + number_to_chars_bigendian (f++, bm, 1); + + emit_15_bit_offset (f, 4, &exp); + + return 1; + + fail: + fail_line_pointer = input_line_pointer; + input_line_pointer = ilp; + return 0; +} + + + + +static const struct instruction opcodes[] = { + {"bgnd", 1, 0x00, no_operands, 0}, + {"nop", 1, 0x01, no_operands, 0}, + + {"brclr", 1, 0x02, test_br_reg_reg_rel, 0}, + {"brset", 1, 0x03, test_br_reg_reg_rel, 0}, + + {"brclr", 1, 0x02, test_br_reg_imm_rel, 0}, + {"brset", 1, 0x03, test_br_reg_imm_rel, 0}, + + {"brclr.b", 1, 0x02, test_br_opr_reg_rel, 0}, + {"brclr.w", 1, 0x02, test_br_opr_reg_rel, 0}, + {"brclr.l", 1, 0x02, test_br_opr_reg_rel, 0}, + + {"brset.b", 1, 0x03, test_br_opr_reg_rel, 0}, + {"brset.w", 1, 0x03, test_br_opr_reg_rel, 0}, + {"brset.l", 1, 0x03, test_br_opr_reg_rel, 0}, + + {"brclr.b", 1, 0x02, test_br_opr_imm_rel, 0}, + {"brclr.w", 1, 0x02, test_br_opr_imm_rel, 0}, + {"brclr.l", 1, 0x02, test_br_opr_imm_rel, 0}, + + {"brset.b", 1, 0x03, test_br_opr_imm_rel, 0}, + {"brset.w", 1, 0x03, test_br_opr_imm_rel, 0}, + {"brset.l", 1, 0x03, test_br_opr_imm_rel, 0}, + + {"psh", 1, 0x04, psh_pull, 0}, + {"pul", 1, 0x04, psh_pull, 0}, + + {"rts", 1, 0x05, no_operands, 0}, + {"lea", 1, 0x06, reg67sxy_opr, 0}, + + {"dbne", 1, 0x0b, tb_reg_rel, 0}, + {"dbeq", 1, 0x0b, tb_reg_rel, 0}, + {"dbpl", 1, 0x0b, tb_reg_rel, 0}, + {"dbmi", 1, 0x0b, tb_reg_rel, 0}, + {"dbgt", 1, 0x0b, tb_reg_rel, 0}, + {"dble", 1, 0x0b, tb_reg_rel, 0}, + + {"dbne.b", 1, 0x0b, tb_opr_rel, 0}, + {"dbeq.b", 1, 0x0b, tb_opr_rel, 0}, + {"dbpl.b", 1, 0x0b, tb_opr_rel, 0}, + {"dbmi.b", 1, 0x0b, tb_opr_rel, 0}, + {"dbgt.b", 1, 0x0b, tb_opr_rel, 0}, + {"dble.b", 1, 0x0b, tb_opr_rel, 0}, + + {"dbne.w", 1, 0x0b, tb_opr_rel, 0}, + {"dbeq.w", 1, 0x0b, tb_opr_rel, 0}, + {"dbpl.w", 1, 0x0b, tb_opr_rel, 0}, + {"dbmi.w", 1, 0x0b, tb_opr_rel, 0}, + {"dbgt.w", 1, 0x0b, tb_opr_rel, 0}, + {"dble.w", 1, 0x0b, tb_opr_rel, 0}, + + {"dbne.p", 1, 0x0b, tb_opr_rel, 0}, + {"dbeq.p", 1, 0x0b, tb_opr_rel, 0}, + {"dbpl.p", 1, 0x0b, tb_opr_rel, 0}, + {"dbmi.p", 1, 0x0b, tb_opr_rel, 0}, + {"dbgt.p", 1, 0x0b, tb_opr_rel, 0}, + {"dble.p", 1, 0x0b, tb_opr_rel, 0}, + + {"dbne.l", 1, 0x0b, tb_opr_rel, 0}, + {"dbeq.l", 1, 0x0b, tb_opr_rel, 0}, + {"dbpl.l", 1, 0x0b, tb_opr_rel, 0}, + {"dbmi.l", 1, 0x0b, tb_opr_rel, 0}, + {"dbgt.l", 1, 0x0b, tb_opr_rel, 0}, + {"dble.l", 1, 0x0b, tb_opr_rel, 0}, + + {"tbne", 1, 0x0b, tb_reg_rel, 0}, + {"tbeq", 1, 0x0b, tb_reg_rel, 0}, + {"tbpl", 1, 0x0b, tb_reg_rel, 0}, + {"tbmi", 1, 0x0b, tb_reg_rel, 0}, + {"tbgt", 1, 0x0b, tb_reg_rel, 0}, + {"tble", 1, 0x0b, tb_reg_rel, 0}, + + {"tbne.b", 1, 0x0b, tb_opr_rel, 0}, + {"tbeq.b", 1, 0x0b, tb_opr_rel, 0}, + {"tbpl.b", 1, 0x0b, tb_opr_rel, 0}, + {"tbmi.b", 1, 0x0b, tb_opr_rel, 0}, + {"tbgt.b", 1, 0x0b, tb_opr_rel, 0}, + {"tble.b", 1, 0x0b, tb_opr_rel, 0}, + + {"tbne.w", 1, 0x0b, tb_opr_rel, 0}, + {"tbeq.w", 1, 0x0b, tb_opr_rel, 0}, + {"tbpl.w", 1, 0x0b, tb_opr_rel, 0}, + {"tbmi.w", 1, 0x0b, tb_opr_rel, 0}, + {"tbgt.w", 1, 0x0b, tb_opr_rel, 0}, + {"tble.w", 1, 0x0b, tb_opr_rel, 0}, + + {"tbne.p", 1, 0x0b, tb_opr_rel, 0}, + {"tbeq.p", 1, 0x0b, tb_opr_rel, 0}, + {"tbpl.p", 1, 0x0b, tb_opr_rel, 0}, + {"tbmi.p", 1, 0x0b, tb_opr_rel, 0}, + {"tbgt.p", 1, 0x0b, tb_opr_rel, 0}, + {"tble.p", 1, 0x0b, tb_opr_rel, 0}, + + {"tbne.l", 1, 0x0b, tb_opr_rel, 0}, + {"tbeq.l", 1, 0x0b, tb_opr_rel, 0}, + {"tbpl.l", 1, 0x0b, tb_opr_rel, 0}, + {"tbmi.l", 1, 0x0b, tb_opr_rel, 0}, + {"tbgt.l", 1, 0x0b, tb_opr_rel, 0}, + {"tble.l", 1, 0x0b, tb_opr_rel, 0}, + + {"mov.b", 1, 0x0c, imm_opr, 0}, + {"mov.w", 1, 0x0d, imm_opr, 0}, + {"mov.p", 1, 0x0e, imm_opr, 0}, + {"mov.l", 1, 0x0f, imm_opr, 0}, + + {"rol", 1, 0x10, rol, 0}, + {"rol.b", 1, 0x10, rol, 0}, + {"rol.w", 1, 0x10, rol, 0}, + {"rol.p", 1, 0x10, rol, 0}, + {"rol.l", 1, 0x10, rol, 0}, + + {"ror", 1, 0x10, ror, 0}, + {"ror.b", 1, 0x10, ror, 0}, + {"ror.w", 1, 0x10, ror, 0}, + {"ror.p", 1, 0x10, ror, 0}, + {"ror.l", 1, 0x10, ror, 0}, + + {"lsl", 1, 0x10, shift_reg, 0}, + {"lsr", 1, 0x10, shift_reg, 0}, + {"asl", 1, 0x10, shift_reg, 0}, + {"asr", 1, 0x10, shift_reg, 0}, + + {"lsl.b", 1, 0x10, shift_two_operand, 0}, + {"lsl.w", 1, 0x10, shift_two_operand, 0}, + {"lsl.p", 1, 0x10, shift_two_operand, 0}, + {"lsl.l", 1, 0x10, shift_two_operand, 0}, + {"asl.b", 1, 0x10, shift_two_operand, 0}, + {"asl.w", 1, 0x10, shift_two_operand, 0}, + {"asl.p", 1, 0x10, shift_two_operand, 0}, + {"asl.l", 1, 0x10, shift_two_operand, 0}, + + {"lsr.b", 1, 0x10, shift_two_operand, 0}, + {"lsr.w", 1, 0x10, shift_two_operand, 0}, + {"lsr.p", 1, 0x10, shift_two_operand, 0}, + {"lsr.l", 1, 0x10, shift_two_operand, 0}, + {"asr.b", 1, 0x10, shift_two_operand, 0}, + {"asr.w", 1, 0x10, shift_two_operand, 0}, + {"asr.p", 1, 0x10, shift_two_operand, 0}, + {"asr.l", 1, 0x10, shift_two_operand, 0}, + + {"lsl.b", 1, 0x10, shift_opr_imm, 0}, + {"lsl.w", 1, 0x10, shift_opr_imm, 0}, + {"lsl.p", 1, 0x10, shift_opr_imm, 0}, + {"lsl.l", 1, 0x10, shift_opr_imm, 0}, + {"asl.b", 1, 0x10, shift_opr_imm, 0}, + {"asl.w", 1, 0x10, shift_opr_imm, 0}, + {"asl.p", 1, 0x10, shift_opr_imm, 0}, + {"asl.l", 1, 0x10, shift_opr_imm, 0}, + + {"lsr.b", 1, 0x10, shift_opr_imm, 0}, + {"lsr.w", 1, 0x10, shift_opr_imm, 0}, + {"lsr.p", 1, 0x10, shift_opr_imm, 0}, + {"lsr.l", 1, 0x10, shift_opr_imm, 0}, + {"asr.b", 1, 0x10, shift_opr_imm, 0}, + {"asr.w", 1, 0x10, shift_opr_imm, 0}, + {"asr.p", 1, 0x10, shift_opr_imm, 0}, + {"asr.l", 1, 0x10, shift_opr_imm, 0}, + + {"mov.b", 1, 0x1c, opr_opr, 0}, + {"mov.w", 1, 0x1d, opr_opr, 0}, + {"mov.p", 1, 0x1e, opr_opr, 0}, + {"mov.l", 1, 0x1f, opr_opr, 0}, + + {"bra", 1, 0x20, rel, 0}, + {"bsr", 1, 0x21, rel, 0}, + {"bhi", 1, 0x22, rel, 0}, + {"bls", 1, 0x23, rel, 0}, + {"bcc", 1, 0x24, rel, 0}, + {"bcs", 1, 0x25, rel, 0}, + {"bne", 1, 0x26, rel, 0}, + {"beq", 1, 0x27, rel, 0}, + {"bvc", 1, 0x28, rel, 0}, + {"bvs", 1, 0x29, rel, 0}, + {"bpl", 1, 0x2a, rel, 0}, + {"bmi", 1, 0x2b, rel, 0}, + {"bge", 1, 0x2c, rel, 0}, + {"blt", 1, 0x2d, rel, 0}, + {"bgt", 1, 0x2e, rel, 0}, + {"ble", 1, 0x2f, rel, 0}, + + {"inc", 1, 0x30, reg_inh, 0}, + {"clr", 1, 0x38, reg_inh, 0}, + {"dec", 1, 0x40, reg_inh, 0}, + + {"muls", 1, 0x48, mul_reg_reg_reg, 0}, + {"mulu", 1, 0x48, mul_reg_reg_reg, 0}, + + {"muls.b", 1, 0x48, mul_reg_reg_opr, 0}, + {"muls.w", 1, 0x48, mul_reg_reg_opr, 0}, + {"muls.l", 1, 0x48, mul_reg_reg_opr, 0}, + + {"mulu.b", 1, 0x48, mul_reg_reg_opr, 0}, + {"mulu.w", 1, 0x48, mul_reg_reg_opr, 0}, + {"mulu.l", 1, 0x48, mul_reg_reg_opr, 0}, + + {"muls.b", 1, 0x48, mul_reg_reg_imm, 0}, + {"muls.w", 1, 0x48, mul_reg_reg_imm, 0}, + {"muls.l", 1, 0x48, mul_reg_reg_imm, 0}, + + {"mulu.b", 1, 0x48, mul_reg_reg_imm, 0}, + {"mulu.w", 1, 0x48, mul_reg_reg_imm, 0}, + {"mulu.l", 1, 0x48, mul_reg_reg_imm, 0}, + + {"muls.bb", 1, 0x48, mul_reg_opr_opr, 0}, + {"muls.bw", 1, 0x48, mul_reg_opr_opr, 0}, + {"muls.bp", 1, 0x48, mul_reg_opr_opr, 0}, + {"muls.bl", 1, 0x48, mul_reg_opr_opr, 0}, + + {"muls.wb", 1, 0x48, mul_reg_opr_opr, 0}, + {"muls.ww", 1, 0x48, mul_reg_opr_opr, 0}, + {"muls.wp", 1, 0x48, mul_reg_opr_opr, 0}, + {"muls.wl", 1, 0x48, mul_reg_opr_opr, 0}, + + {"muls.pb", 1, 0x48, mul_reg_opr_opr, 0}, + {"muls.pw", 1, 0x48, mul_reg_opr_opr, 0}, + {"muls.pp", 1, 0x48, mul_reg_opr_opr, 0}, + {"muls.pl", 1, 0x48, mul_reg_opr_opr, 0}, + + {"muls.lb", 1, 0x48, mul_reg_opr_opr, 0}, + {"muls.lw", 1, 0x48, mul_reg_opr_opr, 0}, + {"muls.lp", 1, 0x48, mul_reg_opr_opr, 0}, + {"muls.ll", 1, 0x48, mul_reg_opr_opr, 0}, + + {"mulu.bb", 1, 0x48, mul_reg_opr_opr, 0}, + {"mulu.bw", 1, 0x48, mul_reg_opr_opr, 0}, + {"mulu.bp", 1, 0x48, mul_reg_opr_opr, 0}, + {"mulu.bl", 1, 0x48, mul_reg_opr_opr, 0}, + + {"mulu.wb", 1, 0x48, mul_reg_opr_opr, 0}, + {"mulu.ww", 1, 0x48, mul_reg_opr_opr, 0}, + {"mulu.wp", 1, 0x48, mul_reg_opr_opr, 0}, + {"mulu.wl", 1, 0x48, mul_reg_opr_opr, 0}, + + {"mulu.pb", 1, 0x48, mul_reg_opr_opr, 0}, + {"mulu.pw", 1, 0x48, mul_reg_opr_opr, 0}, + {"mulu.pp", 1, 0x48, mul_reg_opr_opr, 0}, + {"mulu.pl", 1, 0x48, mul_reg_opr_opr, 0}, + + {"mulu.lb", 1, 0x48, mul_reg_opr_opr, 0}, + {"mulu.lw", 1, 0x48, mul_reg_opr_opr, 0}, + {"mulu.lp", 1, 0x48, mul_reg_opr_opr, 0}, + {"mulu.ll", 1, 0x48, mul_reg_opr_opr, 0}, + + {"add", 1, 0x50, regd_imm, 0}, + {"and", 1, 0x58, regd_imm, 0}, + + {"add", 1, 0x60, regd_opr, 0}, + {"and", 1, 0x68, regd_opr, 0}, + + {"sub", 1, 0x70, regd_imm, 0}, + {"or", 1, 0x78, regd_imm, 0}, + + {"sub", 1, 0x80, regd_opr, 0}, + {"or", 1, 0x88, regd_opr, 0}, + + {"ld", 1, 0x90, regdxy_imm, 0}, + + {"clr", 1, 0x9a, clr_xy, 0}, + {"tfr", 1, 0x9e, tfr, 0}, + {"zex", 1, 0x9e, tfr, 0}, + + {"ld", 1, 0xa0, regdxy_opr, 0xb0}, + + {"jmp", 1, 0xaa, opr, 0xba}, + {"jsr", 1, 0xab, opr, 0xbb}, + + {"exg", 1, 0xae, tfr, 0}, + {"sex", 1, 0xae, tfr, 0}, + + {"st", 1, 0xc0, regdxy_opr, 0xd0}, + + {"andcc", 1, 0xce, imm8, 0}, + {"orcc", 1, 0xde, imm8, 0}, + + {"inc.b", 1, 0x9c, opr, 0}, + {"inc.w", 1, 0x9d, opr, 0}, + {"inc.l", 1, 0x9f, opr, 0}, + + {"dec.b", 1, 0xac, opr, 0}, + {"dec.w", 1, 0xad, opr, 0}, + {"dec.l", 1, 0xaf, opr, 0}, + + {"clr.b", 1, 0xbc, opr, 0}, + {"clr.w", 1, 0xbd, opr, 0}, + {"clr.p", 1, 0xbe, opr, 0}, + {"clr.l", 1, 0xbf, opr, 0}, + + {"com.b", 1, 0xcc, opr, 0}, + {"com.w", 1, 0xcd, opr, 0}, + {"com.l", 1, 0xcf, opr, 0}, + + {"neg.b", 1, 0xdc, opr, 0}, + {"neg.w", 1, 0xdd, opr, 0}, + {"neg.l", 1, 0xdf, opr, 0}, + + {"bclr", 1, 0xec, bm_regd_imm, 0}, + {"bset", 1, 0xed, bm_regd_imm, 0}, + {"btgl", 1, 0xee, bm_regd_imm, 0}, + + {"bclr", 1, 0xec, bm_regd_reg, 0}, + {"bset", 1, 0xed, bm_regd_reg, 0}, + {"btgl", 1, 0xee, bm_regd_reg, 0}, + + {"bclr.b", 1, 0xec, bm_opr_imm, 0}, + {"bclr.w", 1, 0xec, bm_opr_imm, 0}, + {"bclr.l", 1, 0xec, bm_opr_imm, 0}, + + {"bset.b", 1, 0xed, bm_opr_imm, 0}, + {"bset.w", 1, 0xed, bm_opr_imm, 0}, + {"bset.l", 1, 0xed, bm_opr_imm, 0}, + + {"btgl.b", 1, 0xee, bm_opr_imm, 0}, + {"btgl.w", 1, 0xee, bm_opr_imm, 0}, + {"btgl.l", 1, 0xee, bm_opr_imm, 0}, + + {"bclr.b", 1, 0xec, bm_opr_reg, 0}, + {"bclr.w", 1, 0xec, bm_opr_reg, 0}, + {"bclr.l", 1, 0xec, bm_opr_reg, 0}, + + {"bset.b", 1, 0xed, bm_opr_reg, 0}, + {"bset.w", 1, 0xed, bm_opr_reg, 0}, + {"bset.l", 1, 0xed, bm_opr_reg, 0}, + + {"btgl.b", 1, 0xee, bm_opr_reg, 0}, + {"btgl.w", 1, 0xee, bm_opr_reg, 0}, + {"btgl.l", 1, 0xee, bm_opr_reg, 0}, + + {"cmp", 1, 0xe0, regdxy_imm, 0}, + {"cmp", 1, 0xf0, regdxy_opr, 0}, + + {"cmp", 1, 0xfc, regx_regy, 0}, + {"sub", 1, 0xfd, regd6_regx_regy, 0}, + {"sub", 1, 0xfe, regd6_regy_regx, 0}, + + {"swi", 1, 0xff, no_operands, 0}, + + /* Page 2 */ + + /* The -10 below is a kludge. The opcode is in fact 0x00 */ + {"ld", 2, -10, regs_opr, 0}, + + /* The -9 below is a kludge. The opcode is in fact 0x01 */ + {"st", 2, -9, regs_opr, 0}, + + /* The -8 below is a kludge. The opcode is in fact 0x02 */ + {"cmp", 2, -8, regs_opr, 0}, + + /* The -7 below is a kludge. The opcode is in fact 0x03 */ + {"ld", 2, -7, regs_imm, 0}, + + /* The -6 below is a kludge. The opcode is in fact 0x04 */ + {"cmp", 2, -6, regs_imm, 0}, + + {"bfext", 2, 0x08, bfe_reg_reg_reg, 0}, + {"bfext", 2, 0x08, bfe_reg_reg_imm, 0}, + {"bfext.b", 2, 0x08, bfe_reg_opr_reg, 0}, + {"bfext.w", 2, 0x08, bfe_reg_opr_reg, 0}, + {"bfext.p", 2, 0x08, bfe_reg_opr_reg, 0}, + {"bfext.l", 2, 0x08, bfe_reg_opr_reg, 0}, + {"bfext.b", 2, 0x08, bfe_opr_reg_reg, 0}, + {"bfext.w", 2, 0x08, bfe_opr_reg_reg, 0}, + {"bfext.p", 2, 0x08, bfe_opr_reg_reg, 0}, + {"bfext.l", 2, 0x08, bfe_opr_reg_reg, 0}, + {"bfext.b", 2, 0x08, bfe_reg_opr_imm, 0}, + {"bfext.w", 2, 0x08, bfe_reg_opr_imm, 0}, + {"bfext.p", 2, 0x08, bfe_reg_opr_imm, 0}, + {"bfext.l", 2, 0x08, bfe_reg_opr_imm, 0}, + {"bfext.b", 2, 0x08, bfe_opr_reg_imm, 0}, + {"bfext.w", 2, 0x08, bfe_opr_reg_imm, 0}, + {"bfext.p", 2, 0x08, bfe_opr_reg_imm, 0}, + {"bfext.l", 2, 0x08, bfe_opr_reg_imm, 0}, + + + {"bfins", 2, 0x08, bfi_reg_reg_reg, 0}, + {"bfins", 2, 0x08, bfi_reg_reg_imm, 0}, + {"bfins.b", 2, 0x08, bfi_reg_opr_reg, 0}, + {"bfins.w", 2, 0x08, bfi_reg_opr_reg, 0}, + {"bfins.p", 2, 0x08, bfi_reg_opr_reg, 0}, + {"bfins.l", 2, 0x08, bfi_reg_opr_reg, 0}, + {"bfins.b", 2, 0x08, bfi_opr_reg_reg, 0}, + {"bfins.w", 2, 0x08, bfi_opr_reg_reg, 0}, + {"bfins.p", 2, 0x08, bfi_opr_reg_reg, 0}, + {"bfins.l", 2, 0x08, bfi_opr_reg_reg, 0}, + {"bfins.b", 2, 0x08, bfi_reg_opr_imm, 0}, + {"bfins.w", 2, 0x08, bfi_reg_opr_imm, 0}, + {"bfins.p", 2, 0x08, bfi_reg_opr_imm, 0}, + {"bfins.l", 2, 0x08, bfi_reg_opr_imm, 0}, + {"bfins.b", 2, 0x08, bfi_opr_reg_imm, 0}, + {"bfins.w", 2, 0x08, bfi_opr_reg_imm, 0}, + {"bfins.p", 2, 0x08, bfi_opr_reg_imm, 0}, + {"bfins.l", 2, 0x08, bfi_opr_reg_imm, 0}, + + + {"minu", 2, 0x10, regd_opr, 0}, + {"maxu", 2, 0x18, regd_opr, 0}, + {"mins", 2, 0x20, regd_opr, 0}, + {"maxs", 2, 0x28, regd_opr, 0}, + + {"clb", 2, 0x91, tfr, 0}, + + {"trap", 2, 0x00, trap_imm, 0}, + {"abs", 2, 0x40, reg_inh, 0}, + {"sat", 2, 0xa0, reg_inh, 0}, + + {"rti", 2, 0x90, no_operands, 0}, + {"stop", 2, 0x05, no_operands, 0}, + {"wai", 2, 0x06, no_operands, 0}, + {"sys", 2, 0x07, no_operands, 0}, + + {"bit", 2, 0x58, regd_imm, 0}, + {"bit", 2, 0x68, regd_opr, 0}, + + {"adc", 2, 0x50, regd_imm, 0}, + {"adc", 2, 0x60, regd_opr, 0}, + + {"sbc", 2, 0x70, regd_imm, 0}, + {"eor", 2, 0x78, regd_imm, 0}, + + {"sbc", 2, 0x80, regd_opr, 0}, + {"eor", 2, 0x88, regd_opr, 0}, + + {"divs", 2, 0x30, mul_reg_reg_reg, 0}, + {"divu", 2, 0x30, mul_reg_reg_reg, 0}, + + {"divs.b", 2, 0x30, mul_reg_reg_opr, 0}, + {"divs.w", 2, 0x30, mul_reg_reg_opr, 0}, + {"divs.l", 2, 0x30, mul_reg_reg_opr, 0}, + + {"divu.b", 2, 0x30, mul_reg_reg_opr, 0}, + {"divu.w", 2, 0x30, mul_reg_reg_opr, 0}, + {"divu.l", 2, 0x30, mul_reg_reg_opr, 0}, + + {"divs.b", 2, 0x30, mul_reg_reg_imm, 0}, + {"divs.w", 2, 0x30, mul_reg_reg_imm, 0}, + {"divs.l", 2, 0x30, mul_reg_reg_imm, 0}, + + {"divu.b", 2, 0x30, mul_reg_reg_imm, 0}, + {"divu.w", 2, 0x30, mul_reg_reg_imm, 0}, + {"divu.l", 2, 0x30, mul_reg_reg_imm, 0}, + + {"divs.bb", 2, 0x30, mul_reg_opr_opr, 0}, + {"divs.bw", 2, 0x30, mul_reg_opr_opr, 0}, + {"divs.bp", 2, 0x30, mul_reg_opr_opr, 0}, + {"divs.bl", 2, 0x30, mul_reg_opr_opr, 0}, + + {"divs.wb", 2, 0x30, mul_reg_opr_opr, 0}, + {"divs.ww", 2, 0x30, mul_reg_opr_opr, 0}, + {"divs.wp", 2, 0x30, mul_reg_opr_opr, 0}, + {"divs.wl", 2, 0x30, mul_reg_opr_opr, 0}, + + {"divs.pb", 2, 0x30, mul_reg_opr_opr, 0}, + {"divs.pw", 2, 0x30, mul_reg_opr_opr, 0}, + {"divs.pp", 2, 0x30, mul_reg_opr_opr, 0}, + {"divs.pl", 2, 0x30, mul_reg_opr_opr, 0}, + + {"divs.lb", 2, 0x30, mul_reg_opr_opr, 0}, + {"divs.lw", 2, 0x30, mul_reg_opr_opr, 0}, + {"divs.lp", 2, 0x30, mul_reg_opr_opr, 0}, + {"divs.ll", 2, 0x30, mul_reg_opr_opr, 0}, + + {"divu.bb", 2, 0x30, mul_reg_opr_opr, 0}, + {"divu.bw", 2, 0x30, mul_reg_opr_opr, 0}, + {"divu.bp", 2, 0x30, mul_reg_opr_opr, 0}, + {"divu.bl", 2, 0x30, mul_reg_opr_opr, 0}, + + {"divu.wb", 2, 0x30, mul_reg_opr_opr, 0}, + {"divu.ww", 2, 0x30, mul_reg_opr_opr, 0}, + {"divu.wp", 2, 0x30, mul_reg_opr_opr, 0}, + {"divu.wl", 2, 0x30, mul_reg_opr_opr, 0}, + + {"divu.pb", 2, 0x30, mul_reg_opr_opr, 0}, + {"divu.pw", 2, 0x30, mul_reg_opr_opr, 0}, + {"divu.pp", 2, 0x30, mul_reg_opr_opr, 0}, + {"divu.pl", 2, 0x30, mul_reg_opr_opr, 0}, + + {"divu.lb", 2, 0x30, mul_reg_opr_opr, 0}, + {"divu.lw", 2, 0x30, mul_reg_opr_opr, 0}, + {"divu.lp", 2, 0x30, mul_reg_opr_opr, 0}, + {"divu.ll", 2, 0x30, mul_reg_opr_opr, 0}, + + // + + {"qmuls", 2, 0xb0, mul_reg_reg_reg, 0}, + {"qmulu", 2, 0xb0, mul_reg_reg_reg, 0}, + + {"qmuls.b", 2, 0xb0, mul_reg_reg_opr, 0}, + {"qmuls.w", 2, 0xb0, mul_reg_reg_opr, 0}, + {"qmuls.l", 2, 0xb0, mul_reg_reg_opr, 0}, + + {"qmulu.b", 2, 0xb0, mul_reg_reg_opr, 0}, + {"qmulu.w", 2, 0xb0, mul_reg_reg_opr, 0}, + {"qmulu.l", 2, 0xb0, mul_reg_reg_opr, 0}, + + {"qmuls.b", 2, 0xb0, mul_reg_reg_imm, 0}, + {"qmuls.w", 2, 0xb0, mul_reg_reg_imm, 0}, + {"qmuls.l", 2, 0xb0, mul_reg_reg_imm, 0}, + + {"qmulu.b", 2, 0xb0, mul_reg_reg_imm, 0}, + {"qmulu.w", 2, 0xb0, mul_reg_reg_imm, 0}, + {"qmulu.l", 2, 0xb0, mul_reg_reg_imm, 0}, + + {"qmuls.bb", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmuls.bw", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmuls.bp", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmuls.bl", 2, 0xb0, mul_reg_opr_opr, 0}, + + {"qmuls.wb", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmuls.ww", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmuls.wp", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmuls.wl", 2, 0xb0, mul_reg_opr_opr, 0}, + + {"qmuls.pb", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmuls.pw", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmuls.pp", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmuls.pl", 2, 0xb0, mul_reg_opr_opr, 0}, + + {"qmuls.lb", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmuls.lw", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmuls.lp", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmuls.ll", 2, 0xb0, mul_reg_opr_opr, 0}, + + {"qmulu.bb", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmulu.bw", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmulu.bp", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmulu.bl", 2, 0xb0, mul_reg_opr_opr, 0}, + + {"qmulu.wb", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmulu.ww", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmulu.wp", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmulu.wl", 2, 0xb0, mul_reg_opr_opr, 0}, + + {"qmulu.pb", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmulu.pw", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmulu.pp", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmulu.pl", 2, 0xb0, mul_reg_opr_opr, 0}, + + {"qmulu.lb", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmulu.lw", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmulu.lp", 2, 0xb0, mul_reg_opr_opr, 0}, + {"qmulu.ll", 2, 0xb0, mul_reg_opr_opr, 0}, + + + // + + {"macs", 2, 0x48, mul_reg_reg_reg, 0}, + {"macu", 2, 0x48, mul_reg_reg_reg, 0}, + + {"macs.b", 2, 0x48, mul_reg_reg_opr, 0}, + {"macs.w", 2, 0x48, mul_reg_reg_opr, 0}, + {"macs.l", 2, 0x48, mul_reg_reg_opr, 0}, + + {"macu.b", 2, 0x48, mul_reg_reg_opr, 0}, + {"macu.w", 2, 0x48, mul_reg_reg_opr, 0}, + {"macu.l", 2, 0x48, mul_reg_reg_opr, 0}, + + {"macs.b", 2, 0x48, mul_reg_reg_imm, 0}, + {"macs.w", 2, 0x48, mul_reg_reg_imm, 0}, + {"macs.l", 2, 0x48, mul_reg_reg_imm, 0}, + + {"macu.b", 2, 0x48, mul_reg_reg_imm, 0}, + {"macu.w", 2, 0x48, mul_reg_reg_imm, 0}, + {"macu.l", 2, 0x48, mul_reg_reg_imm, 0}, + + {"macs.bb", 2, 0x48, mul_reg_opr_opr, 0}, + {"macs.bw", 2, 0x48, mul_reg_opr_opr, 0}, + {"macs.bp", 2, 0x48, mul_reg_opr_opr, 0}, + {"macs.bl", 2, 0x48, mul_reg_opr_opr, 0}, + + {"macs.wb", 2, 0x48, mul_reg_opr_opr, 0}, + {"macs.ww", 2, 0x48, mul_reg_opr_opr, 0}, + {"macs.wp", 2, 0x48, mul_reg_opr_opr, 0}, + {"macs.wl", 2, 0x48, mul_reg_opr_opr, 0}, + + {"macs.pb", 2, 0x48, mul_reg_opr_opr, 0}, + {"macs.pw", 2, 0x48, mul_reg_opr_opr, 0}, + {"macs.pp", 2, 0x48, mul_reg_opr_opr, 0}, + {"macs.pl", 2, 0x48, mul_reg_opr_opr, 0}, + + {"macs.lb", 2, 0x48, mul_reg_opr_opr, 0}, + {"macs.lw", 2, 0x48, mul_reg_opr_opr, 0}, + {"macs.lp", 2, 0x48, mul_reg_opr_opr, 0}, + {"macs.ll", 2, 0x48, mul_reg_opr_opr, 0}, + + {"macu.bb", 2, 0x48, mul_reg_opr_opr, 0}, + {"macu.bw", 2, 0x48, mul_reg_opr_opr, 0}, + {"macu.bp", 2, 0x48, mul_reg_opr_opr, 0}, + {"macu.bl", 2, 0x48, mul_reg_opr_opr, 0}, + + {"macu.wb", 2, 0x48, mul_reg_opr_opr, 0}, + {"macu.ww", 2, 0x48, mul_reg_opr_opr, 0}, + {"macu.wp", 2, 0x48, mul_reg_opr_opr, 0}, + {"macu.wl", 2, 0x48, mul_reg_opr_opr, 0}, + + {"macu.pb", 2, 0x48, mul_reg_opr_opr, 0}, + {"macu.pw", 2, 0x48, mul_reg_opr_opr, 0}, + {"macu.pp", 2, 0x48, mul_reg_opr_opr, 0}, + {"macu.pl", 2, 0x48, mul_reg_opr_opr, 0}, + + {"macu.lb", 2, 0x48, mul_reg_opr_opr, 0}, + {"macu.lw", 2, 0x48, mul_reg_opr_opr, 0}, + {"macu.lp", 2, 0x48, mul_reg_opr_opr, 0}, + {"macu.ll", 2, 0x48, mul_reg_opr_opr, 0}, + + + // + + {"mods", 2, 0x38, mul_reg_reg_reg, 0}, + {"modu", 2, 0x38, mul_reg_reg_reg, 0}, + + {"mods.b", 2, 0x38, mul_reg_reg_opr, 0}, + {"mods.w", 2, 0x38, mul_reg_reg_opr, 0}, + {"mods.l", 2, 0x38, mul_reg_reg_opr, 0}, + + {"modu.b", 2, 0x38, mul_reg_reg_opr, 0}, + {"modu.w", 2, 0x38, mul_reg_reg_opr, 0}, + {"modu.l", 2, 0x38, mul_reg_reg_opr, 0}, + + {"mods.b", 2, 0x38, mul_reg_reg_imm, 0}, + {"mods.w", 2, 0x38, mul_reg_reg_imm, 0}, + {"mods.l", 2, 0x38, mul_reg_reg_imm, 0}, + + {"modu.b", 2, 0x38, mul_reg_reg_imm, 0}, + {"modu.w", 2, 0x38, mul_reg_reg_imm, 0}, + {"modu.l", 2, 0x38, mul_reg_reg_imm, 0}, + + {"mods.bb", 2, 0x38, mul_reg_opr_opr, 0}, + {"mods.bw", 2, 0x38, mul_reg_opr_opr, 0}, + {"mods.bp", 2, 0x38, mul_reg_opr_opr, 0}, + {"mods.bl", 2, 0x38, mul_reg_opr_opr, 0}, + + {"mods.wb", 2, 0x38, mul_reg_opr_opr, 0}, + {"mods.ww", 2, 0x38, mul_reg_opr_opr, 0}, + {"mods.wp", 2, 0x38, mul_reg_opr_opr, 0}, + {"mods.wl", 2, 0x38, mul_reg_opr_opr, 0}, + + {"mods.pb", 2, 0x38, mul_reg_opr_opr, 0}, + {"mods.pw", 2, 0x38, mul_reg_opr_opr, 0}, + {"mods.pp", 2, 0x38, mul_reg_opr_opr, 0}, + {"mods.pl", 2, 0x38, mul_reg_opr_opr, 0}, + + {"mods.lb", 2, 0x38, mul_reg_opr_opr, 0}, + {"mods.lw", 2, 0x38, mul_reg_opr_opr, 0}, + {"mods.lp", 2, 0x38, mul_reg_opr_opr, 0}, + {"mods.ll", 2, 0x38, mul_reg_opr_opr, 0}, + + {"modu.bb", 2, 0x38, mul_reg_opr_opr, 0}, + {"modu.bw", 2, 0x38, mul_reg_opr_opr, 0}, + {"modu.bp", 2, 0x38, mul_reg_opr_opr, 0}, + {"modu.bl", 2, 0x38, mul_reg_opr_opr, 0}, + + {"modu.wb", 2, 0x38, mul_reg_opr_opr, 0}, + {"modu.ww", 2, 0x38, mul_reg_opr_opr, 0}, + {"modu.wp", 2, 0x38, mul_reg_opr_opr, 0}, + {"modu.wl", 2, 0x38, mul_reg_opr_opr, 0}, + + {"modu.pb", 2, 0x38, mul_reg_opr_opr, 0}, + {"modu.pw", 2, 0x38, mul_reg_opr_opr, 0}, + {"modu.pp", 2, 0x38, mul_reg_opr_opr, 0}, + {"modu.pl", 2, 0x38, mul_reg_opr_opr, 0}, + + {"modu.lb", 2, 0x38, mul_reg_opr_opr, 0}, + {"modu.lw", 2, 0x38, mul_reg_opr_opr, 0}, + {"modu.lp", 2, 0x38, mul_reg_opr_opr, 0}, + {"modu.ll", 2, 0x38, mul_reg_opr_opr, 0} +}; + + +/* Gas line assembler entry point. */ + +/* This is the main entry point for the machine-dependent assembler. str + points to a machine-dependent instruction. This function is supposed to + emit the frags/bytes it assembles to. */ +void +md_assemble (char *str) +{ + char *op_start; + char *op_end; + char name[20]; + size_t nlen = 0; + + fail_line_pointer = NULL; + + /* Find the opcode end and get the opcode in 'name'. The opcode is forced + lower case (the opcode table only has lower case op-codes). */ + for (op_start = op_end = str; + *op_end && !is_end_of_line[(int)*op_end] && *op_end != ' '; + op_end++) + { + name[nlen] = TOLOWER (op_start[nlen]); + nlen++; + gas_assert (nlen < sizeof (name) - 1); + } + name[nlen] = 0; + + if (nlen == 0) + { + as_bad (_("No instruction or missing opcode.")); + return; + } + + input_line_pointer = skip_whites (op_end); + + size_t i; + for (i = 0; i < sizeof (opcodes) / sizeof (opcodes[0]); ++i) + { + const struct instruction *opc = opcodes + i; + if (0 == strcmp (name, opc->name)) + { + if (opc->parse_operands (opc)) + return; + continue; + } + } + + as_bad (_("Invalid instruction: \"%s\""), str); + as_bad (_("First invalid token: \"%s\""), fail_line_pointer); + while (*input_line_pointer++) + ; +} + + + + + +/* Relocation, relaxation and frag conversions. */ + +/* PC-relative offsets are relative to the start of the + next instruction. That is, the address of the offset, plus its + size, since the offset is always the last part of the insn. */ +long +md_pcrel_from (fixS *fixP) +{ + long ret = fixP->fx_size + fixP->fx_frag->fr_address; + if (fixP->fx_addsy && S_IS_DEFINED (fixP->fx_addsy)) + ret += fixP->fx_where; + + return ret; +} + + +/* We need a port-specific relaxation function to cope with sym2 - sym1 + relative expressions with both symbols in the same segment (but not + necessarily in the same frag as this insn), for example: + ldab sym2-(sym1-2),pc + sym1: + The offset can be 5, 9 or 16 bits long. */ + +long +s12z_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS *fragP ATTRIBUTE_UNUSED, + long stretch ATTRIBUTE_UNUSED) +{ + return 0; +} + +void +md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED, + fragS *fragP ATTRIBUTE_UNUSED) +{ +} + +/* On an ELF system, we can't relax a weak symbol. The weak symbol + can be overridden at final link time by a non weak symbol. We can + relax externally visible symbol because there is no shared library + and such symbol can't be overridden (unless they are weak). */ + +/* Force truly undefined symbols to their maximum size, and generally set up + the frag list to be relaxed. */ +int +md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, asection *segment ATTRIBUTE_UNUSED) +{ + return 0; +} + + +/* If while processing a fixup, a reloc really needs to be created + then it is done here. */ +arelent * +tc_gen_reloc (asection *section, fixS *fixp) +{ + arelent *reloc = XNEW (arelent); + reloc->sym_ptr_ptr = XNEW (asymbol *); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); + reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; + reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); + if (reloc->howto == (reloc_howto_type *) NULL) + { + as_bad_where (fixp->fx_file, fixp->fx_line, + _("Relocation %d is not supported by object file format."), + (int) fixp->fx_r_type); + return NULL; + } + + if (0 == (section->flags & SEC_CODE)) + reloc->addend = fixp->fx_offset; + else + reloc->addend = fixp->fx_addnumber; + + return reloc; +} + +/* See whether we need to force a relocation into the output file. */ +int +tc_s12z_force_relocation (fixS *fixP) +{ + return generic_force_reloc (fixP); +} + +/* Here we decide which fixups can be adjusted to make them relative + to the beginning of the section instead of the symbol. Basically + we need to make sure that the linker relaxation is done + correctly, so in some cases we force the original symbol to be + used. */ +int +tc_s12z_fix_adjustable (fixS *fixP ATTRIBUTE_UNUSED) +{ + return 1; +} + +void +md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) +{ + long value = *valP; + + if (fixP->fx_addsy == (symbolS *) NULL) + fixP->fx_done = 1; + + /* We don't actually support subtracting a symbol. */ + if (fixP->fx_subsy != (symbolS *) NULL) + as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex.")); + + /* + Patch the instruction with the resolved operand. Elf relocation + info will also be generated to take care of linker/loader fixups. + */ + char *where = fixP->fx_frag->fr_literal + fixP->fx_where; + + switch (fixP->fx_r_type) + { + case BFD_RELOC_8: + ((bfd_byte *) where)[0] = (bfd_byte) value; + break; + case BFD_RELOC_24: + bfd_putb24 ((bfd_vma) value, (unsigned char *) where); + break; + case BFD_RELOC_32: + bfd_putb32 ((bfd_vma) value, (unsigned char *) where); + break; + case BFD_RELOC_16_PCREL: + if (value < -0x8000 || value > 0x7FFF) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Value out of 16-bit range.")); + + bfd_putb16 ((bfd_vma) value | 0x8000, (unsigned char *) where); + break; + + default: + as_fatal (_("Line %d: unknown relocation type: 0x%x."), + fixP->fx_line, fixP->fx_r_type); + } +} + +/* Set the ELF specific flags. */ +void +s12z_elf_final_processing (void) +{ +} diff --git a/gas/config/tc-s12z.h b/gas/config/tc-s12z.h new file mode 100644 index 00000000000..9d6b571b45c --- /dev/null +++ b/gas/config/tc-s12z.h @@ -0,0 +1,105 @@ +/* tc-s12z.h -- Header file for tc-s12z.c. + Copyright (C) 1999-2018 Free Software Foundation, Inc. + + 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 3, 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. */ + +struct fix; + +/* Define TC_M68K so that we can use the MRI mode. */ +#define TC_M68K + +#define TARGET_BYTES_BIG_ENDIAN 1 + +/* Motorola assembler specs does not require '.' before pseudo-ops. */ +#define NO_PSEUDO_DOT 1 + +/* The target BFD architecture. */ +#define TARGET_ARCH (s12z_arch ()) +extern enum bfd_architecture s12z_arch (void); + +#define TARGET_MACH (s12z_mach ()) +extern int s12z_mach (void); + +#define TARGET_FORMAT (s12z_arch_format ()) +extern const char *s12z_arch_format (void); + +#define LISTING_WORD_SIZE 1 /* A word is 1 bytes */ +#define LISTING_LHS_WIDTH 4 /* One word on the first line */ +#define LISTING_LHS_WIDTH_SECOND 4 /* One word on the second line */ +#define LISTING_LHS_CONT_LINES 4 /* And 4 lines max */ +#define LISTING_HEADER s12z_listing_header () +extern const char *s12z_listing_header (void); + +/* Permit temporary numeric labels. */ +#define LOCAL_LABELS_FB 1 + +#define tc_init_after_args s12z_init_after_args +extern void s12z_init_after_args (void); + +#define md_parse_long_option s12z_parse_long_option +extern int s12z_parse_long_option (char *); + +#define DWARF2_LINE_MIN_INSN_LENGTH 1 + +/* Use 32-bit address to represent a symbol address so that we can + represent them with their page number. */ +#define DWARF2_ADDR_SIZE(bfd) 4 + +/* We don't need to handle .word strangely. */ +#define WORKING_DOT_WORD + +#define md_number_to_chars number_to_chars_bigendian + +/* Relax table to translate short relative branches (-128..127) into + absolute branches. */ +#define TC_GENERIC_RELAX_TABLE md_relax_table +extern struct relax_type md_relax_table[]; + +/* GAS only handles relaxations for pc-relative data targeting addresses + in the same segment, so we have to handle the rest on our own. */ +#define md_relax_frag(SEG, FRAGP, STRETCH) \ + ((FRAGP)->fr_symbol != NULL \ + && S_GET_SEGMENT ((FRAGP)->fr_symbol) == (SEG) \ + ? relax_frag (SEG, FRAGP, STRETCH) \ + : s12z_relax_frag (SEG, FRAGP, STRETCH)) +extern long s12z_relax_frag (segT, fragS*, long); + +#define TC_HANDLES_FX_DONE + +#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */ + +/* Values passed to md_apply_fix don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + +#define TC_FORCE_RELOCATION(fix) tc_s12z_force_relocation (fix) +extern int tc_s12z_force_relocation (struct fix *); + +#define tc_fix_adjustable(X) tc_s12z_fix_adjustable(X) +extern int tc_s12z_fix_adjustable (struct fix *); + +#define md_operand(x) + +#define elf_tc_final_processing s12z_elf_final_processing +extern void s12z_elf_final_processing (void); + +#define tc_print_statistics(FILE) s12z_print_statistics (FILE) +extern void s12z_print_statistics (FILE *); diff --git a/gas/configure.tgt b/gas/configure.tgt index 67edc1d1978..3d0415c1aa4 100644 --- a/gas/configure.tgt +++ b/gas/configure.tgt @@ -75,6 +75,7 @@ case ${cpu} in m680[012346]0) cpu_type=m68k ;; m6811|m6812|m68hc12) cpu_type=m68hc11 ;; m683??) cpu_type=m68k ;; + s12z) cpu_type=s12z ;; mep) cpu_type=mep endian=little ;; microblazeel*) cpu_type=microblaze endian=little;; microblaze*) cpu_type=microblaze endian=big;; @@ -285,6 +286,8 @@ case ${generic_target} in m68k-*-gnu*) fmt=elf ;; m68k-*-netbsdelf*) fmt=elf em=nbsd ;; + s12z-*-*) fmt=elf ;; + mep-*-elf) fmt=elf ;; metag-*-elf) fmt=elf ;; diff --git a/gas/doc/Makefile.am b/gas/doc/Makefile.am index 80893581e12..c9c3405272a 100644 --- a/gas/doc/Makefile.am +++ b/gas/doc/Makefile.am @@ -65,6 +65,7 @@ CPU_DOCS = \ c-m32r.texi \ c-m68hc11.texi \ c-m68k.texi \ + c-s12z.texi \ c-metag.texi \ c-microblaze.texi \ c-mips.texi \ diff --git a/gas/doc/Makefile.in b/gas/doc/Makefile.in index 643df6175d1..a126e2f1596 100644 --- a/gas/doc/Makefile.in +++ b/gas/doc/Makefile.in @@ -340,6 +340,7 @@ CPU_DOCS = \ c-m32r.texi \ c-m68hc11.texi \ c-m68k.texi \ + c-s12z.texi \ c-metag.texi \ c-microblaze.texi \ c-mips.texi \ diff --git a/gas/doc/all.texi b/gas/doc/all.texi index 47d55df4f6b..2b8af690273 100644 --- a/gas/doc/all.texi +++ b/gas/doc/all.texi @@ -46,6 +46,7 @@ @set M32R @set xc16x @set M68HC11 +@set S12Z @set M680X0 @set MCORE @set METAG diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo index 35616c8b55d..b6b16b7b292 100644 --- a/gas/doc/as.texinfo +++ b/gas/doc/as.texinfo @@ -7565,6 +7565,9 @@ subject, see the hardware manufacturer's manual. @ifset M68HC11 * M68HC11-Dependent:: M68HC11 and 68HC12 Dependent Features @end ifset +@ifset S12Z +* S12Z-Dependent:: S12Z Dependent Features +@end ifset @ifset METAG * Meta-Dependent :: Meta Dependent Features @end ifset @@ -7776,6 +7779,10 @@ family. @include c-m68hc11.texi @end ifset +@ifset S12Z +@include c-s12z.texi +@end ifset + @ifset METAG @include c-metag.texi @end ifset diff --git a/gas/doc/c-s12z.texi b/gas/doc/c-s12z.texi new file mode 100644 index 00000000000..9c8a97f3ccb --- /dev/null +++ b/gas/doc/c-s12z.texi @@ -0,0 +1,212 @@ +@c Copyright (C) 2018 Free Software Foundation, Inc. +@c This is part of the GAS manual. +@c For copying conditions, see the file as.texinfo. +@ifset GENERIC +@page +@node S12Z-Dependent +@chapter S12Z Dependent Features +@end ifset +@ifclear GENERIC +@node Machine Dependencies +@chapter S12Z Dependent Features +@end ifclear + +The Freescale S12Z version of @code{@value{AS}} has a few machine +dependent features. + +@cindex S12Z support +@menu +* S12Z-Opts:: S12Z Options +* S12Z-Syntax:: Syntax +* S12Z-Directives:: Assembler Directives +* S12Z-opcodes:: Opcodes +@end menu + +@node S12Z-Opts +@section S12Z Options + +@cindex options, S12Z +@cindex S12Z options + +@node S12Z-Syntax +@section Syntax + +@cindex S12Z syntax +@cindex syntax, S12Z + +In the S12Z syntax, the instruction name comes first and it may +be followed by one or by several operands. +In most cases the maximum number of operands is three. +Some instructions accept and (in certain situations require) a suffix +indicating the size of the operand. +The suffix is separated from the instruction name by a period (@samp{.}) +and may be one of @samp{b}, @samp{w}, @samp{p} or @samp{l} indicating +`byte' (a single byte), `word' (2 bytes), `pointer' (3 bytes) or `long' (4 bytes) +respectively. +Operands are separated by a comma (@samp{,}). +A comma however does not act as a separator if it appears within parentheses +(@samp{()}) or within square brackets (@samp{[]}). +@code{@value{AS}} will complain if too many, too few or inappropriate operands +are specified for a given instruction. +The MRI mode is not supported for this architecture. +Example: + +@smallexample + bset.b 0xA98, #5 + mov.b #6, 0x2409 + ld d0, #4 + mov.l (d0, x), 0x2409 + inc d0 + cmp d0, #12 + blt *-4 + lea x, 0x2409 + st y, (1, x) +@end smallexample + +@cindex line comment character, S12Z +@cindex S12Z line comment character +The presence of a @samp{;} character anywhere +on a line indicates the start of a comment that extends to the end of +that line. + +A @samp{*} or a @samp{#} character at the start of a line also +introduces a line comment, but these characters do not work elsewhere +on the line. If the first character of the line is a @samp{#} then as +well as starting a comment, the line could also be logical line number +directive (@pxref{Comments}) or a preprocessor control command +(@pxref{Preprocessing}). + +@cindex line separator, S12Z +@cindex statement separator, S12Z +@cindex S12Z line separator +The S12Z assembler does not currently support a line separator +character. + +@cindex S12Z addressing modes +@cindex addressing modes, S12Z +The following addressing modes are understood for the S12Z. +@table @dfn +@item Immediate +@samp{#@var{number}} + +@item Immediate Bit Field +@samp{#@var{width}:@var{offset}} + +Bit field instructions in the immediate mode require the width and offset to +be specified. +The @var{width} pararmeter specifies the number of bits in the field. +It should be a number in the range [1,32]. +@var{Offset} determines the position within the field where the operation +should start. +It should be a number in the range [0,31]. + +@item Relative +@samp{*@var{symbol}}, or @samp{*[+-]@var{digits}} + +Program counter relative addresses have a width of 15 bits. +Thus, they must be within the range [-32768, 32767]. + +@item Register +@samp{@var{reg}} + +Some instructions accept a register as an operand. +In general, @var{reg} may be a data register (@samp{D0}, @samp{D1} @dots{} +@samp{D7}), the @var{X} register or the @var{Y} register. + +A few instructions accept as an argument the stack pointer +register (@samp{S}), and/or the program counter (@samp{P}). + +Some very special instructions accept arguments which refer to the +condition code register. For these arguments the syntax is +@samp{CCR}, @samp{CCH} or @samp{CCL} which refer to the complete condition code register, the condition code register high byte and the condition code register low byte respectively. + +@item Absolute Direct +@samp{@var{symbol}}, or @samp{@var{digits}} + +@item Absolute Indirect +@samp{[@var{symbol}}, or @samp{@var{digits}]} + + +@item Constant Offset Indexed +@samp{(@var{number},@var{reg})} + +@var{Reg} may be either @samp{X}, @samp{Y}, @samp{S} or +@samp{P} or one of the data registers @samp{D0}, @samp{D1} @dots{} +@samp{D7}. +If any of the registers @samp{D2} @dots{} @samp{D5} are specified, then the +register value is treated as a signed value. +Otherwise it is treated as unsigned. +@var{Number} may be any integer in the range [-8388608,8388607]. + +@item Offset Indexed Indirect +@samp{[@var{number},@var{reg}]} + +@var{Reg} may be either @samp{X}, @samp{Y}, @samp{S} or +@samp{P}. +@var{Number} may be any integer in the range [-8388608,8388607]. + +@item Auto Pre-Increment/Pre-Decrement/Post-Increment/Post-Decrement +@samp{-@var{reg}}, +@samp{+@var{reg}}, +@samp{@var{reg}-} or +@samp{@var{reg}+} + +This addressing mode is typically used to access a value at an address, +and simultaneously to increment/decrement the register pointing to that +address. +Thus @var{reg} may be any of the 24 bit registers @samp{X}, @samp{Y}, or +@samp{S}. +Pre-increment and post-decrement are not available for +register @samp{S} (only post-increment and pre-decrement are available). + +@item Register Offset Direct +@samp{(@var{data-reg},@var{reg})} + +@var{Reg} can be either @samp{X}, @samp{Y}, or @samp{S}. +@var{Data-reg} +must be one of the data registers @samp{D0}, @samp{D1} @dots{} @samp{D7}. +If any of the registers @samp{D2} @dots{} @samp{D5} are specified, then +the register value is treated as a signed value. +Otherwise it is treated as unsigned. + +@item Register Offset Indirect +@samp{[@var{data-reg},@var{reg}]} + +@var{Reg} can be either @samp{X} or @samp{Y}. +@var{Data-reg} +must be one of the data registers @samp{D0}, @samp{D1} @dots{} @samp{D7}. +If any of the registers @samp{D2} @dots{} @samp{D5} are specified, then +the register value is treated as a signed value. +Otherwise it is treated as unsigned. + + +@end table + +For example: + +@smallexample + trap #197 + bra *+49 + bra .L0 + jmp 0xFE0034 + jmp [0xFD0012] + inc.b (4,x) + dec.w [4,y] + clr.p (-s) + neg.l (d0, s) + com.b [d1, x] + jsr (45, d0) + psh cch +@end smallexample + +@node S12Z-Directives +@section Assembler Directives + +@cindex assembler directives, S12Z + +@node S12Z-opcodes +@section Opcodes + +@cindex S12Z opcodes +@cindex opcodes, S12Z +@cindex instruction set, S12Z diff --git a/gas/testsuite/gas/s12z/abs.d b/gas/testsuite/gas/s12z/abs.d new file mode 100644 index 00000000000..b41238f065a --- /dev/null +++ b/gas/testsuite/gas/s12z/abs.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: abs.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 40 abs d2 + 2: 1b 41 abs d3 + 4: 1b 42 abs d4 + 6: 1b 43 abs d5 + 8: 1b 44 abs d0 + a: 1b 45 abs d1 + c: 1b 46 abs d6 + e: 1b 47 abs d7 diff --git a/gas/testsuite/gas/s12z/abs.s b/gas/testsuite/gas/s12z/abs.s new file mode 100644 index 00000000000..718a2eb2a4c --- /dev/null +++ b/gas/testsuite/gas/s12z/abs.s @@ -0,0 +1,8 @@ + abs d2 + abs d3 + abs d4 + abs d5 + abs d0 + abs d1 + abs d6 + abs d7 diff --git a/gas/testsuite/gas/s12z/adc-imm.d b/gas/testsuite/gas/s12z/adc-imm.d new file mode 100644 index 00000000000..b13d136ee0f --- /dev/null +++ b/gas/testsuite/gas/s12z/adc-imm.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: adc-imm.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 50 12 34 adc d2, #4660 + 4: 1b 51 12 34 adc d3, #4660 + 8: 1b 52 12 34 adc d4, #4660 + c: 1b 53 12 34 adc d5, #4660 + 10: 1b 54 12 adc d0, #18 + 13: 1b 55 34 adc d1, #52 + 16: 1b 56 00 56 adc d6, #5666970 + 1a: 78 9a + 1c: 1b 57 00 98 adc d7, #9991764 + 20: 76 54 diff --git a/gas/testsuite/gas/s12z/adc-imm.s b/gas/testsuite/gas/s12z/adc-imm.s new file mode 100644 index 00000000000..cddf980cf2e --- /dev/null +++ b/gas/testsuite/gas/s12z/adc-imm.s @@ -0,0 +1,8 @@ + adc d2, #0x1234 + adc d3, #0x1234 + adc d4, #0x1234 + adc d5, #0x1234 + adc d0, #0x12 + adc d1, #0x34 + adc d6, #0x56789A + adc d7, #0x987654 diff --git a/gas/testsuite/gas/s12z/adc-opr.d b/gas/testsuite/gas/s12z/adc-opr.d new file mode 100644 index 00000000000..d2023a24b0f --- /dev/null +++ b/gas/testsuite/gas/s12z/adc-opr.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: adc-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 64 c5 21 adc d0, \[-223,x\] + 4: 1b 65 e2 ff adc d1, \(-2000,s\) + 8: f8 30 + a: 1b 60 c7 adc d2, \(x-\) + d: 1b 61 f3 adc d3, \(\+y\) + 10: 1b 62 bb adc d4, d5 + 13: 1b 63 3e ce adc d5, 16078 + 17: 1b 66 fe 01 adc d6, \[73056\] + 1b: 1d 60 + 1d: 1b 67 8a adc d7, \(d4,x\) diff --git a/gas/testsuite/gas/s12z/adc-opr.s b/gas/testsuite/gas/s12z/adc-opr.s new file mode 100644 index 00000000000..b16befc5209 --- /dev/null +++ b/gas/testsuite/gas/s12z/adc-opr.s @@ -0,0 +1,9 @@ + adc d0, [-223,x] + adc d1, (-2000, s) + adc d2, (x-) + adc d3, (+y) + adc d4, d5 + adc d5, 16078 + adc d6, [73056] + adc d7, (d4,x) + diff --git a/gas/testsuite/gas/s12z/add-imm.d b/gas/testsuite/gas/s12z/add-imm.d new file mode 100644 index 00000000000..6125da479fb --- /dev/null +++ b/gas/testsuite/gas/s12z/add-imm.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: add-imm.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 50 12 34 add d2, #4660 + 3: 51 12 34 add d3, #4660 + 6: 52 12 34 add d4, #4660 + 9: 53 12 34 add d5, #4660 + c: 54 12 add d0, #18 + e: 55 34 add d1, #52 + 10: 56 00 56 78 add d6, #5666970 + 14: 9a + 15: 57 00 98 76 add d7, #9991764 + 19: 54 diff --git a/gas/testsuite/gas/s12z/add-imm.s b/gas/testsuite/gas/s12z/add-imm.s new file mode 100644 index 00000000000..5986c8e7bc6 --- /dev/null +++ b/gas/testsuite/gas/s12z/add-imm.s @@ -0,0 +1,8 @@ +start: add d2, #0x1234 + add d3, #0x1234 + add d4, #0x1234 + add d5, #0x1234 + add d0, #0x12 + add d1, #0x34 + add d6, #0x56789A + add d7, #0x987654 diff --git a/gas/testsuite/gas/s12z/add-opr.d b/gas/testsuite/gas/s12z/add-opr.d new file mode 100644 index 00000000000..0528312d343 --- /dev/null +++ b/gas/testsuite/gas/s12z/add-opr.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: add-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 64 c5 21 add d0, \[-223,x\] + 3: 65 e2 00 75 add d1, \(30000,s\) + 7: 30 + 8: 60 c7 add d2, \(x-\) + a: 61 f3 add d3, \(\+y\) + c: 62 bf add d4, d7 + e: 63 17 be add d5, 6078 + 11: 66 fe 01 1d add d6, \[73056\] + 15: 60 + 16: 67 8a add d7, \(d4,x\) diff --git a/gas/testsuite/gas/s12z/add-opr.s b/gas/testsuite/gas/s12z/add-opr.s new file mode 100644 index 00000000000..d86a4aa51f3 --- /dev/null +++ b/gas/testsuite/gas/s12z/add-opr.s @@ -0,0 +1,9 @@ + add d0, [-223,x] + add d1, (30000, s) + add d2, (x-) + add d3, (+y) + add d4, d7 + add d5, 6078 + add d6, [73056] + add d7, (d4,x) + diff --git a/gas/testsuite/gas/s12z/and-imm.d b/gas/testsuite/gas/s12z/and-imm.d new file mode 100644 index 00000000000..fea351d5347 --- /dev/null +++ b/gas/testsuite/gas/s12z/and-imm.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: and-imm.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 58 12 34 and d2, #4660 + 3: 59 12 34 and d3, #4660 + 6: 5a 12 34 and d4, #4660 + 9: 5b 12 34 and d5, #4660 + c: 5c 12 and d0, #18 + e: 5d 34 and d1, #52 + 10: 5e 56 78 9a and d6, #1450744508 + 14: bc + 15: 5f 98 76 54 and d7, #-1737075662 + 19: 32 diff --git a/gas/testsuite/gas/s12z/and-imm.s b/gas/testsuite/gas/s12z/and-imm.s new file mode 100644 index 00000000000..fcd947a3e2a --- /dev/null +++ b/gas/testsuite/gas/s12z/and-imm.s @@ -0,0 +1,8 @@ +start: and d2, #0x1234 + and d3, #0x1234 + and d4, #0x1234 + and d5, #0x1234 + and d0, #0x12 + and d1, #0x34 + and d6, #0x56789ABC + and d7, #-1737075662 diff --git a/gas/testsuite/gas/s12z/and-opr.d b/gas/testsuite/gas/s12z/and-opr.d new file mode 100644 index 00000000000..b9cc366fe52 --- /dev/null +++ b/gas/testsuite/gas/s12z/and-opr.d @@ -0,0 +1,22 @@ +#objdump: -d +#name: +#source: and-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 6c c4 17 and d0, \[23,x\] + 3: 6d d2 ff 8a and d1, \(-30000,y\) + 7: d0 + 8: 68 c7 and d2, \(x-\) + a: 69 f3 and d3, \(\+y\) + c: 6a bb and d4, d5 + e: 6b fa 23 ca and d5, 2345678 + 12: ce + 13: 6e fe 01 e2 and d6, \[123456\] + 17: 40 + 18: 6f ac and d7, \(d0,s\) diff --git a/gas/testsuite/gas/s12z/and-opr.s b/gas/testsuite/gas/s12z/and-opr.s new file mode 100644 index 00000000000..6569ebede3c --- /dev/null +++ b/gas/testsuite/gas/s12z/and-opr.s @@ -0,0 +1,9 @@ + and d0, [23,x] + and d1, (-30000, y) + and d2, (x-) + and d3, (+y) + and d4, d5 + and d5, 2345678 + and d6, [123456] + and d7, (d0,s) + diff --git a/gas/testsuite/gas/s12z/and-or-cc.d b/gas/testsuite/gas/s12z/and-or-cc.d new file mode 100644 index 00000000000..38117e92293 --- /dev/null +++ b/gas/testsuite/gas/s12z/and-or-cc.d @@ -0,0 +1,13 @@ +#objdump: -d +#name: +#source: and-or-cc.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: ce 7b andcc #123 + 2: de 20 orcc #32 diff --git a/gas/testsuite/gas/s12z/and-or-cc.s b/gas/testsuite/gas/s12z/and-or-cc.s new file mode 100644 index 00000000000..afa4a1eb204 --- /dev/null +++ b/gas/testsuite/gas/s12z/and-or-cc.s @@ -0,0 +1,2 @@ +xx: andcc #123 + orcc #32 diff --git a/gas/testsuite/gas/s12z/bfext-special.d b/gas/testsuite/gas/s12z/bfext-special.d new file mode 100644 index 00000000000..380e6275430 --- /dev/null +++ b/gas/testsuite/gas/s12z/bfext-special.d @@ -0,0 +1,13 @@ +#objdump: -d +#name: +#source: bfext-special.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 0f 75 a3 bfext.w \(45,d1\), d7, #13:3 + 4: 85 00 2d diff --git a/gas/testsuite/gas/s12z/bfext-special.s b/gas/testsuite/gas/s12z/bfext-special.s new file mode 100644 index 00000000000..1810c9afa18 --- /dev/null +++ b/gas/testsuite/gas/s12z/bfext-special.s @@ -0,0 +1,2 @@ + bfext.w (45,d1), d7, #13:3 + diff --git a/gas/testsuite/gas/s12z/bfext.d b/gas/testsuite/gas/s12z/bfext.d new file mode 100644 index 00000000000..84f439a2279 --- /dev/null +++ b/gas/testsuite/gas/s12z/bfext.d @@ -0,0 +1,47 @@ +#objdump: -d +#name: +#source: bfext.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 0c 14 bfext d0, d1, d2 + 3: 1b 0d 21 17 bfext d1, d2, #8:23 + 7: 1b 08 41 e3 bfext.b d2, \(\+x\), d3 + b: 1b 09 46 c4 bfext.w d3, \[123,x\], d4 + f: 7b + 10: 1b 0a 4b ac bfext.p d4, \(d0,s\), d5 + 14: 1b 0b 4c 84 bfext.l d5, \(45,d0\), d2 + 18: 00 2d + 1a: 1b 0e 51 84 bfext.b \(45,d0\), d6, d3 + 1e: 00 2d + 20: 1b 0f 54 c4 bfext.w \[45,x\], d7, d2 + 24: 2d + 25: 1b 0c 61 a2 bfext.b d0, \(45,d1\), #13:2 + 29: 85 00 2d + 2c: 1b 0f 75 a3 bfext.w \(45,d1\), d7, #13:3 + 30: 85 00 2d + 33: 1b 0f 58 c6 bfext.p \[451,x\], d7, d2 + 37: 00 01 c3 + 3a: 1b 0c 94 bfins d0, d1, d2 + 3d: 1b 0d a1 17 bfins d1, d2, #8:23 + 41: 1b 08 c1 e3 bfins.b d2, \(\+x\), d3 + 45: 1b 09 c6 c4 bfins.w d3, \[123,x\], d4 + 49: 7b + 4a: 1b 0a cb ac bfins.p d4, \(d0,s\), d5 + 4e: 1b 0b cc 84 bfins.l d5, \(45,d0\), d2 + 52: 00 2d + 54: 1b 0e d1 84 bfins.b \(45,d0\), d6, d3 + 58: 00 2d + 5a: 1b 0f d4 c4 bfins.w \[45,x\], d7, d2 + 5e: 2d + 5f: 1b 0c e1 a2 bfins.b d0, \(45,d1\), #13:2 + 63: 85 00 2d + 66: 1b 0f f5 a3 bfins.w \(45,d1\), d7, #13:3 + 6a: 85 00 2d + 6d: 1b 0f d8 c6 bfins.p \[451,x\], d7, d2 + 71: 00 01 c3 diff --git a/gas/testsuite/gas/s12z/bfext.s b/gas/testsuite/gas/s12z/bfext.s new file mode 100644 index 00000000000..66cb5b6668b --- /dev/null +++ b/gas/testsuite/gas/s12z/bfext.s @@ -0,0 +1,23 @@ + bfext d0, d1, d2 + bfext d1, d2, #8:23 + bfext.b d2, (+x), d3 + bfext.w d3, [123,x], d4 + bfext.p d4, (d0, s), d5 + bfext.l d5, (45,d0), d2 + bfext.b (45,d0), d6, d3 + bfext.w [45,x], d7, d2 + bfext.b d0, (45,d1), #13:2 + bfext.w (45,d1), d7, #13:3 + bfext.p [451,x], d7, d2 + + bfins d0, d1, d2 + bfins d1, d2, #8:23 + bfins.b d2, (+x), d3 + bfins.w d3, [123,x], d4 + bfins.p d4, (d0, s), d5 + bfins.l d5, (45,d0), d2 + bfins.b (45,d0), d6, d3 + bfins.w [45,x], d7, d2 + bfins.b d0, (45,d1), #13:2 + bfins.w (45,d1), d7, #13:3 + bfins.p [451,x], d7, d2 diff --git a/gas/testsuite/gas/s12z/bit-manip.d b/gas/testsuite/gas/s12z/bit-manip.d new file mode 100644 index 00000000000..6a0c7ee7244 --- /dev/null +++ b/gas/testsuite/gas/s12z/bit-manip.d @@ -0,0 +1,26 @@ +#objdump: -d +#name: +#source: bit-manip.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: ec 1c bclr d0, #3 + 2: ed 25 bset d1, #4 + 4: ee 28 btgl d2, #5 + 6: ec b1 b9 bclr d3, d5 + 9: ed e1 ba bset d4, d6 + c: ee f1 bb btgl d5, d7 + f: ec a0 c0 22 bclr.b \(34,x\), #2 + 13: ec c3 ff bclr.w \(s\+\), #12 + 16: ec fd e0 38 bclr.l \(56,s\), d7 + 1a: ed d0 c4 22 bset.b \[34,x\], #5 + 1e: ed db fb bset.l \(-s\), #29 + 21: ed f5 c0 9c bset.w \(156,x\), d7 + 25: ee d0 c4 22 btgl.b \[34,x\], #5 + 29: ee f3 fb btgl.w \(-s\), #15 + 2c: ee fd f0 0f btgl.l \(15,p\), d7 diff --git a/gas/testsuite/gas/s12z/bit-manip.s b/gas/testsuite/gas/s12z/bit-manip.s new file mode 100644 index 00000000000..cebb478624b --- /dev/null +++ b/gas/testsuite/gas/s12z/bit-manip.s @@ -0,0 +1,16 @@ + bclr d0, #3 + bset d1, #4 + btgl d2, #5 + bclr d3, d5 + bset d4, d6 + btgl d5, d7 + bclr.b (34,x), #2 + bclr.w (s+), #12 + bclr.l (56,s), d7 + bset.b [34,x], #5 + bset.l (-s), #29 + bset.w (156,x), d7 + btgl.b [34,x], #5 + btgl.w (-s), #15 + btgl.l (15,p), d7 + diff --git a/gas/testsuite/gas/s12z/bit.d b/gas/testsuite/gas/s12z/bit.d new file mode 100644 index 00000000000..68dd30ca3d0 --- /dev/null +++ b/gas/testsuite/gas/s12z/bit.d @@ -0,0 +1,33 @@ +#objdump: -d +#name: +#source: bit.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 58 fc 84 bit d2, #-892 + 4: 1b 59 ef 32 bit d3, #-4302 + 8: 1b 5f 00 01 bit d7, #123456 + c: e2 40 + e: 1b 5b 04 d2 bit d5, #1234 + 12: 1b 5c 7b bit d0, #123 + 15: 1b 5d 22 bit d1, #34 + 18: 1b 5e ff ff bit d6, #-56789 + 1c: 22 2b + 1e: 1b 5a 22 3d bit d4, #8765 + 22: 1b 6c d5 21 bit d0, \[-223,y\] + 26: 1b 6d f2 00 bit d1, \(34000,p\) + 2a: 84 d0 + 2c: 1b 68 fb bit d2, \(-s\) + 2f: 1b 59 00 04 bit d3, #4 + 33: 1b 6a bc bit d4, d0 + 36: 1b 6b f9 4c bit d5, 85178 + 3a: ba + 3b: 1b 6e fe 00 bit d6, \[15256\] + 3f: 3b 98 + 41: 1b 6f 8b bit d7, \(d5,x\) + 44: 1b 69 f3 bit d3, \(\+y\) diff --git a/gas/testsuite/gas/s12z/bit.s b/gas/testsuite/gas/s12z/bit.s new file mode 100644 index 00000000000..539b593f9f0 --- /dev/null +++ b/gas/testsuite/gas/s12z/bit.s @@ -0,0 +1,17 @@ + bit d2, #-892 + bit d3, #-4302 + bit d7, #123456 + bit d5, #1234 + bit d0, #123 + bit d1, #34 + bit d6, #-56789 + bit d4, #8765 + bit d0, [-223,y] + bit d1, (34000, p) + bit d2, (-s) + bit d3, #4 + bit d4, d0 + bit d5, 85178 + bit d6, [15256] + bit d7, (d5, x) + bit d3, (+y) diff --git a/gas/testsuite/gas/s12z/bra-expression-defined.d b/gas/testsuite/gas/s12z/bra-expression-defined.d new file mode 100644 index 00000000000..700f7cdd164 --- /dev/null +++ b/gas/testsuite/gas/s12z/bra-expression-defined.d @@ -0,0 +1,23 @@ +#objdump: -d +#name: pc_relative expressions defined at assembly time +#source: bra-expression-defined.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 01 nop + 1: 01 nop + 2: 20 80 19 bra \*\+25 + 5: 01 nop + 6: 02 c0 bc 80 brclr.b d0, #4, \*\+31 + a: 1f + b: 01 nop + c: 0b 06 80 23 tbne d6, \*\+35 + 10: 01 nop + +00000011 : + 11: 01 nop diff --git a/gas/testsuite/gas/s12z/bra-expression-defined.s b/gas/testsuite/gas/s12z/bra-expression-defined.s new file mode 100644 index 00000000000..2a1baeb4d53 --- /dev/null +++ b/gas/testsuite/gas/s12z/bra-expression-defined.s @@ -0,0 +1,11 @@ + + nop + nop + bra loop+10 + nop + brclr.b d0, #4, loop+20 + nop + tbne d6, loop+30 + nop +loop: + nop diff --git a/gas/testsuite/gas/s12z/bra-expression-undef.d b/gas/testsuite/gas/s12z/bra-expression-undef.d new file mode 100644 index 00000000000..ddd7dcb9eed --- /dev/null +++ b/gas/testsuite/gas/s12z/bra-expression-undef.d @@ -0,0 +1,24 @@ +#objdump: -dr +#name: pc_relative expressions without a definition +#source: bra-expression-undef.s + + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 01 nop + 1: 01 nop + 2: 20 80 0b bra \*\+11 + 3: R_S12Z_PCREL_7_15 loop\+0x8000 + 5: 01 nop + 6: 02 c0 bc 80 brclr.b d0, #4, \*\+23 + a: 17 + 9: R_S12Z_PCREL_7_15 loop\+0x18000 + b: 01 nop + c: 0b 06 80 20 tbne d6, \*\+32 + e: R_S12Z_PCREL_7_15 loop\+0x10000 + 10: 01 nop diff --git a/gas/testsuite/gas/s12z/bra-expression-undef.s b/gas/testsuite/gas/s12z/bra-expression-undef.s new file mode 100644 index 00000000000..1d5a81ea06c --- /dev/null +++ b/gas/testsuite/gas/s12z/bra-expression-undef.s @@ -0,0 +1,9 @@ + + nop + nop + bra loop+10 + nop + brclr.b d0, #4, loop+20 + nop + tbne d6, loop+30 + nop diff --git a/gas/testsuite/gas/s12z/bra.d b/gas/testsuite/gas/s12z/bra.d new file mode 100644 index 00000000000..7a6cc1cb19b --- /dev/null +++ b/gas/testsuite/gas/s12z/bra.d @@ -0,0 +1,34 @@ +#objdump: -d +#name: +#source: bra.s + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 20 80 0f bra L4 + +00000003 : + 3: 21 ff fd bsr L1 + 6: 22 ff fa bhi L1 + +00000009 : + 9: 23 80 00 bls L3 + c: 24 ff f4 bcc L1 + +0000000f : + f: 25 ff f4 bcs L2 + 12: 26 ff f7 bne L3 + 15: 27 ff fa beq L4 + 18: 28 ff f7 bvc L4 + 1b: 29 ff e8 bvs L2 + 1e: 2a ff e2 bpl L1 + 21: 2b ff e2 bmi L2 + 24: 2c ff dc bge L1 + 27: 2d ff e8 blt L4 + 2a: 2e ff df bgt L3 + 2d: 2f ff d3 ble L1 + 30: 20 02 bra \*\+2 + 32: 20 7c bra \*-4 diff --git a/gas/testsuite/gas/s12z/bra.s b/gas/testsuite/gas/s12z/bra.s new file mode 100644 index 00000000000..a2528b39df3 --- /dev/null +++ b/gas/testsuite/gas/s12z/bra.s @@ -0,0 +1,20 @@ +L1: bra L4 +L2: bsr L1 + bhi L1 +L3: bls L3 + bcc L1 +L4: bcs L2 + bne L3 + beq L4 + bvc L4 + bvs L2 + bpl L1 + bmi L2 + bge L1 + blt L4 + bgt L3 + ble L1 + + bra *+2 + bra *-4 + diff --git a/gas/testsuite/gas/s12z/brclr-symbols.d b/gas/testsuite/gas/s12z/brclr-symbols.d new file mode 100644 index 00000000000..59de1c0e57a --- /dev/null +++ b/gas/testsuite/gas/s12z/brclr-symbols.d @@ -0,0 +1,32 @@ +#objdump: -dt +#name: +#source: brclr-symbols.s + + +dump.o: file format elf32-s12z + +SYMBOL TABLE: +00000000 l d .text 00000000 .text +00000000 l d .data 00000000 .data +00000000 l d .bss 00000000 .bss +00000001 l .text 00000000 foo + + + +Disassembly of section .text: + +00000000 : + 0: 01 nop + +00000001 : + 1: 01 nop + 2: 01 nop + 3: 02 0c ff fe brclr d0, #1, foo + 7: 03 81 bd ff brset d1, d2, foo + b: fa + c: 02 a0 e7 ff brclr.b \(x\+\), #2, foo + 10: f5 + 11: 03 c1 84 00 brset.b \(23,d0\), d0, foo + 15: 17 ff f0 + 18: 02 a0 03 86 brclr.b 902, #2, foo + 1c: ff e9 \ No newline at end of file diff --git a/gas/testsuite/gas/s12z/brclr-symbols.s b/gas/testsuite/gas/s12z/brclr-symbols.s new file mode 100644 index 00000000000..fa212fe2f71 --- /dev/null +++ b/gas/testsuite/gas/s12z/brclr-symbols.s @@ -0,0 +1,9 @@ + nop +foo: + nop + nop + brclr d0, #1, foo + brset d1, d2, foo + brclr.b (x+), #2, foo + brset.b (23,d0), d0, foo + brclr.b 902, #2, foo diff --git a/gas/testsuite/gas/s12z/brset-clr-opr-imm-rel.d b/gas/testsuite/gas/s12z/brset-clr-opr-imm-rel.d new file mode 100644 index 00000000000..588e606580c --- /dev/null +++ b/gas/testsuite/gas/s12z/brset-clr-opr-imm-rel.d @@ -0,0 +1,23 @@ +#objdump: -d +#name: +#source: brset-clr-opr-imm-rel.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 03 c0 e4 2d brset.b \[45,s\], #4, \*\+3 + 4: 03 + 5: 03 e3 e6 00 brset.w \[345,s\], #14, \*\+32 + 9: 01 59 20 + c: 03 99 e2 00 brset.l \(345,s\), #9, \*\+309 + 10: 01 59 81 35 + 14: 02 c0 e6 00 brclr.b \[345,s\], #4, \*\+3 + 18: 01 59 03 + 1b: 02 f3 e6 00 brclr.w \[345,s\], #15, \*\+3087 + 1f: 01 59 8c 0f + 23: 02 fb e6 00 brclr.l \[345,s\], #31, \*\+3 + 27: 01 59 03 diff --git a/gas/testsuite/gas/s12z/brset-clr-opr-imm-rel.s b/gas/testsuite/gas/s12z/brset-clr-opr-imm-rel.s new file mode 100644 index 00000000000..1bb8da9854f --- /dev/null +++ b/gas/testsuite/gas/s12z/brset-clr-opr-imm-rel.s @@ -0,0 +1,7 @@ + brset.b [45,s], #4, *+3 + brset.w [345,s], #14, *+32 + brset.l (345,s), #9, *+309 + brclr.b [345,s], #4, *+3 + brclr.w [345,s], #15, *+3087 + brclr.l [345,s], #31, *+3 + diff --git a/gas/testsuite/gas/s12z/brset-clr-opr-reg-rel.d b/gas/testsuite/gas/s12z/brset-clr-opr-reg-rel.d new file mode 100644 index 00000000000..1a87e786a7f --- /dev/null +++ b/gas/testsuite/gas/s12z/brset-clr-opr-reg-rel.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: brset-clr-opr-reg-rel.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 02 85 d0 22 brclr.w \(34,y\), d2, \*\+3034 + 4: 8b da + +00000006 : + 6: 03 c1 d3 81 brset.b \(-y\), d0, \*\+434 + a: b2 + b: 03 9d e3 88 brset.l \(\+x\), d3, \*\+2134 + f: 56 + 10: 02 ad c4 22 brclr.l \[34,x\], d4, L1 + 14: ff f6 diff --git a/gas/testsuite/gas/s12z/brset-clr-opr-reg-rel.s b/gas/testsuite/gas/s12z/brset-clr-opr-reg-rel.s new file mode 100644 index 00000000000..76c3bb51b3a --- /dev/null +++ b/gas/testsuite/gas/s12z/brset-clr-opr-reg-rel.s @@ -0,0 +1,5 @@ + brclr.w (34,y), d2, *+3034 +L1: brset.b (-y), d0, *+434 + brset.l (+x), d3, *+2134 + brclr.l [34,x], d4, L1 + diff --git a/gas/testsuite/gas/s12z/brset-clr-reg-imm-rel.d b/gas/testsuite/gas/s12z/brset-clr-reg-imm-rel.d new file mode 100644 index 00000000000..ddcc61dc980 --- /dev/null +++ b/gas/testsuite/gas/s12z/brset-clr-reg-imm-rel.d @@ -0,0 +1,24 @@ +#objdump: -d +#name: +#source: brset-clr-reg-imm-rel.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 03 10 05 brset d2, #2, \*\+5 + 3: 03 19 17 brset d3, #3, \*\+23 + 6: 03 11 71 brset d3, #2, \*-15 + 9: 03 40 43 brset d2, #8, \*-61 + c: 03 40 fd 01 brset d2, #8, \*-767 + 10: 03 6e fd 01 brset d6, #13, \*-767 + +00000014 : + 14: 02 10 05 brclr d2, #2, \*\+5 + 17: 02 19 17 brclr d3, #3, \*\+23 + 1a: 02 11 fc c0 brclr d3, #2, \*-832 + 1e: 02 40 43 brclr d2, #8, \*-61 + 21: 02 40 fd 01 brclr d2, #8, \*-767 diff --git a/gas/testsuite/gas/s12z/brset-clr-reg-imm-rel.s b/gas/testsuite/gas/s12z/brset-clr-reg-imm-rel.s new file mode 100644 index 00000000000..3aca6219ec1 --- /dev/null +++ b/gas/testsuite/gas/s12z/brset-clr-reg-imm-rel.s @@ -0,0 +1,12 @@ +L1: brset d2, #2, *+5 + brset d3, #3, *+23 + brset d3, #2, *-15 + brset d2, #8, *-61 + brset d2, #8, *-767 + brset d6, #13, *-767 +L2: brclr d2, #2, *+5 + brclr d3, #3, *+23 + brclr d3, #2, *-832 + brclr d2, #8, *-61 + brclr d2, #8, *-767 + diff --git a/gas/testsuite/gas/s12z/brset-clr-reg-reg-rel.d b/gas/testsuite/gas/s12z/brset-clr-reg-reg-rel.d new file mode 100644 index 00000000000..1cad90684e3 --- /dev/null +++ b/gas/testsuite/gas/s12z/brset-clr-reg-reg-rel.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: brset-clr-reg-reg-rel.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 03 e1 bb 2d brset d5, d6, \*\+45 + 4: 02 d1 b8 6f brclr d2, d1, \*-17 + 8: 03 91 be ff brset d6, d3, \*-90 + c: a6 + d: 02 f1 bc ff brclr d0, d7, \*-90 + 11: a6 + 12: 02 81 bd ff brclr d1, d2, \*-190 + 16: 42 diff --git a/gas/testsuite/gas/s12z/brset-clr-reg-reg-rel.s b/gas/testsuite/gas/s12z/brset-clr-reg-reg-rel.s new file mode 100644 index 00000000000..c78ec979020 --- /dev/null +++ b/gas/testsuite/gas/s12z/brset-clr-reg-reg-rel.s @@ -0,0 +1,6 @@ + brset d5, d6, *+45 + brclr d2, d1, *-17 + brset d6, d3, *-90 + brclr d0, d7, *-90 + brclr d1, d2, *-190 + diff --git a/gas/testsuite/gas/s12z/clb.d b/gas/testsuite/gas/s12z/clb.d new file mode 100644 index 00000000000..fd142dc2b1b --- /dev/null +++ b/gas/testsuite/gas/s12z/clb.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: clb.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 91 47 clb d0, d7 + 3: 1b 91 56 clb d1, d6 + 6: 1b 91 03 clb d2, d5 + 9: 1b 91 12 clb d3, d4 + c: 1b 91 21 clb d4, d3 + f: 1b 91 30 clb d5, d2 + 12: 1b 91 65 clb d6, d1 + 15: 1b 91 74 clb d7, d0 diff --git a/gas/testsuite/gas/s12z/clb.s b/gas/testsuite/gas/s12z/clb.s new file mode 100644 index 00000000000..877bbce1165 --- /dev/null +++ b/gas/testsuite/gas/s12z/clb.s @@ -0,0 +1,8 @@ + clb d0, d7 + clb d1, d6 + clb d2, d5 + clb d3, d4 + clb d4, d3 + clb d5, d2 + clb d6, d1 + clb d7, d0 diff --git a/gas/testsuite/gas/s12z/clr-opr.d b/gas/testsuite/gas/s12z/clr-opr.d new file mode 100644 index 00000000000..7c05ebb9981 --- /dev/null +++ b/gas/testsuite/gas/s12z/clr-opr.d @@ -0,0 +1,15 @@ +#objdump: -d +#name: +#source: clr-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: bc ff clr.b \(s\+\) + 2: bd c0 2d clr.w \(45,x\) + 5: be f9 e2 32 clr.p 123442 + 9: bf d4 03 clr.l \[3,y\] diff --git a/gas/testsuite/gas/s12z/clr-opr.s b/gas/testsuite/gas/s12z/clr-opr.s new file mode 100644 index 00000000000..ecfa2667971 --- /dev/null +++ b/gas/testsuite/gas/s12z/clr-opr.s @@ -0,0 +1,5 @@ + clr.b (s+) + clr.w (45,x) + clr.p 123442 + clr.l [3,y] + diff --git a/gas/testsuite/gas/s12z/clr.d b/gas/testsuite/gas/s12z/clr.d new file mode 100644 index 00000000000..1e902d6678b --- /dev/null +++ b/gas/testsuite/gas/s12z/clr.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: clr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 38 clr d2 + 1: 39 clr d3 + 2: 3a clr d4 + 3: 3b clr d5 + 4: 3c clr d0 + 5: 3d clr d1 + 6: 3e clr d6 + 7: 3f clr d7 + 8: 9a clr x + 9: 9b clr y diff --git a/gas/testsuite/gas/s12z/clr.s b/gas/testsuite/gas/s12z/clr.s new file mode 100644 index 00000000000..1f0b57fae85 --- /dev/null +++ b/gas/testsuite/gas/s12z/clr.s @@ -0,0 +1,10 @@ +L1: clr d2 + clr d3 + clr d4 + clr d5 + clr d0 + clr d1 + clr d6 + clr d7 + clr x + clr y diff --git a/gas/testsuite/gas/s12z/cmp-imm.d b/gas/testsuite/gas/s12z/cmp-imm.d new file mode 100644 index 00000000000..d756b00db97 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-imm.d @@ -0,0 +1,23 @@ +#objdump: -d +#name: +#source: cmp-imm.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: e4 12 cmp d0, #18 + 2: e5 34 cmp d1, #52 + 4: e0 34 56 cmp d2, #13398 + 7: e1 34 56 cmp d3, #13398 + a: e2 34 56 cmp d4, #13398 + d: e3 34 56 cmp d5, #13398 + 10: e6 00 34 56 cmp d6, #3430008 + 14: 78 + 15: e7 00 34 56 cmp d7, #3430008 + 19: 78 + 1a: e8 aa bb cc cmp x, #-5588020 + 1e: e9 dd ee ff cmp y, #-2232577 diff --git a/gas/testsuite/gas/s12z/cmp-imm.s b/gas/testsuite/gas/s12z/cmp-imm.s new file mode 100644 index 00000000000..89b41b585d0 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-imm.s @@ -0,0 +1,12 @@ +here: cmp d0, #0x12 + cmp d1, #0x34 + cmp d2, #0x3456 + cmp d3, #0x3456 + cmp d4, #0x3456 + cmp d5, #0x3456 + cmp d6, #0x345678 + cmp d7, #0x345678 + + cmp x, #-5588020 + cmp y, #-2232577 + diff --git a/gas/testsuite/gas/s12z/cmp-opr-inc.d b/gas/testsuite/gas/s12z/cmp-opr-inc.d new file mode 100644 index 00000000000..bda08de399b --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-opr-inc.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: cmp-opr-inc.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: f0 e3 cmp d2, \(\+x\) + 2: f1 f3 cmp d3, \(\+y\) + 4: f2 c3 cmp d4, \(-x\) + 6: f3 d3 cmp d5, \(-y\) + 8: f4 fb cmp d0, \(-s\) + a: f6 ff cmp d6, \(s\+\) + c: f8 d7 cmp x, \(y-\) + e: f8 c7 cmp x, \(x-\) + 10: f9 f7 cmp y, \(y\+\) + 12: f9 e7 cmp y, \(x\+\) diff --git a/gas/testsuite/gas/s12z/cmp-opr-inc.s b/gas/testsuite/gas/s12z/cmp-opr-inc.s new file mode 100644 index 00000000000..48b1d48f097 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-opr-inc.s @@ -0,0 +1,11 @@ +;; Pre/Post increment/decrement xys + cmp d2, (+x) + cmp d3, (+y) + cmp d4, (-x) + cmp d5, (-y) + cmp d0, (-s) + cmp d6, (s+) + cmp x, (y-) + cmp x, (x-) + cmp y, (y+) + cmp y, (x+) diff --git a/gas/testsuite/gas/s12z/cmp-opr-rdirect.d b/gas/testsuite/gas/s12z/cmp-opr-rdirect.d new file mode 100644 index 00000000000..879ed98c847 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-opr-rdirect.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: cmp-opr-rdirect.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: f0 ad cmp d2, \(d1,s\) + 2: f1 88 cmp d3, \(d2,x\) + 4: f2 89 cmp d4, \(d3,x\) + 6: f3 99 cmp d5, \(d3,y\) + 8: f4 8a cmp d0, \(d4,x\) + a: f5 8b cmp d1, \(d5,x\) + c: f6 8e cmp d6, \(d6,x\) + e: f7 8f cmp d7, \(d7,x\) diff --git a/gas/testsuite/gas/s12z/cmp-opr-rdirect.s b/gas/testsuite/gas/s12z/cmp-opr-rdirect.s new file mode 100644 index 00000000000..ff5dcbcbe2c --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-opr-rdirect.s @@ -0,0 +1,9 @@ +;;; Direct register offset + cmp d2, (d1,s) + cmp d3, (d2,x) + cmp d4, (d3,x) + cmp d5, (d3,y) + cmp d0, (d4,x) + cmp d1, (d5,x) + cmp d6, (d6,x) + cmp d7, (d7,x) diff --git a/gas/testsuite/gas/s12z/cmp-opr-reg.d b/gas/testsuite/gas/s12z/cmp-opr-reg.d new file mode 100644 index 00000000000..cff87d31bb4 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-opr-reg.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: cmp-opr-reg.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: f0 b8 cmp d2, d2 + 2: f1 b9 cmp d3, d3 + 4: f2 ba cmp d4, d4 + 6: f3 bb cmp d5, d5 + 8: f4 bc cmp d0, d0 + a: f5 bd cmp d1, d1 + c: f6 be cmp d6, d6 + e: f7 bf cmp d7, d7 diff --git a/gas/testsuite/gas/s12z/cmp-opr-reg.s b/gas/testsuite/gas/s12z/cmp-opr-reg.s new file mode 100644 index 00000000000..75bb440b20f --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-opr-reg.s @@ -0,0 +1,9 @@ +;; Register as operand + cmp d2, d2 + cmp d3, d3 + cmp d4, d4 + cmp d5, d5 + cmp d0, d0 + cmp d1, d1 + cmp d6, d6 + cmp d7, d7 diff --git a/gas/testsuite/gas/s12z/cmp-opr-rindirect.d b/gas/testsuite/gas/s12z/cmp-opr-rindirect.d new file mode 100644 index 00000000000..7c1108fa705 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-opr-rindirect.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: cmp-opr-rindirect.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: f0 dd cmp d2, \[d1,y\] + 2: f1 dd cmp d3, \[d1,y\] + 4: f2 dc cmp d4, \[d0,y\] + 6: f3 dc cmp d5, \[d0,y\] + 8: f4 ce cmp d0, \[d6,x\] + a: f5 ce cmp d1, \[d6,x\] + c: f6 ce cmp d6, \[d6,x\] + e: f7 cf cmp d7, \[d7,x\] diff --git a/gas/testsuite/gas/s12z/cmp-opr-rindirect.s b/gas/testsuite/gas/s12z/cmp-opr-rindirect.s new file mode 100644 index 00000000000..27ac5fbaafc --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-opr-rindirect.s @@ -0,0 +1,9 @@ +;;; Indirect register offset + cmp d2, [d1,y] + cmp d3, [d1,y] + cmp d4, [d0,y] + cmp d5, [d0,y] + cmp d0, [d6,x] + cmp d1, [d6,x] + cmp d6, [d6,x] + cmp d7, [d7,x] diff --git a/gas/testsuite/gas/s12z/cmp-opr-sxe4.d b/gas/testsuite/gas/s12z/cmp-opr-sxe4.d new file mode 100644 index 00000000000..5eac2fdcd9c --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-opr-sxe4.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: cmp-opr-sxe4.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: e0 ff ff cmp d2, #-1 + 3: e1 00 01 cmp d3, #1 + 6: e2 00 02 cmp d4, #2 + 9: e3 00 03 cmp d5, #3 + c: e4 0e cmp d0, #14 + e: e5 0f cmp d1, #15 + 10: e6 00 00 00 cmp d6, #4 + 14: 04 + 15: e7 00 00 00 cmp d7, #10 + 19: 0a diff --git a/gas/testsuite/gas/s12z/cmp-opr-sxe4.s b/gas/testsuite/gas/s12z/cmp-opr-sxe4.s new file mode 100644 index 00000000000..7b3d113efb9 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-opr-sxe4.s @@ -0,0 +1,10 @@ +;; Short immediate forms + cmp d2, #-1 + cmp d3, #1 + cmp d4, #2 + cmp d5, #3 + cmp d0, #14 + cmp d1, #15 + cmp d6, #4 + cmp d7, #10 + diff --git a/gas/testsuite/gas/s12z/cmp-opr-xys.d b/gas/testsuite/gas/s12z/cmp-opr-xys.d new file mode 100644 index 00000000000..87d065fb1bc --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-opr-xys.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: cmp-opr-xys.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: f0 61 cmp d2, \(1,s\) + 2: f1 42 cmp d3, \(2,x\) + 4: f2 43 cmp d4, \(3,x\) + 6: f3 53 cmp d5, \(3,y\) + 8: f4 44 cmp d0, \(4,x\) + a: f5 45 cmp d1, \(5,x\) + c: f6 46 cmp d6, \(6,x\) + e: f7 47 cmp d7, \(7,x\) diff --git a/gas/testsuite/gas/s12z/cmp-opr-xys.s b/gas/testsuite/gas/s12z/cmp-opr-xys.s new file mode 100644 index 00000000000..929bb081cf5 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-opr-xys.s @@ -0,0 +1,9 @@ +;; Constant offset from xys + cmp d2, (1,s) + cmp d3, (2,x) + cmp d4, (3,x) + cmp d5, (3,y) + cmp d0, (4,x) + cmp d1, (5,x) + cmp d6, (6,x) + cmp d7, (7,x) diff --git a/gas/testsuite/gas/s12z/cmp-s-imm.d b/gas/testsuite/gas/s12z/cmp-s-imm.d new file mode 100644 index 00000000000..d4e7efb2716 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-s-imm.d @@ -0,0 +1,27 @@ +#objdump: -d +#name: +#source: cmp-s-imm.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 04 00 00 cmp s, #0 + 4: 00 + 5: 1b 02 71 cmp s, #1 + 8: 1b 02 70 cmp s, #-1 + b: 1b 04 00 00 cmp s, #255 + f: ff + 10: 1b 04 ff ff cmp s, #-256 + 14: 00 + 15: 1b 04 00 7f cmp s, #32767 + 19: ff + 1a: 1b 04 ff 80 cmp s, #-32768 + 1e: 00 + 1f: 1b 04 07 ff cmp s, #524287 + 23: ff + 24: 1b 04 f8 00 cmp s, #-524288 + 28: 00 diff --git a/gas/testsuite/gas/s12z/cmp-s-imm.s b/gas/testsuite/gas/s12z/cmp-s-imm.s new file mode 100644 index 00000000000..e873d82cf64 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-s-imm.s @@ -0,0 +1,10 @@ + cmp s, #0 + cmp s, #1 + cmp s, #-1 + cmp s, #255 + cmp s, #-256 + cmp s, #32767 + cmp s, #-32768 + cmp s, #524287 + cmp s, #-524288 + diff --git a/gas/testsuite/gas/s12z/cmp-s-opr.d b/gas/testsuite/gas/s12z/cmp-s-opr.d new file mode 100644 index 00000000000..77d2ac7bd66 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-s-opr.d @@ -0,0 +1,25 @@ +#objdump: -d +#name: +#source: cmp-s-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 02 e0 43 cmp s, \(67,s\) + 4: 1b 02 e3 cmp s, \(\+x\) + 7: 1b 02 8c cmp s, \(d0,x\) + a: 1b 02 dd cmp s, \[d1,y\] + d: 1b 02 f2 00 cmp s, \(2134,p\) + 11: 08 56 + 13: 1b 02 f6 00 cmp s, \[2134,p\] + 17: 08 56 + 19: 1b 02 fa 0f cmp s, 987654 + 1d: 12 06 + 1f: 1b 02 e6 08 cmp s, \[565543,s\] + 23: a1 27 + 25: 1b 02 80 04 cmp s, \(1233,d2\) + 29: d1 diff --git a/gas/testsuite/gas/s12z/cmp-s-opr.s b/gas/testsuite/gas/s12z/cmp-s-opr.s new file mode 100644 index 00000000000..5deb45aa6e5 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-s-opr.s @@ -0,0 +1,10 @@ + cmp s, (67,s) + cmp s, (+x) + cmp s, (d0,x) + cmp s, [d1,y] + cmp s, (2134,p) + cmp s, [2134,p] + cmp s, 987654 + cmp s, [565543,s] + cmp s, (1233, d2) + diff --git a/gas/testsuite/gas/s12z/cmp-xy.d b/gas/testsuite/gas/s12z/cmp-xy.d new file mode 100644 index 00000000000..9fef4e13cba --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-xy.d @@ -0,0 +1,12 @@ +#objdump: -d +#name: +#source: cmp-xy.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: fc cmp x, y diff --git a/gas/testsuite/gas/s12z/cmp-xy.s b/gas/testsuite/gas/s12z/cmp-xy.s new file mode 100644 index 00000000000..dcfd47c9db9 --- /dev/null +++ b/gas/testsuite/gas/s12z/cmp-xy.s @@ -0,0 +1 @@ + cmp x, y diff --git a/gas/testsuite/gas/s12z/com-opr.d b/gas/testsuite/gas/s12z/com-opr.d new file mode 100644 index 00000000000..ce51785f1e8 --- /dev/null +++ b/gas/testsuite/gas/s12z/com-opr.d @@ -0,0 +1,15 @@ +#objdump: -d +#name: +#source: com-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: cc df com.b \[d7,y\] + 2: cd fe 00 1f com.w \[8134\] + 6: c6 + 7: cf ae com.l \(d6,s\) diff --git a/gas/testsuite/gas/s12z/com-opr.s b/gas/testsuite/gas/s12z/com-opr.s new file mode 100644 index 00000000000..5eb2760ff6e --- /dev/null +++ b/gas/testsuite/gas/s12z/com-opr.s @@ -0,0 +1,3 @@ + com.b [d7, y] + com.w [8134] + com.l (d6, s) diff --git a/gas/testsuite/gas/s12z/complex-shifts.d b/gas/testsuite/gas/s12z/complex-shifts.d new file mode 100644 index 00000000000..e17fe90a332 --- /dev/null +++ b/gas/testsuite/gas/s12z/complex-shifts.d @@ -0,0 +1,18 @@ +#objdump: -d +#name: +#source: complex-shifts.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 14 73 e3 e6 lsl.l d0, \(\+x\), \[345,s\] + 4: 00 01 59 + 7: 13 32 8e fb lsr.p d5, \(d6,x\), \(-s\) + b: 17 f1 f4 2d asl.w d7, \[45,p\], \(278,y\) + f: d2 00 01 16 + 13: 12 b0 84 00 asr.b d4, \(145,d0\), \(d0,s\) + 17: 91 ac diff --git a/gas/testsuite/gas/s12z/complex-shifts.s b/gas/testsuite/gas/s12z/complex-shifts.s new file mode 100644 index 00000000000..118296ed696 --- /dev/null +++ b/gas/testsuite/gas/s12z/complex-shifts.s @@ -0,0 +1,4 @@ + lsl.l d0, (+x), [345, s] + lsr.p d5, (d6,x), (-s) + asl.w d7, [45,p], (278, y) + asr.b d4, (145,d0), (d0,s) diff --git a/gas/testsuite/gas/s12z/db-tb-cc-opr.d b/gas/testsuite/gas/s12z/db-tb-cc-opr.d new file mode 100644 index 00000000000..ee556e25d0e --- /dev/null +++ b/gas/testsuite/gas/s12z/db-tb-cc-opr.d @@ -0,0 +1,30 @@ +#objdump: -d +#name: +#source: db-tb-cc-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 0b dc 82 00 dble.b \(3,d4\), \*\+1 + 4: 03 01 + 6: 0b cd 83 00 dbgt.w \(23,d5\), \*\+18 + a: 17 12 + c: 0b de 84 00 dble.p \(2,d0\), \*-19 + 10: 02 6d + 12: 0b bf fb ff dbmi.l \(-s\), \*-137 + 16: 77 + 17: 0b 3c e4 22 tbmi.b \[34,s\], \*\+43 + 1b: 2b + 1c: 0b 4d ff 5f tbgt.w \(s\+\), \*-33 + 20: 0b 1e c4 ea tbeq.p \[234,x\], \*-134 + 24: ff 7a + 26: 0b 5f f0 22 tble.l \(34,p\), \*\+331 + 2a: 81 4b + 2c: 0b 0c 5e 81 tbne.b \(14,y\), \*\+431 + 30: af + 31: 0b 2e 4e 80 tbpl.p \(14,x\), \*\+231 + 35: e7 \ No newline at end of file diff --git a/gas/testsuite/gas/s12z/db-tb-cc-opr.s b/gas/testsuite/gas/s12z/db-tb-cc-opr.s new file mode 100644 index 00000000000..a79cbdee9bf --- /dev/null +++ b/gas/testsuite/gas/s12z/db-tb-cc-opr.s @@ -0,0 +1,11 @@ + dble.b (3,d4), *+1 + dbgt.w (23,d5), *+18 + dble.p (2,d0), *-19 + dbmi.l (-s), *-137 + tbmi.b [34,s], *+43 + tbgt.w (s+), *-33 + tbeq.p [234,x], *-134 + tble.l (34, p), *+331 + tbne.b (14, y), *+431 + tbpl.p (14, x), *+231 + diff --git a/gas/testsuite/gas/s12z/db-tb-cc-reg.d b/gas/testsuite/gas/s12z/db-tb-cc-reg.d new file mode 100644 index 00000000000..54ea832a2d0 --- /dev/null +++ b/gas/testsuite/gas/s12z/db-tb-cc-reg.d @@ -0,0 +1,31 @@ +#objdump: -d +#name: +#source: db-tb-cc-reg.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 0b 84 0c dbne d0, \*\+12 + 3: 0b 95 0d dbeq d1, \*\+13 + 6: 0b a8 72 dbpl x, \*-14 + 9: 0b b9 0f dbmi y, \*\+15 + c: 0b c1 80 7b dbgt d3, \*\+123 + 10: 0b d7 fb 1f dble d7, \*-1249 + 14: 0b 04 16 tbne d0, \*\+22 + 17: 0b 15 17 tbeq d1, \*\+23 + 1a: 0b 28 18 tbpl x, \*\+24 + 1d: 0b 39 19 tbmi y, \*\+25 + 20: 0b 41 80 df tbgt d3, \*\+223 + 24: 0b 57 88 c9 tble d7, \*\+2249 + 28: 0b 39 28 tbmi y, \*\+40 + 2b: 0b 84 ff 75 dbne d0, \*-139 + 2f: 0b a5 04 dbpl d1, \*\+4 + 32: 0b c2 ff 76 dbgt d4, \*-138 + 36: 0b 90 29 dbeq d2, \*\+41 + 39: 0b 06 04 tbne d6, \*\+4 + 3c: 0b 27 ff 78 tbpl d7, \*-136 + 40: 0b 18 28 tbeq x, \*\+40 diff --git a/gas/testsuite/gas/s12z/db-tb-cc-reg.s b/gas/testsuite/gas/s12z/db-tb-cc-reg.s new file mode 100644 index 00000000000..524f4d00f70 --- /dev/null +++ b/gas/testsuite/gas/s12z/db-tb-cc-reg.s @@ -0,0 +1,21 @@ + dbne d0, *+12 + dbeq d1, *+13 + dbpl x, *-14 + dbmi y, *+15 + dbgt d3, *+123 + dble d7, *-1249 + tbne d0, *+22 + tbeq d1, *+23 + tbpl x, *+24 + tbmi y, *+25 + tbgt d3, *+223 + tble d7, *+2249 + tbmi y, *+40 + dbne d0, *-139 + dbpl d1, *+4 + dbgt d4, *-138 + dbeq d2, *+41 + tbne d6, *+4 + tbpl d7, *-136 + tbeq x, *+40 + diff --git a/gas/testsuite/gas/s12z/dbCC.d b/gas/testsuite/gas/s12z/dbCC.d new file mode 100644 index 00000000000..87dd7fcabad --- /dev/null +++ b/gas/testsuite/gas/s12z/dbCC.d @@ -0,0 +1,27 @@ +#objdump: -dt +#name: +#source: dbCC.s + + +dump.o: file format elf32-s12z + +SYMBOL TABLE: +00000000 l d .text 00000000 .text +00000000 l d .data 00000000 .data +00000000 l d .bss 00000000 .bss +00000001 l .text 00000000 foo + + + +Disassembly of section .text: + +00000000 : + 0: 01 nop + +00000001 : + 1: 01 nop + 2: 0b 84 ff ff dbne d0, foo + 6: 0b 88 ff fb dbne x, foo + a: 0b 89 ff f7 dbne y, foo + e: 0b 8c f3 ff dbne.b \(\+y\), foo + 12: f3 diff --git a/gas/testsuite/gas/s12z/dbCC.s b/gas/testsuite/gas/s12z/dbCC.s new file mode 100644 index 00000000000..3a637e7b853 --- /dev/null +++ b/gas/testsuite/gas/s12z/dbCC.s @@ -0,0 +1,7 @@ + nop +foo: + nop + dbne d0, foo + dbne x, foo + dbne y, foo + dbne.b (+y), foo diff --git a/gas/testsuite/gas/s12z/dec-opr.d b/gas/testsuite/gas/s12z/dec-opr.d new file mode 100644 index 00000000000..4f490883c1b --- /dev/null +++ b/gas/testsuite/gas/s12z/dec-opr.d @@ -0,0 +1,15 @@ +#objdump: -d +#name: +#source: dec-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: ac ca dec.b \[d4,x\] + 2: ad fe 00 00 dec.w \[134\] + 6: 86 + 7: af ad dec.l \(d1,s\) diff --git a/gas/testsuite/gas/s12z/dec-opr.s b/gas/testsuite/gas/s12z/dec-opr.s new file mode 100644 index 00000000000..2f54a4c452d --- /dev/null +++ b/gas/testsuite/gas/s12z/dec-opr.s @@ -0,0 +1,3 @@ + dec.b [d4, x] + dec.w [134] + dec.l (d1, s) diff --git a/gas/testsuite/gas/s12z/dec.d b/gas/testsuite/gas/s12z/dec.d new file mode 100644 index 00000000000..74a2c3e6037 --- /dev/null +++ b/gas/testsuite/gas/s12z/dec.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: dec.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 40 dec d2 + 1: 41 dec d3 + 2: 42 dec d4 + 3: 43 dec d5 + 4: 44 dec d0 + 5: 45 dec d1 + 6: 46 dec d6 + 7: 47 dec d7 diff --git a/gas/testsuite/gas/s12z/dec.s b/gas/testsuite/gas/s12z/dec.s new file mode 100644 index 00000000000..1280bf4753b --- /dev/null +++ b/gas/testsuite/gas/s12z/dec.s @@ -0,0 +1,8 @@ +L1: dec d2 + dec d3 + dec d4 + dec d5 + dec d0 + dec d1 + dec d6 + dec d7 diff --git a/gas/testsuite/gas/s12z/div.d b/gas/testsuite/gas/s12z/div.d new file mode 100644 index 00000000000..3569519e5a4 --- /dev/null +++ b/gas/testsuite/gas/s12z/div.d @@ -0,0 +1,23 @@ +#objdump: -d +#name: +#source: div.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 34 ec 62 divs.b d0, d1, #98 + 4: 1b 35 c0 b9 divs.b d1, d2, d3 + 8: 1b 30 c9 ba divs.w d2, d3, d4 + c: 1b 31 ff 00 divs.l d3, d7, #9842 + 10: 00 26 72 + 13: 1b 32 68 e0 divu.b d4, d1, \(32,s\) + 17: 20 + 18: 1b 33 49 c4 divu.w d5, d3, \[34,x\] + 1c: 22 + 1d: 1b 36 7b ff divu.l d6, d7, \(s\+\) + 21: 1b 37 7a d4 divu.lp d7, \[12,y\], \(7,d1\) + 25: 0c 85 00 07 diff --git a/gas/testsuite/gas/s12z/div.s b/gas/testsuite/gas/s12z/div.s new file mode 100644 index 00000000000..edd79903cd8 --- /dev/null +++ b/gas/testsuite/gas/s12z/div.s @@ -0,0 +1,8 @@ + divs.b d0, d1, #98 + divs.b d1, d2, d3 + divs.w d2, d3, d4 + divs.l d3, d7, #9842 + divu.b d4, d1, (32,s) + divu.w d5, d3, [34,x] + divu.l d6, d7, (s+) + divu.lp d7, [12,y], (7,d1) diff --git a/gas/testsuite/gas/s12z/eor.d b/gas/testsuite/gas/s12z/eor.d new file mode 100644 index 00000000000..f829a520821 --- /dev/null +++ b/gas/testsuite/gas/s12z/eor.d @@ -0,0 +1,33 @@ +#objdump: -d +#name: +#source: eor.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 78 fc 84 eor d2, #-892 + 4: 1b 79 ef 32 eor d3, #-4302 + 8: 1b 7f 00 01 eor d7, #123456 + c: e2 40 + e: 1b 7b 04 d2 eor d5, #1234 + 12: 1b 7c 7b eor d0, #123 + 15: 1b 7d 22 eor d1, #34 + 18: 1b 7e ff ff eor d6, #-56789 + 1c: 22 2b + 1e: 1b 7a 22 3d eor d4, #8765 + 22: 1b 8c d5 21 eor d0, \[-223,y\] + 26: 1b 8d f2 00 eor d1, \(34000,p\) + 2a: 84 d0 + 2c: 1b 88 fb eor d2, \(-s\) + 2f: 1b 79 00 04 eor d3, #4 + 33: 1b 8a bc eor d4, d0 + 36: 1b 8b f9 4c eor d5, 85178 + 3a: ba + 3b: 1b 8e fe 00 eor d6, \[15256\] + 3f: 3b 98 + 41: 1b 8f 8b eor d7, \(d5,x\) + 44: 1b 89 f7 eor d3, \(y\+\) diff --git a/gas/testsuite/gas/s12z/eor.s b/gas/testsuite/gas/s12z/eor.s new file mode 100644 index 00000000000..cc4985add47 --- /dev/null +++ b/gas/testsuite/gas/s12z/eor.s @@ -0,0 +1,17 @@ + eor d2, #-892 + eor d3, #-4302 + eor d7, #123456 + eor d5, #1234 + eor d0, #123 + eor d1, #34 + eor d6, #-56789 + eor d4, #8765 + eor d0, [-223,y] + eor d1, (34000, p) + eor d2, (-s) + eor d3, #4 + eor d4, d0 + eor d5, 85178 + eor d6, [15256] + eor d7, (d5, x) + eor d3, (y+) diff --git a/gas/testsuite/gas/s12z/exg.d b/gas/testsuite/gas/s12z/exg.d new file mode 100644 index 00000000000..58e4ae7c802 --- /dev/null +++ b/gas/testsuite/gas/s12z/exg.d @@ -0,0 +1,29 @@ +#objdump: -d +#name: +#source: exg.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: ae 45 exg d0, d1 + 2: ae 55 exg d1, d1 + 4: ae 05 exg d2, d1 + 6: ae 15 exg d3, d1 + 8: ae 25 exg d4, d1 + a: ae 35 exg d5, d1 + c: ae 65 exg d6, d1 + e: ae 75 exg d7, d1 + 10: ae 85 exg x, d1 + 12: ae 95 exg y, d1 + 14: ae c5 exg cch, d1 + 16: ae d5 exg ccl, d1 + 18: ae e5 exg ccw, d1 + 1a: ae 68 exg d6, x + 1c: ae 79 exg d7, y + 1e: ae 8e exg x, ccw + 20: ae 97 sex y, d7 + 22: ae cd exg cch, ccl diff --git a/gas/testsuite/gas/s12z/exg.s b/gas/testsuite/gas/s12z/exg.s new file mode 100644 index 00000000000..55ce30139c1 --- /dev/null +++ b/gas/testsuite/gas/s12z/exg.s @@ -0,0 +1,18 @@ + exg d0, d1 + exg d1, d1 + exg d2, d1 + exg d3, d1 + exg d4, d1 + exg d5, d1 + exg d6, d1 + exg d7, d1 + exg x, d1 + exg y, d1 + exg cch, d1 + exg ccl, d1 + exg ccw, d1 + exg d6, x + exg d7, y + exg x, ccw + sex y, d7 + exg cch, ccl diff --git a/gas/testsuite/gas/s12z/ext24-ld-xy.d b/gas/testsuite/gas/s12z/ext24-ld-xy.d new file mode 100644 index 00000000000..a3f075f0be5 --- /dev/null +++ b/gas/testsuite/gas/s12z/ext24-ld-xy.d @@ -0,0 +1,12 @@ +#objdump: -d +#name: +#source: ext24-ld-xy.s + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: b8 74 cb b1 ld x, 7654321 + 4: b9 63 d7 6a ld y, 6543210 diff --git a/gas/testsuite/gas/s12z/ext24-ld-xy.s b/gas/testsuite/gas/s12z/ext24-ld-xy.s new file mode 100644 index 00000000000..2b262f06df0 --- /dev/null +++ b/gas/testsuite/gas/s12z/ext24-ld-xy.s @@ -0,0 +1,2 @@ + .long 0xB874CBB1 ;; LD X,7654321 + .long 0xB963D76A ;; LD Y,6543210 diff --git a/gas/testsuite/gas/s12z/inc-opr.d b/gas/testsuite/gas/s12z/inc-opr.d new file mode 100644 index 00000000000..d013d6ac6f1 --- /dev/null +++ b/gas/testsuite/gas/s12z/inc-opr.d @@ -0,0 +1,15 @@ +#objdump: -d +#name: +#source: inc-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 9c 88 inc.b \(d2,x\) + 2: 9d fe 00 04 inc.w \[1234\] + 6: d2 + 7: 9f 88 inc.l \(d2,x\) diff --git a/gas/testsuite/gas/s12z/inc-opr.s b/gas/testsuite/gas/s12z/inc-opr.s new file mode 100644 index 00000000000..18760826f33 --- /dev/null +++ b/gas/testsuite/gas/s12z/inc-opr.s @@ -0,0 +1,3 @@ + inc.b (d2, x) + inc.w [1234] + inc.l (d2, x) diff --git a/gas/testsuite/gas/s12z/inc.d b/gas/testsuite/gas/s12z/inc.d new file mode 100644 index 00000000000..51b912b9ceb --- /dev/null +++ b/gas/testsuite/gas/s12z/inc.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: inc.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 30 inc d2 + 1: 31 inc d3 + 2: 32 inc d4 + 3: 33 inc d5 + 4: 34 inc d0 + 5: 35 inc d1 + 6: 36 inc d6 + 7: 37 inc d7 diff --git a/gas/testsuite/gas/s12z/inc.s b/gas/testsuite/gas/s12z/inc.s new file mode 100644 index 00000000000..89e0b971623 --- /dev/null +++ b/gas/testsuite/gas/s12z/inc.s @@ -0,0 +1,8 @@ +L1: inc d2 + inc d3 + inc d4 + inc d5 + inc d0 + inc d1 + inc d6 + inc d7 diff --git a/gas/testsuite/gas/s12z/inh.d b/gas/testsuite/gas/s12z/inh.d new file mode 100644 index 00000000000..4f437f1bcaa --- /dev/null +++ b/gas/testsuite/gas/s12z/inh.d @@ -0,0 +1,15 @@ +#objdump: -d +#name: +#source: inh.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: ff swi + 1: 05 rts + 2: 00 bgnd + 3: 01 nop diff --git a/gas/testsuite/gas/s12z/inh.s b/gas/testsuite/gas/s12z/inh.s new file mode 100644 index 00000000000..22b28583252 --- /dev/null +++ b/gas/testsuite/gas/s12z/inh.s @@ -0,0 +1,5 @@ + swi + rts + bgnd + nop + diff --git a/gas/testsuite/gas/s12z/jmp.d b/gas/testsuite/gas/s12z/jmp.d new file mode 100644 index 00000000000..12ff350b47d --- /dev/null +++ b/gas/testsuite/gas/s12z/jmp.d @@ -0,0 +1,33 @@ +#objdump: -d +#name: JMP instruction +#source: jmp.s + + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: aa bb jmp d5 + 2: aa 4c jmp \(12,x\) + 4: aa f3 jmp \(\+y\) + 6: aa d3 jmp \(-y\) + 8: aa f7 jmp \(y\+\) + a: aa d7 jmp \(y-\) + c: aa e3 jmp \(\+x\) + e: aa c3 jmp \(-x\) + 10: aa e7 jmp \(x\+\) + 12: aa c7 jmp \(x-\) + 14: aa fb jmp \(-s\) + 16: aa ff jmp \(s\+\) + 18: aa ab jmp \(d5,s\) + 1a: aa 87 00 5a jmp \(90,d7\) + 1e: aa f0 5a jmp \(90,p\) + 21: aa d4 2d jmp \[45,y\] + 24: aa 00 10 jmp 16 + 27: aa 37 f1 jmp 14321 + 2a: aa f9 be 91 jmp 114321 + 2e: aa fe 06 98 jmp \[432134\] + 32: 06 diff --git a/gas/testsuite/gas/s12z/jmp.s b/gas/testsuite/gas/s12z/jmp.s new file mode 100644 index 00000000000..fa4321d6496 --- /dev/null +++ b/gas/testsuite/gas/s12z/jmp.s @@ -0,0 +1,20 @@ + jmp d5 + jmp (12, x) + jmp (+y) + jmp (-y) + jmp (y+) + jmp (y-) + jmp (+x) + jmp (-x) + jmp (x+) + jmp (x-) + jmp (-s) + jmp (s+) + jmp (d5,s) + jmp (90,d7) + jmp (90,p) + jmp [45,y] + jmp 16 + jmp 14321 + jmp 114321 + jmp [432134] diff --git a/gas/testsuite/gas/s12z/jsr.d b/gas/testsuite/gas/s12z/jsr.d new file mode 100644 index 00000000000..8508a0a740f --- /dev/null +++ b/gas/testsuite/gas/s12z/jsr.d @@ -0,0 +1,33 @@ +#objdump: -d +#name: JSR instruction +#source: jsr.s + + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: ab b8 jsr d2 + 2: ab 52 jsr \(2,y\) + 4: ab f3 jsr \(\+y\) + 6: ab d3 jsr \(-y\) + 8: ab f7 jsr \(y\+\) + a: ab d7 jsr \(y-\) + c: ab e3 jsr \(\+x\) + e: ab c3 jsr \(-x\) + 10: ab e7 jsr \(x\+\) + 12: ab c7 jsr \(x-\) + 14: ab fb jsr \(-s\) + 16: ab ff jsr \(s\+\) + 18: ab 89 jsr \(d3,x\) + 1a: ab 86 00 1e jsr \(30,d6\) + 1e: ab f0 5d jsr \(93,p\) + 21: ab d4 2d jsr \[45,y\] + 24: ab 00 0c jsr 12 + 27: ab 0f b5 jsr 4021 + 2a: ab f9 be 91 jsr 114321 + 2e: ab fe 07 82 jsr \[492134\] + 32: 66 diff --git a/gas/testsuite/gas/s12z/jsr.s b/gas/testsuite/gas/s12z/jsr.s new file mode 100644 index 00000000000..80f0ff1422b --- /dev/null +++ b/gas/testsuite/gas/s12z/jsr.s @@ -0,0 +1,20 @@ + jsr d2 + jsr (2, y) + jsr (+y) + jsr (-y) + jsr (y+) + jsr (y-) + jsr (+x) + jsr (-x) + jsr (x+) + jsr (x-) + jsr (-s) + jsr (s+) + jsr (d3,x) + jsr (30,d6) + jsr (93,p) + jsr [45,y] + jsr 12 + jsr 4021 + jsr 114321 + jsr [492134] diff --git a/gas/testsuite/gas/s12z/ld-imm-page2.d b/gas/testsuite/gas/s12z/ld-imm-page2.d new file mode 100644 index 00000000000..3f1744f8336 --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-imm-page2.d @@ -0,0 +1,15 @@ +#objdump: -d +#name: +#source: ld-imm-page2.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 03 aa bb ld s, #-5588020 + 4: cc + 5: 1b 03 00 30 ld s, #12309 + 9: 15 diff --git a/gas/testsuite/gas/s12z/ld-imm-page2.s b/gas/testsuite/gas/s12z/ld-imm-page2.s new file mode 100644 index 00000000000..09c735c8935 --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-imm-page2.s @@ -0,0 +1,2 @@ + ld s, #-5588020 + ld s, #12309 diff --git a/gas/testsuite/gas/s12z/ld-imm.d b/gas/testsuite/gas/s12z/ld-imm.d new file mode 100644 index 00000000000..b0e4fcbe3f5 --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-imm.d @@ -0,0 +1,25 @@ +#objdump: -d +#name: +#source: ld-imm.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 90 01 23 ld d2, #291 + 3: 91 01 23 ld d3, #291 + 6: 92 01 23 ld d4, #291 + 9: 93 01 23 ld d5, #291 + c: 94 56 ld d0, #86 + e: 95 78 ld d1, #120 + 10: 96 12 34 56 ld d6, #305419896 + 14: 78 + 15: 97 12 34 56 ld d7, #305419896 + 19: 78 + 1a: 98 ab cd ef ld x, #-5517841 + 1e: 99 fe dc ba ld y, #-74566 + 22: 98 00 cd ef ld x, #52719 + 26: 99 00 dc ba ld y, #56506 diff --git a/gas/testsuite/gas/s12z/ld-imm.s b/gas/testsuite/gas/s12z/ld-imm.s new file mode 100644 index 00000000000..569123de204 --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-imm.s @@ -0,0 +1,16 @@ +here: ld d2, #0x0123 + ld d3, #0x0123 + ld d4, #0x0123 + ld d5, #0x0123 + ld d0, #0x56 + ld d1, #0x78 + ld d6, #0x12345678 + ld d7, #0x12345678 + + ld x, #-5517841 + ld y, #-74566 + + + ;; The following two can be encoded using {CDEF}{AB} + ld x, #0xcdef + ld y, #0xdcba diff --git a/gas/testsuite/gas/s12z/ld-immu18.d b/gas/testsuite/gas/s12z/ld-immu18.d new file mode 100644 index 00000000000..ba071dfbdf5 --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-immu18.d @@ -0,0 +1,28 @@ +#objdump: -d +#name: +#source: ld-immu18.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 00 bgnd + 1: ca ff ee ld x, #65518 + 4: 00 bgnd + 5: cb df e4 ld y, #57316 + 8: 00 bgnd + 9: da f0 ea ld x, #127210 + c: 00 bgnd + d: db 7f 6e ld y, #98158 + 10: 00 bgnd + 11: ea 6f ea ld x, #159722 + 14: 00 bgnd + 15: eb 7f 9e ld y, #163742 + 18: 00 bgnd + 19: fa 1f ca ld x, #204746 + 1c: 00 bgnd + 1d: fb 7f 0e ld y, #229134 + 20: 01 nop diff --git a/gas/testsuite/gas/s12z/ld-immu18.s b/gas/testsuite/gas/s12z/ld-immu18.s new file mode 100644 index 00000000000..563765e8bdf --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-immu18.s @@ -0,0 +1,10 @@ + .long 0xCAFFEE + .long 0xCBDFE4 + .long 0xDAF0EA + .long 0xDB7F6E + .long 0xEA6FEA + .long 0xEB7F9E + .long 0xFA1FCA + .long 0xFB7F0E + nop + diff --git a/gas/testsuite/gas/s12z/ld-large-direct.d b/gas/testsuite/gas/s12z/ld-large-direct.d new file mode 100644 index 00000000000..c17f1c96af3 --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-large-direct.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: LD reg - conldant optimised to EXT24 +#source: ld-large-direct.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: b0 12 34 56 ld d2, 1193046 + 4: b1 c0 ff ee ld d3, 12648430 + 8: b2 80 00 02 ld d4, 8388610 + c: b4 80 00 03 ld d0, 8388611 + 10: b5 80 00 03 ld d1, 8388611 + 14: b3 80 00 04 ld d5, 8388612 + 18: b6 80 00 06 ld d6, 8388614 + 1c: b7 80 00 07 ld d7, 8388615 + 20: b8 80 00 08 ld x, 8388616 + 24: b9 80 00 09 ld y, 8388617 diff --git a/gas/testsuite/gas/s12z/ld-large-direct.s b/gas/testsuite/gas/s12z/ld-large-direct.s new file mode 100644 index 00000000000..4c53f2ade7f --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-large-direct.s @@ -0,0 +1,11 @@ + ld d2, 0x123456 + ld d3, 0xc0ffee + ld d4, 0x800002 + ld d0, 0x800003 + ld d1, 0x800003 + ld d5, 0x800004 + ld d6, 0x800006 + ld d7, 0x800007 + ld x, 0x800008 + ld y, 0x800009 + diff --git a/gas/testsuite/gas/s12z/ld-opr.d b/gas/testsuite/gas/s12z/ld-opr.d new file mode 100644 index 00000000000..c0a8ec2d893 --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-opr.d @@ -0,0 +1,22 @@ +#objdump: -d +#name: +#source: ld-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: a4 dc ld d0, \[d0,y\] + 2: a5 cd ld d1, \[d1,x\] + 4: a0 cd ld d2, \[d1,x\] + 6: a1 80 04 d2 ld d3, \(1234,d2\) + a: a2 e2 ff fb ld d4, \(-1234,s\) + e: 2e + f: a3 bf ld d5, d7 + 11: a6 88 ld d6, \(d2,x\) + 13: a7 d9 ld d7, \[d3,y\] + 15: a8 ac ld x, \(d0,s\) + 17: a9 cd ld y, \[d1,x\] diff --git a/gas/testsuite/gas/s12z/ld-opr.s b/gas/testsuite/gas/s12z/ld-opr.s new file mode 100644 index 00000000000..ee452e9c132 --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-opr.s @@ -0,0 +1,10 @@ + ld d0, [d0,y] + ld d1, [d1,x] + ld d2, [d1, x] + ld d3, (1234,d2) + ld d4, (-1234,s) + ld d5, d7 + ld d6, (d2, x) + ld d7, [d3, y] + ld x, (d0, s) + ld y, [d1, x] diff --git a/gas/testsuite/gas/s12z/ld-s-opr.d b/gas/testsuite/gas/s12z/ld-s-opr.d new file mode 100644 index 00000000000..085ebfbd3e3 --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-s-opr.d @@ -0,0 +1,16 @@ +#objdump: -d +#name: +#source: ld-s-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 00 df ld s, \[d7,y\] + 3: 1b 00 fe 00 ld s, \[8134\] + 7: 1f c6 + 9: 1b 00 ae ld s, \(d6,s\) + c: 1b 00 fb ld s, \(-s\) diff --git a/gas/testsuite/gas/s12z/ld-s-opr.s b/gas/testsuite/gas/s12z/ld-s-opr.s new file mode 100644 index 00000000000..41ee23e0955 --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-s-opr.s @@ -0,0 +1,4 @@ + ld s, [d7, y] + ld s, [8134] + ld s, (d6, s) + ld s, (-s) diff --git a/gas/testsuite/gas/s12z/ld-small-direct.d b/gas/testsuite/gas/s12z/ld-small-direct.d new file mode 100644 index 00000000000..e6cffd29c86 --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-small-direct.d @@ -0,0 +1,31 @@ +#objdump: -d +#name: LD reg - small constants left in OPR mode +#source: ld-small-direct.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: a0 fa 00 00 ld d2, L1 + 4: 00 + 5: a1 fa 00 00 ld d3, 25 + 9: 19 + a: a2 fa 00 00 ld d4, L1 + e: 00 + +0000000f : + f: a4 fa 00 00 ld d0, 25 + 13: 19 + 14: a5 fa 00 00 ld d1, L3 + 18: 0f + 19: a3 fa 00 00 ld d5, L1 + 1d: 00 + 1e: a6 fa 00 00 ld d6, L3 + 22: 0f + 23: a7 fa 00 00 ld d7, 25 + 27: 19 + 28: a8 30 39 ld x, 12345 + 2b: a9 26 94 ld y, 9876 diff --git a/gas/testsuite/gas/s12z/ld-small-direct.s b/gas/testsuite/gas/s12z/ld-small-direct.s new file mode 100644 index 00000000000..5d9ea6d433c --- /dev/null +++ b/gas/testsuite/gas/s12z/ld-small-direct.s @@ -0,0 +1,11 @@ +L1: ld d2, L1 + ld d3, .L2 + ld d4, L1 +L3: ld d0, .L2 + ld d1, L3 +.L2: ld d5, L1 + ld d6, L3 + ld d7, .L2 + ld x, 12345 + ld y, 9876 + diff --git a/gas/testsuite/gas/s12z/lea-immu18.d b/gas/testsuite/gas/s12z/lea-immu18.d new file mode 100644 index 00000000000..3088b41ab9f --- /dev/null +++ b/gas/testsuite/gas/s12z/lea-immu18.d @@ -0,0 +1,14 @@ +#objdump: -d +#name: +#source: lea-immu18.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 18 55 lea x, \(85,x\) + 2: 19 aa lea y, \(-86,y\) + 4: 1a 12 lea s, \(18,s\) diff --git a/gas/testsuite/gas/s12z/lea-immu18.s b/gas/testsuite/gas/s12z/lea-immu18.s new file mode 100644 index 00000000000..b003922fa91 --- /dev/null +++ b/gas/testsuite/gas/s12z/lea-immu18.s @@ -0,0 +1,3 @@ + .short 0x1855 + .short 0x19AA + .short 0x1A12 diff --git a/gas/testsuite/gas/s12z/lea.d b/gas/testsuite/gas/s12z/lea.d new file mode 100644 index 00000000000..30722a500dc --- /dev/null +++ b/gas/testsuite/gas/s12z/lea.d @@ -0,0 +1,18 @@ +#objdump: -d +#name: +#source: lea.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 0a 44 lea s, \(4,x\) + 2: 06 c0 7b lea d6, \(123,x\) + 5: 07 d1 16 lea d7, \(-234,y\) + 8: 08 c1 ea lea x, \(-22,x\) + b: 09 d0 16 lea y, \(22,y\) + e: 0a e0 16 lea s, \(22,s\) + 11: 09 c1 d3 lea y, \(-45,x\) diff --git a/gas/testsuite/gas/s12z/lea.s b/gas/testsuite/gas/s12z/lea.s new file mode 100644 index 00000000000..2d75a939afa --- /dev/null +++ b/gas/testsuite/gas/s12z/lea.s @@ -0,0 +1,8 @@ + lea s, (4,x) + lea d6, (123,x) + lea d7, (-234,y) + lea x, (-22,x) + lea y, (22,y) + lea s, (22,s) + lea y, (-45,x) + diff --git a/gas/testsuite/gas/s12z/mac.d b/gas/testsuite/gas/s12z/mac.d new file mode 100644 index 00000000000..d2758b6e1f3 --- /dev/null +++ b/gas/testsuite/gas/s12z/mac.d @@ -0,0 +1,23 @@ +#objdump: -d +#name: +#source: mac.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 4c ec 62 macs.b d0, d1, #98 + 4: 1b 4d c0 b9 macs.b d1, d2, d3 + 8: 1b 48 c9 ba macs.w d2, d3, d4 + c: 1b 49 ff 00 macs.l d3, d7, #9842 + 10: 00 26 72 + 13: 1b 4a 68 e0 macu.b d4, d1, \(32,s\) + 17: 20 + 18: 1b 4b 49 c4 macu.w d5, d3, \[34,x\] + 1c: 22 + 1d: 1b 4e 7b ff macu.l d6, d7, \(s\+\) + 21: 1b 4f 7a d4 macu.lp d7, \[12,y\], \(7,d1\) + 25: 0c 85 00 07 diff --git a/gas/testsuite/gas/s12z/mac.s b/gas/testsuite/gas/s12z/mac.s new file mode 100644 index 00000000000..89145241983 --- /dev/null +++ b/gas/testsuite/gas/s12z/mac.s @@ -0,0 +1,8 @@ + macs.b d0, d1, #98 + macs.b d1, d2, d3 + macs.w d2, d3, d4 + macs.l d3, d7, #9842 + macu.b d4, d1, (32,s) + macu.w d5, d3, [34,x] + macu.l d6, d7, (s+) + macu.lp d7, [12,y], (7,d1) diff --git a/gas/testsuite/gas/s12z/min-max.d b/gas/testsuite/gas/s12z/min-max.d new file mode 100644 index 00000000000..f01684a68d8 --- /dev/null +++ b/gas/testsuite/gas/s12z/min-max.d @@ -0,0 +1,48 @@ +#objdump: -d +#name: +#source: min-max.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 2c fe 01 maxs d0, \[123456\] + 4: e2 40 + 6: 1b 2d c4 04 maxs d1, \[4,x\] + a: 1b 28 b8 maxs d2, d2 + d: 1b 29 dc maxs d3, \[d0,y\] + 10: 1b 2a e4 0c maxs d4, \[12,s\] + 14: 1b 2b 63 maxs d5, \(3,s\) + 17: 1b 2e e1 85 maxs d6, \(-123,s\) + 1b: 1b 2f f2 01 maxs d7, \(123987,p\) + 1f: e4 53 + 21: 1b 24 c7 mins d0, \(x-\) + 24: 1b 25 d7 mins d1, \(y-\) + 27: 1b 20 e7 mins d2, \(x\+\) + 2a: 1b 21 f7 mins d3, \(y\+\) + 2d: 1b 22 ff mins d4, \(s\+\) + 30: 1b 23 e3 mins d5, \(\+x\) + 33: 1b 26 f3 mins d6, \(\+y\) + 36: 1b 27 c3 mins d7, \(-x\) + 39: 1b 1c d3 maxu d0, \(-y\) + 3c: 1b 1d fb maxu d1, \(-s\) + 3f: 1b 18 8b maxu d2, \(d5,x\) + 42: 1b 19 9e maxu d3, \(d6,y\) + 45: 1b 1a af maxu d4, \(d7,s\) + 48: 1b 1b e2 ff maxu d5, \(-1023,s\) + 4c: fc 01 + 4e: 1b 1e f6 00 maxu d6, \[1087,p\] + 52: 04 3f + 54: 1b 1f d3 maxu d7, \(-y\) + 57: 1b 14 c3 minu d0, \(-x\) + 5a: 1b 15 ff minu d1, \(s\+\) + 5d: 1b 10 8d minu d2, \(d1,x\) + 60: 1b 11 98 minu d3, \(d2,y\) + 63: 1b 12 a9 minu d4, \(d3,s\) + 66: 1b 13 e1 85 minu d5, \(-123,s\) + 6a: 1b 16 f6 01 minu d6, \[123987,p\] + 6e: e4 53 + 70: 1b 17 d7 minu d7, \(y-\) diff --git a/gas/testsuite/gas/s12z/min-max.s b/gas/testsuite/gas/s12z/min-max.s new file mode 100644 index 00000000000..1b6b9d7001c --- /dev/null +++ b/gas/testsuite/gas/s12z/min-max.s @@ -0,0 +1,32 @@ + maxs d0, [123456] + maxs d1, [4,x] + maxs d2, d2 + maxs d3, [d0, y] + maxs d4, [12,s] + maxs d5, (3,s) + maxs d6, (-123,s) + maxs d7, (123987, p) + mins d0, (x-) + mins d1, (y-) + mins d2, (x+) + mins d3, (y+) + mins d4, (s+) + mins d5, (+x) + mins d6, (+y) + mins d7, (-x) + maxu d0, (-y) + maxu d1, (-s) + maxu d2, (d5, x) + maxu d3, (d6, y) + maxu d4, (d7, s) + maxu d5, (-1023,s) + maxu d6, [1087, p] + maxu d7, (-y) + minu d0, (-x) + minu d1, (s+) + minu d2, (d1, x) + minu d3, (d2, y) + minu d4, (d3, s) + minu d5, (-123,s) + minu d6, [123987, p] + minu d7, (y-) diff --git a/gas/testsuite/gas/s12z/mod.d b/gas/testsuite/gas/s12z/mod.d new file mode 100644 index 00000000000..34c67dd07a1 --- /dev/null +++ b/gas/testsuite/gas/s12z/mod.d @@ -0,0 +1,23 @@ +#objdump: -d +#name: +#source: mod.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 3c ec 62 mods.b d0, d1, #98 + 4: 1b 3d c0 b9 mods.b d1, d2, d3 + 8: 1b 38 c9 ba mods.w d2, d3, d4 + c: 1b 39 ff 00 mods.l d3, d7, #9842 + 10: 00 26 72 + 13: 1b 3a 68 e0 modu.b d4, d1, \(32,s\) + 17: 20 + 18: 1b 3b 49 c4 modu.w d5, d3, \[34,x\] + 1c: 22 + 1d: 1b 3e 7b ff modu.l d6, d7, \(s\+\) + 21: 1b 3f 7a d4 modu.lp d7, \[12,y\], \(7,d1\) + 25: 0c 85 00 07 diff --git a/gas/testsuite/gas/s12z/mod.s b/gas/testsuite/gas/s12z/mod.s new file mode 100644 index 00000000000..c94994a9acc --- /dev/null +++ b/gas/testsuite/gas/s12z/mod.s @@ -0,0 +1,8 @@ + mods.b d0, d1, #98 + mods.b d1, d2, d3 + mods.w d2, d3, d4 + mods.l d3, d7, #9842 + modu.b d4, d1, (32,s) + modu.w d5, d3, [34,x] + modu.l d6, d7, (s+) + modu.lp d7, [12,y], (7,d1) diff --git a/gas/testsuite/gas/s12z/mov.d b/gas/testsuite/gas/s12z/mov.d new file mode 100644 index 00000000000..e9f40863942 --- /dev/null +++ b/gas/testsuite/gas/s12z/mov.d @@ -0,0 +1,26 @@ +#objdump: -d +#name: +#source: mov.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 0c 7b e3 mov.b #123, \(\+x\) + 3: 0d 11 70 80 mov.w #4464, \(45,d2\) + 7: 00 2d + 9: 0e 12 34 56 mov.p #1193046, \[34,s\] + d: e4 22 + f: 0f 12 34 56 mov.l #305419896, \(2234,d7\) + 13: 78 87 08 ba + 17: 1c 84 00 01 mov.b \(1,d0\), \(2,d1\) + 1b: 85 00 02 + 1e: 1d 82 00 01 mov.w \(1,d4\), \(-s\) + 22: fb + 23: 1e 83 00 03 mov.p \(3,d5\), \(-x\) + 27: c3 + 28: 1f 87 00 26 mov.l \(38,d7\), \(\+x\) + 2c: e3 diff --git a/gas/testsuite/gas/s12z/mov.s b/gas/testsuite/gas/s12z/mov.s new file mode 100644 index 00000000000..35af91963e8 --- /dev/null +++ b/gas/testsuite/gas/s12z/mov.s @@ -0,0 +1,8 @@ + mov.b #123, (+x) + mov.w #4464, (45,d2) + mov.p #0x123456, [34,s] + mov.l #0x12345678, (2234, d7) + mov.b (1,d0), (2,d1) + mov.w (1,d4), (-s) + mov.p (3,d5), (-x) + mov.l (38,d7), (+x) diff --git a/gas/testsuite/gas/s12z/mul-imm.d b/gas/testsuite/gas/s12z/mul-imm.d new file mode 100644 index 00000000000..fdc4e10dd5a --- /dev/null +++ b/gas/testsuite/gas/s12z/mul-imm.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: mul-imm.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 4c ec 85 muls.b d0, d1, #-123 + 3: 4d ed cf c7 muls.w d1, d1, #-12345 + 7: 48 ef ff ed muls.l d2, d1, #-1234567 + b: 29 79 + d: 4c 6c 7b mulu.b d0, d1, #123 + 10: 4d 6d 30 39 mulu.w d1, d1, #12345 + 14: 48 6f 00 12 mulu.l d2, d1, #1234567 + 18: d6 87 diff --git a/gas/testsuite/gas/s12z/mul-imm.s b/gas/testsuite/gas/s12z/mul-imm.s new file mode 100644 index 00000000000..d0479346a48 --- /dev/null +++ b/gas/testsuite/gas/s12z/mul-imm.s @@ -0,0 +1,6 @@ + muls.b d0, d1, #-123 + muls.w d1, d1, #-12345 + muls.l d2, d1, #-1234567 + mulu.b d0, d1, #123 + mulu.w d1, d1, #12345 + mulu.l d2, d1, #1234567 diff --git a/gas/testsuite/gas/s12z/mul-opr-opr.d b/gas/testsuite/gas/s12z/mul-opr-opr.d new file mode 100644 index 00000000000..15bb7a915e4 --- /dev/null +++ b/gas/testsuite/gas/s12z/mul-opr-opr.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: mul-opr-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 4c c2 ff fb muls.bb d0, \(s\+\), \(-s\) + 4: 4d 46 e0 2d mulu.bw d1, \(45,s\), \(d0,s\) + 8: ac + 9: 48 ca e5 d3 muls.bp d2, \[-45,s\], \[1239\] + d: fe 00 04 d7 + 11: 49 4e c5 6f mulu.bl d3, \[-145,x\], \(\+x\) + 15: e3 + 16: 4c d2 e7 d3 muls.wb d0, \(x\+\), \(-y\) diff --git a/gas/testsuite/gas/s12z/mul-opr-opr.s b/gas/testsuite/gas/s12z/mul-opr-opr.s new file mode 100644 index 00000000000..a25372558c8 --- /dev/null +++ b/gas/testsuite/gas/s12z/mul-opr-opr.s @@ -0,0 +1,6 @@ + muls.bb d0, (s+), (-s) + mulu.bw d1, (45, s), (d0, s) + muls.bp d2, [-45, s], [1239] + mulu.bl d3, [-145, x], (+x) + muls.wb d0, (x+), (-y) + diff --git a/gas/testsuite/gas/s12z/mul-opr.d b/gas/testsuite/gas/s12z/mul-opr.d new file mode 100644 index 00000000000..875ba7268e2 --- /dev/null +++ b/gas/testsuite/gas/s12z/mul-opr.d @@ -0,0 +1,17 @@ +#objdump: -d +#name: +#source: mul-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 4c e8 70 muls.b d0, d1, #-1 + 3: 49 f9 fb muls.w d3, d7, \(-s\) + 6: 49 fb e3 muls.l d3, d7, \(\+x\) + 9: 4a 68 e0 20 mulu.b d4, d1, \(32,s\) + d: 4b 49 c4 22 mulu.w d5, d3, \[34,x\] + 11: 4e 7b ff mulu.l d6, d7, \(s\+\) diff --git a/gas/testsuite/gas/s12z/mul-opr.s b/gas/testsuite/gas/s12z/mul-opr.s new file mode 100644 index 00000000000..22e97fb459e --- /dev/null +++ b/gas/testsuite/gas/s12z/mul-opr.s @@ -0,0 +1,6 @@ + muls.b d0, d1, #-1 + muls.w d3, d7, (-s) + muls.l d3, d7, (+x) + mulu.b d4, d1, (32,s) + mulu.w d5, d3, [34,x] + mulu.l d6, d7, (s+) diff --git a/gas/testsuite/gas/s12z/mul-reg.d b/gas/testsuite/gas/s12z/mul-reg.d new file mode 100644 index 00000000000..3f4c84b6890 --- /dev/null +++ b/gas/testsuite/gas/s12z/mul-reg.d @@ -0,0 +1,27 @@ +#objdump: -d +#name: +#source: mul-reg.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 4c a8 muls d0, d1, d2 + 2: 4d 81 muls d1, d2, d3 + 4: 48 8a muls d2, d3, d4 + 6: 49 93 muls d3, d4, d5 + 8: 4a 9e muls d4, d5, d6 + a: 4b b7 muls d5, d6, d7 + c: 4e bc muls d6, d7, d0 + e: 4f a5 muls d7, d0, d1 + 10: 4c 28 mulu d0, d1, d2 + 12: 4d 01 mulu d1, d2, d3 + 14: 48 0a mulu d2, d3, d4 + 16: 49 13 mulu d3, d4, d5 + 18: 4a 1e mulu d4, d5, d6 + 1a: 4b 37 mulu d5, d6, d7 + 1c: 4e 3c mulu d6, d7, d0 + 1e: 4f 25 mulu d7, d0, d1 diff --git a/gas/testsuite/gas/s12z/mul-reg.s b/gas/testsuite/gas/s12z/mul-reg.s new file mode 100644 index 00000000000..9cb9ac9f066 --- /dev/null +++ b/gas/testsuite/gas/s12z/mul-reg.s @@ -0,0 +1,16 @@ + muls d0, d1, d2 + muls d1, d2, d3 + muls d2, d3, d4 + muls d3, d4, d5 + muls d4, d5, d6 + muls d5, d6, d7 + muls d6, d7, d0 + muls d7, d0, d1 + mulu d0, d1, d2 + mulu d1, d2, d3 + mulu d2, d3, d4 + mulu d3, d4, d5 + mulu d4, d5, d6 + mulu d5, d6, d7 + mulu d6, d7, d0 + mulu d7, d0, d1 diff --git a/gas/testsuite/gas/s12z/mul.d b/gas/testsuite/gas/s12z/mul.d new file mode 100644 index 00000000000..e028b8558cd --- /dev/null +++ b/gas/testsuite/gas/s12z/mul.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: mul.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 4c ec 62 muls.b d0, d1, #98 + 3: 49 ff 00 00 muls.l d3, d7, #9842 + 7: 26 72 + 9: 4a 68 e0 20 mulu.b d4, d1, \(32,s\) + d: 4b 49 c4 22 mulu.w d5, d3, \[34,x\] + 11: 4e 7b ff mulu.l d6, d7, \(s\+\) + 14: 4f 7a d4 0c mulu.lp d7, \[12,y\], \(7,d1\) + 18: 85 00 07 diff --git a/gas/testsuite/gas/s12z/mul.s b/gas/testsuite/gas/s12z/mul.s new file mode 100644 index 00000000000..1626ee410fc --- /dev/null +++ b/gas/testsuite/gas/s12z/mul.s @@ -0,0 +1,6 @@ + muls.b d0, d1, #98 + muls.l d3, d7, #9842 + mulu.b d4, d1, (32,s) + mulu.w d5, d3, [34,x] + mulu.l d6, d7, (s+) + mulu.lp d7, [12,y], (7,d1) diff --git a/gas/testsuite/gas/s12z/neg-opr.d b/gas/testsuite/gas/s12z/neg-opr.d new file mode 100644 index 00000000000..7d4116dc7c0 --- /dev/null +++ b/gas/testsuite/gas/s12z/neg-opr.d @@ -0,0 +1,34 @@ +#objdump: -d +#name: +#source: neg-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: df fe 12 34 neg.l \[1193046\] + 4: 56 + 5: dc c4 04 neg.b \[4,x\] + 8: dd b8 neg.w d2 + a: dc dc neg.b \[d0,y\] + c: dc e4 0c neg.b \[12,s\] + f: dc 63 neg.b \(3,s\) + 11: dc e1 85 neg.b \(-123,s\) + 14: df f2 12 3a neg.l \(1194684,p\) + 18: bc + 19: dd c7 neg.w \(x-\) + 1b: dd d7 neg.w \(y-\) + 1d: dc e7 neg.b \(x\+\) + 1f: dc f7 neg.b \(y\+\) + 21: dc ff neg.b \(s\+\) + 23: df e3 neg.l \(\+x\) + 25: dd f3 neg.w \(\+y\) + 27: df c3 neg.l \(-x\) + 29: dd d3 neg.w \(-y\) + 2b: dc fb neg.b \(-s\) + 2d: df 8d neg.l \(d1,x\) + 2f: df 98 neg.l \(d2,y\) + 31: df a9 neg.l \(d3,s\) diff --git a/gas/testsuite/gas/s12z/neg-opr.s b/gas/testsuite/gas/s12z/neg-opr.s new file mode 100644 index 00000000000..6e36326d3de --- /dev/null +++ b/gas/testsuite/gas/s12z/neg-opr.s @@ -0,0 +1,21 @@ + neg.l [0x123456] + neg.b [4,x] + neg.w d2 + neg.b [d0, y] + neg.b [12,s] + neg.b (3,s) + neg.b (-123,s) + neg.l (0x123abc,p) + neg.w (x-) + neg.w (y-) + neg.b (x+) + neg.b (y+) + neg.b (s+) + neg.l (+x) + neg.w (+y) + neg.l (-x) + neg.w (-y) + neg.b (-s) + neg.l (d1, x) + neg.l (d2, y) + neg.l (d3, s) diff --git a/gas/testsuite/gas/s12z/not-so-simple-shifts.d b/gas/testsuite/gas/s12z/not-so-simple-shifts.d new file mode 100644 index 00000000000..f9b4e11a10b --- /dev/null +++ b/gas/testsuite/gas/s12z/not-so-simple-shifts.d @@ -0,0 +1,17 @@ +#objdump: -d +#name: +#source: not-so-simple-shifts.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 14 7b e3 71 lsl.l d0, \(\+x\), #3 + 4: 13 2a 8e lsr.p d5, \(d6,x\), #2 + 7: 17 f9 f4 2d asl.w d7, \[45,p\], #13 + b: 76 + c: 12 b8 84 00 asr.b d4, \(145,d0\), #3 + 10: 91 71 diff --git a/gas/testsuite/gas/s12z/not-so-simple-shifts.s b/gas/testsuite/gas/s12z/not-so-simple-shifts.s new file mode 100644 index 00000000000..fe546e10f1d --- /dev/null +++ b/gas/testsuite/gas/s12z/not-so-simple-shifts.s @@ -0,0 +1,4 @@ + lsl.l d0, (+x), #3 + lsr.p d5, (d6,x), #2 + asl.w d7, [45,p], #13 + asr.b d4, (145,d0), #3 diff --git a/gas/testsuite/gas/s12z/opr-18u.d b/gas/testsuite/gas/s12z/opr-18u.d new file mode 100644 index 00000000000..d3a75cd3352 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-18u.d @@ -0,0 +1,26 @@ +#objdump: -d +#name: +#source: opr-18u.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 87 84 00 2d sub d7, \(45,d0\) + 4: 87 85 00 2d sub d7, \(45,d1\) + 8: 87 80 00 2d sub d7, \(45,d2\) + c: 87 81 00 2d sub d7, \(45,d3\) + 10: 87 82 00 2d sub d7, \(45,d4\) + 14: 87 83 00 2d sub d7, \(45,d5\) + 18: 87 83 00 2d sub d7, \(45,d5\) + 1c: 87 86 00 2d sub d7, \(45,d6\) + 20: 87 87 00 2d sub d7, \(45,d7\) + 24: 87 ef 03 ff sub d7, \(262143,d7\) + 28: ff + 29: 87 ef 04 00 sub d7, \(262144,d7\) + 2d: 00 + 2e: 87 ef 04 00 sub d7, \(262145,d7\) + 32: 01 diff --git a/gas/testsuite/gas/s12z/opr-18u.s b/gas/testsuite/gas/s12z/opr-18u.s new file mode 100644 index 00000000000..79f95f13fc3 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-18u.s @@ -0,0 +1,15 @@ + sub d7, (45,D0) + sub d7, (45,D1) + sub d7, (45,D2) + sub d7, (45,D3) + sub d7, (45,D4) + sub d7, (45,D5) + sub d7, (45,D5) + sub d7, (45,D6) + sub d7, (45,D7) + + sub d7, (262143,D7) + sub d7, (262144,D7) + sub d7, (262145,D7) + + diff --git a/gas/testsuite/gas/s12z/opr-expr.d b/gas/testsuite/gas/s12z/opr-expr.d new file mode 100644 index 00000000000..e02a78e56f3 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-expr.d @@ -0,0 +1,13 @@ +#objdump: -d +#name: Expressions in OPR direct submode +#source: opr-expr.s + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 01 nop + 1: 01 nop + 2: bc 12 39 clr.b 4665 diff --git a/gas/testsuite/gas/s12z/opr-expr.s b/gas/testsuite/gas/s12z/opr-expr.s new file mode 100644 index 00000000000..d52ac382135 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-expr.s @@ -0,0 +1,5 @@ + equiv FOO, 0x1230 + + nop + nop + clr.b FOO+9 diff --git a/gas/testsuite/gas/s12z/opr-ext-18.d b/gas/testsuite/gas/s12z/opr-ext-18.d new file mode 100644 index 00000000000..481ce9f5aa7 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-ext-18.d @@ -0,0 +1,13 @@ +#objdump: -d +#name: +#source: opr-ext-18.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 85 fc ab cd sub d1, 175053 + 4: 84 f9 fe ed sub d0, 130797 \ No newline at end of file diff --git a/gas/testsuite/gas/s12z/opr-ext-18.s b/gas/testsuite/gas/s12z/opr-ext-18.s new file mode 100644 index 00000000000..e0fdc3e24f9 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-ext-18.s @@ -0,0 +1,5 @@ +;;; Test the 18 bit OPR mode +;;; This should encode to four bytes only + sub d1, 0x2abcd + sub d0, 0x1feed + diff --git a/gas/testsuite/gas/s12z/opr-idx-24-reg.d b/gas/testsuite/gas/s12z/opr-idx-24-reg.d new file mode 100644 index 00000000000..2ee64f5d22e --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-idx-24-reg.d @@ -0,0 +1,13 @@ +#objdump: -d +#name: +#source: opr-idx-24-reg.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: bc e8 02 ab clr.b \(175053,d2\) + 4: cd diff --git a/gas/testsuite/gas/s12z/opr-idx-24-reg.s b/gas/testsuite/gas/s12z/opr-idx-24-reg.s new file mode 100644 index 00000000000..e25468c4f0c --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-idx-24-reg.s @@ -0,0 +1,2 @@ + clr.b (175053, d2) + diff --git a/gas/testsuite/gas/s12z/opr-idx3-reg.d b/gas/testsuite/gas/s12z/opr-idx3-reg.d new file mode 100644 index 00000000000..9b66f06fd70 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-idx3-reg.d @@ -0,0 +1,17 @@ +#objdump: -d +#name: +#source: opr-idx3-reg.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: a9 c6 11 22 ld y, \[1122867,x\] + 4: 33 + 5: df fe 11 77 neg.l \[1144678\] + 9: 66 + a: 0c 9a fa 11 mov.b #-102, 1162188 + e: bb cc diff --git a/gas/testsuite/gas/s12z/opr-idx3-reg.s b/gas/testsuite/gas/s12z/opr-idx3-reg.s new file mode 100644 index 00000000000..b4d95ac39f0 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-idx3-reg.s @@ -0,0 +1,3 @@ +L1: ld y, [0x112233, x] + neg.l [0x117766] + mov.b #-102, 0x11bbcc diff --git a/gas/testsuite/gas/s12z/opr-idx3-xysp-24.d b/gas/testsuite/gas/s12z/opr-idx3-xysp-24.d new file mode 100644 index 00000000000..28fafbc42c8 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-idx3-xysp-24.d @@ -0,0 +1,15 @@ +#objdump: -d +#name: +#source: opr-idx3-xysp-24.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: a6 c2 99 aa ld d6, \(-6706501,x\) + 4: bb + 5: a7 d2 0a d3 ld d7, \(709501,y\) + 9: 7d diff --git a/gas/testsuite/gas/s12z/opr-idx3-xysp-24.s b/gas/testsuite/gas/s12z/opr-idx3-xysp-24.s new file mode 100644 index 00000000000..384a4cfc762 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-idx3-xysp-24.s @@ -0,0 +1,3 @@ + ld d6, (-6706501,x) + ld d7, (709501,y) + diff --git a/gas/testsuite/gas/s12z/opr-indirect-expr.d b/gas/testsuite/gas/s12z/opr-indirect-expr.d new file mode 100644 index 00000000000..95d51b34f05 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-indirect-expr.d @@ -0,0 +1,14 @@ +#objdump: -dr +#name: Expressions in OPR indirect mode +#source: opr-indirect-expr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: a7 fe 00 00 ld d7, \[1\] + 4: 01 + 2: R_S12Z_EXT24 FOO diff --git a/gas/testsuite/gas/s12z/opr-indirect-expr.s b/gas/testsuite/gas/s12z/opr-indirect-expr.s new file mode 100644 index 00000000000..ee1fb12002a --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-indirect-expr.s @@ -0,0 +1 @@ + ld d7, [FOO+1] diff --git a/gas/testsuite/gas/s12z/opr-symbol.d b/gas/testsuite/gas/s12z/opr-symbol.d new file mode 100644 index 00000000000..97e5b4fc323 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-symbol.d @@ -0,0 +1,170 @@ +#objdump: -dt +#name: OPR addressing mode: symbols in its direct submode +#source: opr-symbol.s + +dump.o: file format elf32-s12z + +SYMBOL TABLE: +00000000 l d .text 00000000 .text +00000000 l d .data 00000000 .data +00000000 l d .bss 00000000 .bss +00123456 l \*ABS\* 00000000 sym1 +00abcdef l \*ABS\* 00000000 sym2 + + + +Disassembly of section .text: + +00000000 <.text>: + 0: 0c 17 fa 12 mov.b #23, sym1 + 4: 34 56 + 6: 0d 00 17 fa mov.w #23, sym1 + a: 12 34 56 + d: 0e 00 00 17 mov.p #23, sym1 + 11: fa 12 34 56 + 15: 0f 00 00 00 mov.l #23, sym1 + 19: 17 fa 12 34 + 1d: 56 + 1e: 1c fa 12 34 mov.b sym1, sym2 + 22: 56 fa ab cd + 26: ef + 27: 1d fa 12 34 mov.w sym1, sym2 + 2b: 56 fa ab cd + 2f: ef + 30: 1e fa 12 34 mov.p sym1, sym2 + 34: 56 fa ab cd + 38: ef + 39: 1f fa 12 34 mov.l sym1, sym2 + 3d: 56 fa ab cd + 41: ef + 42: 65 fa 12 34 add d1, sym1 + 46: 56 + 47: 68 fa 12 34 and d2, sym1 + 4b: 56 + 4c: 81 fa 12 34 sub d3, sym1 + 50: 56 + 51: 8a fa 12 34 or d4, sym1 + 55: 56 + 56: 9c fa 12 34 inc.b sym1 + 5a: 56 + 5b: 9d fa 12 34 inc.w sym1 + 5f: 56 + 60: 9f fa 12 34 inc.l sym1 + 64: 56 + 65: b2 12 34 56 ld d4, sym1 + 69: ba ab cd ef jmp sym2 + 6d: bb 12 34 56 jsr sym1 + 71: ac fa 12 34 dec.b sym1 + 75: 56 + 76: ad fa 12 34 dec.w sym1 + 7a: 56 + 7b: af fa 12 34 dec.l sym1 + 7f: 56 + 80: bc fa 12 34 clr.b sym1 + 84: 56 + 85: bd fa 12 34 clr.w sym1 + 89: 56 + 8a: bf fa 12 34 clr.l sym1 + 8e: 56 + 8f: d3 12 34 56 st d5, sym1 + 93: cc fa 12 34 com.b sym1 + 97: 56 + 98: cd fa 12 34 com.w sym1 + 9c: 56 + 9d: cf fa 12 34 com.l sym1 + a1: 56 + a2: dc fa 12 34 neg.b sym1 + a6: 56 + a7: dd fa 12 34 neg.w sym1 + ab: 56 + ac: df fa 12 34 neg.l sym1 + b0: 56 + b1: f3 fa 12 34 cmp d5, sym1 + b5: 56 + b6: 1b 00 fa 12 ld s, sym1 + ba: 34 56 + bc: 1b 01 fa 12 st s, sym1 + c0: 34 56 + c2: 1b 02 fa 12 cmp s, sym1 + c6: 34 56 + c8: 1b 10 fa 12 minu d2, sym1 + cc: 34 56 + ce: 1b 18 fa 12 maxu d2, sym1 + d2: 34 56 + d4: 1b 20 fa 12 mins d2, sym1 + d8: 34 56 + da: 1b 28 fa 12 maxs d2, sym1 + de: 34 56 + e0: 1b 61 fa 12 adc d3, sym1 + e4: 34 56 + e6: 1b 69 fa 12 bit d3, sym1 + ea: 34 56 + ec: 1b 81 fa 12 sbc d3, sym1 + f0: 34 56 + f2: 1b 89 fa 12 eor d3, sym1 + f6: 34 56 + f8: 02 d1 fa 12 brclr.b sym1, d1, \*\+3 + fc: 34 56 03 + ff: 02 a2 fa 12 brclr.w sym1, #2, \*\+4 + 103: 34 56 04 + 106: 03 81 fa ab brset.b sym2, d2, \*\+5 + 10a: cd ef 05 + 10d: 03 b2 fa ab brset.w sym2, #3, \*\+6 + 111: cd ef 06 + 114: 4d 40 fa 12 mulu.b d1, d2, sym1 + 118: 34 56 + 11a: 4e 7e fa 12 mulu.ll d6, sym1, sym2 + 11e: 34 56 fa ab + 122: cd ef + 124: 4d c0 fa 12 muls.b d1, d2, sym1 + 128: 34 56 + 12a: 4e fe fa 12 muls.ll d6, sym1, sym2 + 12e: 34 56 fa ab + 132: cd ef + 134: 1b b5 c0 fa qmuls.b d1, d2, sym1 + 138: 12 34 56 + 13b: 1b b6 fe fa qmuls.ll d6, sym1, sym2 + 13f: 12 34 56 fa + 143: ab cd ef + 146: 1b 35 40 fa divu.b d1, d2, sym1 + 14a: 12 34 56 + 14d: 1b 36 7e fa divu.ll d6, sym1, sym2 + 151: 12 34 56 fa + 155: ab cd ef + 158: 1b 35 c0 fa divs.b d1, d2, sym1 + 15c: 12 34 56 + 15f: 1b 36 fe fa divs.ll d6, sym1, sym2 + 163: 12 34 56 fa + 167: ab cd ef + 16a: ec a0 fa 12 bclr.b sym1, #2 + 16e: 34 56 + 170: ec 85 fa ab bclr.w sym2, d2 + 174: cd ef + 176: ed a0 fa 12 bset.b sym1, #2 + 17a: 34 56 + 17c: ed 85 fa ab bset.w sym2, d2 + 180: cd ef + 182: ee a0 fa 12 btgl.b sym1, #2 + 186: 34 56 + 188: ee 85 fa ab btgl.w sym2, d2 + 18c: cd ef + 18e: 0b 0c fa 12 tbne.b sym1, \*\+8 + 192: 34 56 08 + 195: 0b ad fa ab dbpl.w sym2, \*\+9 + 199: cd ef 09 + 19c: 1b 08 c0 fa bfins.b d2, sym1, d2 + 1a0: 12 34 56 + 1a3: 1b 08 d4 fa bfins.w sym1, d2, d2 + 1a7: 12 34 56 + 1aa: 1b 08 e9 01 bfins.p d2, sym1, #8\:1 + 1ae: fa 12 34 56 + 1b2: 1b 08 fd 01 bfins.l sym1, d2, #8\:1 + 1b6: fa 12 34 56 + 1ba: 1b 08 40 fa bfext.b d2, sym1, d2 + 1be: 12 34 56 + 1c1: 1b 08 54 fa bfext.w sym1, d2, d2 + 1c5: 12 34 56 + 1c8: 1b 08 69 01 bfext.p d2, sym1, #8\:1 + 1cc: fa 12 34 56 + 1d0: 1b 08 7c e2 bfext.l sym1, d2, #7\:2 + 1d4: fa 12 34 56 diff --git a/gas/testsuite/gas/s12z/opr-symbol.s b/gas/testsuite/gas/s12z/opr-symbol.s new file mode 100644 index 00000000000..6ce2afb8e84 --- /dev/null +++ b/gas/testsuite/gas/s12z/opr-symbol.s @@ -0,0 +1,109 @@ +#sym1: set $123456 + +#sym2: set $abcdef + + .equiv sym1, 0x123456 + .equiv sym2, 0xabcdef + + mov.b #23, sym1 + mov.w #23, sym1 + mov.p #23, sym1 + mov.l #23, sym1 + + mov.b sym1, sym2 + mov.w sym1, sym2 + mov.p sym1, sym2 + mov.l sym1, sym2 + + add d1, sym1 + and d2, sym1 + sub d3, sym1 + or d4, sym1 + + inc.b sym1 + inc.w sym1 + inc.l sym1 + + ld d4, sym1 + + jmp sym2 + jsr sym1 + + dec.b sym1 + dec.w sym1 + dec.l sym1 + + clr.b sym1 + clr.w sym1 + clr.l sym1 + + st d5, sym1 + + com.b sym1 + com.w sym1 + com.l sym1 + + neg.b sym1 + neg.w sym1 + neg.l sym1 + + cmp d5, sym1 + + ld s, sym1 + st s, sym1 + cmp s, sym1 + + minu d2, sym1 + maxu d2, sym1 + + mins d2, sym1 + maxs d2, sym1 + + adc d3, sym1 + bit d3, sym1 + sbc d3, sym1 + eor d3, sym1 + + brclr.b sym1, d1, *+3 + brclr.w sym1, #2, *+4 + + brset.b sym2, d2, *+5 + brset.w sym2, #3, *+6 + + mulu.b d1, d2, sym1 + mulu.ll d6, sym1, sym2 + + muls.b d1, d2, sym1 + muls.ll d6, sym1, sym2 + + qmuls.b d1, d2, sym1 + qmuls.ll d6, sym1, sym2 + + divu.b d1, d2, sym1 + divu.ll d6, sym1, sym2 + + divs.b d1, d2, sym1 + divs.ll d6, sym1, sym2 + + bclr.b sym1, #2 + bclr.w sym2, d2 + + bset.b sym1, #2 + bset.w sym2, d2 + + btgl.b sym1, #2 + btgl.w sym2, d2 + + tbne.b sym1, *+8 + dbpl.w sym2, *+9 + + bfins.b d2, sym1, d2 + bfins.w sym1, d2, d2 + bfins.p d2, sym1, #8:1 + bfins.l sym1, d2, #8:1 + + bfext.b d2, sym1, d2 + bfext.w sym1, d2, d2 + bfext.p d2, sym1, #8:1 + bfext.l sym1, d2, #7:2 + diff --git a/gas/testsuite/gas/s12z/or-imm.d b/gas/testsuite/gas/s12z/or-imm.d new file mode 100644 index 00000000000..dbaa77ddf9c --- /dev/null +++ b/gas/testsuite/gas/s12z/or-imm.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: or-imm.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 78 12 34 or d2, #4660 + 3: 79 12 34 or d3, #4660 + 6: 7a fc 7a or d4, #-902 + 9: 7b 01 59 or d5, #345 + c: 7c 12 or d0, #18 + e: 7d 34 or d1, #52 + 10: 7e 56 78 9a or d6, #1450744508 + 14: bc + 15: 7f ff 43 9e or d7, #-12345678 + 19: b2 diff --git a/gas/testsuite/gas/s12z/or-imm.s b/gas/testsuite/gas/s12z/or-imm.s new file mode 100644 index 00000000000..65585250a6e --- /dev/null +++ b/gas/testsuite/gas/s12z/or-imm.s @@ -0,0 +1,8 @@ +start: or d2, #0x1234 + or d3, #0x1234 + or d4, #-902 + or d5, #345 + or d0, #0x12 + or d1, #0x34 + or d6, #0x56789ABC + or d7, #-12345678 diff --git a/gas/testsuite/gas/s12z/or-opr.d b/gas/testsuite/gas/s12z/or-opr.d new file mode 100644 index 00000000000..188bb654b8d --- /dev/null +++ b/gas/testsuite/gas/s12z/or-opr.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: or-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 8c d5 21 or d0, \[-223,y\] + 3: 8d f2 00 84 or d1, \(34000,p\) + 7: d0 + 8: 88 c3 or d2, \(-x\) + a: 89 f7 or d3, \(y\+\) + c: 8a ba or d4, d4 + e: 8b f8 77 d6 or d5, 30678 + 12: 8e fe 01 64 or d6, \[91256\] + 16: 78 + 17: 8f 9a or d7, \(d4,y\) diff --git a/gas/testsuite/gas/s12z/or-opr.s b/gas/testsuite/gas/s12z/or-opr.s new file mode 100644 index 00000000000..4dabcb6c624 --- /dev/null +++ b/gas/testsuite/gas/s12z/or-opr.s @@ -0,0 +1,8 @@ + or d0, [-223,y] + or d1, (34000, p) + or d2, (-x) + or d3, (y+) + or d4, d4 + or d5, 30678 + or d6, [91256] + or d7, (d4,y) diff --git a/gas/testsuite/gas/s12z/p2-mul.d b/gas/testsuite/gas/s12z/p2-mul.d new file mode 100644 index 00000000000..ce52171dde7 --- /dev/null +++ b/gas/testsuite/gas/s12z/p2-mul.d @@ -0,0 +1,17 @@ +#objdump: -d +#name: Multiply instructions from page2 in all reg-reg-reg mode +#source: p2-mul.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b b4 a9 qmuls d0, d1, d3 + 3: 1b b2 1e qmulu d4, d5, d6 + 6: 1b 37 a5 divs d7, d0, d1 + 9: 1b 30 0a divu d2, d3, d4 + c: 1b 3b b7 mods d5, d6, d7 + f: 1b 3c 28 modu d0, d1, d2 diff --git a/gas/testsuite/gas/s12z/p2-mul.s b/gas/testsuite/gas/s12z/p2-mul.s new file mode 100644 index 00000000000..b9952e366bd --- /dev/null +++ b/gas/testsuite/gas/s12z/p2-mul.s @@ -0,0 +1,7 @@ + qmuls d0, d1, d3 + qmulu d4, d5, d6 + divs d7, d0, d1 + divu d2, d3, d4 + mods d5, d6, d7 + modu d0, d1, d2 + diff --git a/gas/testsuite/gas/s12z/page2-inh.d b/gas/testsuite/gas/s12z/page2-inh.d new file mode 100644 index 00000000000..0903fa7ac1c --- /dev/null +++ b/gas/testsuite/gas/s12z/page2-inh.d @@ -0,0 +1,15 @@ +#objdump: -d +#name: +#source: page2-inh.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 90 rti + 2: 1b 07 sys + 4: 1b 05 stop + 6: 1b 06 wai diff --git a/gas/testsuite/gas/s12z/page2-inh.s b/gas/testsuite/gas/s12z/page2-inh.s new file mode 100644 index 00000000000..0351ec61f16 --- /dev/null +++ b/gas/testsuite/gas/s12z/page2-inh.s @@ -0,0 +1,5 @@ + RTI + SYS + STOP + WAI + diff --git a/gas/testsuite/gas/s12z/psh-pul.d b/gas/testsuite/gas/s12z/psh-pul.d new file mode 100644 index 00000000000..40113e7869d --- /dev/null +++ b/gas/testsuite/gas/s12z/psh-pul.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: psh-pul.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 04 00 psh ALL + 2: 04 40 psh ALL16b + 4: 04 3c psh cch, ccl, d0, d1 + 6: 04 43 psh x, y + +00000008 : + 8: 04 80 pul ALL + a: 04 c0 pul ALL16b + c: 04 bc pul cch, ccl, d0, d1 + e: 04 c3 pul x, y diff --git a/gas/testsuite/gas/s12z/psh-pul.s b/gas/testsuite/gas/s12z/psh-pul.s new file mode 100644 index 00000000000..57a2d5930ae --- /dev/null +++ b/gas/testsuite/gas/s12z/psh-pul.s @@ -0,0 +1,8 @@ +here: psh all + psh all16b + psh cch, ccl, d1, d0 + psh x, y +there: pul all + pul all16b + pul cch, ccl, d1, d0 + pul x, y diff --git a/gas/testsuite/gas/s12z/qmul.d b/gas/testsuite/gas/s12z/qmul.d new file mode 100644 index 00000000000..6cd5af7fecc --- /dev/null +++ b/gas/testsuite/gas/s12z/qmul.d @@ -0,0 +1,23 @@ +#objdump: -d +#name: +#source: qmul.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b b4 ec 62 qmuls.b d0, d1, #98 + 4: 1b b5 c0 b9 qmuls.b d1, d2, d3 + 8: 1b b0 c9 ba qmuls.w d2, d3, d4 + c: 1b b1 ff 00 qmuls.l d3, d7, #9842 + 10: 00 26 72 + 13: 1b b2 68 e0 qmulu.b d4, d1, \(32,s\) + 17: 20 + 18: 1b b3 49 c4 qmulu.w d5, d3, \[34,x\] + 1c: 22 + 1d: 1b b6 7b ff qmulu.l d6, d7, \(s\+\) + 21: 1b b7 7a d4 qmulu.lp d7, \[12,y\], \(7,d1\) + 25: 0c 85 00 07 diff --git a/gas/testsuite/gas/s12z/qmul.s b/gas/testsuite/gas/s12z/qmul.s new file mode 100644 index 00000000000..6237d48ece3 --- /dev/null +++ b/gas/testsuite/gas/s12z/qmul.s @@ -0,0 +1,8 @@ + qmuls.b d0, d1, #98 + qmuls.b d1, d2, d3 + qmuls.w d2, d3, d4 + qmuls.l d3, d7, #9842 + qmulu.b d4, d1, (32,s) + qmulu.w d5, d3, [34,x] + qmulu.l d6, d7, (s+) + qmulu.lp d7, [12,y], (7,d1) diff --git a/gas/testsuite/gas/s12z/rotate.d b/gas/testsuite/gas/s12z/rotate.d new file mode 100644 index 00000000000..a58eb9a6379 --- /dev/null +++ b/gas/testsuite/gas/s12z/rotate.d @@ -0,0 +1,22 @@ +#objdump: -d +#name: +#source: rotate.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 10 24 b8 ror.b d2 + 3: 10 64 fb rol.b \(-s\) + 6: 10 65 ff rol.w \(s\+\) + 9: 10 66 d4 2d rol.p \[45,y\] + d: 10 67 87 00 rol.l \(78,d7\) + 11: 4e + 12: 10 24 bc ror.b d0 + 15: 10 24 c3 ror.b \(-x\) + 18: 10 25 f7 ror.w \(y\+\) + 1b: 10 26 f4 29 ror.p \[41,p\] + 1f: 10 27 8b ror.l \(d5,x\) diff --git a/gas/testsuite/gas/s12z/rotate.s b/gas/testsuite/gas/s12z/rotate.s new file mode 100644 index 00000000000..91e3f6d1a3f --- /dev/null +++ b/gas/testsuite/gas/s12z/rotate.s @@ -0,0 +1,10 @@ + ror d2 + rol.b (-s) + rol.w (s+) + rol.p [45,y] + rol.l (78, d7) + ror d0 + ror.b (-x) + ror.w (y+) + ror.p [41,p] + ror.l (d5, x) diff --git a/gas/testsuite/gas/s12z/s12z.exp b/gas/testsuite/gas/s12z/s12z.exp new file mode 100644 index 00000000000..acd50cf4d3a --- /dev/null +++ b/gas/testsuite/gas/s12z/s12z.exp @@ -0,0 +1,132 @@ +# Copyright (C) 2018 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + +# +# Some s12z tests +# +if { ![istarget "s12z*-*-*"] } then { + return +} + + +run_dump_test abs +run_dump_test adc-imm +run_dump_test adc-opr +run_dump_test add-imm +run_dump_test add-opr +run_dump_test and-imm +run_dump_test and-opr +run_dump_test and-or-cc +run_dump_test bfext-special +run_dump_test bfext +run_dump_test bit-manip +run_dump_test bit +run_dump_test bra +run_dump_test brset-clr-opr-imm-rel +run_dump_test brset-clr-opr-reg-rel +run_dump_test brset-clr-reg-imm-rel +run_dump_test brset-clr-reg-reg-rel +run_dump_test clb +run_dump_test clr-opr +run_dump_test clr +run_dump_test cmp-imm +run_dump_test cmp-opr-inc +run_dump_test cmp-opr-rdirect +run_dump_test cmp-opr-reg +run_dump_test cmp-opr-rindirect +run_dump_test cmp-opr-sxe4 +run_dump_test cmp-opr-xys +run_dump_test cmp-s-imm +run_dump_test cmp-s-opr +run_dump_test cmp-xy +run_dump_test com-opr +run_dump_test complex-shifts +run_dump_test db-tb-cc-opr +run_dump_test db-tb-cc-reg +run_dump_test dec-opr +run_dump_test dec +run_dump_test div +run_dump_test eor +run_dump_test exg +run_dump_test inc-opr +run_dump_test inc +run_dump_test inh +run_dump_test jmp +run_dump_test jsr +run_dump_test ld-imm-page2 +run_dump_test ld-imm +run_dump_test ld-opr +run_dump_test ld-s-opr +run_dump_test lea +run_dump_test mac +run_dump_test min-max +run_dump_test mod +run_dump_test mov +run_dump_test p2-mul +run_dump_test mul-imm +run_dump_test mul-opr-opr +run_dump_test mul-opr +run_dump_test mul-reg +run_dump_test mul +run_dump_test neg-opr +run_dump_test not-so-simple-shifts +run_dump_test opr-18u +run_dump_test opr-ext-18 +run_dump_test opr-idx-24-reg +run_dump_test opr-idx3-reg +run_dump_test opr-idx3-xysp-24 +run_dump_test or-imm +run_dump_test or-opr +run_dump_test page2-inh +run_dump_test psh-pul +run_dump_test qmul +run_dump_test rotate +run_dump_test sat +run_dump_test sbc-imm +run_dump_test sbc-opr +run_dump_test shift +run_dump_test simple-shift +run_dump_test single-ops +run_dump_test st-opr +run_dump_test st-s-opr +run_dump_test sub-imm +run_dump_test sub-opr +run_dump_test tfr +run_dump_test trap +run_dump_test specd6 + +# Tests of the disassembler - these are hard to force the assembler to generate +run_dump_test ld-immu18 +run_dump_test lea-immu18 +run_dump_test ext24-ld-xy +run_dump_test st-xy + +# Symbol related tests +run_dump_test opr-symbol +run_dump_test brclr-symbols +run_dump_test dbCC + +# Expression related tests +run_dump_test opr-expr +run_dump_test opr-indirect-expr +run_dump_test bra-expression-defined +run_dump_test bra-expression-undef + +# Tests related to optimisation +run_dump_test ld-large-direct +run_dump_test ld-small-direct +run_dump_test st-large-direct +run_dump_test st-small-direct diff --git a/gas/testsuite/gas/s12z/sat.d b/gas/testsuite/gas/s12z/sat.d new file mode 100644 index 00000000000..4cbac0ba97d --- /dev/null +++ b/gas/testsuite/gas/s12z/sat.d @@ -0,0 +1,19 @@ +#objdump: -d +#name: +#source: sat.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b a0 sat d2 + 2: 1b a1 sat d3 + 4: 1b a2 sat d4 + 6: 1b a3 sat d5 + 8: 1b a4 sat d0 + a: 1b a5 sat d1 + c: 1b a6 sat d6 + e: 1b a7 sat d7 diff --git a/gas/testsuite/gas/s12z/sat.s b/gas/testsuite/gas/s12z/sat.s new file mode 100644 index 00000000000..ba2ff8eed1a --- /dev/null +++ b/gas/testsuite/gas/s12z/sat.s @@ -0,0 +1,8 @@ + sat d2 + sat d3 + sat d4 + sat d5 + sat d0 + sat d1 + sat d6 + sat d7 diff --git a/gas/testsuite/gas/s12z/sbc-imm.d b/gas/testsuite/gas/s12z/sbc-imm.d new file mode 100644 index 00000000000..1bca708ff1c --- /dev/null +++ b/gas/testsuite/gas/s12z/sbc-imm.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: sbc-imm.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 70 12 34 sbc d2, #4660 + 4: 1b 71 12 34 sbc d3, #4660 + 8: 1b 72 12 34 sbc d4, #4660 + c: 1b 73 12 34 sbc d5, #4660 + 10: 1b 74 ef sbc d0, #-17 + 13: 1b 75 34 sbc d1, #52 + 16: 1b 76 56 78 sbc d6, #1450744508 + 1a: 9a bc + 1c: 1b 77 98 77 sbc d7, #-1737025662 + 20: 17 82 diff --git a/gas/testsuite/gas/s12z/sbc-imm.s b/gas/testsuite/gas/s12z/sbc-imm.s new file mode 100644 index 00000000000..9879e33eb9a --- /dev/null +++ b/gas/testsuite/gas/s12z/sbc-imm.s @@ -0,0 +1,8 @@ + sbc d2, #0x1234 + sbc d3, #0x1234 + sbc d4, #0x1234 + sbc d5, #0x1234 + sbc d0, #-17 + sbc d1, #0x34 + sbc d6, #0x56789ABC + sbc d7, #-1737025662 diff --git a/gas/testsuite/gas/s12z/sbc-opr.d b/gas/testsuite/gas/s12z/sbc-opr.d new file mode 100644 index 00000000000..bd5ed4982a0 --- /dev/null +++ b/gas/testsuite/gas/s12z/sbc-opr.d @@ -0,0 +1,23 @@ +#objdump: -d +#name: +#source: sbc-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 84 d5 21 sbc d0, \[-223,y\] + 4: 1b 85 f2 00 sbc d1, \(34000,p\) + 8: 84 d0 + a: 1b 80 fb sbc d2, \(-s\) + d: 1b 71 00 22 sbc d3, #34 + 11: 1b 82 bc sbc d4, d0 + 14: 1b 83 0a 76 sbc d5, 2678 + 18: 1b 86 fe 00 sbc d6, \[56\] + 1c: 00 38 + 1e: 1b 87 9b sbc d7, \(d5,y\) + 21: 1b 81 85 00 sbc d3, \(34,d1\) + 25: 22 diff --git a/gas/testsuite/gas/s12z/sbc-opr.s b/gas/testsuite/gas/s12z/sbc-opr.s new file mode 100644 index 00000000000..3202174cf8f --- /dev/null +++ b/gas/testsuite/gas/s12z/sbc-opr.s @@ -0,0 +1,9 @@ + sbc d0, [-223,y] + sbc d1, (34000, p) + sbc d2, (-s) + sbc d3, #34 + sbc d4, d0 + sbc d5, 2678 + sbc d6, [56] + sbc d7, (d5,y) + sbc d3, (34, d1) diff --git a/gas/testsuite/gas/s12z/shift.d b/gas/testsuite/gas/s12z/shift.d new file mode 100644 index 00000000000..41e061f9981 --- /dev/null +++ b/gas/testsuite/gas/s12z/shift.d @@ -0,0 +1,22 @@ +#objdump: -d +#name: +#source: shift.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 14 11 bb lsr d0, d3, d5 + 3: 15 9a 76 asr d1, d4, #13 + 6: 15 84 asr d1, d0, #1 + 8: 17 68 fb lsl.b d7, \(-s\), #2 + b: 17 69 fb lsl.w d7, \(-s\), #2 + e: 17 6b fb lsl.l d7, \(-s\), #2 + 11: 17 2a fb lsr.p d7, \(-s\), #2 + 14: 10 3d f3 lsr.w \(\+y\), #2 + 17: 10 3e 8e lsr.p \(d6,x\), #2 + 1a: 10 f4 bf asl d7, #1 + 1d: 10 bc bd asr d1, #2 diff --git a/gas/testsuite/gas/s12z/shift.s b/gas/testsuite/gas/s12z/shift.s new file mode 100644 index 00000000000..cb41f3c030f --- /dev/null +++ b/gas/testsuite/gas/s12z/shift.s @@ -0,0 +1,11 @@ + lsr d0, d3, d5 + asr d1, d4, #13 + asr d1, d0, #1 + lsl.b d7, (-s), #2 + lsl.w d7, (-s), #2 + lsl.l d7, (-s), #2 + lsr.p d7, (-s), #2 + lsr.w (+y), #2 + lsr.p (d6,x), #2 + asl d7, #1 + asr d1, #2 diff --git a/gas/testsuite/gas/s12z/simple-shift.d b/gas/testsuite/gas/s12z/simple-shift.d new file mode 100644 index 00000000000..13af3bf9f04 --- /dev/null +++ b/gas/testsuite/gas/s12z/simple-shift.d @@ -0,0 +1,18 @@ +#objdump: -d +#name: +#source: simple-shift.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 14 55 b8 lsl d0, d1, d2 + 3: 11 12 bb lsr d3, d4, d5 + 6: 17 d4 bd asl d7, d0, d1 + 9: 10 91 ba asr d2, d3, d4 + c: 16 d5 b8 asl d6, d1, d2 + f: 15 5a 76 lsl d1, d4, #13 + 12: 13 46 lsl d5, d6, #1 diff --git a/gas/testsuite/gas/s12z/simple-shift.s b/gas/testsuite/gas/s12z/simple-shift.s new file mode 100644 index 00000000000..045e0718f7a --- /dev/null +++ b/gas/testsuite/gas/s12z/simple-shift.s @@ -0,0 +1,9 @@ + lsl d0, d1, d2 + lsr d3, d4, d5 + asl d7, d0, d1 + asr d2, d3, d4 + asl d6, d1, d2 + + lsl d1, d4, #13 + lsl d5, d6, #1 ; this creates a short form + diff --git a/gas/testsuite/gas/s12z/single-ops.d b/gas/testsuite/gas/s12z/single-ops.d new file mode 100644 index 00000000000..ca9b38a40fb --- /dev/null +++ b/gas/testsuite/gas/s12z/single-ops.d @@ -0,0 +1,15 @@ +#objdump: -d +#name: +#source: single-ops.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 01 nop + 1: 05 rts + 2: 00 bgnd + 3: ff swi diff --git a/gas/testsuite/gas/s12z/single-ops.s b/gas/testsuite/gas/s12z/single-ops.s new file mode 100644 index 00000000000..ab6fe2ceb21 --- /dev/null +++ b/gas/testsuite/gas/s12z/single-ops.s @@ -0,0 +1,4 @@ + nop + rts + bgnd + swi diff --git a/gas/testsuite/gas/s12z/specd6.d b/gas/testsuite/gas/s12z/specd6.d new file mode 100644 index 00000000000..0c743cd9d91 --- /dev/null +++ b/gas/testsuite/gas/s12z/specd6.d @@ -0,0 +1,14 @@ +#objdump: -d +#name: +#source: specd6.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: fc cmp x, y + 1: fd sub d6, x, y + 2: fe sub d6, y, x diff --git a/gas/testsuite/gas/s12z/specd6.s b/gas/testsuite/gas/s12z/specd6.s new file mode 100644 index 00000000000..92308b4dcd5 --- /dev/null +++ b/gas/testsuite/gas/s12z/specd6.s @@ -0,0 +1,4 @@ + cmp x, y + sub d6, x, y + sub d6, y, x + diff --git a/gas/testsuite/gas/s12z/st-large-direct.d b/gas/testsuite/gas/s12z/st-large-direct.d new file mode 100644 index 00000000000..03ca41e904f --- /dev/null +++ b/gas/testsuite/gas/s12z/st-large-direct.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: ST reg - constant optimised to EXT24 +#source: st-large-direct.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: d0 12 34 56 st d2, 1193046 + 4: d1 c0 ff ee st d3, 12648430 + 8: d2 80 00 02 st d4, 8388610 + c: d4 80 00 03 st d0, 8388611 + 10: d5 80 00 03 st d1, 8388611 + 14: d3 80 00 04 st d5, 8388612 + 18: d6 80 00 06 st d6, 8388614 + 1c: d7 80 00 07 st d7, 8388615 + 20: d8 80 00 08 st x, 8388616 + 24: d9 80 00 09 st y, 8388617 diff --git a/gas/testsuite/gas/s12z/st-large-direct.s b/gas/testsuite/gas/s12z/st-large-direct.s new file mode 100644 index 00000000000..74956d14179 --- /dev/null +++ b/gas/testsuite/gas/s12z/st-large-direct.s @@ -0,0 +1,11 @@ + st d2, 0x123456 + st d3, 0xc0ffee + st d4, 0x800002 + st d0, 0x800003 + st d1, 0x800003 + st d5, 0x800004 + st d6, 0x800006 + st d7, 0x800007 + st x, 0x800008 + st y, 0x800009 + diff --git a/gas/testsuite/gas/s12z/st-opr.d b/gas/testsuite/gas/s12z/st-opr.d new file mode 100644 index 00000000000..d39bb62ab0b --- /dev/null +++ b/gas/testsuite/gas/s12z/st-opr.d @@ -0,0 +1,22 @@ +#objdump: -d +#name: +#source: st-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: c4 d8 st d0, \[d2,y\] + 2: c5 c9 st d1, \[d3,x\] + 4: c0 ca st d2, \[d4,x\] + 6: c1 87 3b 82 st d3, \(15234,d7\) + a: c2 e1 16 st d4, \(-234,s\) + d: c3 bc st d5, d0 + f: c6 88 st d6, \(d2,x\) + 11: c7 fe 00 04 st d7, \[1234\] + 15: d2 + 16: c8 88 st x, \(d2,x\) + 18: c9 db st y, \[d5,y\] diff --git a/gas/testsuite/gas/s12z/st-opr.s b/gas/testsuite/gas/s12z/st-opr.s new file mode 100644 index 00000000000..c5257a5b1a4 --- /dev/null +++ b/gas/testsuite/gas/s12z/st-opr.s @@ -0,0 +1,10 @@ + st d0, [d2,y] + st d1, [d3,x] + st d2, [d4,x] + st d3, (15234,d7) + st d4, (-234,s) + st d5, d0 + st d6, (d2, x) + st d7, [1234] + st x, (d2, x) + st y, [d5, y] diff --git a/gas/testsuite/gas/s12z/st-s-opr.d b/gas/testsuite/gas/s12z/st-s-opr.d new file mode 100644 index 00000000000..3748914a34d --- /dev/null +++ b/gas/testsuite/gas/s12z/st-s-opr.d @@ -0,0 +1,16 @@ +#objdump: -d +#name: +#source: st-s-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 01 aa st s, \(d4,s\) + 3: 1b 01 fe 00 st s, \[1340\] + 7: 05 3c + 9: 1b 01 9b st s, \(d5,y\) + c: 1b 01 d3 st s, \(-y\) diff --git a/gas/testsuite/gas/s12z/st-s-opr.s b/gas/testsuite/gas/s12z/st-s-opr.s new file mode 100644 index 00000000000..90cc5e8072c --- /dev/null +++ b/gas/testsuite/gas/s12z/st-s-opr.s @@ -0,0 +1,4 @@ + st s, (d4, s) + st s, [1340] + st s, (d5, y) + st s, (-y) diff --git a/gas/testsuite/gas/s12z/st-small-direct.d b/gas/testsuite/gas/s12z/st-small-direct.d new file mode 100644 index 00000000000..df67d4adeb5 --- /dev/null +++ b/gas/testsuite/gas/s12z/st-small-direct.d @@ -0,0 +1,34 @@ +#objdump: -d +#name: ST reg - small constants left in OPR mode +#source: st-small-direct.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: c0 fa 00 00 st d2, L1 + 4: 00 + 5: c1 fa 00 00 st d3, L2 + 9: 1a + a: c2 fa 00 00 st d4, L1 + e: 00 + +0000000f : + f: 01 nop + 10: c4 fa 00 00 st d0, L2 + 14: 1a + 15: c5 fa 00 00 st d1, L3 + 19: 0f + +0000001a : + 1a: c3 fa 00 00 st d5, L1 + 1e: 00 + 1f: c6 fa 00 00 st d6, L3 + 23: 0f + 24: c7 fa 00 00 st d7, L2 + 28: 1a + 29: c8 30 39 st x, 12345 + 2c: c9 26 94 st y, 9876 diff --git a/gas/testsuite/gas/s12z/st-small-direct.s b/gas/testsuite/gas/s12z/st-small-direct.s new file mode 100644 index 00000000000..c0d736ddf75 --- /dev/null +++ b/gas/testsuite/gas/s12z/st-small-direct.s @@ -0,0 +1,12 @@ +L1: st d2, L1 + st d3, L2 + st d4, L1 +L3: nop + st d0, L2 + st d1, L3 +L2: st d5, L1 + st d6, L3 + st d7, L2 + st x, 12345 + st y, 9876 + diff --git a/gas/testsuite/gas/s12z/st-xy.d b/gas/testsuite/gas/s12z/st-xy.d new file mode 100644 index 00000000000..335e77eee46 --- /dev/null +++ b/gas/testsuite/gas/s12z/st-xy.d @@ -0,0 +1,12 @@ +#objdump: -d +#name: +#source: st-xy.s + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: d8 90 12 34 st x, 9441844 + 4: d9 80 12 34 st y, 8393268 diff --git a/gas/testsuite/gas/s12z/st-xy.s b/gas/testsuite/gas/s12z/st-xy.s new file mode 100644 index 00000000000..6e774657a13 --- /dev/null +++ b/gas/testsuite/gas/s12z/st-xy.s @@ -0,0 +1,3 @@ + .long 0xD8901234 ;; ST X,9441844 + .long 0xD9801234 ;; ST Y,8393268 + diff --git a/gas/testsuite/gas/s12z/sub-imm.d b/gas/testsuite/gas/s12z/sub-imm.d new file mode 100644 index 00000000000..7c1064ab6aa --- /dev/null +++ b/gas/testsuite/gas/s12z/sub-imm.d @@ -0,0 +1,21 @@ +#objdump: -d +#name: +#source: sub-imm.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 70 12 34 sub d2, #4660 + 3: 71 12 34 sub d3, #4660 + 6: 72 12 34 sub d4, #4660 + 9: 73 12 34 sub d5, #4660 + c: 74 ef sub d0, #-17 + e: 75 34 sub d1, #52 + 10: 76 56 78 9a sub d6, #1450744508 + 14: bc + 15: 77 98 77 17 sub d7, #-1737025662 + 19: 82 diff --git a/gas/testsuite/gas/s12z/sub-imm.s b/gas/testsuite/gas/s12z/sub-imm.s new file mode 100644 index 00000000000..1b4f38c479d --- /dev/null +++ b/gas/testsuite/gas/s12z/sub-imm.s @@ -0,0 +1,8 @@ +start: sub d2, #0x1234 + sub d3, #0x1234 + sub d4, #0x1234 + sub d5, #0x1234 + sub d0, #-17 + sub d1, #0x34 + sub d6, #0x56789ABC + sub d7, #-1737025662 diff --git a/gas/testsuite/gas/s12z/sub-opr.d b/gas/testsuite/gas/s12z/sub-opr.d new file mode 100644 index 00000000000..e98e26cb672 --- /dev/null +++ b/gas/testsuite/gas/s12z/sub-opr.d @@ -0,0 +1,22 @@ +#objdump: -d +#name: +#source: sub-opr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 84 d5 21 sub d0, \[-223,y\] + 3: 85 f2 00 84 sub d1, \(34000,p\) + 7: d0 + 8: 80 fb sub d2, \(-s\) + a: 71 00 04 sub d3, #4 + d: 82 bc sub d4, d0 + f: 83 f9 4e ae sub d5, 85678 + 13: 86 fe 00 4b sub d6, \[19256\] + 17: 38 + 18: 87 8a sub d7, \(d4,x\) + 1a: 81 81 00 0b sub d3, \(11,d3\) \ No newline at end of file diff --git a/gas/testsuite/gas/s12z/sub-opr.s b/gas/testsuite/gas/s12z/sub-opr.s new file mode 100644 index 00000000000..f1f7b541212 --- /dev/null +++ b/gas/testsuite/gas/s12z/sub-opr.s @@ -0,0 +1,9 @@ + sub d0, [-223,y] + sub d1, (34000, p) + sub d2, (-s) + sub d3, #4 + sub d4, d0 + sub d5, 85678 + sub d6, [19256] + sub d7, (d4,x) + sub d3, (11, d3) diff --git a/gas/testsuite/gas/s12z/tfr.d b/gas/testsuite/gas/s12z/tfr.d new file mode 100644 index 00000000000..58c76424652 --- /dev/null +++ b/gas/testsuite/gas/s12z/tfr.d @@ -0,0 +1,20 @@ +#objdump: -d +#name: The TFR (incl ZEX) instruction +#source: tfr.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 : + 0: 9e 45 tfr d0, d1 + 2: 9e 58 tfr d1, x + 4: 9e 0a tfr d2, s + 6: 9e 0d tfr d2, ccl + 8: 9e 6e tfr d6, ccw + a: 9e 29 tfr d4, y + c: 9e 37 tfr d5, d7 + e: 9e 5e tfr d1, ccw + 10: 9e 40 tfr d0, d2 diff --git a/gas/testsuite/gas/s12z/tfr.s b/gas/testsuite/gas/s12z/tfr.s new file mode 100644 index 00000000000..c61551ee6ca --- /dev/null +++ b/gas/testsuite/gas/s12z/tfr.s @@ -0,0 +1,9 @@ +L1: tfr d0,d1 + tfr d1, x + tfr d2, s + tfr d2, ccl + tfr d6, ccw + tfr d4, y + zex d5, d7 + zex d1, ccw + zex d0, d2 diff --git a/gas/testsuite/gas/s12z/trap.d b/gas/testsuite/gas/s12z/trap.d new file mode 100644 index 00000000000..bf6961346d9 --- /dev/null +++ b/gas/testsuite/gas/s12z/trap.d @@ -0,0 +1,105 @@ +#objdump: -d +#name: +#source: trap.s + + +dump.o: file format elf32-s12z + + +Disassembly of section .text: + +00000000 <.text>: + 0: 1b 92 trap #146 + 2: 1b 93 trap #147 + 4: 1b 94 trap #148 + 6: 1b 95 trap #149 + 8: 1b 96 trap #150 + a: 1b 97 trap #151 + c: 1b 98 trap #152 + e: 1b 99 trap #153 + 10: 1b 9a trap #154 + 12: 1b 9b trap #155 + 14: 1b 9c trap #156 + 16: 1b 9d trap #157 + 18: 1b 9e trap #158 + 1a: 1b 9f trap #159 + 1c: 1b a8 trap #168 + 1e: 1b a9 trap #169 + 20: 1b aa trap #170 + 22: 1b ab trap #171 + 24: 1b ac trap #172 + 26: 1b ad trap #173 + 28: 1b ae trap #174 + 2a: 1b af trap #175 + 2c: 1b b8 trap #184 + 2e: 1b b9 trap #185 + 30: 1b ba trap #186 + 32: 1b bb trap #187 + 34: 1b bc trap #188 + 36: 1b bd trap #189 + 38: 1b be trap #190 + 3a: 1b bf trap #191 + 3c: 1b c0 trap #192 + 3e: 1b c1 trap #193 + 40: 1b c2 trap #194 + 42: 1b c3 trap #195 + 44: 1b c4 trap #196 + 46: 1b c5 trap #197 + 48: 1b c6 trap #198 + 4a: 1b c7 trap #199 + 4c: 1b c8 trap #200 + 4e: 1b c9 trap #201 + 50: 1b ca trap #202 + 52: 1b cb trap #203 + 54: 1b cc trap #204 + 56: 1b cd trap #205 + 58: 1b ce trap #206 + 5a: 1b cf trap #207 + 5c: 1b d0 trap #208 + 5e: 1b d1 trap #209 + 60: 1b d2 trap #210 + 62: 1b d3 trap #211 + 64: 1b d4 trap #212 + 66: 1b d5 trap #213 + 68: 1b d6 trap #214 + 6a: 1b d7 trap #215 + 6c: 1b d8 trap #216 + 6e: 1b d9 trap #217 + 70: 1b da trap #218 + 72: 1b db trap #219 + 74: 1b dc trap #220 + 76: 1b dd trap #221 + 78: 1b de trap #222 + 7a: 1b df trap #223 + 7c: 1b e0 trap #224 + 7e: 1b e1 trap #225 + 80: 1b e2 trap #226 + 82: 1b e3 trap #227 + 84: 1b e4 trap #228 + 86: 1b e5 trap #229 + 88: 1b e6 trap #230 + 8a: 1b e7 trap #231 + 8c: 1b e8 trap #232 + 8e: 1b e9 trap #233 + 90: 1b ea trap #234 + 92: 1b eb trap #235 + 94: 1b ec trap #236 + 96: 1b ed trap #237 + 98: 1b ee trap #238 + 9a: 1b ef trap #239 + 9c: 1b f0 trap #240 + 9e: 1b f1 trap #241 + a0: 1b f2 trap #242 + a2: 1b f3 trap #243 + a4: 1b f4 trap #244 + a6: 1b f5 trap #245 + a8: 1b f6 trap #246 + aa: 1b f7 trap #247 + ac: 1b f8 trap #248 + ae: 1b f9 trap #249 + b0: 1b fa trap #250 + b2: 1b fb trap #251 + b4: 1b fc trap #252 + b6: 1b fd trap #253 + b8: 1b fe trap #254 + ba: 1b ff trap #255 diff --git a/gas/testsuite/gas/s12z/trap.s b/gas/testsuite/gas/s12z/trap.s new file mode 100644 index 00000000000..7ea72bb6f85 --- /dev/null +++ b/gas/testsuite/gas/s12z/trap.s @@ -0,0 +1,96 @@ + trap #146 + trap #147 + trap #148 + trap #149 + trap #150 + trap #151 + trap #152 + trap #153 + trap #154 + trap #155 + trap #156 + trap #157 + trap #158 + trap #159 + + trap #168 + trap #169 + trap #170 + trap #171 + trap #172 + trap #173 + trap #174 + trap #175 + + trap #184 + trap #185 + trap #186 + trap #187 + trap #188 + trap #189 + trap #190 + trap #191 + trap #192 + trap #193 + trap #194 + trap #195 + trap #196 + trap #197 + trap #198 + trap #199 + trap #200 + trap #201 + trap #202 + trap #203 + trap #204 + trap #205 + trap #206 + trap #207 + trap #208 + trap #209 + trap #210 + trap #211 + trap #212 + trap #213 + trap #214 + trap #215 + trap #216 + trap #217 + trap #218 + trap #219 + trap #220 + trap #221 + trap #222 + trap #223 + trap #224 + trap #225 + trap #226 + trap #227 + trap #228 + trap #229 + trap #230 + trap #231 + trap #232 + trap #233 + trap #234 + trap #235 + trap #236 + trap #237 + trap #238 + trap #239 + trap #240 + trap #241 + trap #242 + trap #243 + trap #244 + trap #245 + trap #246 + trap #247 + trap #248 + trap #249 + trap #250 + trap #251 + trap #252 + trap #253 + trap #254 + trap #255 diff --git a/include/ChangeLog b/include/ChangeLog index fe9cad66143..649b65ce2d6 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2018-05-18 John Darrington + + * elf/s12z.h: New header. + 2018-05-15 Tamar Christina PR binutils/21446 diff --git a/include/elf/s12z.h b/include/elf/s12z.h new file mode 100644 index 00000000000..72504ee9f42 --- /dev/null +++ b/include/elf/s12z.h @@ -0,0 +1,36 @@ +/* s12z ELF support for BFD. + Copyright (C) 1999-2018 Free Software Foundation, Inc. + + 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _ELF_S12Z_H +#define _ELF_S12Z_H + +#include "elf/reloc-macros.h" + +/* Relocation types. */ +START_RELOC_NUMBERS (elf_s12z_reloc_type) + RELOC_NUMBER (R_S12Z_NONE, 0) + RELOC_NUMBER (R_S12Z_OPR, 1) + RELOC_NUMBER (R_S12Z_UKNWN_2, 2) + RELOC_NUMBER (R_S12Z_PCREL_7_15, 3) + RELOC_NUMBER (R_S12Z_EXT24, 4) + RELOC_NUMBER (R_S12Z_UKNWN_3, 5) + RELOC_NUMBER (R_S12Z_EXT32, 6) +END_RELOC_NUMBERS (R_S12Z_max) + +#endif diff --git a/ld/ChangeLog b/ld/ChangeLog index 5986f3c15d0..fcd50a5dd02 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,23 @@ +2018-05-18 John Darrington + + * Makefile.am: Add support for s12z architecture. + * configure.tgt: Likewise. + * Makefile.in: Regenerate. + * emulparams/m9s12zelf.sh: New file. + * scripttempl/elfm9s12z.sc: New file. + * testsuite/ld-discard/static.d: Expect to fail for the s12z + target. + * testsuite/ld-elf/endsym.d: Likewise. + * testsuite/ld-elf/merge.d: Likewise. + * testsuite/ld-elf/pr14926.d: Skip for the s12z target. + * testsuite/ld-elf/sec64k.exp: Likewise. + * testsuite/ld-s12z: New directory. + * testsuite/ld-s12z/opr-linking.d: New file. + * testsuite/ld-s12z/opr-linking.s: New file. + * testsuite/ld-s12z/relative-linking.d: New file. + * testsuite/ld-s12z/relative-linking.s: New file. + * testsuite/ld-s12z/z12s.exp: New file. + 2018-05-18 H.J. Lu PR ld/23189 diff --git a/ld/Makefile.am b/ld/Makefile.am index 8e4c8774d1b..151e1e200a4 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -324,6 +324,7 @@ ALL_EMULATION_SOURCES = \ em68hc12elfb.c \ em68kelf.c \ em68kelfnbsd.c \ + em9s12zelf.c \ emcorepe.c \ emn10200.c \ emn10300.c \ @@ -1433,6 +1434,10 @@ em68kelfnbsd.c: $(srcdir)/emulparams/m68kelfnbsd.sh \ $(ELF_DEPS) $(srcdir)/emultempl/m68kelf.em \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} +em9s12zelf.c: $(srcdir)/emulparams/m9s12zelf.sh \ + $(ELF_DEPS) $(srcdir)/emultempl/generic.em \ + $(srcdir)/scripttempl/elfm9s12z.sc ${GEN_DEPENDS} + emcorepe.c: $(srcdir)/emulparams/mcorepe.sh \ $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS} diff --git a/ld/Makefile.in b/ld/Makefile.in index afd2a4bb881..5cfd4ab0fbb 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -693,6 +693,7 @@ ALL_EMULATION_SOURCES = \ em68hc12elfb.c \ em68kelf.c \ em68kelfnbsd.c \ + em9s12zelf.c \ emcorepe.c \ emn10200.c \ emn10300.c \ @@ -1305,6 +1306,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc12elfb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kelf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kelfnbsd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em9s12zelf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emcorepe.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emmo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10200.Po@am__quote@ @@ -2938,6 +2940,10 @@ em68kelfnbsd.c: $(srcdir)/emulparams/m68kelfnbsd.sh \ $(ELF_DEPS) $(srcdir)/emultempl/m68kelf.em \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} +em9s12zelf.c: $(srcdir)/emulparams/m9s12zelf.sh \ + $(ELF_DEPS) $(srcdir)/emultempl/generic.em \ + $(srcdir)/scripttempl/elfm9s12z.sc ${GEN_DEPENDS} + emcorepe.c: $(srcdir)/emulparams/mcorepe.sh \ $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS} diff --git a/ld/configure.tgt b/ld/configure.tgt index 4c4ab850f22..3386c3d9287 100644 --- a/ld/configure.tgt +++ b/ld/configure.tgt @@ -402,6 +402,8 @@ m68hc12-*-*|m6812-*-*) targ_emul=m68hc12elf targ_extra_emuls="m68hc12elfb m68hc11elf m68hc11elfb" ;; m68*-*-netbsdelf*) targ_emul=m68kelfnbsd ;; m68*-*-*) targ_emul=m68kelf ;; +s12z-*-*) targ_emul=m9s12zelf + ;; mcore-*-pe) targ_emul=mcorepe ; targ_extra_ofiles="deffilep.o pe-dll.o" ;; mcore-*-elf) targ_emul=elf32mcore diff --git a/ld/emulparams/m9s12zelf.sh b/ld/emulparams/m9s12zelf.sh new file mode 100644 index 00000000000..7a819e84094 --- /dev/null +++ b/ld/emulparams/m9s12zelf.sh @@ -0,0 +1,18 @@ +MACHINE= +SCRIPT_NAME=elfm9s12z +OUTPUT_FORMAT="elf32-s12z" +ROM_TOP=0xFFFFFF +ROM_SIZE=0x20000 +RAM_START_ADDR=0x001000 +RAM_SIZE=8192 +EEPROM_START_ADDR=0x100000 +EEPROM_SIZE=2048 +TEXT_MEMORY=text +DATA_MEMORY=data +EEPROM_MEMORY=eeprom +ARCH=s12z +EMBEDDED=yes +GENERIC_BOARD=no +TEMPLATE_NAME=elf32 +NOP=0x00 + diff --git a/ld/scripttempl/elfm9s12z.sc b/ld/scripttempl/elfm9s12z.sc new file mode 100644 index 00000000000..c39d2708af8 --- /dev/null +++ b/ld/scripttempl/elfm9s12z.sc @@ -0,0 +1,444 @@ +# Copyright (C) 2014-2018 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +# +# Unusual variables checked by this code: +# NOP - four byte opcode for no-op (defaults to 0) +# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start +# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ... +# (e.g., .PARISC.global) +# OTHER_SECTIONS - at the end +# EXECUTABLE_SYMBOLS - symbols that must be defined for an +# executable (e.g., _DYNAMIC_LINK) +# TEXT_START_SYMBOLS - symbols that appear at the start of the +# .text section. +# DATA_START_SYMBOLS - symbols that appear at the start of the +# .data section. +# OTHER_BSS_SYMBOLS - symbols that appear at the start of the +# .bss section besides __bss_start. +# EMBEDDED - whether this is for an embedded system. +# +# When adding sections, do note that the names of some sections are used +# when specifying the start address of the next. +# +test -z "$ENTRY" && ENTRY=_start +test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT} +test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} +if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi +test "$LD_FLAG" = "N" && DATA_ADDR=. + +CTOR=".ctors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+ PROVIDE (__CTOR_LIST__ = .); } + ${CONSTRUCTING+${CTOR_START}} + KEEP (*(.ctors)) + + ${CONSTRUCTING+${CTOR_END}} + ${CONSTRUCTING+ PROVIDE(__CTOR_END__ = .); } + } ${RELOCATING+ > ${TEXT_MEMORY}}" + +DTOR=" .dtors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+ PROVIDE(__DTOR_LIST__ = .); } + KEEP (*(.dtors)) + ${CONSTRUCTING+ PROVIDE(__DTOR_END__ = .); } + } ${RELOCATING+ > ${TEXT_MEMORY}}" + + +VECTORS=" + /* If the 'vectors_addr' symbol is defined, it indicates the start address + of interrupt vectors. + + In general, the vectors address is 0xfffe00. This can be overriden + with the '-defsym vectors_addr=0xbfc000' ld option. If you do this, + then your startup code should also set the IVBR register accordingly. + */ + + PROVIDE (_vectors_addr = DEFINED (vectors_addr) ? vectors_addr : 0xfffe00); + .vectors DEFINED (vectors_addr) ? vectors_addr : 0xfffe00 : + { + KEEP (*(.vectors)) + }" + +# +# We provide two emulations: a fixed on that defines some memory banks +# and a configurable one that includes a user provided memory definition. +# +case $GENERIC_BOARD in + yes|1|YES) + MEMORY_DEF=" +/* Get memory banks definition from some user configuration file. + This file must be located in some linker directory (search path + with -L). See fixed memory banks emulation script. */ +INCLUDE memory.x; +" + ;; + *) +MEMORY_DEF=" +/* Fixed definition of the available memory banks. + See generic emulation script for a user defined configuration. */ +MEMORY +{ + text (rx) : ORIGIN = $[$ROM_TOP - $ROM_SIZE + 1], LENGTH = ${ROM_SIZE} - 4 + data : ORIGIN = ${RAM_START_ADDR}, LENGTH = ${RAM_SIZE} + eeprom : ORIGIN = ${EEPROM_START_ADDR}, LENGTH = ${EEPROM_SIZE} + rvec : ORIGIN = 0xFFFFFC, LENGTH = 4 +} + +/* Setup the stack on the top of the data memory bank. */ +PROVIDE (_stack = ${RAM_START_ADDR} + ${RAM_SIZE} - 1); +" + ;; +esac + +STARTUP_CODE=" + /* Startup code. */ + KEEP (*(.install0)) /* Section should setup the stack pointer. */ + KEEP (*(.install1)) /* Place holder for applications. */ + KEEP (*(.install2)) /* Optional installation of data sections in RAM. */ + KEEP (*(.install3)) /* Place holder for applications. */ + KEEP (*(.install4)) /* Section that calls the main. */ +" + +FINISH_CODE=" + /* Finish code. */ + KEEP (*(.fini0)) /* Beginning of finish code (_exit symbol). */ + KEEP (*(.fini1)) /* Place holder for applications. */ + KEEP (*(.fini2)) /* C++ destructors. */ + KEEP (*(.fini3)) /* Place holder for applications. */ + KEEP (*(.fini4)) /* Runtime exit. */ +" + +PRE_COMPUTE_DATA_SIZE=" +/* SCz: this does not work yet... This is supposed to force the loading + of _map_data.o (from libgcc.a) when the .data section is not empty. + By doing so, this should bring the code that copies the .data section + from ROM to RAM at init time. + + ___pre_comp_data_size = SIZEOF(.data); + __install_data_sections = ___pre_comp_data_size > 0 ? + __map_data_sections : 0; +*/ +" + +INSTALL_RELOC=" + .install0 0 : { *(.install0) } + .install1 0 : { *(.install1) } + .install2 0 : { *(.install2) } + .install3 0 : { *(.install3) } + .install4 0 : { *(.install4) } +" + +FINISH_RELOC=" + .fini0 0 : { *(.fini0) } + .fini1 0 : { *(.fini1) } + .fini2 0 : { *(.fini2) } + .fini3 0 : { *(.fini3) } + .fini4 0 : { *(.fini4) } +" + +BSS_DATA_RELOC=" + .data1 0 : { *(.data1) } + + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata 0 : { *(.sdata) } + .sbss 0 : { *(.sbss) } + .scommon 0 : { *(.scommon) } +" + +SOFT_REGS_RELOC=" + .softregs 0 : { *(.softregs) } +" + +cat < ${TEXT_MEMORY}} + + .init ${RELOCATING-0} : + { + *(.init) + } ${RELOCATING+=${NOP-0}} + + ${RELOCATING-${INSTALL_RELOC}} + ${RELOCATING-${FINISH_RELOC}} + + .text ${RELOCATING-0}: + { + /* Put startup code at beginning so that _start keeps same address. */ + ${RELOCATING+${STARTUP_CODE}} + + ${RELOCATING+*(.init)} + *(.text) + ${RELOCATING+*(.text.*)} + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + ${RELOCATING+*(.gnu.linkonce.t.*)} + ${RELOCATING+*(.tramp)} + ${RELOCATING+*(.tramp.*)} + + ${RELOCATING+${FINISH_CODE}} + + ${RELOCATING+_etext = .;} + ${RELOCATING+PROVIDE (etext = .);} + ${RELOCATING+. = ALIGN(2);} + } ${RELOCATING+ > ${TEXT_MEMORY} =${NOP}} + .rvec ${RELOCATING-0} : + { + ${RELOCATING+LONG(_start);} + } ${RELOCATING+ > rvec} + .eh_frame ${RELOCATING-0} : + { + KEEP (*(.eh_frame)) + } ${RELOCATING+ > ${TEXT_MEMORY}} + + .gcc_except_table ${RELOCATING-0} : + { + *(.gcc_except_table) + } ${RELOCATING+ > ${TEXT_MEMORY}} + + .rodata ${RELOCATING-0} : + { + *(.rodata) + ${RELOCATING+*(.rodata.*)} + ${RELOCATING+*(.gnu.linkonce.r*)} + ${RELOCATING+. = ALIGN(2);} + } ${RELOCATING+ > ${TEXT_MEMORY} =0xffffffff} + + .rodata1 ${RELOCATING-0} : + { + *(.rodata1) + ${RELOCATING+. = ALIGN(2);} + } ${RELOCATING+ > ${TEXT_MEMORY} =0xffffffff} + + /* Constructor and destructor tables are in ROM. */ + ${RELOCATING+${CTOR}} + ${RELOCATING+${DTOR}} + + .jcr ${RELOCATING-0} : + { + KEEP (*(.jcr)) + } ${RELOCATING+ > ${TEXT_MEMORY}} + + /* Start of the data section image in ROM. */ + ${RELOCATING+__data_image = .;} + ${RELOCATING+PROVIDE (__data_image = .);} + + /* All read-only sections that normally go in PROM must be above. + We construct the DATA image section in PROM at end of all these + read-only sections. The data image must be copied at init time. + Refer to GNU ld, Section 3.6.8.2 Output Section LMA. */ + .data ${RELOCATING-0} : ${RELOCATING+AT (__data_image)} + { + ${RELOCATING+__data_section_start = .;} + ${RELOCATING+PROVIDE (__data_section_start = .);} + + ${RELOCATING+${DATA_START_SYMBOLS}} + ${RELOCATING+*(.sdata)} + *(.data) + ${RELOCATING+*(.data.*)} + ${RELOCATING+*(.data1)} + ${RELOCATING+*(.gnu.linkonce.d.*)} + ${CONSTRUCTING+CONSTRUCTORS} + + ${RELOCATING+_edata = .;} + ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+. = ALIGN(2);} + } ${RELOCATING+ > ${DATA_MEMORY} =0xffffffff} + + ${RELOCATING+__data_section_size = SIZEOF(.data);} + ${RELOCATING+PROVIDE (__data_section_size = SIZEOF(.data));} + ${RELOCATING+__data_image_end = __data_image + __data_section_size;} + + ${RELOCATING+${PRE_COMPUTE_DATA_SIZE}} + + /* .install ${RELOCATING-0}: + { + . = _data_image_end; + } ${RELOCATING+ > ${TEXT_MEMORY}} */ + + /* Relocation for some bss and data sections. */ + ${RELOCATING-${BSS_DATA_RELOC}} + ${RELOCATING-${SOFT_REGS_RELOC}} + + .bss ${RELOCATING-0} : + { + ${RELOCATING+__bss_start = .;} + ${RELOCATING+*(.softregs)} + ${RELOCATING+*(.sbss)} + ${RELOCATING+*(.scommon)} + + *(.dynbss) + *(.bss) + ${RELOCATING+*(.bss.*)} + ${RELOCATING+*(.gnu.linkonce.b.*)} + *(COMMON) + ${RELOCATING+PROVIDE (_end = .);} + } ${RELOCATING+ > ${DATA_MEMORY}} + ${RELOCATING+__bss_size = SIZEOF(.bss);} + ${RELOCATING+PROVIDE (__bss_size = SIZEOF(.bss));} + + .eeprom ${RELOCATING-0} : + { + *(.eeprom) + *(.eeprom.*) + } ${RELOCATING+ > ${EEPROM_MEMORY}} + + ${RELOCATING+${VECTORS}} + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + + .comment 0 : { *(.comment) } + + /* Treatment of DWARF debug section must be at end of the linker + script to avoid problems when there are undefined symbols. It's necessary + to avoid that the DWARF section is relocated before such undefined + symbols are found. */ +EOF + +. $srcdir/scripttempl/DWARF.sc + +cat <: + fe0000: 20 80 08 bra foo + fe0003: 02 b0 bc 80 brclr.b d0, #3, bar + fe0007: 0d + fe0008: 0b 85 80 38 dbne d1, wiz diff --git a/ld/testsuite/ld-s12z/relative-linking.s b/ld/testsuite/ld-s12z/relative-linking.s new file mode 100644 index 00000000000..fa52edbc78f --- /dev/null +++ b/ld/testsuite/ld-s12z/relative-linking.s @@ -0,0 +1,5 @@ + +here: + bra foo + brclr.b d0, #3, bar + dbne d1, wiz diff --git a/ld/testsuite/ld-s12z/z12s.exp b/ld/testsuite/ld-s12z/z12s.exp new file mode 100644 index 00000000000..4c9baa4a7a2 --- /dev/null +++ b/ld/testsuite/ld-s12z/z12s.exp @@ -0,0 +1,33 @@ +# Expect script for run_dump_test based ld-m68hc11 tests. +# Copyright (C) 2018 Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +# Test S12Z linker tests. This tests the assembler as well as the linker. + +if { ![istarget s12z-*-*] } { + return +} + +set rd_test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]] +foreach shtest $rd_test_list { + # We need to strip the ".d", but can leave the dirname. + verbose [file rootname $shtest] + run_dump_test [file rootname $shtest] +} diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index c3f345bafd3..a147cc3991d 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,14 @@ +2018-05-18 John Darrington + + * Makefile.am: Add support for s12z architecture. + * configure.ac: Likewise. + * disassemble.c: Likewise. + * disassemble.h: Likewise. + * Makefile.in: Regenerate. + * configure: Regenerate. + * s12z-dis.c: New file. + * s12z.h: New file. + 2018-05-18 Alan Modra * nfp-dis.c: Don't #include libbfd.h. diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am index 0c7d09d7597..98fd7f3f70c 100644 --- a/opcodes/Makefile.am +++ b/opcodes/Makefile.am @@ -175,6 +175,7 @@ TARGET_LIBOPCODES_CFILES = \ m68hc11-opc.c \ m68k-dis.c \ m68k-opc.c \ + s12z-dis.c \ mcore-dis.c \ mep-asm.c \ mep-desc.c \ diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in index 0d85bd43fa0..b55daea21bd 100644 --- a/opcodes/Makefile.in +++ b/opcodes/Makefile.in @@ -477,6 +477,7 @@ TARGET_LIBOPCODES_CFILES = \ m68hc11-opc.c \ m68k-dis.c \ m68k-opc.c \ + s12z-dis.c \ mcore-dis.c \ mep-asm.c \ mep-desc.c \ @@ -878,6 +879,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68hc11-opc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68k-dis.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68k-opc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s12z-dis.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcore-dis.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mep-asm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mep-desc.Plo@am__quote@ diff --git a/opcodes/configure b/opcodes/configure index c7a88054b36..c5f0c1000cc 100755 --- a/opcodes/configure +++ b/opcodes/configure @@ -12659,6 +12659,7 @@ if test x${all_targets} = xfalse ; then bfd_m68hc12_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;; bfd_m9s12x_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;; bfd_m9s12xg_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;; + bfd_s12z_arch) ta="$ta s12z-dis.lo m68hc11-opc.lo" ;; bfd_m68k_arch) ta="$ta m68k-dis.lo m68k-opc.lo" ;; bfd_mcore_arch) ta="$ta mcore-dis.lo" ;; bfd_mep_arch) ta="$ta mep-asm.lo mep-desc.lo mep-dis.lo mep-ibld.lo mep-opc.lo" using_cgen=yes ;; diff --git a/opcodes/configure.ac b/opcodes/configure.ac index e42b661fcf3..86a0ca01ffd 100644 --- a/opcodes/configure.ac +++ b/opcodes/configure.ac @@ -283,6 +283,7 @@ if test x${all_targets} = xfalse ; then bfd_m68hc12_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;; bfd_m9s12x_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;; bfd_m9s12xg_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;; + bfd_s12z_arch) ta="$ta s12z-dis.lo m68hc11-opc.lo" ;; bfd_m68k_arch) ta="$ta m68k-dis.lo m68k-opc.lo" ;; bfd_mcore_arch) ta="$ta mcore-dis.lo" ;; bfd_mep_arch) ta="$ta mep-asm.lo mep-desc.lo mep-dis.lo mep-ibld.lo mep-opc.lo" using_cgen=yes ;; diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c index 100ccd3fac4..c8fda59b6e1 100644 --- a/opcodes/disassemble.c +++ b/opcodes/disassemble.c @@ -251,6 +251,11 @@ disassembler (enum bfd_architecture a, disassemble = print_insn_m9s12xg; break; #endif +#if defined(ARCH_s12z) + case bfd_arch_s12z: + disassemble = print_insn_s12z; + break; +#endif #ifdef ARCH_m68k case bfd_arch_m68k: disassemble = print_insn_m68k; diff --git a/opcodes/disassemble.h b/opcodes/disassemble.h index 9d78b2193f8..04573446127 100644 --- a/opcodes/disassemble.h +++ b/opcodes/disassemble.h @@ -61,6 +61,7 @@ extern int print_insn_m68hc11 (bfd_vma, disassemble_info *); extern int print_insn_m68hc12 (bfd_vma, disassemble_info *); extern int print_insn_m9s12x (bfd_vma, disassemble_info *); extern int print_insn_m9s12xg (bfd_vma, disassemble_info *); +extern int print_insn_s12z (bfd_vma, disassemble_info *); extern int print_insn_m68k (bfd_vma, disassemble_info *); extern int print_insn_mcore (bfd_vma, disassemble_info *); extern int print_insn_metag (bfd_vma, disassemble_info *); diff --git a/opcodes/s12z-dis.c b/opcodes/s12z-dis.c new file mode 100644 index 00000000000..45123112223 --- /dev/null +++ b/opcodes/s12z-dis.c @@ -0,0 +1,2672 @@ +/* s12z-dis.c -- Freescale S12Z disassembly + Copyright (C) 2018 Free Software Foundation, Inc. + + This file is part of the GNU opcodes library. + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + It 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 +#include +#include +#include + +#include "s12z.h" + +#include "bfd.h" +#include "dis-asm.h" + + +#include "disassemble.h" + +static int +read_memory (bfd_vma memaddr, bfd_byte* buffer, int size, + struct disassemble_info* info) +{ + int status = (*info->read_memory_func) (memaddr, buffer, size, info); + if (status != 0) + { + (*info->memory_error_func) (status, memaddr, info); + return -1; + } + return 0; +} + +typedef int (* insn_bytes_f) (bfd_vma memaddr, + struct disassemble_info* info); + +typedef void (*operands_f) (bfd_vma memaddr, struct disassemble_info* info); + +enum OPR_MODE + { + OPR_IMMe4, + OPR_REG, + OPR_OFXYS, + OPR_XY_PRE_INC, + OPR_XY_POST_INC, + OPR_XY_PRE_DEC, + OPR_XY_POST_DEC, + OPR_S_PRE_DEC, + OPR_S_POST_INC, + OPR_REG_DIRECT, + OPR_REG_INDIRECT, + OPR_IDX_DIRECT, + OPR_IDX_INDIRECT, + OPR_EXT1, + OPR_IDX2_REG, + OPR_IDX3_DIRECT, + OPR_IDX3_INDIRECT, + + OPR_EXT18, + OPR_IDX3_DIRECT_REG, + OPR_EXT3_DIRECT, + OPR_EXT3_INDIRECT + }; + +struct opr_pb +{ + uint8_t mask; + uint8_t value; + int n_operands; + enum OPR_MODE mode; +}; + +static const struct opr_pb opr_pb[] = { + {0xF0, 0x70, 1, OPR_IMMe4}, + {0xF8, 0xB8, 1, OPR_REG}, + {0xC0, 0x40, 1, OPR_OFXYS}, + {0xEF, 0xE3, 1, OPR_XY_PRE_INC}, + {0xEF, 0xE7, 1, OPR_XY_POST_INC}, + {0xEF, 0xC3, 1, OPR_XY_PRE_DEC}, + {0xEF, 0xC7, 1, OPR_XY_POST_DEC}, + {0xFF, 0xFB, 1, OPR_S_PRE_DEC}, + {0xFF, 0xFF, 1, OPR_S_POST_INC}, + {0xC8, 0x88, 1, OPR_REG_DIRECT}, + {0xE8, 0xC8, 1, OPR_REG_INDIRECT}, + + {0xCE, 0xC0, 2, OPR_IDX_DIRECT}, + {0xCE, 0xC4, 2, OPR_IDX_INDIRECT}, + {0xC0, 0x00, 2, OPR_EXT1}, + + {0xC8, 0x80, 3, OPR_IDX2_REG}, + {0xFA, 0xF8, 3, OPR_EXT18}, + + {0xCF, 0xC2, 4, OPR_IDX3_DIRECT}, + {0xCF, 0xC6, 4, OPR_IDX3_INDIRECT}, + + {0xF8, 0xE8, 4, OPR_IDX3_DIRECT_REG}, + {0xFF, 0xFA, 4, OPR_EXT3_DIRECT}, + {0xFF, 0xFE, 4, OPR_EXT3_INDIRECT}, +}; + + +/* Return the number of bytes in a OPR operand, including the XB postbyte. + It does not include any preceeding opcodes. */ +static int +opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte xb; + int status = read_memory (memaddr, &xb, 1, info); + if (status < 0) + return status; + + size_t i; + for (i = 0; i < sizeof (opr_pb) / sizeof (opr_pb[0]); ++i) + { + const struct opr_pb *pb = opr_pb + i; + if ((xb & pb->mask) == pb->value) + { + return pb->n_operands; + } + } + + return 1; +} + +static int +opr_n_bytes_p1 (bfd_vma memaddr, struct disassemble_info* info) +{ + return 1 + opr_n_bytes (memaddr, info); +} + +static int +opr_n_bytes2 (bfd_vma memaddr, struct disassemble_info* info) +{ + int s = opr_n_bytes (memaddr, info); + s += opr_n_bytes (memaddr + s, info); + return s + 1; +} + +enum BB_MODE + { + BB_REG_REG_REG, + BB_REG_REG_IMM, + BB_REG_OPR_REG, + BB_OPR_REG_REG, + BB_REG_OPR_IMM, + BB_OPR_REG_IMM + }; + +struct opr_bb +{ + uint8_t mask; + uint8_t value; + int n_operands; + bool opr; + enum BB_MODE mode; +}; + +static const struct opr_bb bb_modes[] = + { + {0x60, 0x00, 2, false, BB_REG_REG_REG}, + {0x60, 0x20, 3, false, BB_REG_REG_IMM}, + {0x70, 0x40, 2, true, BB_REG_OPR_REG}, + {0x70, 0x50, 2, true, BB_OPR_REG_REG}, + {0x70, 0x60, 3, true, BB_REG_OPR_IMM}, + {0x70, 0x70, 3, true, BB_OPR_REG_IMM} + }; + +static int +bfextins_n_bytes (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte bb; + int status = read_memory (memaddr, &bb, 1, info); + if (status < 0) + return status; + + size_t i; + const struct opr_bb *bbs = 0; + for (i = 0; i < sizeof (bb_modes) / sizeof (bb_modes[0]); ++i) + { + bbs = bb_modes + i; + if ((bb & bbs->mask) == bbs->value) + { + break; + } + } + + int n = bbs->n_operands; + if (bbs->opr) + n += opr_n_bytes (memaddr + n - 1, info); + + return n; +} + +static int +single (bfd_vma memaddr ATTRIBUTE_UNUSED, + struct disassemble_info* info ATTRIBUTE_UNUSED) +{ + return 1; +} + +static int +two (bfd_vma memaddr ATTRIBUTE_UNUSED, + struct disassemble_info* info ATTRIBUTE_UNUSED) +{ + return 2; +} + +static int +three (bfd_vma memaddr ATTRIBUTE_UNUSED, + struct disassemble_info* info ATTRIBUTE_UNUSED) +{ + return 3; +} + +static int +four (bfd_vma memaddr ATTRIBUTE_UNUSED, + struct disassemble_info* info ATTRIBUTE_UNUSED) +{ + return 4; +} + +static int +five (bfd_vma memaddr ATTRIBUTE_UNUSED, + struct disassemble_info* info ATTRIBUTE_UNUSED) +{ + return 5; +} + +static int +pcrel_15bit (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte byte; + int status = read_memory (memaddr, &byte, 1, info); + if (status < 0) + return status; + return (byte & 0x80) ? 3 : 2; +} + + + + +static void +operand_separator (struct disassemble_info *info) +{ + if ((info->flags & 0x2)) + { + (*info->fprintf_func) (info->stream, ", "); + } + else + { + (*info->fprintf_func) (info->stream, " "); + } + + info->flags |= 0x2; +} + + + +static void +imm1 (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte byte; + int status = read_memory (memaddr, &byte, 1, info); + if (status < 0) + return; + + operand_separator (info); + (*info->fprintf_func) (info->stream, "#%d", byte); +} + +static void +trap_decode (bfd_vma memaddr, struct disassemble_info* info) +{ + imm1 (memaddr - 1, info); +} + + +const struct reg registers[S12Z_N_REGISTERS] = + { + {"d2", 2}, + {"d3", 2}, + {"d4", 2}, + {"d5", 2}, + + {"d0", 1}, + {"d1", 1}, + + {"d6", 4}, + {"d7", 4}, + + {"x", 3}, + {"y", 3}, + {"s", 3}, + {"p", 3}, + {"cch", 1}, + {"ccl", 1}, + {"ccw", 2} + }; + +static char * +xys_from_postbyte (uint8_t postbyte) +{ + char *reg = "?"; + switch ((postbyte & 0x30) >> 4) + { + case 0: + reg = "x"; + break; + case 1: + reg = "y"; + break; + case 2: + reg = "s"; + break; + default: + reg = "?"; + break; + } + return reg; +} + +static char * +xysp_from_postbyte (uint8_t postbyte) +{ + char *reg = "?"; + switch ((postbyte & 0x30) >> 4) + { + case 0: + reg = "x"; + break; + case 1: + reg = "y"; + break; + case 2: + reg = "s"; + break; + default: + reg = "p"; + break; + } + return reg; +} + +/* Render the symbol name whose value is ADDR or the adddress itself if there is + no symbol. */ +static void +decode_possible_symbol (bfd_vma addr, struct disassemble_info *info) +{ + if (!info->symbol_at_address_func (addr, info)) + { + (*info->fprintf_func) (info->stream, "%" BFD_VMA_FMT "d", addr); + } + else + { + asymbol *sym = NULL; + int j; + for (j = 0; j < info->symtab_size; ++j) + { + sym = info->symtab[j]; + if (bfd_asymbol_value (sym) == addr) + { + break; + } + } + if (j < info->symtab_size) + (*info->fprintf_func) (info->stream, "%s", bfd_asymbol_name (sym)); + } +} + +static void ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info); + +static void +ext24_decode (bfd_vma memaddr, struct disassemble_info* info) +{ + uint8_t buffer[3]; + int status = read_memory (memaddr, buffer, 3, info); + if (status < 0) + return; + + int i; + uint32_t addr = 0; + for (i = 0; i < 3; ++i) + { + addr <<= 8; + addr |= buffer[i]; + } + + operand_separator (info); + decode_possible_symbol (addr, info); +} + + +static uint32_t +decode_signed_value (bfd_vma memaddr, struct disassemble_info* info, short size) +{ + assert (size >0); + assert (size <= 4); + bfd_byte buffer[4]; + if (0 > read_memory (memaddr, buffer, size, info)) + { + return 0; + } + + int i; + uint32_t value = 0; + for (i = 0; i < size; ++i) + { + value |= buffer[i] << (8 * (size - i - 1)); + } + + if (buffer[0] & 0x80) + { + /* Deal with negative values */ + value -= 0x1UL << (size * 8); + } + return value; +} + + +static void +opr_decode (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte postbyte; + int status = read_memory (memaddr, &postbyte, 1, info); + if (status < 0) + return; + + enum OPR_MODE mode = -1; + size_t i; + for (i = 0; i < sizeof (opr_pb) / sizeof (opr_pb[0]); ++i) + { + const struct opr_pb *pb = opr_pb + i; + if ((postbyte & pb->mask) == pb->value) + { + mode = pb->mode; + break; + } + } + + operand_separator (info); + switch (mode) + { + case OPR_IMMe4: + { + int n; + uint8_t x = (postbyte & 0x0F); + if (x == 0) + n = -1; + else + n = x; + + (*info->fprintf_func) (info->stream, "#%d", n); + break; + } + case OPR_REG: + { + uint8_t x = (postbyte & 0x07); + (*info->fprintf_func) (info->stream, "%s", registers[x].name); + break; + } + case OPR_OFXYS: + { + const char *reg = xys_from_postbyte (postbyte); + (*info->fprintf_func) (info->stream, "(%d,%s)", postbyte & 0x0F, reg); + break; + } + case OPR_REG_DIRECT: + { + (*info->fprintf_func) (info->stream, "(%s,%s)", registers[postbyte & 0x07].name, + xys_from_postbyte (postbyte)); + break; + } + case OPR_REG_INDIRECT: + { + (*info->fprintf_func) (info->stream, "[%s,%s]", registers[postbyte & 0x07].name, + (postbyte & 0x10) ? "y": "x"); + break; + } + + case OPR_IDX_INDIRECT: + { + uint8_t x1; + read_memory (memaddr + 1, &x1, 1, info); + int idx = x1; + + if (postbyte & 0x01) + { + /* Deal with negative values */ + idx -= 0x1UL << 8; + } + + (*info->fprintf_func) (info->stream, "[%d,%s]", idx, + xysp_from_postbyte (postbyte)); + break; + } + + case OPR_IDX3_DIRECT: + { + uint8_t x[3]; + read_memory (memaddr + 1, x, 3, info); + int idx = x[0] << 16 | x[1] << 8 | x[2]; + + if (x[0] & 0x80) + { + /* Deal with negative values */ + idx -= 0x1UL << 24; + } + + (*info->fprintf_func) (info->stream, "(%d,%s)", idx, + xysp_from_postbyte (postbyte)); + break; + } + + case OPR_IDX3_DIRECT_REG: + { + uint8_t x[3]; + read_memory (memaddr + 1, x, 3, info); + int idx = x[0] << 16 | x[1] << 8 | x[2]; + + if (x[0] & 0x80) + { + /* Deal with negative values */ + idx -= 0x1UL << 24; + } + + (*info->fprintf_func) (info->stream, "(%d,%s)", idx, + registers[postbyte & 0x07].name); + break; + } + + case OPR_IDX3_INDIRECT: + { + uint8_t x[3]; + read_memory (memaddr + 1, x, 3, info); + int idx = x[0] << 16 | x[1] << 8 | x[2]; + + if (x[0] & 0x80) + { + /* Deal with negative values */ + idx -= 0x1UL << 24; + } + + (*info->fprintf_func) (info->stream, "[%d,%s]", idx, + xysp_from_postbyte (postbyte)); + break; + } + + case OPR_IDX_DIRECT: + { + uint8_t x1; + read_memory (memaddr + 1, &x1, 1, info); + int idx = x1; + + if (postbyte & 0x01) + { + /* Deal with negative values */ + idx -= 0x1UL << 8; + } + + (*info->fprintf_func) (info->stream, "(%d,%s)", idx, + xysp_from_postbyte (postbyte)); + break; + } + + case OPR_IDX2_REG: + { + uint8_t x[2]; + read_memory (memaddr + 1, x, 2, info); + uint32_t offset = x[1] | x[0] << 8 ; + offset |= (postbyte & 0x30) << 12; + + (*info->fprintf_func) (info->stream, "(%d,%s)", offset, + registers[postbyte & 0x07].name); + break; + } + + case OPR_XY_PRE_INC: + { + (*info->fprintf_func) (info->stream, "(+%s)", + (postbyte & 0x10) ? "y": "x"); + + break; + } + case OPR_XY_POST_INC: + { + (*info->fprintf_func) (info->stream, "(%s+)", + (postbyte & 0x10) ? "y": "x"); + + break; + } + case OPR_XY_PRE_DEC: + { + (*info->fprintf_func) (info->stream, "(-%s)", + (postbyte & 0x10) ? "y": "x"); + + break; + } + case OPR_XY_POST_DEC: + { + (*info->fprintf_func) (info->stream, "(%s-)", + (postbyte & 0x10) ? "y": "x"); + + break; + } + case OPR_S_PRE_DEC: + { + (*info->fprintf_func) (info->stream, "(-s)"); + break; + } + case OPR_S_POST_INC: + { + (*info->fprintf_func) (info->stream, "(s+)"); + break; + } + + case OPR_EXT18: + { + const size_t size = 2; + bfd_byte buffer[4]; + status = read_memory (memaddr + 1, buffer, size, info); + if (status < 0) + return; + + uint32_t ext18 = 0; + for (i = 0; i < size; ++i) + { + ext18 <<= 8; + ext18 |= buffer[i]; + } + + ext18 |= (postbyte & 0x01) << 16; + ext18 |= (postbyte & 0x04) << 15; + + decode_possible_symbol (ext18, info); + break; + } + + case OPR_EXT1: + { + uint8_t x1 = 0; + read_memory (memaddr + 1, &x1, 1, info); + int16_t addr; + addr = x1; + addr |= (postbyte & 0x3f) << 8; + + decode_possible_symbol (addr, info); + break; + } + + case OPR_EXT3_DIRECT: + { + const size_t size = 3; + bfd_byte buffer[4]; + status = read_memory (memaddr + 1, buffer, size, info); + if (status < 0) + return; + + uint32_t ext24 = 0; + for (i = 0; i < size; ++i) + { + ext24 |= buffer[i] << (8 * (size - i - 1)); + } + + decode_possible_symbol (ext24, info); + break; + } + + case OPR_EXT3_INDIRECT: + { + const size_t size = 3; + bfd_byte buffer[4]; + status = read_memory (memaddr + 1, buffer, size, info); + if (status < 0) + return; + + uint32_t ext24 = 0; + for (i = 0; i < size; ++i) + { + ext24 |= buffer[i] << (8 * (size - i - 1)); + } + + (*info->fprintf_func) (info->stream, "[%d]", ext24); + + break; + } + + default: + (*info->fprintf_func) (info->stream, "Unknown OPR mode #0x%x (%d)", postbyte, mode); + } +} + + +static void +opr_decode2 (bfd_vma memaddr, struct disassemble_info* info) +{ + int n = opr_n_bytes (memaddr, info); + opr_decode (memaddr, info); + opr_decode (memaddr + n, info); +} + +static void +imm1234 (bfd_vma memaddr, struct disassemble_info* info, int base) +{ + bfd_byte opcode; + int status = read_memory (memaddr - 1, &opcode, 1, info); + if (status < 0) + return; + + opcode -= base; + + int size = registers[opcode & 0xF].bytes; + + uint32_t imm = decode_signed_value (memaddr, info, size); + operand_separator (info); + (*info->fprintf_func) (info->stream, "#%d", imm); +} + + +/* Special case of LD and CMP with register S and IMM operand */ +static void +reg_s_imm (bfd_vma memaddr, struct disassemble_info* info) +{ + operand_separator (info); + (*info->fprintf_func) (info->stream, "s"); + + uint32_t imm = decode_signed_value (memaddr, info, 3); + operand_separator (info); + (*info->fprintf_func) (info->stream, "#%d", imm); +} + +/* Special case of LD, CMP and ST with register S and OPR operand */ +static void +reg_s_opr (bfd_vma memaddr, struct disassemble_info* info) +{ + operand_separator (info); + (*info->fprintf_func) (info->stream, "s"); + + opr_decode (memaddr, info); +} + +static void +imm1234_8base (bfd_vma memaddr, struct disassemble_info* info) +{ + imm1234 (memaddr, info, 8); +} + +static void +imm1234_0base (bfd_vma memaddr, struct disassemble_info* info) +{ + imm1234 (memaddr, info, 0); +} + +static void +tfr (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte byte; + int status = read_memory (memaddr, &byte, 1, info); + if (status < 0) + return; + + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s, %s", + registers[byte >> 4].name, + registers[byte & 0xF].name); +} + + +static void +reg (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte byte; + int status = read_memory (memaddr - 1, &byte, 1, info); + if (status < 0) + return; + + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x07].name); +} + +static void +reg_xy (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte byte; + int status = read_memory (memaddr - 1, &byte, 1, info); + if (status < 0) + return; + + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", (byte & 0x01) ? "y" : "x"); +} + +static void +lea_reg_xys_opr (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte byte; + int status = read_memory (memaddr - 1, &byte, 1, info); + if (status < 0) + return; + + char *reg = NULL; + switch (byte & 0x03) + { + case 0x00: + reg = "x"; + break; + case 0x01: + reg = "y"; + break; + case 0x02: + reg = "s"; + break; + } + + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", reg); + opr_decode (memaddr, info); +} + + + +static void +lea_reg_xys (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte byte; + int status = read_memory (memaddr - 1, &byte, 1, info); + if (status < 0) + return; + + char *reg = NULL; + switch (byte & 0x03) + { + case 0x00: + reg = "x"; + break; + case 0x01: + reg = "y"; + break; + case 0x02: + reg = "s"; + break; + } + + status = read_memory (memaddr, &byte, 1, info); + if (status < 0) + return; + + int8_t v = byte; + + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s, (%d,%s)", reg, v, reg); +} + + +/* PC Relative offsets of size 15 or 7 bits */ +static void +rel_15_7 (bfd_vma memaddr, struct disassemble_info* info, int offset) +{ + bfd_byte upper; + int status = read_memory (memaddr, &upper, 1, info); + if (status < 0) + return; + + bool rel_size = (upper & 0x80); + + int16_t addr = upper; + if (rel_size) + { + /* 15 bits. Get the next byte */ + bfd_byte lower; + status = read_memory (memaddr + 1, &lower, 1, info); + if (status < 0) + return; + + addr <<= 8; + addr |= lower; + addr &= 0x7FFF; + + bool negative = (addr & 0x4000); + addr &= 0x3FFF; + if (negative) + addr = addr - 0x4000; + } + else + { + /* 7 bits. */ + bool negative = (addr & 0x40); + addr &= 0x3F; + if (negative) + addr = addr - 0x40; + } + + operand_separator (info); + if (!info->symbol_at_address_func (addr + memaddr - offset, info)) + { + (*info->fprintf_func) (info->stream, "*%+d", addr); + } + else + { + asymbol *sym = NULL; + int i; + for (i = 0; i < info->symtab_size; ++i) + { + sym = info->symtab[i]; + if (bfd_asymbol_value (sym) == addr + memaddr - offset) + { + break; + } + } + if (i < info->symtab_size) + (*info->fprintf_func) (info->stream, "%s", bfd_asymbol_name (sym)); + } +} + + +/* PC Relative offsets of size 15 or 7 bits */ +static void +decode_rel_15_7 (bfd_vma memaddr, struct disassemble_info* info) +{ + rel_15_7 (memaddr, info, 1); +} + +struct opcode +{ + const char *mnemonic; + insn_bytes_f insn_bytes; + operands_f operands; + operands_f operands2; +}; + +static int shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info); +static int mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info); +static int loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info); +static void mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info); +static void bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info); +static int bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info); +static int mul_n_bytes (bfd_vma memaddr, struct disassemble_info* info); +static void mul_decode (bfd_vma memaddr, struct disassemble_info* info); +static int bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info); +static void bm_decode (bfd_vma memaddr, struct disassemble_info* info); + +static void +cmp_xy (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info) +{ + operand_separator (info); + (*info->fprintf_func) (info->stream, "x, y"); +} + +static void +sub_d6_x_y (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info) +{ + operand_separator (info); + (*info->fprintf_func) (info->stream, "d6, x, y"); +} + +static void +sub_d6_y_x (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info) +{ + operand_separator (info); + (*info->fprintf_func) (info->stream, "d6, y, x"); +} + +static const char shift_size_table[] = { + 'b', 'w', 'p', 'l' +}; + +static const struct opcode page2[] = + { + [0x00] = {"ld", opr_n_bytes_p1, 0, reg_s_opr}, + [0x01] = {"st", opr_n_bytes_p1, 0, reg_s_opr}, + [0x02] = {"cmp", opr_n_bytes_p1, 0, reg_s_opr}, + [0x03] = {"ld", four, 0, reg_s_imm}, + [0x04] = {"cmp", four, 0, reg_s_imm}, + [0x05] = {"stop", single, 0, 0}, + [0x06] = {"wai", single, 0, 0}, + [0x07] = {"sys", single, 0, 0}, + [0x08] = {NULL, bfextins_n_bytes, 0, 0}, /* BFEXT / BFINS */ + [0x09] = {NULL, bfextins_n_bytes, 0, 0}, + [0x0a] = {NULL, bfextins_n_bytes, 0, 0}, + [0x0b] = {NULL, bfextins_n_bytes, 0, 0}, + [0x0c] = {NULL, bfextins_n_bytes, 0, 0}, + [0x0d] = {NULL, bfextins_n_bytes, 0, 0}, + [0x0e] = {NULL, bfextins_n_bytes, 0, 0}, + [0x0f] = {NULL, bfextins_n_bytes, 0, 0}, + [0x10] = {"minu", opr_n_bytes_p1, reg, opr_decode}, + [0x11] = {"minu", opr_n_bytes_p1, reg, opr_decode}, + [0x12] = {"minu", opr_n_bytes_p1, reg, opr_decode}, + [0x13] = {"minu", opr_n_bytes_p1, reg, opr_decode}, + [0x14] = {"minu", opr_n_bytes_p1, reg, opr_decode}, + [0x15] = {"minu", opr_n_bytes_p1, reg, opr_decode}, + [0x16] = {"minu", opr_n_bytes_p1, reg, opr_decode}, + [0x17] = {"minu", opr_n_bytes_p1, reg, opr_decode}, + [0x18] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, + [0x19] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, + [0x1a] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, + [0x1b] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, + [0x1c] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, + [0x1d] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, + [0x1e] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, + [0x1f] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, + [0x20] = {"mins", opr_n_bytes_p1, reg, opr_decode}, + [0x21] = {"mins", opr_n_bytes_p1, reg, opr_decode}, + [0x22] = {"mins", opr_n_bytes_p1, reg, opr_decode}, + [0x23] = {"mins", opr_n_bytes_p1, reg, opr_decode}, + [0x24] = {"mins", opr_n_bytes_p1, reg, opr_decode}, + [0x25] = {"mins", opr_n_bytes_p1, reg, opr_decode}, + [0x26] = {"mins", opr_n_bytes_p1, reg, opr_decode}, + [0x27] = {"mins", opr_n_bytes_p1, reg, opr_decode}, + [0x28] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, + [0x29] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, + [0x2a] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, + [0x2b] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, + [0x2c] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, + [0x2d] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, + [0x2e] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, + [0x2f] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, + [0x30] = {"div", mul_n_bytes, mul_decode, 0}, + [0x31] = {"div", mul_n_bytes, mul_decode, 0}, + [0x32] = {"div", mul_n_bytes, mul_decode, 0}, + [0x33] = {"div", mul_n_bytes, mul_decode, 0}, + [0x34] = {"div", mul_n_bytes, mul_decode, 0}, + [0x35] = {"div", mul_n_bytes, mul_decode, 0}, + [0x36] = {"div", mul_n_bytes, mul_decode, 0}, + [0x37] = {"div", mul_n_bytes, mul_decode, 0}, + [0x38] = {"mod", mul_n_bytes, mul_decode, 0}, + [0x39] = {"mod", mul_n_bytes, mul_decode, 0}, + [0x3a] = {"mod", mul_n_bytes, mul_decode, 0}, + [0x3b] = {"mod", mul_n_bytes, mul_decode, 0}, + [0x3c] = {"mod", mul_n_bytes, mul_decode, 0}, + [0x3d] = {"mod", mul_n_bytes, mul_decode, 0}, + [0x3e] = {"mod", mul_n_bytes, mul_decode, 0}, + [0x3f] = {"mod", mul_n_bytes, mul_decode, 0}, + [0x40] = {"abs", single, reg, 0}, + [0x41] = {"abs", single, reg, 0}, + [0x42] = {"abs", single, reg, 0}, + [0x43] = {"abs", single, reg, 0}, + [0x44] = {"abs", single, reg, 0}, + [0x45] = {"abs", single, reg, 0}, + [0x46] = {"abs", single, reg, 0}, + [0x47] = {"abs", single, reg, 0}, + [0x48] = {"mac", mul_n_bytes, mul_decode, 0}, + [0x49] = {"mac", mul_n_bytes, mul_decode, 0}, + [0x4a] = {"mac", mul_n_bytes, mul_decode, 0}, + [0x4b] = {"mac", mul_n_bytes, mul_decode, 0}, + [0x4c] = {"mac", mul_n_bytes, mul_decode, 0}, + [0x4d] = {"mac", mul_n_bytes, mul_decode, 0}, + [0x4e] = {"mac", mul_n_bytes, mul_decode, 0}, + [0x4f] = {"mac", mul_n_bytes, mul_decode, 0}, + [0x50] = {"adc", three, reg, imm1234_0base}, + [0x51] = {"adc", three, reg, imm1234_0base}, + [0x52] = {"adc", three, reg, imm1234_0base}, + [0x53] = {"adc", three, reg, imm1234_0base}, + [0x54] = {"adc", two, reg, imm1234_0base}, + [0x55] = {"adc", two, reg, imm1234_0base}, + [0x56] = {"adc", five, reg, imm1234_0base}, + [0x57] = {"adc", five, reg, imm1234_0base}, + [0x58] = {"bit", three, reg, imm1234_8base}, + [0x59] = {"bit", three, reg, imm1234_8base}, + [0x5a] = {"bit", three, reg, imm1234_8base}, + [0x5b] = {"bit", three, reg, imm1234_8base}, + [0x5c] = {"bit", two, reg, imm1234_8base}, + [0x5d] = {"bit", two, reg, imm1234_8base}, + [0x5e] = {"bit", five, reg, imm1234_8base}, + [0x5f] = {"bit", five, reg, imm1234_8base}, + [0x60] = {"adc", opr_n_bytes_p1, reg, opr_decode}, + [0x61] = {"adc", opr_n_bytes_p1, reg, opr_decode}, + [0x62] = {"adc", opr_n_bytes_p1, reg, opr_decode}, + [0x63] = {"adc", opr_n_bytes_p1, reg, opr_decode}, + [0x64] = {"adc", opr_n_bytes_p1, reg, opr_decode}, + [0x65] = {"adc", opr_n_bytes_p1, reg, opr_decode}, + [0x66] = {"adc", opr_n_bytes_p1, reg, opr_decode}, + [0x67] = {"adc", opr_n_bytes_p1, reg, opr_decode}, + [0x68] = {"bit", opr_n_bytes_p1, reg, opr_decode}, + [0x69] = {"bit", opr_n_bytes_p1, reg, opr_decode}, + [0x6a] = {"bit", opr_n_bytes_p1, reg, opr_decode}, + [0x6b] = {"bit", opr_n_bytes_p1, reg, opr_decode}, + [0x6c] = {"bit", opr_n_bytes_p1, reg, opr_decode}, + [0x6d] = {"bit", opr_n_bytes_p1, reg, opr_decode}, + [0x6e] = {"bit", opr_n_bytes_p1, reg, opr_decode}, + [0x6f] = {"bit", opr_n_bytes_p1, reg, opr_decode}, + [0x70] = {"sbc", three, reg, imm1234_0base}, + [0x71] = {"sbc", three, reg, imm1234_0base}, + [0x72] = {"sbc", three, reg, imm1234_0base}, + [0x73] = {"sbc", three, reg, imm1234_0base}, + [0x74] = {"sbc", two, reg, imm1234_0base}, + [0x75] = {"sbc", two, reg, imm1234_0base}, + [0x76] = {"sbc", five, reg, imm1234_0base}, + [0x77] = {"sbc", five, reg, imm1234_0base}, + [0x78] = {"eor", three, reg, imm1234_8base}, + [0x79] = {"eor", three, reg, imm1234_8base}, + [0x7a] = {"eor", three, reg, imm1234_8base}, + [0x7b] = {"eor", three, reg, imm1234_8base}, + [0x7c] = {"eor", two, reg, imm1234_8base}, + [0x7d] = {"eor", two, reg, imm1234_8base}, + [0x7e] = {"eor", five, reg, imm1234_8base}, + [0x7f] = {"eor", five, reg, imm1234_8base}, + [0x80] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, + [0x81] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, + [0x82] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, + [0x83] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, + [0x84] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, + [0x85] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, + [0x86] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, + [0x87] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, + [0x88] = {"eor", opr_n_bytes_p1, reg, opr_decode}, + [0x89] = {"eor", opr_n_bytes_p1, reg, opr_decode}, + [0x8a] = {"eor", opr_n_bytes_p1, reg, opr_decode}, + [0x8b] = {"eor", opr_n_bytes_p1, reg, opr_decode}, + [0x8c] = {"eor", opr_n_bytes_p1, reg, opr_decode}, + [0x8d] = {"eor", opr_n_bytes_p1, reg, opr_decode}, + [0x8e] = {"eor", opr_n_bytes_p1, reg, opr_decode}, + [0x8f] = {"eor", opr_n_bytes_p1, reg, opr_decode}, + [0x90] = {"rti", single, 0, 0}, + [0x91] = {"clb", two, tfr, 0}, + [0x92] = {"trap", single, trap_decode, 0}, + [0x93] = {"trap", single, trap_decode, 0}, + [0x94] = {"trap", single, trap_decode, 0}, + [0x95] = {"trap", single, trap_decode, 0}, + [0x96] = {"trap", single, trap_decode, 0}, + [0x97] = {"trap", single, trap_decode, 0}, + [0x98] = {"trap", single, trap_decode, 0}, + [0x99] = {"trap", single, trap_decode, 0}, + [0x9a] = {"trap", single, trap_decode, 0}, + [0x9b] = {"trap", single, trap_decode, 0}, + [0x9c] = {"trap", single, trap_decode, 0}, + [0x9d] = {"trap", single, trap_decode, 0}, + [0x9e] = {"trap", single, trap_decode, 0}, + [0x9f] = {"trap", single, trap_decode, 0}, + [0xa0] = {"sat", single, reg, 0}, + [0xa1] = {"sat", single, reg, 0}, + [0xa2] = {"sat", single, reg, 0}, + [0xa3] = {"sat", single, reg, 0}, + [0xa4] = {"sat", single, reg, 0}, + [0xa5] = {"sat", single, reg, 0}, + [0xa6] = {"sat", single, reg, 0}, + [0xa7] = {"sat", single, reg, 0}, + [0xa8] = {"trap", single, trap_decode, 0}, + [0xa9] = {"trap", single, trap_decode, 0}, + [0xaa] = {"trap", single, trap_decode, 0}, + [0xab] = {"trap", single, trap_decode, 0}, + [0xac] = {"trap", single, trap_decode, 0}, + [0xad] = {"trap", single, trap_decode, 0}, + [0xae] = {"trap", single, trap_decode, 0}, + [0xaf] = {"trap", single, trap_decode, 0}, + [0xb0] = {"qmul", mul_n_bytes, mul_decode, 0}, + [0xb1] = {"qmul", mul_n_bytes, mul_decode, 0}, + [0xb2] = {"qmul", mul_n_bytes, mul_decode, 0}, + [0xb3] = {"qmul", mul_n_bytes, mul_decode, 0}, + [0xb4] = {"qmul", mul_n_bytes, mul_decode, 0}, + [0xb5] = {"qmul", mul_n_bytes, mul_decode, 0}, + [0xb6] = {"qmul", mul_n_bytes, mul_decode, 0}, + [0xb7] = {"qmul", mul_n_bytes, mul_decode, 0}, + [0xb8] = {"trap", single, trap_decode, 0}, + [0xb9] = {"trap", single, trap_decode, 0}, + [0xba] = {"trap", single, trap_decode, 0}, + [0xbb] = {"trap", single, trap_decode, 0}, + [0xbc] = {"trap", single, trap_decode, 0}, + [0xbd] = {"trap", single, trap_decode, 0}, + [0xbe] = {"trap", single, trap_decode, 0}, + [0xbf] = {"trap", single, trap_decode, 0}, + [0xc0] = {"trap", single, trap_decode, 0}, + [0xc1] = {"trap", single, trap_decode, 0}, + [0xc2] = {"trap", single, trap_decode, 0}, + [0xc3] = {"trap", single, trap_decode, 0}, + [0xc4] = {"trap", single, trap_decode, 0}, + [0xc5] = {"trap", single, trap_decode, 0}, + [0xc6] = {"trap", single, trap_decode, 0}, + [0xc7] = {"trap", single, trap_decode, 0}, + [0xc8] = {"trap", single, trap_decode, 0}, + [0xc9] = {"trap", single, trap_decode, 0}, + [0xca] = {"trap", single, trap_decode, 0}, + [0xcb] = {"trap", single, trap_decode, 0}, + [0xcc] = {"trap", single, trap_decode, 0}, + [0xcd] = {"trap", single, trap_decode, 0}, + [0xce] = {"trap", single, trap_decode, 0}, + [0xcf] = {"trap", single, trap_decode, 0}, + [0xd0] = {"trap", single, trap_decode, 0}, + [0xd1] = {"trap", single, trap_decode, 0}, + [0xd2] = {"trap", single, trap_decode, 0}, + [0xd3] = {"trap", single, trap_decode, 0}, + [0xd4] = {"trap", single, trap_decode, 0}, + [0xd5] = {"trap", single, trap_decode, 0}, + [0xd6] = {"trap", single, trap_decode, 0}, + [0xd7] = {"trap", single, trap_decode, 0}, + [0xd8] = {"trap", single, trap_decode, 0}, + [0xd9] = {"trap", single, trap_decode, 0}, + [0xda] = {"trap", single, trap_decode, 0}, + [0xdb] = {"trap", single, trap_decode, 0}, + [0xdc] = {"trap", single, trap_decode, 0}, + [0xdd] = {"trap", single, trap_decode, 0}, + [0xde] = {"trap", single, trap_decode, 0}, + [0xdf] = {"trap", single, trap_decode, 0}, + [0xe0] = {"trap", single, trap_decode, 0}, + [0xe1] = {"trap", single, trap_decode, 0}, + [0xe2] = {"trap", single, trap_decode, 0}, + [0xe3] = {"trap", single, trap_decode, 0}, + [0xe4] = {"trap", single, trap_decode, 0}, + [0xe5] = {"trap", single, trap_decode, 0}, + [0xe6] = {"trap", single, trap_decode, 0}, + [0xe7] = {"trap", single, trap_decode, 0}, + [0xe8] = {"trap", single, trap_decode, 0}, + [0xe9] = {"trap", single, trap_decode, 0}, + [0xea] = {"trap", single, trap_decode, 0}, + [0xeb] = {"trap", single, trap_decode, 0}, + [0xec] = {"trap", single, trap_decode, 0}, + [0xed] = {"trap", single, trap_decode, 0}, + [0xee] = {"trap", single, trap_decode, 0}, + [0xef] = {"trap", single, trap_decode, 0}, + [0xf0] = {"trap", single, trap_decode, 0}, + [0xf1] = {"trap", single, trap_decode, 0}, + [0xf2] = {"trap", single, trap_decode, 0}, + [0xf3] = {"trap", single, trap_decode, 0}, + [0xf4] = {"trap", single, trap_decode, 0}, + [0xf5] = {"trap", single, trap_decode, 0}, + [0xf6] = {"trap", single, trap_decode, 0}, + [0xf7] = {"trap", single, trap_decode, 0}, + [0xf8] = {"trap", single, trap_decode, 0}, + [0xf9] = {"trap", single, trap_decode, 0}, + [0xfa] = {"trap", single, trap_decode, 0}, + [0xfb] = {"trap", single, trap_decode, 0}, + [0xfc] = {"trap", single, trap_decode, 0}, + [0xfd] = {"trap", single, trap_decode, 0}, + [0xfe] = {"trap", single, trap_decode, 0}, + [0xff] = {"trap", single, trap_decode, 0}, + }; + +static const struct opcode page1[] = + { + [0x00] = {"bgnd", single, 0, 0}, + [0x01] = {"nop", single, 0, 0}, + [0x02] = {"brclr", bm_rel_n_bytes, bm_rel_decode, 0}, + [0x03] = {"brset", bm_rel_n_bytes, bm_rel_decode, 0}, + [0x04] = {NULL, two, 0, 0}, /* psh/pul */ + [0x05] = {"rts", single, 0, 0}, + [0x06] = {"lea", opr_n_bytes_p1, reg, opr_decode}, + [0x07] = {"lea", opr_n_bytes_p1, reg, opr_decode}, + [0x08] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0}, + [0x09] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0}, + [0x0a] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0}, + [0x0b] = {NULL, loop_prim_n_bytes, 0, 0}, /* Loop primitives TBcc / DBcc */ + [0x0c] = {"mov.b", mov_imm_opr_n_bytes, mov_imm_opr, 0}, + [0x0d] = {"mov.w", mov_imm_opr_n_bytes, mov_imm_opr, 0}, + [0x0e] = {"mov.p", mov_imm_opr_n_bytes, mov_imm_opr, 0}, + [0x0f] = {"mov.l", mov_imm_opr_n_bytes, mov_imm_opr, 0}, + [0x10] = {NULL, shift_n_bytes, 0, 0}, /* lsr/lsl/asl/asr/rol/ror */ + [0x11] = {NULL, shift_n_bytes, 0, 0}, + [0x12] = {NULL, shift_n_bytes, 0, 0}, + [0x13] = {NULL, shift_n_bytes, 0, 0}, + [0x14] = {NULL, shift_n_bytes, 0, 0}, + [0x15] = {NULL, shift_n_bytes, 0, 0}, + [0x16] = {NULL, shift_n_bytes, 0, 0}, + [0x17] = {NULL, shift_n_bytes, 0, 0}, + [0x18] = {"lea", two, lea_reg_xys, NULL}, + [0x19] = {"lea", two, lea_reg_xys, NULL}, + [0x1a] = {"lea", two, lea_reg_xys, NULL}, + /* 0x1b PG2 */ + [0x1c] = {"mov.b", opr_n_bytes2, 0, opr_decode2}, + [0x1d] = {"mov.w", opr_n_bytes2, 0, opr_decode2}, + [0x1e] = {"mov.p", opr_n_bytes2, 0, opr_decode2}, + [0x1f] = {"mov.l", opr_n_bytes2, 0, opr_decode2}, + [0x20] = {"bra", pcrel_15bit, decode_rel_15_7, 0}, + [0x21] = {"bsr", pcrel_15bit, decode_rel_15_7, 0}, + [0x22] = {"bhi", pcrel_15bit, decode_rel_15_7, 0}, + [0x23] = {"bls", pcrel_15bit, decode_rel_15_7, 0}, + [0x24] = {"bcc", pcrel_15bit, decode_rel_15_7, 0}, + [0x25] = {"bcs", pcrel_15bit, decode_rel_15_7, 0}, + [0x26] = {"bne", pcrel_15bit, decode_rel_15_7, 0}, + [0x27] = {"beq", pcrel_15bit, decode_rel_15_7, 0}, + [0x28] = {"bvc", pcrel_15bit, decode_rel_15_7, 0}, + [0x29] = {"bvs", pcrel_15bit, decode_rel_15_7, 0}, + [0x2a] = {"bpl", pcrel_15bit, decode_rel_15_7, 0}, + [0x2b] = {"bmi", pcrel_15bit, decode_rel_15_7, 0}, + [0x2c] = {"bge", pcrel_15bit, decode_rel_15_7, 0}, + [0x2d] = {"blt", pcrel_15bit, decode_rel_15_7, 0}, + [0x2e] = {"bgt", pcrel_15bit, decode_rel_15_7, 0}, + [0x2f] = {"ble", pcrel_15bit, decode_rel_15_7, 0}, + [0x30] = {"inc", single, reg, 0}, + [0x31] = {"inc", single, reg, 0}, + [0x32] = {"inc", single, reg, 0}, + [0x33] = {"inc", single, reg, 0}, + [0x34] = {"inc", single, reg, 0}, + [0x35] = {"inc", single, reg, 0}, + [0x36] = {"inc", single, reg, 0}, + [0x37] = {"inc", single, reg, 0}, + [0x38] = {"clr", single, reg, 0}, + [0x39] = {"clr", single, reg, 0}, + [0x3a] = {"clr", single, reg, 0}, + [0x3b] = {"clr", single, reg, 0}, + [0x3c] = {"clr", single, reg, 0}, + [0x3d] = {"clr", single, reg, 0}, + [0x3e] = {"clr", single, reg, 0}, + [0x3f] = {"clr", single, reg, 0}, + [0x40] = {"dec", single, reg, 0}, + [0x41] = {"dec", single, reg, 0}, + [0x42] = {"dec", single, reg, 0}, + [0x43] = {"dec", single, reg, 0}, + [0x44] = {"dec", single, reg, 0}, + [0x45] = {"dec", single, reg, 0}, + [0x46] = {"dec", single, reg, 0}, + [0x47] = {"dec", single, reg, 0}, + [0x48] = {"mul", mul_n_bytes, mul_decode, 0}, + [0x49] = {"mul", mul_n_bytes, mul_decode, 0}, + [0x4a] = {"mul", mul_n_bytes, mul_decode, 0}, + [0x4b] = {"mul", mul_n_bytes, mul_decode, 0}, + [0x4c] = {"mul", mul_n_bytes, mul_decode, 0}, + [0x4d] = {"mul", mul_n_bytes, mul_decode, 0}, + [0x4e] = {"mul", mul_n_bytes, mul_decode, 0}, + [0x4f] = {"mul", mul_n_bytes, mul_decode, 0}, + [0x50] = {"add", three, reg, imm1234_0base}, + [0x51] = {"add", three, reg, imm1234_0base}, + [0x52] = {"add", three, reg, imm1234_0base}, + [0x53] = {"add", three, reg, imm1234_0base}, + [0x54] = {"add", two, reg, imm1234_0base}, + [0x55] = {"add", two, reg, imm1234_0base}, + [0x56] = {"add", five, reg, imm1234_0base}, + [0x57] = {"add", five, reg, imm1234_0base}, + [0x58] = {"and", three, reg, imm1234_8base}, + [0x59] = {"and", three, reg, imm1234_8base}, + [0x5a] = {"and", three, reg, imm1234_8base}, + [0x5b] = {"and", three, reg, imm1234_8base}, + [0x5c] = {"and", two, reg, imm1234_8base}, + [0x5d] = {"and", two, reg, imm1234_8base}, + [0x5e] = {"and", five, reg, imm1234_8base}, + [0x5f] = {"and", five, reg, imm1234_8base}, + [0x60] = {"add", opr_n_bytes_p1, reg, opr_decode}, + [0x61] = {"add", opr_n_bytes_p1, reg, opr_decode}, + [0x62] = {"add", opr_n_bytes_p1, reg, opr_decode}, + [0x63] = {"add", opr_n_bytes_p1, reg, opr_decode}, + [0x64] = {"add", opr_n_bytes_p1, reg, opr_decode}, + [0x65] = {"add", opr_n_bytes_p1, reg, opr_decode}, + [0x66] = {"add", opr_n_bytes_p1, reg, opr_decode}, + [0x67] = {"add", opr_n_bytes_p1, reg, opr_decode}, + [0x68] = {"and", opr_n_bytes_p1, reg, opr_decode}, + [0x69] = {"and", opr_n_bytes_p1, reg, opr_decode}, + [0x6a] = {"and", opr_n_bytes_p1, reg, opr_decode}, + [0x6b] = {"and", opr_n_bytes_p1, reg, opr_decode}, + [0x6c] = {"and", opr_n_bytes_p1, reg, opr_decode}, + [0x6d] = {"and", opr_n_bytes_p1, reg, opr_decode}, + [0x6e] = {"and", opr_n_bytes_p1, reg, opr_decode}, + [0x6f] = {"and", opr_n_bytes_p1, reg, opr_decode}, + [0x70] = {"sub", three, reg, imm1234_0base}, + [0x71] = {"sub", three, reg, imm1234_0base}, + [0x72] = {"sub", three, reg, imm1234_0base}, + [0x73] = {"sub", three, reg, imm1234_0base}, + [0x74] = {"sub", two, reg, imm1234_0base}, + [0x75] = {"sub", two, reg, imm1234_0base}, + [0x76] = {"sub", five, reg, imm1234_0base}, + [0x77] = {"sub", five, reg, imm1234_0base}, + [0x78] = {"or", three, reg, imm1234_8base}, + [0x79] = {"or", three, reg, imm1234_8base}, + [0x7a] = {"or", three, reg, imm1234_8base}, + [0x7b] = {"or", three, reg, imm1234_8base}, + [0x7c] = {"or", two, reg, imm1234_8base}, + [0x7d] = {"or", two, reg, imm1234_8base}, + [0x7e] = {"or", five, reg, imm1234_8base}, + [0x7f] = {"or", five, reg, imm1234_8base}, + [0x80] = {"sub", opr_n_bytes_p1, reg, opr_decode}, + [0x81] = {"sub", opr_n_bytes_p1, reg, opr_decode}, + [0x82] = {"sub", opr_n_bytes_p1, reg, opr_decode}, + [0x83] = {"sub", opr_n_bytes_p1, reg, opr_decode}, + [0x84] = {"sub", opr_n_bytes_p1, reg, opr_decode}, + [0x85] = {"sub", opr_n_bytes_p1, reg, opr_decode}, + [0x86] = {"sub", opr_n_bytes_p1, reg, opr_decode}, + [0x87] = {"sub", opr_n_bytes_p1, reg, opr_decode}, + [0x88] = {"or", opr_n_bytes_p1, reg, opr_decode}, + [0x89] = {"or", opr_n_bytes_p1, reg, opr_decode}, + [0x8a] = {"or", opr_n_bytes_p1, reg, opr_decode}, + [0x8b] = {"or", opr_n_bytes_p1, reg, opr_decode}, + [0x8c] = {"or", opr_n_bytes_p1, reg, opr_decode}, + [0x8d] = {"or", opr_n_bytes_p1, reg, opr_decode}, + [0x8e] = {"or", opr_n_bytes_p1, reg, opr_decode}, + [0x8f] = {"or", opr_n_bytes_p1, reg, opr_decode}, + [0x90] = {"ld", three, reg, imm1234_0base}, + [0x91] = {"ld", three, reg, imm1234_0base}, + [0x92] = {"ld", three, reg, imm1234_0base}, + [0x93] = {"ld", three, reg, imm1234_0base}, + [0x94] = {"ld", two, reg, imm1234_0base}, + [0x95] = {"ld", two, reg, imm1234_0base}, + [0x96] = {"ld", five, reg, imm1234_0base}, + [0x97] = {"ld", five, reg, imm1234_0base}, + [0x98] = {"ld", four, reg_xy, imm1234_0base}, + [0x99] = {"ld", four, reg_xy, imm1234_0base}, + [0x9a] = {"clr", single, reg_xy, 0}, + [0x9b] = {"clr", single, reg_xy, 0}, + [0x9c] = {"inc.b", opr_n_bytes_p1, 0, opr_decode}, + [0x9d] = {"inc.w", opr_n_bytes_p1, 0, opr_decode}, + [0x9e] = {"tfr", two, tfr, NULL}, + [0x9f] = {"inc.l", opr_n_bytes_p1, 0, opr_decode}, + [0xa0] = {"ld", opr_n_bytes_p1, reg, opr_decode}, + [0xa1] = {"ld", opr_n_bytes_p1, reg, opr_decode}, + [0xa2] = {"ld", opr_n_bytes_p1, reg, opr_decode}, + [0xa3] = {"ld", opr_n_bytes_p1, reg, opr_decode}, + [0xa4] = {"ld", opr_n_bytes_p1, reg, opr_decode}, + [0xa5] = {"ld", opr_n_bytes_p1, reg, opr_decode}, + [0xa6] = {"ld", opr_n_bytes_p1, reg, opr_decode}, + [0xa7] = {"ld", opr_n_bytes_p1, reg, opr_decode}, + [0xa8] = {"ld", opr_n_bytes_p1, reg_xy, opr_decode}, + [0xa9] = {"ld", opr_n_bytes_p1, reg_xy, opr_decode}, + [0xaa] = {"jmp", opr_n_bytes_p1, opr_decode, 0}, + [0xab] = {"jsr", opr_n_bytes_p1, opr_decode, 0}, + [0xac] = {"dec.b", opr_n_bytes_p1, 0, opr_decode}, + [0xad] = {"dec.w", opr_n_bytes_p1, 0, opr_decode}, + [0xae] = {NULL, two, 0, 0}, /* EXG / SEX */ + [0xaf] = {"dec.l", opr_n_bytes_p1, 0, opr_decode}, + [0xb0] = {"ld", four, reg, ext24_decode}, + [0xb1] = {"ld", four, reg, ext24_decode}, + [0xb2] = {"ld", four, reg, ext24_decode}, + [0xb3] = {"ld", four, reg, ext24_decode}, + [0xb4] = {"ld", four, reg, ext24_decode}, + [0xb5] = {"ld", four, reg, ext24_decode}, + [0xb6] = {"ld", four, reg, ext24_decode}, + [0xb7] = {"ld", four, reg, ext24_decode}, + [0xb8] = {"ld", four, reg_xy, ext24_decode}, + [0xb9] = {"ld", four, reg_xy, ext24_decode}, + [0xba] = {"jmp", four, ext24_decode, 0}, + [0xbb] = {"jsr", four, ext24_decode, 0}, + [0xbc] = {"clr.b", opr_n_bytes_p1, 0, opr_decode}, + [0xbd] = {"clr.w", opr_n_bytes_p1, 0, opr_decode}, + [0xbe] = {"clr.p", opr_n_bytes_p1, 0, opr_decode}, + [0xbf] = {"clr.l", opr_n_bytes_p1, 0, opr_decode}, + [0xc0] = {"st", opr_n_bytes_p1, reg, opr_decode}, + [0xc1] = {"st", opr_n_bytes_p1, reg, opr_decode}, + [0xc2] = {"st", opr_n_bytes_p1, reg, opr_decode}, + [0xc3] = {"st", opr_n_bytes_p1, reg, opr_decode}, + [0xc4] = {"st", opr_n_bytes_p1, reg, opr_decode}, + [0xc5] = {"st", opr_n_bytes_p1, reg, opr_decode}, + [0xc6] = {"st", opr_n_bytes_p1, reg, opr_decode}, + [0xc7] = {"st", opr_n_bytes_p1, reg, opr_decode}, + [0xc8] = {"st", opr_n_bytes_p1, reg_xy, opr_decode}, + [0xc9] = {"st", opr_n_bytes_p1, reg_xy, opr_decode}, + [0xca] = {"ld", three, reg_xy, ld_18bit_decode}, + [0xcb] = {"ld", three, reg_xy, ld_18bit_decode}, + [0xcc] = {"com.b", opr_n_bytes_p1, NULL, opr_decode}, + [0xcd] = {"com.w", opr_n_bytes_p1, NULL, opr_decode}, + [0xce] = {"andcc", two, imm1, 0}, + [0xcf] = {"com.l", opr_n_bytes_p1, NULL, opr_decode}, + [0xd0] = {"st", four, reg, ext24_decode}, + [0xd1] = {"st", four, reg, ext24_decode}, + [0xd2] = {"st", four, reg, ext24_decode}, + [0xd3] = {"st", four, reg, ext24_decode}, + [0xd4] = {"st", four, reg, ext24_decode}, + [0xd5] = {"st", four, reg, ext24_decode}, + [0xd6] = {"st", four, reg, ext24_decode}, + [0xd7] = {"st", four, reg, ext24_decode}, + [0xd8] = {"st", four, reg_xy, ext24_decode}, + [0xd9] = {"st", four, reg_xy, ext24_decode}, + [0xda] = {"ld", three, reg_xy, ld_18bit_decode}, + [0xdb] = {"ld", three, reg_xy, ld_18bit_decode}, + [0xdc] = {"neg.b", opr_n_bytes_p1, NULL, opr_decode}, + [0xdd] = {"neg.w", opr_n_bytes_p1, NULL, opr_decode}, + [0xde] = {"orcc", two, imm1, 0}, + [0xdf] = {"neg.l", opr_n_bytes_p1, NULL, opr_decode}, + [0xe0] = {"cmp", three, reg, imm1234_0base}, + [0xe1] = {"cmp", three, reg, imm1234_0base}, + [0xe2] = {"cmp", three, reg, imm1234_0base}, + [0xe3] = {"cmp", three, reg, imm1234_0base}, + [0xe4] = {"cmp", two, reg, imm1234_0base}, + [0xe5] = {"cmp", two, reg, imm1234_0base}, + [0xe6] = {"cmp", five, reg, imm1234_0base}, + [0xe7] = {"cmp", five, reg, imm1234_0base}, + [0xe8] = {"cmp", four, reg_xy, imm1234_0base}, + [0xe9] = {"cmp", four, reg_xy, imm1234_0base}, + [0xea] = {"ld", three, reg_xy, ld_18bit_decode}, + [0xeb] = {"ld", three, reg_xy, ld_18bit_decode}, + [0xec] = {"bclr", bm_n_bytes, bm_decode, 0}, + [0xed] = {"bset", bm_n_bytes, bm_decode, 0}, + [0xee] = {"btgl", bm_n_bytes, bm_decode, 0}, + [0xef] = {"!!invalid!!", NULL, NULL, NULL}, /* SPARE */ + [0xf0] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, + [0xf1] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, + [0xf2] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, + [0xf3] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, + [0xf4] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, + [0xf5] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, + [0xf6] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, + [0xf7] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, + [0xf8] = {"cmp", opr_n_bytes_p1, reg_xy, opr_decode}, + [0xf9] = {"cmp", opr_n_bytes_p1, reg_xy, opr_decode}, + [0xfa] = {"ld", three, reg_xy, ld_18bit_decode}, + [0xfb] = {"ld", three, reg_xy, ld_18bit_decode}, + [0xfc] = {"cmp", single, cmp_xy, 0}, + [0xfd] = {"sub", single, sub_d6_x_y, 0}, + [0xfe] = {"sub", single, sub_d6_y_x, 0}, + [0xff] = {"swi", single, 0, 0} + }; + + +static const char *oprregs1[] = + { + "d3", "d2", "d1", "d0", "ccl", "cch" + }; + +static const char *oprregs2[] = + { + "y", "x", "d7", "d6", "d5", "d4" + }; + + + + +enum MUL_MODE + { + MUL_REG_REG, + MUL_REG_OPR, + MUL_REG_IMM, + MUL_OPR_OPR + }; + +struct mb +{ + uint8_t mask; + uint8_t value; + enum MUL_MODE mode; +}; + +static const struct mb mul_table[] = { + {0x40, 0x00, MUL_REG_REG}, + + {0x47, 0x40, MUL_REG_OPR}, + {0x47, 0x41, MUL_REG_OPR}, + {0x47, 0x43, MUL_REG_OPR}, + + {0x47, 0x44, MUL_REG_IMM}, + {0x47, 0x45, MUL_REG_IMM}, + {0x47, 0x47, MUL_REG_IMM}, + + {0x43, 0x42, MUL_OPR_OPR}, +}; + +static void +mul_decode (bfd_vma memaddr, struct disassemble_info* info) +{ + uint8_t mb; + int status = read_memory (memaddr, &mb, 1, info); + if (status < 0) + return; + + + uint8_t byte; + status = read_memory (memaddr - 1, &byte, 1, info); + if (status < 0) + return; + + (*info->fprintf_func) (info->stream, "%c", (mb & 0x80) ? 's' : 'u'); + + enum MUL_MODE mode = -1; + size_t i; + for (i = 0; i < sizeof (mul_table) / sizeof (mul_table[0]); ++i) + { + const struct mb *mm = mul_table + i; + if ((mb & mm->mask) == mm->value) + { + mode = mm->mode; + break; + } + } + + switch (mode) + { + case MUL_REG_REG: + break; + case MUL_OPR_OPR: + { + int size1 = (mb & 0x30) >> 4; + int size2 = (mb & 0x0c) >> 2; + (*info->fprintf_func) (info->stream, ".%c%c", + shift_size_table [size1], + shift_size_table [size2]); + } + break; + default: + { + int size = (mb & 0x3); + (*info->fprintf_func) (info->stream, ".%c", shift_size_table [size]); + } + break; + } + + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x7].name); + + switch (mode) + { + case MUL_REG_REG: + case MUL_REG_IMM: + case MUL_REG_OPR: + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", registers[(mb & 0x38) >> 3].name); + break; + default: + break; + } + + switch (mode) + { + case MUL_REG_IMM: + operand_separator (info); + int size = (mb & 0x3); + uint32_t imm = decode_signed_value (memaddr + 1, info, size + 1); + (*info->fprintf_func) (info->stream, "#%d", imm); + break; + case MUL_REG_REG: + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", registers[mb & 0x07].name); + break; + case MUL_REG_OPR: + opr_decode (memaddr + 1, info); + break; + case MUL_OPR_OPR: + { + int first = opr_n_bytes (memaddr + 1, info); + opr_decode (memaddr + 1, info); + opr_decode (memaddr + first + 1, info); + break; + } + } +} + + +static int +mul_n_bytes (bfd_vma memaddr, struct disassemble_info* info) +{ + int nx = 2; + uint8_t mb; + int status = read_memory (memaddr, &mb, 1, info); + if (status < 0) + return 0; + + enum MUL_MODE mode = -1; + size_t i; + for (i = 0; i < sizeof (mul_table) / sizeof (mul_table[0]); ++i) + { + const struct mb *mm = mul_table + i; + if ((mb & mm->mask) == mm->value) + { + mode = mm->mode; + break; + } + } + + int size = (mb & 0x3) + 1; + + switch (mode) + { + case MUL_REG_IMM: + nx += size; + break; + case MUL_REG_REG: + break; + case MUL_REG_OPR: + nx += opr_n_bytes (memaddr + 1, info); + break; + case MUL_OPR_OPR: + { + int first = opr_n_bytes (memaddr + nx - 1, info); + nx += first; + int second = opr_n_bytes (memaddr + nx - 1, info); + nx += second; + } + break; + } + + return nx; +} + + +enum BM_MODE { + BM_REG_IMM, + BM_RESERVED0, + BM_OPR_B, + BM_OPR_W, + BM_OPR_L, + BM_OPR_REG, + BM_RESERVED1 +}; + +struct bm +{ + uint8_t mask; + uint8_t value; + enum BM_MODE mode; +}; + +static const struct bm bm_table[] = { + { 0xC6, 0x04, BM_REG_IMM}, + { 0x84, 0x00, BM_REG_IMM}, + { 0x06, 0x06, BM_REG_IMM}, + { 0xC6, 0x44, BM_RESERVED0}, + // 00 + { 0x8F, 0x80, BM_OPR_B}, + { 0x8E, 0x82, BM_OPR_W}, + { 0x8C, 0x88, BM_OPR_L}, + + { 0x83, 0x81, BM_OPR_REG}, + { 0x87, 0x84, BM_RESERVED1}, +}; + +static void +bm_decode (bfd_vma memaddr, struct disassemble_info* info) +{ + uint8_t bm; + int status = read_memory (memaddr, &bm, 1, info); + if (status < 0) + return; + + size_t i; + enum BM_MODE mode = -1; + for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i) + { + const struct bm *bme = bm_table + i; + if ((bm & bme->mask) == bme->value) + { + mode = bme->mode; + break; + } + } + + switch (mode) + { + case BM_REG_IMM: + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", registers[bm & 0x07].name); + break; + case BM_OPR_B: + (*info->fprintf_func) (info->stream, ".%c", 'b'); + opr_decode (memaddr + 1, info); + break; + case BM_OPR_W: + (*info->fprintf_func) (info->stream, ".%c", 'w'); + opr_decode (memaddr + 1, info); + break; + case BM_OPR_L: + (*info->fprintf_func) (info->stream, ".%c", 'l'); + opr_decode (memaddr + 1, info); + break; + case BM_OPR_REG: + { + uint8_t xb; + read_memory (memaddr + 1, &xb, 1, info); + /* Don't emit a size suffix for register operands */ + if ((xb & 0xF8) != 0xB8) + (*info->fprintf_func) (info->stream, ".%c", shift_size_table[(bm & 0x0c) >> 2]); + opr_decode (memaddr + 1, info); + } + break; + case BM_RESERVED0: + case BM_RESERVED1: + assert (0); + break; + } + + uint8_t imm = 0; + operand_separator (info); + switch (mode) + { + case BM_REG_IMM: + { + imm = (bm & 0xF8) >> 3; + (*info->fprintf_func) (info->stream, "#%d", imm); + } + break; + case BM_OPR_L: + imm |= (bm & 0x03) << 3; + /* fallthrough */ + case BM_OPR_W: + imm |= (bm & 0x01) << 3; + /* fallthrough */ + case BM_OPR_B: + imm |= (bm & 0x70) >> 4; + (*info->fprintf_func) (info->stream, "#%d", imm); + break; + case BM_OPR_REG: + (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name); + break; + case BM_RESERVED0: + case BM_RESERVED1: + assert (0); + break; + } +} + + +static void +bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info) +{ + uint8_t bm; + int status = read_memory (memaddr, &bm, 1, info); + if (status < 0) + return; + + size_t i; + enum BM_MODE mode = -1; + for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i) + { + const struct bm *bme = bm_table + i; + if ((bm & bme->mask) == bme->value) + { + mode = bme->mode; + break; + } + } + + switch (mode) + { + case BM_REG_IMM: + break; + case BM_OPR_B: + (*info->fprintf_func) (info->stream, ".%c", 'b'); + break; + case BM_OPR_W: + (*info->fprintf_func) (info->stream, ".%c", 'w'); + break; + case BM_OPR_L: + (*info->fprintf_func) (info->stream, ".%c", 'l'); + break; + case BM_OPR_REG: + { + uint8_t xb; + read_memory (memaddr + 1, &xb, 1, info); + /* Don't emit a size suffix for register operands */ + if ((xb & 0xF8) != 0xB8) + (*info->fprintf_func) (info->stream, ".%c", + shift_size_table[(bm & 0x0C) >> 2]); + } + break; + case BM_RESERVED0: + case BM_RESERVED1: + assert (0); + break; + } + + int n = 1; + switch (mode) + { + case BM_REG_IMM: + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", registers[bm & 0x07].name); + break; + case BM_OPR_B: + case BM_OPR_W: + case BM_OPR_L: + opr_decode (memaddr + 1, info); + n = 1 + opr_n_bytes (memaddr + 1, info); + break; + case BM_OPR_REG: + opr_decode (memaddr + 1, info); + break; + case BM_RESERVED0: + case BM_RESERVED1: + assert (0); + break; + } + + + int imm = 0; + operand_separator (info); + switch (mode) + { + case BM_OPR_L: + imm |= (bm & 0x02) << 3; + /* fall through */ + case BM_OPR_W: + imm |= (bm & 0x01) << 3; + /* fall through */ + case BM_OPR_B: + imm |= (bm & 0x70) >> 4; + (*info->fprintf_func) (info->stream, "#%d", imm); + break; + case BM_REG_IMM: + imm = (bm & 0xF8) >> 3; + (*info->fprintf_func) (info->stream, "#%d", imm); + break; + case BM_RESERVED0: + case BM_RESERVED1: + assert (0); + break; + case BM_OPR_REG: + (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name); + n += opr_n_bytes (memaddr + 1, info); + break; + } + + rel_15_7 (memaddr + n, info, n + 1); +} + +static int +bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info) +{ + uint8_t bm; + int status = read_memory (memaddr, &bm, 1, info); + if (status < 0) + return status; + + size_t i; + enum BM_MODE mode = -1; + for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i) + { + const struct bm *bme = bm_table + i; + if ((bm & bme->mask) == bme->value) + { + mode = bme->mode; + break; + } + } + + int n = 2; + switch (mode) + { + case BM_REG_IMM: + break; + + case BM_OPR_B: + case BM_OPR_W: + case BM_OPR_L: + n += opr_n_bytes (memaddr + 1, info); + break; + case BM_OPR_REG: + n += opr_n_bytes (memaddr + 1, info); + break; + default: + break; + } + + return n; +} + +static int +bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info) +{ + int n = 1 + bm_n_bytes (memaddr, info); + + bfd_byte rb; + int status = read_memory (memaddr + n - 2, &rb, 1, info); + if (status != 0) + return status; + + if (rb & 0x80) + n++; + + return n; +} + + + + + +/* shift direction */ +enum SB_DIR + { + SB_LEFT, + SB_RIGHT + }; + +enum SB_TYPE + { + SB_ARITHMETIC, + SB_LOGICAL + }; + + +enum SB_MODE + { + SB_REG_REG_N_EFF, + SB_REG_REG_N, + SB_REG_OPR_EFF, + SB_ROT, + SB_REG_OPR_OPR, + SB_OPR_N + }; + +struct sb +{ + uint8_t mask; + uint8_t value; + enum SB_MODE mode; +}; + +static const struct sb sb_table[] = { + {0x30, 0x00, SB_REG_REG_N_EFF}, + {0x30, 0x10, SB_REG_REG_N}, + {0x34, 0x20, SB_REG_OPR_EFF}, + {0x34, 0x24, SB_ROT}, + {0x34, 0x30, SB_REG_OPR_OPR}, + {0x34, 0x34, SB_OPR_N}, +}; + +static int +shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte sb; + int status = read_memory (memaddr++, &sb, 1, info); + if (status != 0) + return status; + + size_t i; + enum SB_MODE mode = -1; + for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i) + { + const struct sb *sbe = sb_table + i; + if ((sb & sbe->mask) == sbe->value) + mode = sbe->mode; + } + + switch (mode) + { + case SB_REG_REG_N_EFF: + return 2; + break; + case SB_REG_OPR_EFF: + case SB_ROT: + return 2 + opr_n_bytes (memaddr, info); + break; + case SB_REG_OPR_OPR: + { + int opr1 = opr_n_bytes (memaddr, info); + int opr2 = 0; + if ((sb & 0x30) != 0x20) + opr2 = opr_n_bytes (memaddr + opr1, info); + return 2 + opr1 + opr2; + } + break; + default: + return 3; + } + + /* not reached */ + return -1; +} + + +static int +mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte byte; + int status = read_memory (memaddr - 1, &byte, 1, info); + if (status < 0) + return status; + + int size = byte - 0x0c + 1; + + return size + opr_n_bytes (memaddr + size, info) + 1; +} + +static void +mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte byte; + int status = read_memory (memaddr - 1, &byte, 1, info); + if (status < 0) + return ; + + int size = byte - 0x0c + 1; + uint32_t imm = decode_signed_value (memaddr, info, size); + + operand_separator (info); + (*info->fprintf_func) (info->stream, "#%d", imm); + opr_decode (memaddr + size, info); +} + + + +static void +ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info) +{ + size_t size = 3; + bfd_byte buffer[3]; + int status = read_memory (memaddr, buffer + 1, 2, info); + if (status < 0) + return ; + + + status = read_memory (memaddr - 1, buffer, 1, info); + if (status < 0) + return ; + + buffer[0] = (buffer[0] & 0x30) >> 4; + + size_t i; + uint32_t imm = 0; + for (i = 0; i < size; ++i) + { + imm |= buffer[i] << (8 * (size - i - 1)); + } + + operand_separator (info); + (*info->fprintf_func) (info->stream, "#%d", imm); +} + + + +/* Loop Primitives */ + +enum LP_MODE { + LP_REG, + LP_XY, + LP_OPR +}; + +struct lp +{ + uint8_t mask; + uint8_t value; + enum LP_MODE mode; +}; + +static const struct lp lp_mode[] = { + {0x08, 0x00, LP_REG}, + {0x0C, 0x08, LP_XY}, + {0x0C, 0x0C, LP_OPR}, +}; + + +static const char *lb_condition[] = + { + "ne", "eq", "pl", "mi", "gt", "le", + "??", "??" + }; + +static int +loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info) +{ + int mx = 0; + uint8_t lb; + read_memory (memaddr + mx++, &lb, 1, info); + + enum LP_MODE mode = -1; + size_t i; + for (i = 0; i < sizeof (lp_mode) / sizeof (lp_mode[0]); ++i) + { + const struct lp *pb = lp_mode + i; + if ((lb & pb->mask) == pb->value) + { + mode = pb->mode; + break; + } + } + + if (mode == LP_OPR) + { + mx += opr_n_bytes (memaddr + mx, info) ; + } + + uint8_t rb; + read_memory (memaddr + mx++, &rb, 1, info); + if (rb & 0x80) + mx++; + + return mx + 1; +} + + + + +static int +print_insn_exg_sex (bfd_vma memaddr, struct disassemble_info* info) +{ + uint8_t eb; + int status = read_memory (memaddr, &eb, 1, info); + if (status < 0) + return -1; + + const struct reg *first = ®isters[(eb & 0xf0) >> 4]; + const struct reg *second = ®isters[(eb & 0xf)]; + + if (first->bytes < second->bytes) + (*info->fprintf_func) (info->stream, "sex"); + else + (*info->fprintf_func) (info->stream, "exg"); + + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", first->name); + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", second->name); + return 0; +} + + + +static int +print_insn_loop_primitive (bfd_vma memaddr, struct disassemble_info* info) +{ + int offs = 1; + uint8_t lb; + int status = read_memory (memaddr, &lb, 1, info); + + char mnemonic[7]; + int x = 0; + mnemonic[x++] = (lb & 0x80) ? 'd' : 't'; + mnemonic[x++] = 'b'; + stpcpy (mnemonic + x, lb_condition [(lb & 0x70) >> 4]); + x += 2; + + const char *reg = NULL; + enum LP_MODE mode = -1; + size_t i; + for (i = 0; i < sizeof (lp_mode) / sizeof (lp_mode[0]); ++i) + { + const struct lp *pb = lp_mode + i; + if ((lb & pb->mask) == pb->value) + { + mode = pb->mode; + break; + } + } + + switch (mode) + { + case LP_REG: + reg = registers [lb & 0x07].name; + break; + case LP_XY: + reg = (lb & 0x1) ? "y" : "x"; + break; + case LP_OPR: + mnemonic[x++] = '.'; + mnemonic[x++] = shift_size_table [lb & 0x03]; + offs += opr_n_bytes (memaddr + 1, info); + break; + } + + mnemonic[x++] = '\0'; + + (*info->fprintf_func) (info->stream, "%s", mnemonic); + + if (mode == LP_OPR) + opr_decode (memaddr + 1, info); + else + { + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", reg); + } + + rel_15_7 (memaddr + offs, info, offs + 1); + + return status; +} + + +static int +print_insn_shift (bfd_vma memaddr, struct disassemble_info* info, uint8_t byte) +{ + size_t i; + uint8_t sb; + int status = read_memory (memaddr, &sb, 1, info); + if (status < 0) + return status; + + enum SB_DIR dir = (sb & 0x40) ? SB_LEFT : SB_RIGHT; + enum SB_TYPE type = (sb & 0x80) ? SB_ARITHMETIC : SB_LOGICAL; + enum SB_MODE mode = -1; + for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i) + { + const struct sb *sbe = sb_table + i; + if ((sb & sbe->mask) == sbe->value) + mode = sbe->mode; + } + + char mnemonic[6]; + int x = 0; + if (mode == SB_ROT) + { + mnemonic[x++] = 'r'; + mnemonic[x++] = 'o'; + } + else + { + mnemonic[x++] = (type == SB_LOGICAL) ? 'l' : 'a'; + mnemonic[x++] = 's'; + } + + mnemonic[x++] = (dir == SB_LEFT) ? 'l' : 'r'; + + switch (mode) + { + case SB_REG_OPR_EFF: + case SB_ROT: + case SB_REG_OPR_OPR: + mnemonic[x++] = '.'; + mnemonic[x++] = shift_size_table[sb & 0x03]; + break; + case SB_OPR_N: + { + uint8_t xb; + read_memory (memaddr + 1, &xb, 1, info); + /* The size suffix is not printed if the OPR operand refers + directly to a register, because the size is implied by the + size of that register. */ + if ((xb & 0xF8) != 0xB8) + { + mnemonic[x++] = '.'; + mnemonic[x++] = shift_size_table[sb & 0x03]; + } + } + break; + default: + break; + }; + + mnemonic[x++] = '\0'; + + (*info->fprintf_func) (info->stream, "%s", mnemonic); + + /* Destination register */ + switch (mode) + { + case SB_REG_REG_N_EFF: + case SB_REG_REG_N: + case SB_REG_OPR_EFF: + case SB_REG_OPR_OPR: + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x7].name); + break; + + case SB_ROT: + opr_decode (memaddr + 1, info); + break; + + default: + break; + } + + /* Source register */ + switch (mode) + { + case SB_REG_REG_N_EFF: + case SB_REG_REG_N: + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", registers[sb & 0x7].name); + break; + + case SB_REG_OPR_OPR: + opr_decode (memaddr + 1, info); + break; + + default: + break; + } + + /* 3rd arg */ + switch (mode) + { + case SB_REG_OPR_EFF: + case SB_OPR_N: + opr_decode (memaddr + 1, info); + break; + + case SB_REG_REG_N: + if (sb & 0x08) + { + operand_separator (info); + if (byte & 0x10) + { + uint8_t xb; + read_memory (memaddr + 1, &xb, 1, info); + int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1); + (*info->fprintf_func) (info->stream, "#%d", shift); + } + else + { + (*info->fprintf_func) (info->stream, "%s:%d", __FILE__, __LINE__); + } + } + else + { + opr_decode (memaddr + 1, info); + } + break; + case SB_REG_OPR_OPR: + { + uint8_t xb; + int n = opr_n_bytes (memaddr + 1, info); + read_memory (memaddr + 1 + n, &xb, 1, info); + + if ((xb & 0xF0) == 0x70) + { + int imm = xb & 0x0F; + imm <<= 1; + imm |= (sb & 0x08) >> 3; + operand_separator (info); + (*info->fprintf_func) (info->stream, "#%d", imm); + } + else + { + opr_decode (memaddr + 1 + n, info); + } + } + break; + default: + break; + } + + switch (mode) + { + case SB_REG_REG_N_EFF: + case SB_REG_OPR_EFF: + case SB_OPR_N: + operand_separator (info); + (*info->fprintf_func) (info->stream, "#%d", + (sb & 0x08) ? 2 : 1); + break; + + default: + break; + } + + return 0; +} + +int +print_insn_s12z (bfd_vma memaddr, struct disassemble_info* info) +{ + bfd_byte byte; + int status = read_memory (memaddr++, &byte, 1, info); + if (status != 0) + return status; + + const struct opcode *opc2 = NULL; + const struct opcode *opc = page1 + byte; + if (opc->mnemonic) + { + (*info->fprintf_func) (info->stream, "%s", opc->mnemonic); + } + else + { + /* The special cases ... */ + switch (byte) + { + case PAGE2_PREBYTE: + { + bfd_byte byte2; + read_memory (memaddr++, &byte2, 1, info); + opc2 = page2 + byte2; + if (opc2->mnemonic) + { + (*info->fprintf_func) (info->stream, "%s", opc2->mnemonic); + + if (opc2->operands) + { + opc2->operands (memaddr, info); + } + + if (opc2->operands2) + { + opc2->operands2 (memaddr, info); + } + } + else if (byte2 >= 0x08 && byte2 <= 0x1F) + { + bfd_byte bb; + read_memory (memaddr, &bb, 1, info); + if (bb & 0x80) + (*info->fprintf_func) (info->stream, "bfins"); + else + (*info->fprintf_func) (info->stream, "bfext"); + + enum BB_MODE mode = -1; + size_t i; + const struct opr_bb *bbs = 0; + for (i = 0; i < sizeof (bb_modes) / sizeof (bb_modes[0]); ++i) + { + bbs = bb_modes + i; + if ((bb & bbs->mask) == bbs->value) + { + mode = bbs->mode; + break; + } + } + + switch (mode) + { + case BB_REG_OPR_REG: + case BB_REG_OPR_IMM: + case BB_OPR_REG_REG: + case BB_OPR_REG_IMM: + { + int size = (bb >> 2) & 0x03; + (*info->fprintf_func) (info->stream, ".%c", + shift_size_table [size]); + } + break; + default: + break; + } + + int reg1 = byte2 & 0x07; + /* First operand */ + switch (mode) + { + case BB_REG_REG_REG: + case BB_REG_REG_IMM: + case BB_REG_OPR_REG: + case BB_REG_OPR_IMM: + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", + registers[reg1].name); + break; + case BB_OPR_REG_REG: + opr_decode (memaddr + 1, info); + break; + case BB_OPR_REG_IMM: + opr_decode (memaddr + 2, info); + break; + } + + /* Second operand */ + switch (mode) + { + case BB_REG_REG_REG: + case BB_REG_REG_IMM: + { + int reg_src = (bb >> 2) & 0x07; + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", + registers[reg_src].name); + } + break; + case BB_OPR_REG_REG: + case BB_OPR_REG_IMM: + { + int reg_src = (byte2 & 0x07); + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", + registers[reg_src].name); + } + break; + case BB_REG_OPR_REG: + opr_decode (memaddr + 1, info); + break; + case BB_REG_OPR_IMM: + opr_decode (memaddr + 2, info); + break; + } + + /* Third operand */ + operand_separator (info); + switch (mode) + { + case BB_REG_REG_REG: + case BB_OPR_REG_REG: + case BB_REG_OPR_REG: + { + int reg_parm = bb & 0x03; + (*info->fprintf_func) (info->stream, "%s", + registers[reg_parm].name); + } + break; + case BB_REG_REG_IMM: + case BB_OPR_REG_IMM: + case BB_REG_OPR_IMM: + { + bfd_byte i1; + read_memory (memaddr + 1, &i1, 1, info); + int offset = i1 & 0x1f; + int width = bb & 0x03; + width <<= 3; + width |= i1 >> 5; + (*info->fprintf_func) (info->stream, "#%d:%d", width, offset); + } + break; + } + } + } + break; + case 0xae: /* EXG / SEX */ + status = print_insn_exg_sex (memaddr, info); + break; + case 0x0b: /* Loop Primitives TBcc and DBcc */ + status = print_insn_loop_primitive (memaddr, info); + break; + case 0x10: /* shift */ + case 0x11: /* shift */ + case 0x12: /* shift */ + case 0x13: /* shift */ + case 0x14: /* shift */ + case 0x15: /* shift */ + case 0x16: /* shift */ + case 0x17: /* shift */ + status = print_insn_shift (memaddr, info, byte); + break; + case 0x04: /* psh / pul */ + { + read_memory (memaddr, &byte, 1, info); + (*info->fprintf_func) (info->stream, (byte & 0x80) ? "pul" : "psh"); + int bit; + if (byte & 0x40) + { + if ((byte & 0x3F) == 0) + { + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", "ALL16b"); + } + else + for (bit = 5; bit >= 0; --bit) + { + if (byte & (0x1 << bit)) + { + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", oprregs2[bit]); + } + } + } + else + { + if ((byte & 0x3F) == 0) + { + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", "ALL"); + } + else + for (bit = 5; bit >= 0; --bit) + { + if (byte & (0x1 << bit)) + { + operand_separator (info); + (*info->fprintf_func) (info->stream, "%s", oprregs1[bit]); + } + } + } + } + break; + default: + operand_separator (info); + (*info->fprintf_func) (info->stream, "???"); + break; + } + } + + if (opc2 == NULL) + { + if (opc->operands) + { + opc->operands (memaddr, info); + } + + if (opc->operands2) + { + opc->operands2 (memaddr, info); + } + } + + int n = 0; + + /* Opcodes in page2 have an additional byte */ + if (opc2) + n++; + + if (opc2 && opc2->insn_bytes == 0) + return n; + + if (!opc2 && opc->insn_bytes == 0) + return n; + + if (opc2) + n += opc2->insn_bytes (memaddr, info); + else + n += opc->insn_bytes (memaddr, info); + + return n; +} diff --git a/opcodes/s12z.h b/opcodes/s12z.h new file mode 100644 index 00000000000..7e38ac5e1ce --- /dev/null +++ b/opcodes/s12z.h @@ -0,0 +1,71 @@ +#ifndef S12Z_H +#define S12Z_H + +/* This byte is used to prefix instructions in "page 2" of the opcode + space */ +#define PAGE2_PREBYTE (0x1b) + +struct reg +{ + char *name; /* The canonical name of the register */ + int bytes; /* its size, in bytes */ +}; + + +/* How many registers do we have. Actually there are only 13, + because CCL and CCH are the low and high bytes of CCW. But + for assemnbly / disassembly purposes they are considered + distinct registers. */ +#define S12Z_N_REGISTERS 15 + +extern const struct reg registers[S12Z_N_REGISTERS]; + +enum { + REG_D2 = 0, + REG_D3, + REG_D4, + REG_D5, + REG_D0, + REG_D1, + REG_D6, + REG_D7, + REG_X, + REG_Y, + REG_S, + REG_P, + REG_CCH, + REG_CCL, + REG_CCW + }; + +/* Any of the registers d0, d1, ... d7 */ +#define REG_BIT_Dn \ +((0x1U << REG_D2) | \ + (0x1U << REG_D3) | \ + (0x1U << REG_D4) | \ + (0x1U << REG_D5) | \ + (0x1U << REG_D6) | \ + (0x1U << REG_D7) | \ + (0x1U << REG_D0) | \ + (0x1U << REG_D1)) + +/* Any of the registers x, y or z */ +#define REG_BIT_XYS \ +((0x1U << REG_X) | \ + (0x1U << REG_Y) | \ + (0x1U << REG_S)) + +/* Any of the registers x, y, z or p */ +#define REG_BIT_XYSP \ +((0x1U << REG_X) | \ + (0x1U << REG_Y) | \ + (0x1U << REG_S) | \ + (0x1U << REG_P)) + +/* The x register or the y register */ +#define REG_BIT_XY \ +((0x1U << REG_X) | \ + (0x1U << REG_Y)) + + +#endif