* txvu-dis.c, txvu-opc.c: New files.
authorDoug Evans <dje@google.com>
Mon, 5 Jan 1998 13:46:22 +0000 (13:46 +0000)
committerDoug Evans <dje@google.com>
Mon, 5 Jan 1998 13:46:22 +0000 (13:46 +0000)
* configure.in: Compile them.
* configure: Regenerate.
* Makefile.am (ALL_MACHINES): Add txvu-{dis,opc}.lo.
(txvu-dis.lo,txvu-opc.lo): Add rules for.
* Makefile.in: Regenerate.

opcodes/.Sanitize
opcodes/ChangeLog
opcodes/Makefile.am [new file with mode: 0644]
opcodes/Makefile.in
opcodes/configure
opcodes/configure.in
opcodes/txvu-dis.c [new file with mode: 0644]
opcodes/txvu-opc.c [new file with mode: 0644]

index d6b7ed8d204062509985578c7396df26293ecba9..39ebf43adae3210f85abf4dbdfcb610ab41be1c0 100644 (file)
@@ -31,6 +31,14 @@ else
        lose_these_too="${tic80_files} ${lose_these_too}"
 fi
 
+sky_files="txvu-opc.c txvu-dis.c"
+
+if ( echo $* | grep keep\-sky > /dev/null ) ; then
+       keep_these_too="${sky_files} ${keep_these_too}"
+else
+       lose_these_too="${sky_files} ${lose_these_too}"
+fi
+
 # All files listed between the "Things-to-keep:" line and the
 # "Files-to-sed:" line will be kept.  All other files will be removed.
 # Directories listed in this section will have their own Sanitize
index c5c4aad0c67f9ca85b5f60050b93b07156a638bf..fa423dc0ae123d0d67a60e5121a69c8a36e552f3 100644 (file)
@@ -1,4 +1,13 @@
 start-sanitize-sky
+Mon Jan  5 13:41:07 1998  Doug Evans  <devans@seba.cygnus.com>
+
+       * txvu-dis.c, txvu-opc.c: New files.
+       * configure.in: Compile them.
+       * configure: Regenerate.
+       * Makefile.am (ALL_MACHINES): Add txvu-{dis,opc}.lo.
+       (txvu-dis.lo,txvu-opc.lo): Add rules for.
+       * Makefile.in: Regenerate.
+
 Mon Dec 22 17:17:03 1997  Doug Evans  <devans@canuck.cygnus.com>
 
        * configure.in: Add txvu support.
diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
new file mode 100644 (file)
index 0000000..28ba82b
--- /dev/null
@@ -0,0 +1,268 @@
+## Process this file with automake to generate Makefile.in
+
+INCDIR = $(srcdir)/../include
+BFDDIR = $(srcdir)/../bfd
+DEP = mkdep
+
+lib_LTLIBRARIES = libopcodes.la
+
+# This is where bfd.h lives.
+BFD_H = ../bfd/bfd.h
+
+# Header files.
+HFILES = \
+       arm-opc.h \
+       h8500-opc.h \
+       sh-opc.h \
+       sysdep.h \
+       w65-opc.h \
+       z8k-opc.h
+
+# C source files that correspond to .o's.
+CFILES = \
+       a29k-dis.c \
+       alpha-dis.c \
+       alpha-opc.c \
+       arm-dis.c \
+       cgen-asm.c \
+       cgen-dis.c \
+       cgen-opc.c \
+       d10v-dis.c \
+       d10v-opc.c \
+       dis-buf.c \
+       disassemble.c \
+       h8300-dis.c \
+       h8500-dis.c \
+       hppa-dis.c \
+       i386-dis.c \
+       i960-dis.c \
+       m32r-asm.c \
+       m32r-dis.c \
+       m32r-opc.c \
+       m68k-dis.c \
+       m68k-opc.c \
+       m88k-dis.c \
+       mips-dis.c \
+       mips-opc.c \
+       mips16-opc.c \
+       m10200-dis.c \
+       m10200-opc.c \
+       m10300-dis.c \
+       m10300-opc.c \
+       ns32k-dis.c \
+       ppc-dis.c \
+       ppc-opc.c \
+       sh-dis.c \
+       sparc-dis.c \
+       sparc-opc.c \
+       w65-dis.c \
+       z8k-dis.c \
+       z8kgen.c
+
+ALL_MACHINES = \
+       a29k-dis.lo \
+       alpha-dis.lo \
+       alpha-opc.lo \
+       arc-dis.lo \
+       arc-opc.lo \
+       arm-dis.lo \
+       cgen-asm.lo \
+       cgen-dis.lo \
+       cgen-opc.lo \
+       d10v-dis.lo \
+       d10v-opc.lo \
+       $(start-sanitize-d30v) \
+       d30v-dis.lo \
+       d30v-opc.lo \
+       $(end-sanitize-d30v) \
+       h8300-dis.lo \
+       h8500-dis.lo \
+       hppa-dis.lo \
+       i386-dis.lo \
+       i960-dis.lo \
+       m32r-asm.lo \
+       m32r-dis.lo \
+       m32r-opc.lo \
+       m68k-dis.lo \
+       m68k-opc.lo \
+       m88k-dis.lo \
+       m10200-dis.lo \
+       m10200-opc.lo \
+       m10300-dis.lo \
+       m10300-opc.lo \
+       mips-dis.lo \
+       mips-opc.lo \
+       mips16-opc.lo \
+       ppc-dis.lo \
+       ppc-opc.lo \
+       ns32k-dis.lo \
+       sh-dis.lo \
+       sparc-dis.lo \
+       sparc-opc.lo \
+       $(start-sanitize-tic80) \
+       tic80-dis.lo \
+       tic80-opc.lo \
+       $(end-sanitize-tic80) \
+       $(start-sanitize-sky) \
+       txvu-dis.lo \
+       txvu-opc.lo \
+       $(end-sanitize-sky) \
+       v850-dis.lo \
+       v850-opc.lo \
+       w65-dis.lo \
+       z8k-dis.lo
+
+OFILES = @BFD_MACHINES@
+
+INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(INCDIR) -I$(BFDDIR) @HDEFINES@
+
+disassemble.lo: disassemble.c $(INCDIR)/dis-asm.h
+       $(LIBTOOL) --mode=compile $(COMPILE) -c @archdefs@ $(srcdir)/disassemble.c
+
+libopcodes_la_SOURCES =  dis-buf.c disassemble.c
+libopcodes_la_DEPENDENCIES = $(OFILES)
+libopcodes_la_LIBADD = $(OFILES)
+
+# libtool will build .libs/libopcodes.a.  We create libopcodes.a in
+# the build directory so that we don't have to convert all the
+# programs that use libopcodes.a simultaneously.  This is a hack which
+# should be removed if everything else starts using libtool.  FIXME.
+
+noinst_LIBRARIES = libopcodes.a
+
+stamp-lib: libopcodes.la
+       cp .libs/libopcodes.a libopcodes.tmp
+       $(SHELL) $(srcdir)/../move-if-change libopcodes.tmp libopcodes.a
+       touch stamp-lib
+
+libopcodes.a: stamp-lib ; @true
+
+CLEANFILES = libopcodes.a stamp-lib dep.sed .dep .dep1
+
+# start-sanitize-tic80
+tic80-dis.lo: tic80-dis.c $(INCDIR)/dis-asm.h ../bfd/bfd.h \
+       $(INCDIR)/opcode/tic80.h
+tic80-opc.lo: tic80-opc.c $(INCDIR)/opcode/tic80.h
+# end-sanitize-tic80
+
+# start-sanitize-sky
+txvu-dis.lo: txvu-dis.c $(INCDIR)/dis-asm.h ../bfd/bfd.h \
+       $(INCDIR)/opcode/txvu.h
+txvu-opc.lo: txvu-opc.c $(INCDIR)/opcode/txvu.h
+# end-sanitize-sky
+
+# This dependency stuff is copied from BFD.
+
+.dep: dep.sed $(CFILES) $(HFILES) config.h
+       rm -f .dep1
+       $(MAKE) DEP=$(DEP) .dep1
+       sed -f dep.sed < .dep1 > .dep
+
+.dep1: $(CFILES)
+       rm -f .dep2 .dep2a
+       echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2
+       echo > .dep2a
+       $(DEP) -f .dep2a $(INCLUDES) $(CFLAGS) $?
+       sed -e '/DO NOT DELETE/d' -e '/^$$/d' < .dep2a >> .dep2
+       rm -f .dep2a
+       $(srcdir)/../move-if-change .dep2 .dep1
+
+dep.sed: dep-in.sed config.status
+       sed <$(srcdir)/dep-in.sed >dep.sed      \
+               -e 's!@BFD_H@!$(BFD_H)!'        \
+               -e 's!@INCDIR@!$(INCDIR)!'      \
+               -e 's!@BFDDIR@!$(BFDDIR)!'      \
+               -e 's!@SRCDIR@!$(srcdir)!'
+
+dep: .dep
+       sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile
+       cat .dep >> tmp-Makefile
+       $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: .dep
+       sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in
+       cat .dep >> tmp-Makefile.in
+       $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: .dep
+       sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am
+       cat .dep >> tmp-Makefile.am
+       $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+.PHONY: dep dep-in dep-am
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+a29k-dis.lo: a29k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+  $(INCDIR)/ansidecl.h $(INCDIR)/opcode/a29k.h
+alpha-dis.lo: alpha-dis.c $(INCDIR)/ansidecl.h sysdep.h \
+  config.h $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/opcode/alpha.h
+alpha-opc.lo: alpha-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/alpha.h \
+  $(BFD_H)
+arm-dis.lo: arm-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+  $(INCDIR)/ansidecl.h arm-opc.h
+cgen-asm.lo: cgen-asm.c sysdep.h config.h $(INCDIR)/libiberty.h \
+  $(BFD_H) $(INCDIR)/opcode/cgen.h
+cgen-dis.lo: cgen-dis.c sysdep.h config.h $(INCDIR)/libiberty.h \
+  $(BFD_H) $(INCDIR)/opcode/cgen.h
+cgen-opc.lo: cgen-opc.c sysdep.h config.h $(INCDIR)/libiberty.h \
+  $(BFD_H) $(INCDIR)/opcode/cgen.h
+d10v-dis.lo: d10v-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d10v.h \
+  $(INCDIR)/dis-asm.h $(BFD_H)
+d10v-opc.lo: d10v-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d10v.h
+dis-buf.lo: dis-buf.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+  $(BFD_H)
+disassemble.lo: disassemble.c $(INCDIR)/ansidecl.h \
+  $(INCDIR)/dis-asm.h $(BFD_H)
+h8300-dis.lo: h8300-dis.c $(INCDIR)/opcode/h8300.h \
+  $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h
+h8500-dis.lo: h8500-dis.c h8500-opc.h $(INCDIR)/dis-asm.h \
+  $(BFD_H) $(INCDIR)/ansidecl.h
+hppa-dis.lo: hppa-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+  $(BFD_H) $(BFDDIR)/libhppa.h $(INCDIR)/opcode/hppa.h
+i386-dis.lo: i386-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+  $(INCDIR)/ansidecl.h sysdep.h config.h
+i960-dis.lo: i960-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+  $(INCDIR)/ansidecl.h
+m32r-asm.lo: m32r-asm.c sysdep.h config.h $(BFD_H) \
+  m32r-opc.h $(INCDIR)/opcode/cgen.h
+m32r-dis.lo: m32r-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+  $(BFD_H) m32r-opc.h $(INCDIR)/opcode/cgen.h
+m32r-opc.lo: m32r-opc.c sysdep.h config.h $(INCDIR)/libiberty.h \
+  $(BFD_H) m32r-opc.h $(INCDIR)/opcode/cgen.h
+m68k-dis.lo: m68k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+  $(INCDIR)/ansidecl.h $(INCDIR)/floatformat.h $(INCDIR)/opcode/m68k.h
+m68k-opc.lo: m68k-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/m68k.h
+m88k-dis.lo: m88k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+  $(INCDIR)/ansidecl.h $(INCDIR)/opcode/m88k.h
+mips-dis.lo: mips-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+  $(BFD_H) $(INCDIR)/opcode/mips.h $(BFDDIR)/elf-bfd.h \
+  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+  $(INCDIR)/bfdlink.h $(INCDIR)/elf/mips.h
+mips-opc.lo: mips-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h
+mips16-opc.lo: mips16-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h
+m10200-dis.lo: m10200-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10200.h \
+  $(INCDIR)/dis-asm.h $(BFD_H)
+m10200-opc.lo: m10200-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10200.h
+m10300-dis.lo: m10300-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10300.h \
+  $(INCDIR)/dis-asm.h $(BFD_H)
+m10300-opc.lo: m10300-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10300.h
+ns32k-dis.lo: ns32k-dis.c $(BFD_H) $(INCDIR)/ansidecl.h \
+  sysdep.h config.h $(INCDIR)/dis-asm.h $(INCDIR)/opcode/ns32k.h
+ppc-dis.lo: ppc-dis.c $(INCDIR)/ansidecl.h sysdep.h \
+  config.h $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/opcode/ppc.h
+ppc-opc.lo: ppc-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/ppc.h
+sh-dis.lo: sh-dis.c sh-opc.h $(INCDIR)/dis-asm.h $(BFD_H) \
+  $(INCDIR)/ansidecl.h
+sparc-dis.lo: sparc-dis.c $(INCDIR)/ansidecl.h sysdep.h \
+  config.h $(INCDIR)/opcode/sparc.h $(INCDIR)/dis-asm.h \
+  $(BFD_H) $(INCDIR)/libiberty.h
+sparc-opc.lo: sparc-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/sparc.h
+w65-dis.lo: w65-dis.c w65-opc.h $(INCDIR)/dis-asm.h \
+  $(BFD_H) $(INCDIR)/ansidecl.h
+z8k-dis.lo: z8k-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+  $(BFD_H) z8k-opc.h
+z8kgen.lo: z8kgen.c sysdep.h config.h
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
index 5ae42c3d8610b597add0a25d231c15c66e016fad..efe5b51a629b3f1216436cfd1f894fb309b6f661 100644 (file)
@@ -173,6 +173,10 @@ ALL_MACHINES = \
        tic80-dis.lo \
        tic80-opc.lo \
        $(end-sanitize-tic80) \
+       $(start-sanitize-sky) \
+       txvu-dis.lo \
+       txvu-opc.lo \
+       $(end-sanitize-sky) \
        v850-dis.lo \
        v850-opc.lo \
        w65-dis.lo \
@@ -497,6 +501,12 @@ tic80-dis.lo: tic80-dis.c $(INCDIR)/dis-asm.h ../bfd/bfd.h \
 tic80-opc.lo: tic80-opc.c $(INCDIR)/opcode/tic80.h
 # end-sanitize-tic80
 
+# start-sanitize-sky
+txvu-dis.lo: txvu-dis.c $(INCDIR)/dis-asm.h ../bfd/bfd.h \
+       $(INCDIR)/opcode/txvu.h
+txvu-opc.lo: txvu-opc.c $(INCDIR)/opcode/txvu.h
+# end-sanitize-sky
+
 # This dependency stuff is copied from BFD.
 
 .dep: dep.sed $(CFILES) $(HFILES) config.h
index 8e9513dbfa6e60e2b0b9fc191c0ec221a1eccfe5..682f86b15cf7b0a2ea2162238c49140a808e9ea0 100755 (executable)
@@ -1837,7 +1837,7 @@ if test x${all_targets} = xfalse ; then
        bfd_tic80_arch)         ta="$ta tic80-dis.lo tic80-opc.lo" ;;
 # end-sanitize-tic80
 # start-sanitize-sky
-       bfd_txvu_arch)          ta="$ta" ;;
+       bfd_txvu_arch)          ta="$ta txvu-dis.lo txvu-opc.lo" ;;
 # end-sanitize-sky
        bfd_v850_arch)          ta="$ta v850-opc.lo v850-dis.lo" ;;
 # start-sanitize-v850e
index 8cb9df0d8530bd0e22c0734ca04c22953d555635..76fcd525c807b8a94caf95c863f4bf1cd074d903 100644 (file)
@@ -138,7 +138,7 @@ if test x${all_targets} = xfalse ; then
        bfd_tic80_arch)         ta="$ta tic80-dis.lo tic80-opc.lo" ;;
 # end-sanitize-tic80
 # start-sanitize-sky
-       bfd_txvu_arch)          ta="$ta" ;;
+       bfd_txvu_arch)          ta="$ta txvu-dis.lo txvu-opc.lo" ;;
 # end-sanitize-sky
        bfd_v850_arch)          ta="$ta v850-opc.lo v850-dis.lo" ;;
 # start-sanitize-v850e
diff --git a/opcodes/txvu-dis.c b/opcodes/txvu-dis.c
new file mode 100644 (file)
index 0000000..f3649e6
--- /dev/null
@@ -0,0 +1,191 @@
+/* Instruction printing code for the TXVU
+   Copyright (C) 1998 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 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "dis-asm.h"
+#include "opcode/txvu.h"
+#include "elf-bfd.h"
+#include "elf/txvu.h"
+
+static void print_insn PARAMS ((bfd_vma, disassemble_info *, TXVU_INSN, int));
+
+/* Print one instruction from PC on INFO->STREAM.
+   Return the size of the instruction.  */
+
+int
+print_insn_txvu (pc, info)
+     bfd_vma pc;
+     disassemble_info *info;
+{
+  bfd_byte buffer[8];
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+  int status;
+  /* First element is upper, second is lower.  */
+  TXVU_INSN upper,lower;
+  static int initialized = 0;
+
+  if (!initialized)
+    {
+      initialized = 1;
+      txvu_opcode_init_tables (0);
+    }
+
+  status = (*info->read_memory_func) (pc, buffer, 8, info);
+  if (status != 0)
+    {
+      (*info->memory_error_func) (status, pc, info);
+      return -1;
+    }
+  upper = bfd_getl32 (buffer);
+  lower = bfd_getl32 (buffer + 4);
+
+  /* FIXME: This will need revisiting.  */
+  print_insn (pc, info, upper, 0);
+  (*func) (stream, " || ");
+  print_insn (pc, info, lower, 1);
+
+  return 8;
+}
+
+/* Print one instruction.
+   LOWER_P is non-zero if disassembling a lower slot insn.  */
+
+static void
+print_insn (pc, info, insn, lower_p)
+     bfd_vma pc;
+     disassemble_info *info;
+     TXVU_INSN insn;
+     int lower_p;
+{
+  const struct txvu_opcode *opcode;
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  /* The instructions are stored in lists hashed by the insn code
+     (though we needn't care how they're hashed).  */
+
+  if (lower_p)
+    opcode = txvu_lower_opcode_lookup_dis (insn);
+  else
+    opcode = txvu_upper_opcode_lookup_dis (insn);
+  for ( ; opcode != NULL; opcode = TXVU_OPCODE_NEXT_DIS (opcode))
+    {
+      const unsigned char *syn;
+      int mods,invalid,num_operands;
+      long value;
+      const struct txvu_operand *operand;
+
+      /* Basic bit mask must be correct.  */
+      if ((insn & opcode->mask) != opcode->value)
+       continue;
+
+      /* Make two passes over the operands.  First see if any of them
+        have extraction functions, and, if they do, make sure the
+        instruction is valid.  */
+
+      txvu_opcode_init_print ();
+      invalid = 0;
+
+      for (syn = opcode->syntax; *syn; ++syn)
+       {
+         int index;
+
+         if (*syn < 128)
+           continue;
+
+         mods = 0;
+         index = TXVU_OPERAND_INDEX (*syn);
+         while (TXVU_MOD_P (txvu_operands[index].flags))
+           {
+             mods |= txvu_operands[index].flags & TXVU_MOD_BITS;
+             ++syn;
+             index = TXVU_OPERAND_INDEX (*syn);
+           }
+         operand = txvu_operands + index;
+         if (operand->extract)
+           (*operand->extract) (insn, operand, mods, &invalid);
+       }
+      if (invalid)
+       continue;
+
+      /* The instruction is valid.  */
+
+      (*func) (stream, "%s", opcode->mnemonic);
+      num_operands = 0;
+      for (syn = opcode->syntax; *syn; ++syn)
+       {
+         int index;
+
+         if (*syn < 128)
+           {
+             (*func) (stream, "%c", *syn);
+             continue;
+           }
+
+         /* We have an operand.  Fetch any special modifiers.  */
+         mods = 0;
+         index = TXVU_OPERAND_INDEX (*syn);
+         while (TXVU_MOD_P (txvu_operands[index].flags))
+           {
+             mods |= txvu_operands[index].flags & TXVU_MOD_BITS;
+             ++syn;
+             index = TXVU_OPERAND_INDEX (*syn);
+           }
+         operand = txvu_operands + index;
+
+         /* Extract the value from the instruction.  */
+         if (operand->extract)
+           {
+             value = (*operand->extract) (insn, operand, mods, (int *) NULL);
+           }
+         else
+           {
+             value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
+             if ((operand->flags & TXVU_OPERAND_SIGNED)
+                 && (value & (1 << (operand->bits - 1))))
+               value -= 1 << operand->bits;
+           }
+
+         /* If second or later operand, print a comma.  */
+         if (num_operands > 0)
+           (*func) (stream, ",");
+
+         /* Print the operand as directed by the flags.  */
+         if (operand->print)
+           (*operand->print) (info, insn, value);
+         else if (operand->flags & TXVU_OPERAND_FAKE)
+           ; /* nothing to do (??? at least not yet) */
+         else if (operand->flags & TXVU_OPERAND_RELATIVE_BRANCH)
+           (*info->print_address_func) (pc + value, info);
+         /* ??? Not all cases of this are currently caught.  */
+         else if (operand->flags & TXVU_OPERAND_ABSOLUTE_BRANCH)
+           (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
+         else if (operand->flags & TXVU_OPERAND_ADDRESS)
+           (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
+         else
+           (*func) (stream, "%ld", value);
+
+         if (! (operand->flags & TXVU_OPERAND_SUFFIX))
+           ++num_operands;
+       }
+
+      /* We have found and printed an instruction; return.  */
+      return;
+    }
+
+  (*func) (stream, "*unknown*");
+}
diff --git a/opcodes/txvu-opc.c b/opcodes/txvu-opc.c
new file mode 100644 (file)
index 0000000..a9d0bec
--- /dev/null
@@ -0,0 +1,359 @@
+/* Opcode table for the TXVU
+   Copyright 1998 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 2, 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.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "ansidecl.h"
+#include "dis-asm.h"
+#include "opcode/txvu.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#if defined (__STDC__) || defined (ALMOST_STDC)
+#define XCONCAT2(a,b)  a##b
+#else
+#define XCONCAT2(a,b)  a/**/b
+#endif
+#define CONCAT2(a,b)   XCONCAT2(a,b)
+
+/* ??? One can argue it's preferable to have the PARSE_FN support in tc-vxvu.c
+   and the PRINT_FN support in txvu-dis.c.  For this project I like having
+   them all in one place.  */
+
+#define PARSE_FN(fn) \
+static long CONCAT2 (parse_,fn) \
+     PARAMS ((char **, const char **));
+#define INSERT_FN(fn) \
+static TXVU_INSN CONCAT2 (insert_,fn) \
+     PARAMS ((TXVU_INSN, const struct txvu_operand *, \
+             int, long, const char **))
+#define EXTRACT_FN(fn) \
+static long CONCAT2 (extract_,fn) \
+     PARAMS ((TXVU_INSN, const struct txvu_operand *, \
+             int, int *))
+#define PRINT_FN(fn) \
+static void CONCAT2 (print_,fn) \
+     PARAMS ((disassemble_info *, TXVU_INSN, long));
+
+PARSE_FN (dotdest);
+PRINT_FN (dotdest);
+
+PARSE_FN (reg);
+PRINT_FN (reg);
+
+/* Various types of ARC operands, including insn suffixes.
+
+   Fields are:
+
+   BITS SHIFT FLAGS PARSE_FN INSERT_FN EXTRACT_FN PRINT_FN
+
+   Operand values are 128 + table index.  This allows ASCII chars to be
+   included in the syntax spec.  */
+
+const struct txvu_operand txvu_operands[] =
+{
+/* place holder (??? not sure if needed) */
+#define UNUSED 128
+  { 0 },
+
+/* Destination indicator, with leading '.'.  */
+#define DOTDEST (UNUSED + 1)
+  { 4, TXVU_SHIFT_DEST, TXVU_OPERAND_SUFFIX,
+      parse_dotdest, 0, 0, print_dotdest },
+
+/* ft reg */
+#define FTREG (DOTDEST + 1)
+  { 5, TXVU_SHIFT_FTREG, 0, parse_reg, 0, 0, print_reg },
+
+/* fs reg */
+#define FSREG (FTREG + 1)
+  { 5, TXVU_SHIFT_FSREG, 0, parse_reg, 0, 0, print_reg },
+
+/* fd reg */
+#define FDREG (FSREG + 1)
+  { 5, TXVU_SHIFT_FDREG, 0, parse_reg, 0, 0, print_reg },
+
+/* end of list place holder */
+  { 0 }
+};
+\f
+/* Macros to put a field's value into the right place.  */
+#define FT(x) (((x) & TXVU_MASK_REG) << TXVU_SHIFT_FTREG)
+#define FS(x) (((x) & TXVU_MASK_REG) << TXVU_SHIFT_FSREG)
+#define FD(x) (((x) & TXVU_MASK_REG) << TXVU_SHIFT_FDREG)
+#define R(x,b,m) (((x) & (m)) << (b))  /* value X, mask M, at bit B */
+
+/* TXVU instructions.
+   [??? some of these comments are left over from the ARC port from which
+   this code is borrowed, delete in time]
+
+   Longer versions of insns must appear before shorter ones (if gas sees
+   "lsr r2,r3,1" when it's parsing "lsr %a,%b" it will think the ",1" is
+   junk).  This isn't necessary for `ld' because of the trailing ']'.
+
+   Instructions that are really macros based on other insns must appear
+   before the real insn so they're chosen when disassembling.  Eg: The `mov'
+   insn is really the `and' insn.
+
+   This table is best viewed on a wide screen (161 columns).  I'd prefer to
+   keep it this way.  The rest of the file, however, should be viewable on an
+   80 column terminal.  */
+
+/* ??? This table also includes macros: asl, lsl, and mov.  The ppc port has
+   a more general facility for dealing with macros which could be used if
+   we need to.  */
+
+/* These tables can't be `const' because members `next_asm' and `next_dis' are
+   computed at run-time.  We could split this into two, as that would put the
+   constant stuff into a readonly section.  */
+
+struct txvu_opcode txvu_upper_opcodes[] = {
+
+  /* Macros appear first.  */
+  /* ??? Any aliases?  */
+
+  /* The rest of these needn't be sorted, but it helps to find them if they
+     are.  */
+  { "abs", { DOTDEST, ' ', FTREG, FSREG }, 0xfe0001ff, 0x1fd, 0 },
+  { "add", { DOTDEST, ' ', FDREG, FSREG, FTREG }, 0xfe00003f, 0x28, 0 },
+};
+const int txvu_upper_opcodes_count = sizeof (txvu_upper_opcodes) / sizeof (txvu_opcodes[0]);
+
+struct txvu_opcode txvu_lower_opcodes[] = {
+
+  /* Macros appear first.  */
+  /* ??? Any aliases?  */
+
+  /* The rest of these needn't be sorted, but it helps to find them if they
+     are.  */
+  { "waitp", { 0 }, 0xffffffff, 0x800007bf, 0 },
+  { "waitq", { 0 }, 0xffffffff, 0x800003bf, 0 },
+};
+const int txvu_lower_opcodes_count = sizeof (txvu_lower_opcodes) / sizeof (txvu_opcodes[0]);
+
+/* Indexed by first letter of opcode.  Points to chain of opcodes with same
+   first letter.  */
+/* ??? One can certainly use a better hash.  Later.  */
+static struct txvu_opcode *upper_opcode_map[26 + 1];
+static struct txvu_opcode *lower_opcode_map[26 + 1];
+
+/* Indexed by insn code.  Points to chain of opcodes with same insn code.  */
+static struct txvu_opcode *upper_icode_map[64];
+static struct txvu_opcode *lower_icode_map[64];
+\f
+/* Initialize any tables that need it.
+   Must be called once at start up (or when first needed).
+
+   FLAGS is currently unused but is intended to control initialization.  */
+
+void
+txvu_opcode_init_tables (flags)
+     int flags;
+{
+  static int init_p = 0;
+
+  /* We may be intentionally called more than once (for example gdb will call
+     us each time the user switches cpu).  These tables only need to be init'd
+     once though.  */
+  /* ??? We can remove the need for txvu_opcode_supported by taking it into
+     account here, but I'm not sure I want to do that yet (if ever).  */
+  if (!init_p)
+    {
+      int i,n;
+
+      memset (upper_opcode_map, 0, sizeof (upper_opcode_map));
+      memset (upper_icode_map, 0, sizeof (upper_icode_map));
+
+      /* Scan the table backwards so macros appear at the front.  */
+      for (i = txvu_upper_opcodes_count - 1; i >= 0; --i)
+       {
+         int opcode_hash = TXVU_HASH_UPPER_OPCODE (txvu_upper_opcodes[i].mnemonic);
+         int icode_hash = TXVU_HASH_UPPER_ICODE (txvu_upper_opcodes[i].value);
+
+         txvu_upper_opcodes[i].next_asm = upper_opcode_map[opcode_hash];
+         upper_opcode_map[opcode_hash] = &txvu_upper_opcodes[i];
+
+         txvu_upper_opcodes[i].next_dis = upper_icode_map[icode_hash];
+         upper_icode_map[icode_hash] = &txvu_upper_opcodes[i];
+       }
+
+      memset (lower_opcode_map, 0, sizeof (lower_opcode_map));
+      memset (lower_icode_map, 0, sizeof (lower_icode_map));
+
+      /* Scan the table backwards so macros appear at the front.  */
+      for (i = txvu_lower_opcodes_count - 1; i >= 0; --i)
+       {
+         int opcode_hash = TXVU_HASH_LOWER_OPCODE (txvu_lower_opcodes[i].mnemonic);
+         int icode_hash = TXVU_HASH_LOWER_ICODE (txvu_lower_opcodes[i].value);
+
+         txvu_lower_opcodes[i].next_asm = lower_opcode_map[opcode_hash];
+         lower_opcode_map[opcode_hash] = &txvu_lower_opcodes[i];
+
+         txvu_lower_opcodes[i].next_dis = lower_icode_map[icode_hash];
+         lower_icode_map[icode_hash] = &txvu_lower_opcodes[i];
+       }
+
+      init_p = 1;
+    }
+}
+
+/* Return the first insn in the chain for assembling upper INSN.  */
+
+const struct txvu_opcode *
+txvu_upper_opcode_lookup_asm (insn)
+     const char *insn;
+{
+  return upper_opcode_map[TXVU_HASH_UPPER_OPCODE (insn)];
+}
+
+/* Return the first insn in the chain for assembling lower INSN.  */
+
+const struct txvu_opcode *
+txvu_lower_opcode_lookup_asm (insn)
+     const char *insn;
+{
+  return lower_opcode_map[TXVU_HASH_LOWER_OPCODE (insn)];
+}
+
+/* Return the first insn in the chain for disassembling upper INSN.  */
+
+const struct txvu_opcode *
+txvu_upper_opcode_lookup_dis (insn)
+     TXVU_INSN insn;
+{
+  return upper_icode_map[TXVU_HASH_UPPER_ICODE (insn)];
+}
+
+/* Return the first insn in the chain for disassembling lower INSN.  */
+
+const struct txvu_opcode *
+txvu_lower_opcode_lookup_dis (insn)
+     TXVU_INSN insn;
+{
+  return lower_icode_map[TXVU_HASH_LOWER_ICODE (insn)];
+}
+\f
+/* Value of DEST in use.
+   Each of the registers must specify the same value.
+   ??? Perhaps remove the duplication?  */
+static int dest;
+\f
+/* Init fns.
+   These are called before doing each of the respective activities.  */
+
+/* Called by the assembler before parsing an instruction.  */
+
+void
+txvu_opcode_init_parse ()
+{
+  dest = -1;
+}
+
+/* Called by the disassembler before printing an instruction.  */
+
+void
+txvu_opcode_init_print ()
+{
+  dest = -1;
+}
+\f
+/* Destination choice support.
+   The "dest" string selects any combination of x,y,z,w.
+   [The letters are ordered that way to follow the manual's style.]  */
+
+static long
+parse_dotdest (pstr, errmsg)
+     char **pstr;
+     const char **errmsg;
+{
+  long dest = 0;
+
+  if (**pstr != '.')
+    {
+      *errmsg = "missing `.'";
+      return 0;
+    }
+
+  ++*pstr;
+  while (**pstr)
+    {
+      switch (**pstr)
+       {
+       case 'x' : case 'X' : dest |= TXVU_DEST_X; break;
+       case 'y' : case 'Y' : dest |= TXVU_DEST_Y; break;
+       case 'z' : case 'Z' : dest |= TXVU_DEST_Z; break;
+       case 'w' : case 'W' : dest |= TXVU_DEST_W; break;
+       default : *errmsg = "unknown dest letter"; return 0;
+       }
+      ++*pstr;
+    }
+
+  *errmsg = NULL;
+  return dest;
+}
+
+static void
+print_dotdest (info, insn, value)
+     disassemble_info *info;
+     TXVU_INSN insn;
+     long value;
+{
+  (*info->fprintf_func) (info->stream, ".");
+  if (value & TXVU_DEST_X)
+    (*info->fprintf_func) (info->stream, "x");
+  if (value & TXVU_DEST_Y)
+    (*info->fprintf_func) (info->stream, "y");
+  if (value & TXVU_DEST_Z)
+    (*info->fprintf_func) (info->stream, "z");
+  if (value & TXVU_DEST_W)
+    (*info->fprintf_func) (info->stream, "w");
+}
+\f
+static long
+parse_reg (pstr, errmsg)
+     char **pstr;
+     const char **errmsg;
+{
+  char *str = *pstr;
+  char *start;
+  long reg;
+
+  if (tolower (str[0]) != 'v'
+      || tolower (str[1]) != 'f')
+    {
+      *errmsg = "unknown register";
+      return 0;
+    }
+
+  /* FIXME: quick hack until the framework works.  */
+  start = str = str + 2;
+  while (*str && isdigit (*str))
+    ++str;
+  reg = atoi (start);
+  *pstr = str;
+  *errmsg = NULL;
+  return reg;
+}
+
+static void
+print_reg (info, insn, value)
+     disassemble_info *info;
+     TXVU_INSN insn;
+     long value;
+{
+  (*info->fprintf_func) (info->stream, "vf%ld", value);
+}