Add Visium support to opcodes
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 6 Dec 2014 15:25:55 +0000 (16:25 +0100)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 6 Dec 2014 15:25:55 +0000 (16:25 +0100)
include/
* dis-asm.h (print_insn_visium): Declare.
include/opcode/
* visium.h: New file.
opcodes/
* configure.ac: Add Visium support.
* configure: Regenerate.
* Makefile.am (TARGET_LIBOPCODES_CFILES): Add visium-dis.c and
visium-opc.c.
* Makefile.in: Regenerate.
* disassemble.c (ARCH_visium): Define if ARCH_all.
(disassembler): Deal with bfd_arch_visium if ARCH_visium.
* visium-dis.c: New file.
* visium-opc.c: Likewise.
* po/POTFILES.in: Regenerate.

13 files changed:
include/ChangeLog
include/dis-asm.h
include/opcode/ChangeLog
include/opcode/visium.h [new file with mode: 0644]
opcodes/ChangeLog
opcodes/Makefile.am
opcodes/Makefile.in
opcodes/configure
opcodes/configure.ac
opcodes/disassemble.c
opcodes/po/POTFILES.in
opcodes/visium-dis.c [new file with mode: 0644]
opcodes/visium-opc.c [new file with mode: 0644]

index ea72295487644a8f0aac2e8189171996d77de283..e80d2ec993b86bb5505fd20fca73049a32765d33 100644 (file)
@@ -1,3 +1,7 @@
+2014-12-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * dis-asm.h (print_insn_visium): Declare.
+
 2014-11-24  Mark Wielaard  <mjw@redhat.com>
 
        * dwarf2.h: Add DW_LANG_C_plus_plus_11, DW_LANG_C11 and
index 1b653b5db9e1147b21ae0f4ab3432629846edc5b..7260d59a7b8d90e256afca0ec07ef1b3be96b637 100644 (file)
@@ -295,6 +295,7 @@ extern int print_insn_tilegx                (bfd_vma, disassemble_info *);
 extern int print_insn_tilepro          (bfd_vma, disassemble_info *);
 extern int print_insn_v850             (bfd_vma, disassemble_info *);
 extern int print_insn_vax              (bfd_vma, disassemble_info *);
+extern int print_insn_visium           (bfd_vma, disassemble_info *);
 extern int print_insn_w65              (bfd_vma, disassemble_info *);
 extern int print_insn_xc16x            (bfd_vma, disassemble_info *);
 extern int print_insn_xgate             (bfd_vma, disassemble_info *);
index 062ecc008fae2fbe6bdc47adce68ad6406a938d7..a2248dc6bd6b2bd771aa1ee3ad7cf4b864ccc3b0 100644 (file)
@@ -1,3 +1,7 @@
+2014-12-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * visium.h: New file.
+
 2014-11-28  Sandra Loosemore  <sandra@codesourcery.com>
 
        * nios2.h (NIOS2_INSN_ADDI, NIOS2_INSN_ANDI): Delete.
diff --git a/include/opcode/visium.h b/include/opcode/visium.h
new file mode 100644 (file)
index 0000000..49a8e1a
--- /dev/null
@@ -0,0 +1,337 @@
+/* Opcode table header for Visium.
+
+   Copyright (C) 2003-2014 Free Software Foundation.
+
+   This file is part of GDB, GAS, and GNU binutils.
+
+   GDB, GAS and the GNU binutils are free software; you can redistribute
+   them and/or modify them 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.
+
+   GDB, GAS, and the GNU binutils are distributed in the hope that they
+   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 file; see the file COPYING3.  If not, write to the Free
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+enum visium_opcode_arch_val
+{
+  VISIUM_OPCODE_ARCH_DEF = 0,
+  VISIUM_OPCODE_ARCH_GR5,
+  VISIUM_OPCODE_ARCH_GR6,
+  VISIUM_OPCODE_ARCH_BAD
+};
+
+/* The highest architecture in the table.  */
+#define VISIUM_OPCODE_ARCH_MAX (VISIUM_OPCODE_ARCH_BAD - 1)
+
+/* Given an enum visium_opcode_arch_val, return the bitmask to use in
+   insn encoding/decoding.  */
+#define VISIUM_OPCODE_ARCH_MASK(arch) (1 << (arch))
+
+/* Some defines to make life easy.  */
+#define MASK_DEF VISIUM_OPCODE_ARCH_MASK (VISIUM_OPCODE_ARCH_DEF)
+#define MASK_GR5 VISIUM_OPCODE_ARCH_MASK (VISIUM_OPCODE_ARCH_GR5)
+#define MASK_GR6 VISIUM_OPCODE_ARCH_MASK (VISIUM_OPCODE_ARCH_GR6)
+
+/* Bit masks of architectures supporting the insn.  */
+#define def (MASK_DEF | MASK_GR5 | MASK_GR6)
+#define gr5 (MASK_GR5 | MASK_GR6)
+#define gr6 (MASK_GR6)
+
+/* The condition code field is not used (zero) for most instructions.
+   BRR and BRA make normal use of it. Floating point instructions use
+   it as a sub-opcode.  */
+#define CC_MASK (0xf << 27)
+
+/* It seems a shame not to use these bits in a class 0 instruction,
+   since they could be used to extend the range of the branch.  */
+#define CLASS0_UNUSED_MASK (0x1f << 16)
+
+/* For class 1 instructions the following bit is unused.  */
+#define CLASS1_UNUSED_MASK (1 << 9)
+
+/* For class 1 instructions this field gives the index for a write
+   instruction, the specific operation for an EAM instruction, or
+   the floating point destination register for a floating point
+   instruction.  */
+#define CLASS1_INDEX_MASK (0x1f << 10)
+
+/* For class 3 instructions the following field gives the destination
+   general register.  */
+#define CLASS3_DEST_MASK (0x1f << 10)
+
+/* For class 1 and class 3 instructions the following bit selects an
+   EAM write/read rather than a memory write/read.  */
+#define EAM_SELECT_MASK (1 << 15)
+
+/* Floating point instructions are distinguished from general EAM
+   instructions by the following bit.  */
+#define FP_SELECT_MASK (1 << 3)
+
+/* For both class 1 and class 3 the following fields give, where
+   appropriate the srcA and srcB registers whether floating point
+   or general.  */
+#define SRCA_MASK (0x1f << 16)
+#define SRCB_MASK (0x1f << 4)
+
+/* The class 3 interrupt bit. It turns a BRA into a SYS1, and an
+   RFLAG into a SYS2. This bit should not be set in the user's
+   class 3 instructions. This bit is also used in class 3
+   to distinguish between floating point and other EAM operations.
+   (see FP_SELECT_MASK).  */
+#define CLASS3_INT (1 << 3)
+
+/* Class 3 shift instructions use this bit to indicate that the
+   srcB field is a 5 bit immediate shift count rather than a
+   register number.  */
+#define CLASS3_SOURCEB_IMMED (1 << 9)
+
+#define BMD 0x02630004
+#define BMI 0x82230004
+#define DSI 0x82800004
+#define ENI 0x02a00004
+#define RFI 0x82fe01d4
+
+struct reg_entry
+{
+  char *name;
+  unsigned char code;
+};
+
+const struct reg_entry gen_reg_table[] =
+{
+  {"fp", 0x16},
+  {"r0", 0x0},
+  {"r1", 0x1},
+  {"r10", 0xA},
+  {"r11", 0xB},
+  {"r12", 0xC},
+  {"r13", 0xD},
+  {"r14", 0xE},
+  {"r15", 0xF},
+  {"r16", 0x10},
+  {"r17", 0x11},
+  {"r18", 0x12},
+  {"r19", 0x13},
+  {"r2", 0x2},
+  {"r20", 0x14},
+  {"r21", 0x15},
+  {"r22", 0x16},
+  {"r23", 0x17},
+  {"r24", 0x18},
+  {"r25", 0x19},
+  {"r26", 0x1a},
+  {"r27", 0x1b},
+  {"r28", 0x1c},
+  {"r29", 0x1d},
+  {"r3", 0x3},
+  {"r30", 0x1e},
+  {"r31", 0x1f},
+  {"r4", 0x4},
+  {"r5", 0x5},
+  {"r6", 0x6},
+  {"r7", 0x7},
+  {"r8", 0x8},
+  {"r9", 0x9},
+  {"sp", 0x17},
+};
+
+const struct reg_entry fp_reg_table[] =
+{
+  {"f0", 0x0},
+  {"f1", 0x1},
+  {"f10", 0xa},
+  {"f11", 0xb},
+  {"f12", 0xc},
+  {"f13", 0xd},
+  {"f14", 0xe},
+  {"f15", 0xf},
+  {"f2", 0x2},
+  {"f3", 0x3},
+  {"f4", 0x4},
+  {"f5", 0x5},
+  {"f6", 0x6},
+  {"f7", 0x7},
+  {"f8", 0x8},
+  {"f9", 0x9},
+};
+
+const struct cc_entry
+{
+  char *name;
+  int code;
+} cc_table [] =
+{
+  {"cc", 6},
+  {"cs", 2},
+  {"eq", 1},
+  {"fa", 0},
+  {"ge", 9},
+  {"gt", 10},
+  {"hi", 11},
+  {"le", 12},
+  {"ls", 13},
+  {"lt", 14},
+  {"nc", 8},
+  {"ne", 5},
+  {"ns", 4},
+  {"oc", 7},
+  {"os", 3},
+  {"tr", 15},
+};
+
+enum addressing_mode
+{
+  mode_d,      /* register := */
+  mode_a,      /* op= register */
+  mode_da,     /* register := register */
+  mode_ab,     /* register * register */
+  mode_dab,    /* register := register * register */
+  mode_iab,    /* 5-bit immediate * register * register */
+  mode_0ab,    /* zero * register * register */
+  mode_da0,    /* register := register * zero */
+  mode_cad,    /* condition * register * register */
+  mode_das,    /* register := register * 5-bit immed/register shift count */
+  mode_di,     /* register := 5-bit immediate */
+  mode_ir,     /* 5-bit immediate * register */
+  mode_ai,     /* register 16-bit unsigned immediate */
+  mode_i,      /* 16-bit unsigned immediate */
+  mode_bax,    /* register * register * 5-bit immediate */
+  mode_dax,    /* register := register * 5-bit immediate */
+  mode_s,      /* special mode */
+  mode_sr,     /* special mode with register */
+  mode_ci,     /* condition * 16-bit signed word displacement */
+  mode_fdab,   /* float := float * float */
+  mode_ifdab,  /* fpinst: 4-bit immediate * float * float * float */
+  mode_idfab,  /* fpuread: 4-bit immediate * register * float * float */
+  mode_fda,    /* float := float */
+  mode_fdra,   /* float := register */
+  mode_rdfab,  /* register := float * float */
+  mode_rdfa,   /* register := float */
+  mode_rrr,    /* 3 register sources and destinations (block move) */
+};
+
+#define class0 (0<<25)
+#define class1 (1<<25)
+#define class2 (2<<25)
+#define class3 (3<<25)
+
+static const struct opcode_entry
+{
+  char *mnem;
+  enum addressing_mode mode;
+  unsigned code;
+  char flags;
+}
+opcode_table[] =
+{
+  { "adc.b",    mode_dab,  class3|(1<<21)|(1), def },
+  { "adc.l",    mode_dab,  class3|(1<<21)|(4), def },
+  { "adc.w",    mode_dab,  class3|(1<<21)|(2), def },
+  { "add.b",    mode_dab,  class3|(0<<21)|(1), def },
+  { "add.l",    mode_dab,  class3|(0<<21)|(4), def },
+  { "add.w",    mode_dab,  class3|(0<<21)|(2), def },
+  { "addi",     mode_ai,   class2, def },
+  { "and.b",    mode_dab,  class3|(10<<21)|(1), def},
+  { "and.l",    mode_dab,  class3|(10<<21)|(4), def },
+  { "and.w",    mode_dab,  class3|(10<<21)|(2), def },
+  { "asl.b",    mode_das,  class3|(7<<21)|(1), def },
+  { "asl.l",    mode_das,  class3|(7<<21)|(4), def },
+  { "asl.w",    mode_das,  class3|(7<<21)|(2), def },
+  { "asld",     mode_a,    class1|(15<<21)|(1<<15)|(11<<10)|(4), def },
+  { "asr.b",    mode_das,  class3|(5<<21)|(1), def },
+  { "asr.l",    mode_das,  class3|(5<<21)|(4), def },
+  { "asr.w",    mode_das,  class3|(5<<21)|(2), def },
+  { "asrd",     mode_a,    class1|(15<<21)|(1<<15)|(9<<10)|(4), def },
+  { "bmd",      mode_rrr,  class1|(3<<21)|(3<<16)|(4), gr6 },
+  { "bmi",      mode_rrr,  class1|(1<<21)|(3<<16)|(4), gr6 },
+  { "bra",      mode_cad,  class3|(12<<21)|(4), def },
+  { "brr",      mode_ci,   class0, def },
+  { "cmp.b",    mode_0ab,  class3|(2<<21)|(1), def },
+  { "cmp.l",    mode_0ab,  class3|(2<<21)|(4), def },
+  { "cmp.w",    mode_0ab,  class3|(2<<21)|(2), def },
+  { "cmpc.b",   mode_0ab,  class3|(3<<21)|(1), def },
+  { "cmpc.l",   mode_0ab,  class3|(3<<21)|(4), def },
+  { "cmpc.w",   mode_0ab,  class3|(3<<21)|(2), def },
+  { "divds",    mode_a,    class1|(15<<21)|(1<<15)|(6<<10)|(4), def },
+  { "divdu",    mode_a,    class1|(15<<21)|(1<<15)|(7<<10)|(4), def },
+  { "divs",     mode_a,    class1|(15<<21)|(1<<15)|(2<<10)|(4), def },
+  { "divu",     mode_a,    class1|(15<<21)|(1<<15)|(3<<10)|(4), def },
+  { "dsi",      mode_s,    class1|(4<<21)|(4), def },
+  { "eamread",  mode_di,   class3|(15<<21)|(1<<15)|(1<<9)|(4), def },
+  { "eamwrite", mode_iab,  class1|(15<<21)|(1<<15)|(4), def },
+  { "eni",      mode_s,    class1|(5<<21)|(4), def },
+  { "extb.b",   mode_da,   class3|(14<<21)|(1), def },
+  { "extb.l",   mode_da,   class3|(14<<21)|(4), def },
+  { "extb.w",   mode_da,   class3|(14<<21)|(2), def },
+  { "extw.l",   mode_da,   class3|(4<<21)|(4), def },
+  { "extw.w",   mode_da,   class3|(4<<21)|(2), def },
+  { "fabs",     mode_fda,  class1|(7<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fadd",     mode_fdab, class1|(1<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fcmp",     mode_rdfab,class3|(10<<27)|(15<<21)|(1<<15)|(1<<9)|(1<<3)|(4), gr5 },
+  { "fcmpe",    mode_rdfab,class3|(11<<27)|(15<<21)|(1<<15)|(1<<9)|(1<<3)|(4), gr5 },
+  { "fdiv",     mode_fdab, class1|(4<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fload",    mode_fdra, class1|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fmove",    mode_fda,  class1|(12<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5},
+  { "fmult",    mode_fdab, class1|(3<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fneg",     mode_fda,  class1|(6<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fpinst",   mode_ifdab,class1|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fpuread",  mode_idfab,class3|(15<<21)|(1<<15)|(1<<9)|(1<<3)|(4), gr5 },
+  { "fsqrt",    mode_fda,  class1|(5<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fstore",   mode_rdfa, class3|(15<<21)|(1<<15)|(1<<9)|(1<<3)|(4), gr5 },
+  { "fsub",     mode_fdab, class1|(2<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "ftoi",     mode_fda,  class1|(8<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "itof",     mode_fda,  class1|(9<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "lsr.b",    mode_das,  class3|(6<<21)|(1), def },
+  { "lsr.l",    mode_das,  class3|(6<<21)|(4), def },
+  { "lsr.w",    mode_das,  class3|(6<<21)|(2), def },
+  { "lsrd",     mode_a,    class1|(15<<21)|(1<<15)|(10<<10)|(4), def },
+  { "move.b",   mode_da0,  class3|(9<<21)|(1), def },
+  { "move.l",   mode_da0,  class3|(9<<21)|(4), def },
+  { "move.w",   mode_da0,  class3|(9<<21)|(2), def },
+  { "movil",    mode_ai,   class2|(4<<21), def },
+  { "moviq",    mode_ai,   class2|(6<<21), def },
+  { "moviu",    mode_ai,   class2|(5<<21), def },
+  { "mults",    mode_ab,   class1|(15<<21)|(1<<15)|(0<<10)|(4), def },
+  { "multu",    mode_ab,   class1|(15<<21)|(1<<15)|(1<<10)|(4), def },
+  { "nop",      mode_s,    class0, def },
+  { "not.b",    mode_da,   class3|(11<<21)|(1), def },
+  { "not.l",    mode_da,   class3|(11<<21)|(4), def },
+  { "not.w",    mode_da,   class3|(11<<21)|(2), def },
+  { "or.b",     mode_dab,  class3|(9<<21)|(1), def },
+  { "or.l",     mode_dab,  class3|(9<<21)|(4), def },
+  { "or.w",     mode_dab,  class3|(9<<21)|(2), def },
+  { "read.b",   mode_dax,  class3|(15<<21)|(1<<9)|(1), def },
+  { "read.l",   mode_dax,  class3|(15<<21)|(1<<9)|(4), def },
+  { "read.w",   mode_dax,  class3|(15<<21)|(1<<9)|(2), def },
+  { "readmda",  mode_d,    class3|(15<<21)|(1<<15)|(1<<9)|(4), def },
+  { "readmdb",  mode_d,    class3|(15<<21)|(1<<15)|(1<<9)|(1<<4)|(4), def },
+  { "readmdc",  mode_d,    class3|(15<<21)|(1<<15)|(1<<9)|(2<<4)|(4), def },
+  { "rfi",      mode_s,    class1|(7<<21)|(30<<16)|(29<<4)|(4), def },
+  { "rflag",    mode_d,    class3|(13<<21)|(4), def },
+  { "stop",     mode_ir,   class1|(0<<21)|(4), def },
+  { "sub.b",    mode_dab,  class3|(2<<21)|(1), def },
+  { "sub.l",    mode_dab,  class3|(2<<21)|(4), def },
+  { "sub.w",    mode_dab,  class3|(2<<21)|(2), def },
+  { "subc.b",   mode_dab,  class3|(3<<21)|(1), def },
+  { "subc.l",   mode_dab,  class3|(3<<21)|(4), def },
+  { "subc.w",   mode_dab,  class3|(3<<21)|(2), def },
+  { "subi",     mode_ai,   class2|(2<<21), def },
+  { "trace",    mode_ir,   class1|(13<<21), def },
+  { "write.b",  mode_bax,  class1|(15<<21)|(1), def },
+  { "write.l",  mode_bax,  class1|(15<<21)|(4), def },
+  { "write.w",  mode_bax,  class1|(15<<21)|(2), def },
+  { "writemd",  mode_ab,   class1|(15<<21)|(1<<15)|(4<<10)|(4), def },
+  { "writemdc", mode_a,    class1|(15<<21)|(1<<15)|(5<<10)|(4), def },
+  { "wrtl",     mode_i,    class2|(8<<21), gr6 },
+  { "wrtu",     mode_i,    class2|(9<<21), gr6 },
+  { "xor.b",    mode_dab,  class3|(8<<21)|(1), def },
+  { "xor.l",    mode_dab,  class3|(8<<21)|(4), def },
+  { "xor.w",    mode_dab,  class3|(8<<21)|(2), def },
+};
index 00bb53ad3600af712e520a42d56ade1f684c19ac..d64d138d767114aa5e57ba3646625806163fab03 100644 (file)
@@ -1,3 +1,16 @@
+2014-12-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * configure.ac: Add Visium support.
+       * configure: Regenerate.
+       * Makefile.am (TARGET_LIBOPCODES_CFILES): Add visium-dis.c and
+       visium-opc.c.
+       * Makefile.in: Regenerate.
+       * disassemble.c (ARCH_visium): Define if ARCH_all.
+       (disassembler): Deal with bfd_arch_visium if ARCH_visium.
+       * visium-dis.c: New file.
+       * visium-opc.c: Likewise.
+       * po/POTFILES.in: Regenerate.
+
 2014-11-30  Alan Modra  <amodra@gmail.com>
 
        * ppc-opc.c (powerpc_opcodes): Make mftb* generate mfspr for
index 4acc4363f389ca951b9b32732c70c69e5767deed..9b762398d92fe2607b37f18f1f086d664b242585 100644 (file)
@@ -250,6 +250,8 @@ TARGET_LIBOPCODES_CFILES = \
        v850-dis.c \
        v850-opc.c \
        vax-dis.c \
+       visium-dis.c \
+       visium-opc.c \
        w65-dis.c \
        xc16x-asm.c \
        xc16x-desc.c \
index 46ef017de6a61798dce48f0e9b5f9315f5170fc9..4f02d81c8d76a386847176c539f038db6707db64 100644 (file)
@@ -523,6 +523,8 @@ TARGET_LIBOPCODES_CFILES = \
        v850-dis.c \
        v850-opc.c \
        vax-dis.c \
+       visium-dis.c \
+       visium-opc.c \
        w65-dis.c \
        xc16x-asm.c \
        xc16x-desc.c \
@@ -923,6 +925,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v850-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v850-opc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vax-dis.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/visium-dis.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/visium-opc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/w65-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xc16x-asm.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xc16x-desc.Plo@am__quote@
index 7f1369930e0cc4519ef1e1ab16835e30471e8e16..c97bdf6403281e9c8e8581ccb406d68b77271dfb 100755 (executable)
@@ -12626,6 +12626,7 @@ if test x${all_targets} = xfalse ; then
        bfd_v850ea_arch)        ta="$ta v850-opc.lo v850-dis.lo" ;;
        bfd_v850_rh850_arch)    ta="$ta v850-opc.lo v850-dis.lo" ;;
        bfd_vax_arch)           ta="$ta vax-dis.lo" ;;
+       bfd_visium_arch)        ta="$ta visium-dis.lo visium-opc.lo" ;;
        bfd_w65_arch)           ta="$ta w65-dis.lo" ;;
        bfd_we32k_arch)         ;;
        bfd_xc16x_arch)         ta="$ta xc16x-asm.lo xc16x-desc.lo xc16x-dis.lo xc16x-ibld.lo xc16x-opc.lo" using_cgen=yes ;;
index b93e855a719e83fe671b9802614507a7f8c5b7aa..39eb2fbe9a7bf1f9c6797a3b4288cf1719320873 100644 (file)
@@ -343,6 +343,7 @@ if test x${all_targets} = xfalse ; then
        bfd_v850ea_arch)        ta="$ta v850-opc.lo v850-dis.lo" ;;
        bfd_v850_rh850_arch)    ta="$ta v850-opc.lo v850-dis.lo" ;;
        bfd_vax_arch)           ta="$ta vax-dis.lo" ;;
+       bfd_visium_arch)        ta="$ta visium-dis.lo visium-opc.lo" ;;
        bfd_w65_arch)           ta="$ta w65-dis.lo" ;;
        bfd_we32k_arch)         ;;
        bfd_xc16x_arch)         ta="$ta xc16x-asm.lo xc16x-desc.lo xc16x-dis.lo xc16x-ibld.lo xc16x-opc.lo" using_cgen=yes ;;
index 0a0814ebddb6e63c65ec775f2b639b15e8814b12..63103bb4b8f7cc48128532da3d130df171aa989b 100644 (file)
@@ -89,6 +89,7 @@
 #define ARCH_tilepro
 #define ARCH_v850
 #define ARCH_vax
+#define ARCH_visium
 #define ARCH_w65
 #define ARCH_xstormy16
 #define ARCH_xc16x
@@ -493,6 +494,11 @@ disassembler (abfd)
       disassemble = print_insn_vax;
       break;
 #endif
+#ifdef ARCH_visium
+     case bfd_arch_visium:
+       disassemble = print_insn_visium;
+       break;
+#endif
 #ifdef ARCH_frv
     case bfd_arch_frv:
       disassemble = print_insn_frv;
index 0212748ba05d56c4b459297a42cb45b8ff2d4924..8e8e122bd6792e8887e9f1b2b2d6ca9b53a11d14 100644 (file)
@@ -207,6 +207,8 @@ tilepro-opc.c
 v850-dis.c
 v850-opc.c
 vax-dis.c
+visium-dis.c
+visium-opc.c
 w65-dis.c
 w65-opc.h
 xc16x-asm.c
diff --git a/opcodes/visium-dis.c b/opcodes/visium-dis.c
new file mode 100644 (file)
index 0000000..96be972
--- /dev/null
@@ -0,0 +1,834 @@
+/* Single instruction disassembler for the Visium.
+
+   Copyright (C) 2002-2014 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 "dis-asm.h"
+#include "opcode/visium.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <setjmp.h>
+
+/* Maximum length of an instruction.  */
+#define MAXLEN 4
+
+struct private
+{
+  /* Points to first byte not fetched.  */
+  bfd_byte *max_fetched;
+  bfd_byte the_buffer[MAXLEN];
+  bfd_vma insn_start;
+  jmp_buf bailout;
+};
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
+   on error.  */
+#define FETCH_DATA(info, addr) \
+  ((addr) <= ((struct private *)(info->private_data))->max_fetched \
+   ? 1 : fetch_data ((info), (addr)))
+
+static int fetch_data (struct disassemble_info *info, bfd_byte * addr);
+
+static int
+fetch_data (struct disassemble_info *info, bfd_byte *addr)
+{
+  int status;
+  struct private *priv = (struct private *) info->private_data;
+  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+  status = (*info->read_memory_func) (start,
+                                     priv->max_fetched,
+                                     addr - priv->max_fetched, info);
+  if (status != 0)
+    {
+      (*info->memory_error_func) (status, start, info);
+      longjmp (priv->bailout, 1);
+    }
+  else
+    priv->max_fetched = addr;
+  return 1;
+}
+
+static char *size_names[] = { "?", "b", "w", "?", "l", "?", "?", "?" };
+
+static char *cc_names[] =
+{
+  "fa", "eq", "cs", "os", "ns", "ne", "cc", "oc",
+  "nc", "ge", "gt", "hi", "le", "ls", "lt", "tr"
+};
+
+/* Disassemble non-storage relative instructions.  */
+
+static int
+disassem_class0 (disassemble_info *info, unsigned int ins)
+{
+  int opcode = (ins >> 21) & 0x000f;
+
+  if (ins & CLASS0_UNUSED_MASK)
+    goto illegal_opcode;
+
+  switch (opcode)
+    {
+    case 0:
+      /* BRR instruction.  */
+      {
+       unsigned cbf = (ins >> 27) & 0x000f;
+       int displacement = ((int) (ins << 16)) >> 16;
+
+       if (ins == 0)
+         (*info->fprintf_func) (info->stream, "nop");
+       else
+         (*info->fprintf_func) (info->stream, "brr     %s,%+d",
+                                cc_names[cbf], displacement);
+      }
+      break;
+    case 1:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 2:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 3:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 4:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 5:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 6:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 7:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 8:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 9:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 10:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 11:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 12:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 13:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 14:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 15:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    }
+  return 0;
+
+illegal_opcode:
+  return -1;
+}
+
+/* Disassemble non-storage register class instructions.   */
+
+static int
+disassem_class1 (disassemble_info *info, unsigned int ins)
+{
+  int opcode = (ins >> 21) & 0xf;
+  int source_a = (ins >> 16) & 0x1f;
+  int source_b = (ins >> 4) & 0x1f;
+  int indx = (ins >> 10) & 0x1f;
+
+  int size = ins & 0x7;
+
+  if (ins & CLASS1_UNUSED_MASK)
+    goto illegal_opcode;
+
+  switch (opcode)
+    {
+    case 0:
+      /* Stop.  */
+      (*info->fprintf_func) (info->stream, "stop");
+      break;
+    case 1:
+      /* BMI - Block Move Indirect.  */
+      if (ins != BMI)
+       goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "bmi     r1,r2,r3");
+      break;
+    case 2:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 3:
+      /* BMD - Block Move Direct.  */
+      if (ins != BMD)
+       goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "bmd     r1,r2,r3");
+      break;
+    case 4:
+      /* DSI - Disable Interrupts.  */
+      if (ins != DSI)
+       goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "dsi");
+      break;
+
+    case 5:
+      /* ENI - Enable Interrupts.  */
+      if (ins != ENI)
+       goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "eni");
+      break;
+
+    case 6:
+      /* Illegal opcode (was EUT).  */
+      goto illegal_opcode;
+      break;
+    case 7:
+      /* RFI - Return from Interrupt.  */
+      if (ins != RFI)
+       goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "rfi");
+      break;
+    case 8:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 9:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 10:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 11:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 12:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 13:
+      goto illegal_opcode;
+      break;
+    case 14:
+      goto illegal_opcode;
+      break;
+    case 15:
+      if (ins & EAM_SELECT_MASK)
+       {
+         /* Extension arithmetic module write */
+         int fp_ins = (ins >> 27) & 0xf;
+
+         if (size != 4)
+           goto illegal_opcode;
+
+         if (ins & FP_SELECT_MASK)
+           {
+             /* Which floating point instructions don't need a fsrcB
+                register.  */
+             const int no_fsrcb[16] = { 1, 0, 0, 0, 0, 1, 1, 1,
+               1, 1, 0, 0, 1, 0, 0, 0
+             };
+             if (no_fsrcb[fp_ins] && source_b)
+               goto illegal_opcode;
+
+             /* Check that none of the floating register register numbers
+                is higher than 15. (If this is fload, then srcA is a
+                general register.  */
+             if (ins & ((1 << 14) | (1 << 8)) || (fp_ins && ins & (1 << 20)))
+               goto illegal_opcode;
+
+             switch (fp_ins)
+               {
+               case 0:
+                 (*info->fprintf_func) (info->stream, "fload   f%d,r%d",
+                                        indx, source_a);
+                 break;
+               case 1:
+                 (*info->fprintf_func) (info->stream, "fadd    f%d,f%d,f%d",
+                                        indx, source_a, source_b);
+                 break;
+               case 2:
+                 (*info->fprintf_func) (info->stream, "fsub    f%d,f%d,f%d",
+                                        indx, source_a, source_b);
+                 break;
+               case 3:
+                 (*info->fprintf_func) (info->stream, "fmult   f%d,f%d,f%d",
+                                        indx, source_a, source_b);
+                 break;
+               case 4:
+                 (*info->fprintf_func) (info->stream, "fdiv    f%d,f%d,f%d",
+                                        indx, source_a, source_b);
+                 break;
+               case 5:
+                 (*info->fprintf_func) (info->stream, "fsqrt   f%d,f%d",
+                                        indx, source_a);
+                 break;
+               case 6:
+                 (*info->fprintf_func) (info->stream, "fneg    f%d,f%d",
+                                        indx, source_a);
+                 break;
+               case 7:
+                 (*info->fprintf_func) (info->stream, "fabs    f%d,f%d",
+                                        indx, source_a);
+                 break;
+               case 8:
+                 (*info->fprintf_func) (info->stream, "ftoi    f%d,f%d",
+                                        indx, source_a);
+                 break;
+               case 9:
+                 (*info->fprintf_func) (info->stream, "itof    f%d,f%d",
+                                        indx, source_a);
+                 break;
+               case 12:
+                 (*info->fprintf_func) (info->stream, "fmove   f%d,f%d",
+                                        indx, source_a);
+                 break;
+               default:
+                 (*info->fprintf_func) (info->stream,
+                                        "fpinst  %d,f%d,f%d,f%d", fp_ins,
+                                        indx, source_a, source_b);
+                 break;
+               }
+           }
+         else
+           {
+             /* Which EAM operations do not need a srcB register.  */
+             const int no_srcb[32] =
+             { 0, 0, 1, 1, 0, 1, 1, 1,
+               0, 1, 1, 1, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0
+             };
+
+             if (no_srcb[indx] && source_b)
+               goto illegal_opcode;
+
+             if (fp_ins)
+               goto illegal_opcode;
+
+             switch (indx)
+               {
+               case 0:
+                 (*info->fprintf_func) (info->stream, "mults   r%d,r%d",
+                                        source_a, source_b);
+                 break;
+               case 1:
+                 (*info->fprintf_func) (info->stream, "multu   r%d,r%d",
+                                        source_a, source_b);
+                 break;
+               case 2:
+                 (*info->fprintf_func) (info->stream, "divs    r%d",
+                                        source_a);
+                 break;
+               case 3:
+                 (*info->fprintf_func) (info->stream, "divu    r%d",
+                                        source_a);
+                 break;
+               case 4:
+                 (*info->fprintf_func) (info->stream, "writemd r%d,r%d",
+                                        source_a, source_b);
+                 break;
+               case 5:
+                 (*info->fprintf_func) (info->stream, "writemdc r%d",
+                                        source_a);
+                 break;
+               case 6:
+                 (*info->fprintf_func) (info->stream, "divds   r%d",
+                                        source_a);
+                 break;
+               case 7:
+                 (*info->fprintf_func) (info->stream, "divdu   r%d",
+                                        source_a);
+                 break;
+               case 9:
+                 (*info->fprintf_func) (info->stream, "asrd    r%d",
+                                        source_a);
+                 break;
+               case 10:
+                 (*info->fprintf_func) (info->stream, "lsrd    r%d",
+                                        source_a);
+                 break;
+               case 11:
+                 (*info->fprintf_func) (info->stream, "asld    r%d",
+                                        source_a);
+                 break;
+               default:
+                 (*info->fprintf_func) (info->stream,
+                                        "eamwrite %d,r%d,r%d", indx,
+                                        source_a, source_b);
+                 break;
+               }
+           }
+       }
+      else
+       {
+         /* WRITE - write to memory.  */
+         (*info->fprintf_func) (info->stream, "write.%s %d(r%d),r%d",
+                                size_names[size], indx, source_a, source_b);
+       }
+      break;
+    }
+
+  return 0;
+
+illegal_opcode:
+  return -1;
+}
+
+/* Disassemble storage immediate class instructions.   */
+
+static int
+disassem_class2 (disassemble_info *info, unsigned int ins)
+{
+  int opcode = (ins >> 21) & 0xf;
+  int source_a = (ins >> 16) & 0x1f;
+  unsigned immediate = ins & 0x0000ffff;
+
+  if (ins & CC_MASK)
+    goto illegal_opcode;
+
+  switch (opcode)
+    {
+    case 0:
+      /* ADDI instruction.  */
+      (*info->fprintf_func) (info->stream, "addi    r%d,%d", source_a,
+                            immediate);
+      break;
+    case 1:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 2:
+      /* SUBI instruction.  */
+      (*info->fprintf_func) (info->stream, "subi    r%d,%d", source_a,
+                            immediate);
+      break;
+    case 3:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 4:
+      /* MOVIL instruction.  */
+      (*info->fprintf_func) (info->stream, "movil   r%d,0x%04X", source_a,
+                            immediate);
+      break;
+    case 5:
+      /* MOVIU instruction.  */
+      (*info->fprintf_func) (info->stream, "moviu   r%d,0x%04X", source_a,
+                            immediate);
+      break;
+    case 6:
+      /* MOVIQ instruction.  */
+      (*info->fprintf_func) (info->stream, "moviq   r%d,%u", source_a,
+                            immediate);
+      break;
+    case 7:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 8:
+      /* WRTL instruction.  */
+      if (source_a != 0)
+       goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "wrtl    0x%04X", immediate);
+      break;
+    case 9:
+      /* WRTU instruction.  */
+      if (source_a != 0)
+       goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "wrtu    0x%04X", immediate);
+      break;
+    case 10:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 11:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 12:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 13:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 14:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 15:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    }
+
+  return 0;
+
+illegal_opcode:
+  return -1;
+}
+
+/* Disassemble storage register class instructions.  */
+
+static int
+disassem_class3 (disassemble_info *info, unsigned int ins)
+{
+  int opcode = (ins >> 21) & 0xf;
+  int source_b = (ins >> 4) & 0x1f;
+  int source_a = (ins >> 16) & 0x1f;
+  int size = ins & 0x7;
+  int dest = (ins >> 10) & 0x1f;
+
+  /* Those instructions that don't have a srcB register.  */
+  const int no_srcb[16] =
+  { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0 };
+
+  /* These are instructions which can take an immediate srcB value.  */
+  const int srcb_immed[16] =
+  { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+  /* User opcodes should not provide a non-zero srcB register
+     when none is required. Only a BRA or floating point
+     instruction should have a non-zero condition code field.
+     Only a WRITE or EAMWRITE (opcode 15) should select an EAM
+     or floating point operation.  Note that FP_SELECT_MASK is
+     the same bit (bit 3) as the interrupt bit which
+     distinguishes SYS1 from BRA and SYS2 from RFLAG.  */
+  if ((no_srcb[opcode] && source_b)
+      || (!srcb_immed[opcode] && ins & CLASS3_SOURCEB_IMMED)
+      || (opcode != 12 && opcode != 15 && ins & CC_MASK)
+      || (opcode != 15 && ins & (EAM_SELECT_MASK | FP_SELECT_MASK)))
+    goto illegal_opcode;
+
+
+  switch (opcode)
+    {
+    case 0:
+      /* ADD instruction.  */
+      (*info->fprintf_func) (info->stream, "add.%s   r%d,r%d,r%d",
+                            size_names[size], dest, source_a, source_b);
+      break;
+    case 1:
+      /* ADC instruction.  */
+      (*info->fprintf_func) (info->stream, "adc.%s   r%d,r%d,r%d",
+                            size_names[size], dest, source_a, source_b);
+      break;
+    case 2:
+      /* SUB instruction.  */
+      if (dest == 0)
+       (*info->fprintf_func) (info->stream, "cmp.%s   r%d,r%d",
+                              size_names[size], source_a, source_b);
+      else
+       (*info->fprintf_func) (info->stream, "sub.%s   r%d,r%d,r%d",
+                              size_names[size], dest, source_a, source_b);
+      break;
+    case 3:
+      /* SUBC instruction.  */
+      if (dest == 0)
+       (*info->fprintf_func) (info->stream, "cmpc.%s  r%d,r%d",
+                              size_names[size], source_a, source_b);
+      else
+       (*info->fprintf_func) (info->stream, "subc.%s  r%d,r%d,r%d",
+                              size_names[size], dest, source_a, source_b);
+      break;
+    case 4:
+      /* EXTW instruction.  */
+      if (size == 1)
+       goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "extw.%s  r%d,r%d",
+                            size_names[size], dest, source_a);
+      break;
+    case 5:
+      /* ASR instruction.  */
+      if (ins & CLASS3_SOURCEB_IMMED)
+       (*info->fprintf_func) (info->stream, "asr.%s   r%d,r%d,%d",
+                              size_names[size], dest, source_a, source_b);
+      else
+       (*info->fprintf_func) (info->stream, "asr.%s   r%d,r%d,r%d",
+                              size_names[size], dest, source_a, source_b);
+      break;
+    case 6:
+      /* LSR instruction.  */
+      if (ins & CLASS3_SOURCEB_IMMED)
+       (*info->fprintf_func) (info->stream, "lsr.%s   r%d,r%d,%d",
+                              size_names[size], dest, source_a, source_b);
+      else
+       (*info->fprintf_func) (info->stream, "lsr.%s   r%d,r%d,r%d",
+                              size_names[size], dest, source_a, source_b);
+      break;
+    case 7:
+      /* ASL instruction.  */
+      if (ins & CLASS3_SOURCEB_IMMED)
+       (*info->fprintf_func) (info->stream, "asl.%s   r%d,r%d,%d",
+                              size_names[size], dest, source_a, source_b);
+      else
+       (*info->fprintf_func) (info->stream, "asl.%s   r%d,r%d,r%d",
+                              size_names[size], dest, source_a, source_b);
+      break;
+    case 8:
+      /* XOR instruction.  */
+      (*info->fprintf_func) (info->stream, "xor.%s   r%d,r%d,r%d",
+                            size_names[size], dest, source_a, source_b);
+      break;
+    case 9:
+      /* OR instruction.  */
+      if (source_b == 0)
+       (*info->fprintf_func) (info->stream, "move.%s  r%d,r%d",
+                              size_names[size], dest, source_a);
+      else
+       (*info->fprintf_func) (info->stream, "or.%s    r%d,r%d,r%d",
+                              size_names[size], dest, source_a, source_b);
+      break;
+    case 10:
+      /* AND instruction.  */
+      (*info->fprintf_func) (info->stream, "and.%s   r%d,r%d,r%d",
+                            size_names[size], dest, source_a, source_b);
+      break;
+    case 11:
+      /* NOT instruction.  */
+      (*info->fprintf_func) (info->stream, "not.%s   r%d,r%d",
+                            size_names[size], dest, source_a);
+      break;
+    case 12:
+      /* BRA instruction.  */
+      {
+       unsigned cbf = (ins >> 27) & 0x000f;
+
+       if (size != 4)
+         goto illegal_opcode;
+
+       (*info->fprintf_func) (info->stream, "bra     %s,r%d,r%d",
+                              cc_names[cbf], source_a, dest);
+      }
+      break;
+    case 13:
+      /* RFLAG instruction.  */
+      if (source_a || size != 4)
+       goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "rflag   r%d", dest);
+      break;
+    case 14:
+      /* EXTB instruction.  */
+      (*info->fprintf_func) (info->stream, "extb.%s  r%d,r%d",
+                            size_names[size], dest, source_a);
+      break;
+    case 15:
+      if (!(ins & CLASS3_SOURCEB_IMMED))
+       goto illegal_opcode;
+
+      if (ins & EAM_SELECT_MASK)
+       {
+         /* Extension arithmetic module read.  */
+         int fp_ins = (ins >> 27) & 0xf;
+
+         if (size != 4)
+           goto illegal_opcode;
+
+         if (ins & FP_SELECT_MASK)
+           {
+             /* Check fsrcA <= 15 and fsrcB <= 15.  */
+             if (ins & ((1 << 20) | (1 << 8)))
+               goto illegal_opcode;
+
+             switch (fp_ins)
+               {
+               case 0:
+                 if (source_b)
+                   goto illegal_opcode;
+
+                 (*info->fprintf_func) (info->stream, "fstore  r%d,f%d",
+                                        dest, source_a);
+                 break;
+               case 10:
+                 (*info->fprintf_func) (info->stream, "fcmp    r%d,f%d,f%d",
+                                        dest, source_a, source_b);
+                 break;
+               case 11:
+                 (*info->fprintf_func) (info->stream, "fcmpe   r%d,f%d,f%d",
+                                        dest, source_a, source_b);
+                 break;
+               default:
+                 (*info->fprintf_func) (info->stream,
+                                        "fpuread %d,r%d,f%d,f%d", fp_ins,
+                                        dest, source_a, source_b);
+                 break;
+               }
+           }
+         else
+           {
+             if (fp_ins || source_a)
+               goto illegal_opcode;
+
+             switch (source_b)
+               {
+               case 0:
+                 (*info->fprintf_func) (info->stream, "readmda r%d", dest);
+                 break;
+               case 1:
+                 (*info->fprintf_func) (info->stream, "readmdb r%d", dest);
+                 break;
+               case 2:
+                 (*info->fprintf_func) (info->stream, "readmdc r%d", dest);
+                 break;
+               default:
+                 (*info->fprintf_func) (info->stream, "eamread r%d,%d",
+                                        dest, source_b);
+                 break;
+               }
+           }
+       }
+      else
+       {
+         if (ins & FP_SELECT_MASK)
+           goto illegal_opcode;
+
+         /* READ instruction.  */
+         (*info->fprintf_func) (info->stream, "read.%s  r%d,%d(r%d)",
+                                size_names[size], dest, source_b, source_a);
+       }
+      break;
+    }
+
+  return 0;
+
+illegal_opcode:
+  return -1;
+
+}
+
+/* Print the visium instruction at address addr in debugged memory,
+   on info->stream. Return length of the instruction, in bytes.  */
+
+int
+print_insn_visium (bfd_vma addr, disassemble_info *info)
+{
+  unsigned ins;
+  unsigned p1, p2;
+  int ans;
+  int i;
+
+  /* Stuff copied from m68k-dis.c.  */
+  struct private priv;
+  bfd_byte *buffer = priv.the_buffer;
+  info->private_data = (PTR) & priv;
+  priv.max_fetched = priv.the_buffer;
+  priv.insn_start = addr;
+  if (setjmp (priv.bailout) != 0)
+    {
+      /* Error return.  */
+      return -1;
+    }
+
+  /* We do return this info.  */
+  info->insn_info_valid = 1;
+
+  /* Assume non branch insn.  */
+  info->insn_type = dis_nonbranch;
+
+  /* Assume no delay.  */
+  info->branch_delay_insns = 0;
+
+  /* Assume no target known.  */
+  info->target = 0;
+
+  /* Get 32-bit instruction word.  */
+  FETCH_DATA (info, buffer + 4);
+  ins = buffer[0] << 24;
+  ins |= buffer[1] << 16;
+  ins |= buffer[2] << 8;
+  ins |= buffer[3];
+
+  ans = 0;
+
+  p1 = buffer[0] ^ buffer[1] ^ buffer[2] ^ buffer[3];
+  p2 = 0;
+  for (i = 0; i < 8; i++)
+    {
+      p2 += p1 & 1;
+      p1 >>= 1;
+    }
+
+  /* Decode the instruction.  */
+  if (p2 & 1)
+    ans = -1;
+  else
+    {
+      switch ((ins >> 25) & 0x3)
+       {
+       case 0:
+         ans = disassem_class0 (info, ins);
+         break;
+       case 1:
+         ans = disassem_class1 (info, ins);
+         break;
+       case 2:
+         ans = disassem_class2 (info, ins);
+         break;
+       case 3:
+         ans = disassem_class3 (info, ins);
+         break;
+       }
+    }
+
+  if (ans != 0)
+    (*info->fprintf_func) (info->stream, "err");
+
+  /* Return number of bytes consumed (always 4 for the Visium).  */
+  return 4;
+}
diff --git a/opcodes/visium-opc.c b/opcodes/visium-opc.c
new file mode 100644 (file)
index 0000000..742452c
--- /dev/null
@@ -0,0 +1,23 @@
+/* Opcode table for the Visium.
+
+   Copyright (C) 2002-2014 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 "ansidecl.h"
+#include "opcode/visium.h"