aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ChangeLog4
-rw-r--r--include/dis-asm.h1
-rw-r--r--include/opcode/ChangeLog4
-rw-r--r--include/opcode/visium.h337
-rw-r--r--opcodes/ChangeLog13
-rw-r--r--opcodes/Makefile.am2
-rw-r--r--opcodes/Makefile.in4
-rwxr-xr-xopcodes/configure1
-rw-r--r--opcodes/configure.ac1
-rw-r--r--opcodes/disassemble.c6
-rw-r--r--opcodes/po/POTFILES.in2
-rw-r--r--opcodes/visium-dis.c834
-rw-r--r--opcodes/visium-opc.c23
13 files changed, 1232 insertions, 0 deletions
diff --git a/include/ChangeLog b/include/ChangeLog
index ea72295..e80d2ec 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -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
diff --git a/include/dis-asm.h b/include/dis-asm.h
index 1b653b5..7260d59 100644
--- a/include/dis-asm.h
+++ b/include/dis-asm.h
@@ -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 *);
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index 062ecc0..a2248dc 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -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
index 0000000..49a8e1a
--- /dev/null
+++ b/include/opcode/visium.h
@@ -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 },
+};
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 00bb53a..d64d138 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -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
diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
index 4acc436..9b76239 100644
--- a/opcodes/Makefile.am
+++ b/opcodes/Makefile.am
@@ -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 \
diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in
index 46ef017..4f02d81 100644
--- a/opcodes/Makefile.in
+++ b/opcodes/Makefile.in
@@ -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@
diff --git a/opcodes/configure b/opcodes/configure
index 7f13699..c97bdf6 100755
--- a/opcodes/configure
+++ b/opcodes/configure
@@ -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 ;;
diff --git a/opcodes/configure.ac b/opcodes/configure.ac
index b93e855..39eb2fb 100644
--- a/opcodes/configure.ac
+++ b/opcodes/configure.ac
@@ -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 ;;
diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c
index 0a0814e..63103bb 100644
--- a/opcodes/disassemble.c
+++ b/opcodes/disassemble.c
@@ -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;
diff --git a/opcodes/po/POTFILES.in b/opcodes/po/POTFILES.in
index 0212748..8e8e122 100644
--- a/opcodes/po/POTFILES.in
+++ b/opcodes/po/POTFILES.in
@@ -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
index 0000000..96be972
--- /dev/null
+++ b/opcodes/visium-dis.c
@@ -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
index 0000000..742452c
--- /dev/null
+++ b/opcodes/visium-opc.c
@@ -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"