Add Visium support to opcodes
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.
This commit is contained in:
parent
bb5f769091
commit
1945cfa59d
|
@ -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
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 },
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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@
|
||||
|
|
|
@ -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 ;;
|
||||
|
|
|
@ -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 ;;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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"
|
Loading…
Reference in New Issue