mirror of
https://github.com/capstone-engine/capstone.git
synced 2024-11-26 23:10:32 +00:00
sh: superh support backend.
Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
This commit is contained in:
parent
5b6846c2c8
commit
b681153238
2231
arch/SH/SHDisassembler.c
Normal file
2231
arch/SH/SHDisassembler.c
Normal file
File diff suppressed because it is too large
Load Diff
19
arch/SH/SHDisassembler.h
Normal file
19
arch/SH/SHDisassembler.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh, 2018 */
|
||||
|
||||
#ifndef CS_SHDISASSEMBLER_H
|
||||
#define CS_SHDISASSEMBLER_H
|
||||
|
||||
#include "../../MCInst.h"
|
||||
|
||||
typedef struct sh_info {
|
||||
cs_sh op;
|
||||
} sh_info;
|
||||
|
||||
bool SH_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address, void *info);
|
||||
|
||||
void SH_reg_access(const cs_insn *insn,
|
||||
cs_regs regs_read, uint8_t *regs_read_count,
|
||||
cs_regs regs_write, uint8_t *regs_write_count);
|
||||
#endif
|
66
arch/SH/SHInsnTable.inc
Normal file
66
arch/SH/SHInsnTable.inc
Normal file
@ -0,0 +1,66 @@
|
||||
bool (*decode[])(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode, sh_info *info, cs_detail *detail) = {
|
||||
/// 00000000
|
||||
NULL, NULL, opSTC, op0xx3, opMOV_B, opMOV_W, opMOV_L, opMUL_L,
|
||||
/// 00001000
|
||||
op0xx8, op0xx9, op0xxa, op0xxb, opMOV_B, opMOV_W, opMOV_L, opMAC_L,
|
||||
/// 00010000
|
||||
opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp,
|
||||
/// 00011000
|
||||
opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp,
|
||||
/// 00100000
|
||||
opMOV_rind, opMOV_rind, opMOV_rind, NULL, opMOV_rpd, opMOV_rpd, opMOV_rpd, opDIV0S,
|
||||
/// 00101000
|
||||
opTST, opAND, opXOR, opOR, opCMP_STR, opXTRCT, opMULU_W, opMULS_W,
|
||||
/// 00110000
|
||||
opCMP_EQ, NULL, opCMP_HS, opCMP_GE, opDIV1, opDMULU_L, opCMP_HI, opCMP_GT,
|
||||
/// 00111000
|
||||
opSUB, NULL, opSUBC, opSUBV, opADD_r, opDMULS_L, opADDC, opADDV,
|
||||
/// 01000000
|
||||
op4xx0, op4xx1, op4xx2, opSTC_L, op4xx4, op4xx5, op4xx6, opLDC_L,
|
||||
/// 01001000
|
||||
op4xx8, op4xx9, op4xxa, op4xxb, opSHAD, opSHLD, opLDC, opMAC_W,
|
||||
/// 01010000
|
||||
opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp,
|
||||
/// 01011000
|
||||
opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp, opMOV_L_dsp,
|
||||
/// 01100000
|
||||
opMOV_rind, opMOV_rind, opMOV_rind, opMOV, opMOV_rpi, opMOV_rpi, opMOV_rpi, opNOT,
|
||||
/// 01101000
|
||||
opSWAP_B, opSWAP_W, opNEGC, opNEG, opEXTU_B, opEXTU_W, opEXTS_B, opEXTS_W,
|
||||
/// 01110000
|
||||
opADD_i, opADD_i, opADD_i, opADD_i, opADD_i, opADD_i, opADD_i, opADD_i,
|
||||
/// 01111000
|
||||
opADD_i, opADD_i, opADD_i, opADD_i, opADD_i, opADD_i, opADD_i, opADD_i,
|
||||
/// 10000000
|
||||
opMOV_BW_dsp, opMOV_BW_dsp, opSETRC, opJSR_N, opMOV_BW_dsp, opMOV_BW_dsp, op86xx, op87xx,
|
||||
/// 10001000
|
||||
opCMP_EQi, opBT, opLDRC, opBF, opLDRS, opBT_S, opLDRE, opBF_S,
|
||||
/// 10010000
|
||||
opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc,
|
||||
/// 10011000
|
||||
opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc,
|
||||
/// 10100000
|
||||
opBRA, opBRA, opBRA, opBRA, opBRA, opBRA, opBRA, opBRA,
|
||||
/// 10101000
|
||||
opBRA, opBRA, opBRA, opBRA, opBRA, opBRA, opBRA, opBRA,
|
||||
/// 10110000
|
||||
opBSR, opBSR, opBSR, opBSR, opBSR, opBSR, opBSR, opBSR,
|
||||
/// 10111000
|
||||
opBSR, opBSR, opBSR, opBSR, opBSR, opBSR, opBSR, opBSR,
|
||||
/// 11000000
|
||||
opMOV_gbr, opMOV_gbr, opMOV_gbr, opTRAPA, opMOV_gbr, opMOV_gbr, opMOV_gbr, opMOVA,
|
||||
/// 11001000
|
||||
opTST_i, opAND_i, opXOR_i, opOR_i, opTST_B, opAND_B, opXOR_B, opOR_B,
|
||||
/// 11010000
|
||||
opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc,
|
||||
/// 11011000
|
||||
opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc, opMOV_pc,
|
||||
/// 11100000
|
||||
opMOV_i, opMOV_i, opMOV_i, opMOV_i, opMOV_i, opMOV_i, opMOV_i, opMOV_i,
|
||||
/// 11101000
|
||||
opMOV_i, opMOV_i, opMOV_i, opMOV_i, opMOV_i, opMOV_i, opMOV_i, opMOV_i,
|
||||
/// 11110000
|
||||
opFADD, opFSUB, opFMUL, opFDIV, opFCMP_EQ, opFCMP_GT, opfxx6, opfxx7,
|
||||
/// 11111000
|
||||
opfxx8, opfxx9, opfxxa, opfxxb, opFMOV, opfxxd, opFMAC, NULL,
|
||||
};
|
431
arch/SH/SHInstPrinter.c
Normal file
431
arch/SH/SHInstPrinter.c
Normal file
@ -0,0 +1,431 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Yoshinori Sato, 2022 */
|
||||
|
||||
#include <string.h>
|
||||
#include "SHInstPrinter.h"
|
||||
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const char* const s_reg_names[] = {
|
||||
"invalid",
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||
"r0_bank", "r1_bank", "r2_bank", "r3_bank",
|
||||
"r4_bank", "r5_bank", "r6_bank", "r7_bank",
|
||||
"fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
|
||||
"fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
|
||||
"dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
|
||||
"xd0", "xd2", "xd4", "xd6", "xd8", "xd10", "xd12", "xd14",
|
||||
"xf0", "xf1", "xf2", "xf3", "xf4", "xf5", "xf6", "xf7",
|
||||
"xf8", "xf9", "xf10", "xf11", "xf12", "xf13", "xf14", "xf15",
|
||||
"fv0", "fv4", "fv8", "fv12",
|
||||
"xmtrx",
|
||||
"pc", "pr", "mach", "macl",
|
||||
"sr", "gbr", "ssr", "spc", "sgr", "dbr", "vbr", "tbr",
|
||||
"rs", "re", "mod",
|
||||
"fpul", "fpscr",
|
||||
"x0", "x1", "y0", "y1", "a0", "a1", "a0g", "a1g", "m0", "m1",
|
||||
"dsr",
|
||||
"0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7",
|
||||
"0x8", "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf",
|
||||
};
|
||||
#endif
|
||||
|
||||
const char* SH_reg_name(csh handle, unsigned int reg)
|
||||
{
|
||||
#ifdef CAPSTONE_DIET
|
||||
return NULL;
|
||||
#else
|
||||
if (reg >= ARR_SIZE(s_reg_names)) {
|
||||
return NULL;
|
||||
}
|
||||
return s_reg_names[(int)reg];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void SH_get_insn_id(cs_struct* h, cs_insn* insn, unsigned int id)
|
||||
{
|
||||
insn->id = id; // These id's matches for sh
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const char* const s_insn_names[] = {
|
||||
"unknwon",
|
||||
"add", "add", "addc", "addv", "and",
|
||||
"band", "bandnot", "bclr",
|
||||
"bf", "bf/s", "bld", "bldnot", "bor", "bornot", "bra", "braf",
|
||||
"bset", "bsr", "bsrf", "bst", "bt", "bt/s", "bxor",
|
||||
"clips", "clipu",
|
||||
"clrdmxy",
|
||||
"clrmac", "clrs", "clrt",
|
||||
"cmp/eq", "cmp/ge", "cmp/gt", "cmp/hi", "cmp/hs", "cmp/pl",
|
||||
"cmp/pz", "cmp/str",
|
||||
"div0s", "div0u", "div1",
|
||||
"divs", "divu",
|
||||
"dmuls.l", "dmulu.l",
|
||||
"dt",
|
||||
"exts", "exts", "extu", "extu",
|
||||
"fabs", "fadd", "fcmp/eq", "fcmp/gt",
|
||||
"fcnvds", "fcnvsd", "fdiv",
|
||||
"fipr", "fldi0", "fldi1", "flds", "float",
|
||||
"fmac", "fmov", "fmul", "fneg", "fpchg",
|
||||
"frchg", "fsca", "fschg", "fsqrt", "fsrra",
|
||||
"fsts", "fsub", "ftrc", "ftrv",
|
||||
"icbi",
|
||||
"jmp", "jsr", "jsr/n",
|
||||
"ldbank",
|
||||
"ldc", "ldrc", "ldre", "ldrs", "lds",
|
||||
"ldtlb",
|
||||
"mac.l", "mac.w",
|
||||
"mov", "mova", "movca", "movco", "movi20", "movi20s",
|
||||
"movli", "movml", "movmu", "movrt", "movt", "movu", "movua",
|
||||
"mul.l", "mulr", "muls", "mulu",
|
||||
"neg", "negc",
|
||||
"nop",
|
||||
"not", "nott",
|
||||
"ocbi", "ocbp", "ocbwb",
|
||||
"or",
|
||||
"pref", "prefi",
|
||||
"resbank",
|
||||
"rotcl", "rotcr", "rotl", "rotr",
|
||||
"rte", "rts", "rts/n", "rtv/n",
|
||||
"setdmx", "setdmy", "setrc",
|
||||
"sets", "sett",
|
||||
"shad", "shal", "shar", "shld", "shll",
|
||||
"shll16", "shll2", "shll8",
|
||||
"shlr", "shlr16", "shlr2", "shlr8",
|
||||
"sleep",
|
||||
"stbank",
|
||||
"stc", "sts",
|
||||
"sub", "subc", "subv",
|
||||
"swap", "swap",
|
||||
"synco",
|
||||
"tas",
|
||||
"trapa",
|
||||
"tst",
|
||||
"xor",
|
||||
"xtrct",
|
||||
};
|
||||
#endif
|
||||
|
||||
const char* SH_insn_name(csh handle, unsigned int id)
|
||||
{
|
||||
#ifdef CAPSTONE_DIET
|
||||
return NULL;
|
||||
#else
|
||||
if (id >= ARR_SIZE(s_insn_names)) {
|
||||
return NULL;
|
||||
}
|
||||
return s_insn_names[id];
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
#endif
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static void print_dsp_double(SStream *O, sh_info *info, int xy)
|
||||
{
|
||||
char suffix_xy = 'x' + xy;
|
||||
int i;
|
||||
if (info->op.operands[xy].dsp.insn == SH_INS_DSP_NOP) {
|
||||
if ((info->op.operands[0].dsp.insn == SH_INS_DSP_NOP) &&
|
||||
(info->op.operands[1].dsp.insn == SH_INS_DSP_NOP)) {
|
||||
SStream_concat(O, "nop%c", suffix_xy);
|
||||
}
|
||||
} else {
|
||||
SStream_concat(O, "mov%c", suffix_xy);
|
||||
switch(info->op.operands[xy].dsp.size) {
|
||||
case 16:
|
||||
SStream_concat0(O, ".w ");
|
||||
break;
|
||||
case 32:
|
||||
SStream_concat0(O, ".l ");
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
switch(info->op.operands[xy].dsp.operand[i]) {
|
||||
case SH_OP_DSP_REG_IND:
|
||||
SStream_concat(O, "@%s", s_reg_names[info->op.operands[xy].dsp.r[i]]);
|
||||
break;
|
||||
case SH_OP_DSP_REG_POST:
|
||||
SStream_concat(O, "@%s+", s_reg_names[info->op.operands[xy].dsp.r[i]]);
|
||||
break;
|
||||
case SH_OP_DSP_REG_INDEX:
|
||||
SStream_concat(O, "@%s+%s", s_reg_names[info->op.operands[xy].dsp.r[i]], s_reg_names[SH_REG_R8 + xy]);
|
||||
break;
|
||||
case SH_OP_DSP_REG:
|
||||
SStream_concat(O, "%s", s_reg_names[info->op.operands[xy].dsp.r[i]]);
|
||||
break;
|
||||
}
|
||||
if (i == 0)
|
||||
SStream_concat0(O, ",");
|
||||
}
|
||||
}
|
||||
if (xy == 0)
|
||||
SStream_concat0(O, " ");
|
||||
}
|
||||
|
||||
static const char *s_dsp_insns[] = {
|
||||
"invalid",
|
||||
"nop",
|
||||
"mov",
|
||||
"pshl",
|
||||
"psha",
|
||||
"pmuls",
|
||||
"pclr_pmuls",
|
||||
"psub_pmuls",
|
||||
"padd_pmuls",
|
||||
"psubc",
|
||||
"paddc",
|
||||
"pcmp",
|
||||
"pabs",
|
||||
"prnd",
|
||||
"psub",
|
||||
"psub",
|
||||
"padd",
|
||||
"pand",
|
||||
"pxor",
|
||||
"por",
|
||||
"pdec",
|
||||
"pinc",
|
||||
"pclr",
|
||||
"pdmsb",
|
||||
"pneg",
|
||||
"pcopy",
|
||||
"psts",
|
||||
"plds",
|
||||
"pswap",
|
||||
"pwad",
|
||||
"pwsb",
|
||||
};
|
||||
|
||||
static void print_dsp(SStream *O, sh_info *info)
|
||||
{
|
||||
int i;
|
||||
switch(info->op.op_count) {
|
||||
case 1:
|
||||
// single transfer
|
||||
SStream_concat0(O, "movs");
|
||||
switch(info->op.operands[0].dsp.size) {
|
||||
case 16:
|
||||
SStream_concat0(O, ".w ");
|
||||
break;
|
||||
case 32:
|
||||
SStream_concat0(O, ".l ");
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
switch(info->op.operands[0].dsp.operand[i]) {
|
||||
case SH_OP_DSP_REG_PRE:
|
||||
SStream_concat(O, "@-%s", s_reg_names[info->op.operands[0].dsp.r[i]]);
|
||||
break;
|
||||
case SH_OP_DSP_REG_IND:
|
||||
SStream_concat(O, "@%s", s_reg_names[info->op.operands[0].dsp.r[i]]);
|
||||
break;
|
||||
case SH_OP_DSP_REG_POST:
|
||||
SStream_concat(O, "@%s+", s_reg_names[info->op.operands[0].dsp.r[i]]);
|
||||
break;
|
||||
case SH_OP_DSP_REG_INDEX:
|
||||
SStream_concat(O, "@%s+%s", s_reg_names[info->op.operands[0].dsp.r[i]],s_reg_names[SH_REG_R8]);
|
||||
break;
|
||||
case SH_OP_DSP_REG:
|
||||
SStream_concat(O, "%s", s_reg_names[info->op.operands[0].dsp.r[i]]);
|
||||
}
|
||||
if (i == 0)
|
||||
SStream_concat0(O, ",");
|
||||
}
|
||||
break;
|
||||
case 2: // Double transfer
|
||||
print_dsp_double(O, info, 0);
|
||||
print_dsp_double(O, info, 1);
|
||||
break;
|
||||
case 3: // Parallel
|
||||
switch(info->op.operands[2].dsp.cc) {
|
||||
case SH_DSP_CC_DCT:
|
||||
SStream_concat0(O,"dct ");
|
||||
break;
|
||||
case SH_DSP_CC_DCF:
|
||||
SStream_concat0(O,"dcf ");
|
||||
break;
|
||||
}
|
||||
switch(info->op.operands[2].dsp.insn) {
|
||||
case SH_INS_DSP_PSUB_PMULS:
|
||||
case SH_INS_DSP_PADD_PMULS:
|
||||
switch(info->op.operands[2].dsp.insn) {
|
||||
case SH_INS_DSP_PSUB_PMULS:
|
||||
SStream_concat0(O, "psub ");
|
||||
break;
|
||||
case SH_INS_DSP_PADD_PMULS:
|
||||
SStream_concat0(O, "padd ");
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 6; i++) {
|
||||
SStream_concat(O, "%s", s_reg_names[info->op.operands[2].dsp.r[i]]);
|
||||
if ((i % 3) < 2)
|
||||
SStream_concat0(O, ",");
|
||||
if (i == 2)
|
||||
SStream_concat(O, " %s ", s_dsp_insns[SH_INS_DSP_PMULS]);
|
||||
}
|
||||
break;
|
||||
case SH_INS_DSP_PCLR_PMULS:
|
||||
SStream_concat0(O, s_dsp_insns[SH_INS_DSP_PCLR]);
|
||||
SStream_concat(O, " %s ", s_reg_names[info->op.operands[2].dsp.r[3]]);
|
||||
SStream_concat(O, "%s ", s_dsp_insns[SH_INS_DSP_PMULS]);
|
||||
for (i = 0; i < 3; i++) {
|
||||
SStream_concat(O, "%s", s_reg_names[info->op.operands[2].dsp.r[i]]);
|
||||
if (i < 2)
|
||||
SStream_concat0(O, ",");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
SStream_concat0(O, s_dsp_insns[info->op.operands[2].dsp.insn]);
|
||||
SStream_concat0(O, " ");
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (info->op.operands[2].dsp.r[i] == SH_REG_INVALID) {
|
||||
if (i == 0) {
|
||||
SStream_concat(O, "#%d", info->op.operands[2].dsp.imm);
|
||||
}
|
||||
} else
|
||||
SStream_concat(O, "%s", s_reg_names[info->op.operands[2].dsp.r[i]]);
|
||||
if (i < 2 && info->op.operands[2].dsp.r[i + 1] != SH_REG_INVALID)
|
||||
SStream_concat0(O, ",");
|
||||
}
|
||||
}
|
||||
|
||||
if (info->op.operands[0].dsp.insn != SH_INS_DSP_NOP) {
|
||||
SStream_concat0(O, " ");
|
||||
print_dsp_double(O, info, 0);
|
||||
}
|
||||
if (info->op.operands[1].dsp.insn != SH_INS_DSP_NOP) {
|
||||
SStream_concat0(O, " ");
|
||||
print_dsp_double(O, info, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintMemop(SStream *O, sh_op_mem *op) {
|
||||
switch(op->address) {
|
||||
case SH_OP_MEM_INVALID:
|
||||
break;
|
||||
case SH_OP_MEM_REG_IND:
|
||||
SStream_concat(O, "@%s", s_reg_names[op->reg]);
|
||||
break;
|
||||
case SH_OP_MEM_REG_POST:
|
||||
SStream_concat(O, "@%s+", s_reg_names[op->reg]);
|
||||
break;
|
||||
case SH_OP_MEM_REG_PRE:
|
||||
SStream_concat(O, "@-%s", s_reg_names[op->reg]);
|
||||
break;
|
||||
case SH_OP_MEM_REG_DISP:
|
||||
SStream_concat(O, "@(%d,%s)", op->disp, s_reg_names[op->reg]);
|
||||
break;
|
||||
case SH_OP_MEM_REG_R0: /// <= R0 indexed
|
||||
SStream_concat(O, "@(%s,%s)",
|
||||
s_reg_names[SH_REG_R0], s_reg_names[op->reg]);
|
||||
break;
|
||||
case SH_OP_MEM_GBR_DISP: /// <= GBR based displaysment
|
||||
SStream_concat(O, "@(%d,%s)",
|
||||
op->disp, s_reg_names[SH_REG_GBR]);
|
||||
break;
|
||||
case SH_OP_MEM_GBR_R0: /// <= GBR based R0 indexed
|
||||
SStream_concat(O, "@(%s,%s)",
|
||||
s_reg_names[SH_REG_R0], s_reg_names[SH_REG_GBR]);
|
||||
break;
|
||||
case SH_OP_MEM_PCR: /// <= PC relative
|
||||
SStream_concat(O, "0x%x", op->disp);
|
||||
break;
|
||||
case SH_OP_MEM_TBR_DISP: /// <= GBR based displaysment
|
||||
SStream_concat(O, "@@(%d,%s)",
|
||||
op->disp, s_reg_names[SH_REG_TBR]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void SH_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
sh_info *info = (sh_info *)PrinterInfo;
|
||||
cs_detail *detail = MI->flat_insn->detail;
|
||||
int i;
|
||||
int imm;
|
||||
|
||||
if (MI->Opcode == SH_INS_DSP) {
|
||||
print_dsp(O, info);
|
||||
return;
|
||||
}
|
||||
|
||||
SStream_concat0(O, (char*)s_insn_names[MI->Opcode]);
|
||||
switch(info->op.size) {
|
||||
case 8:
|
||||
SStream_concat0(O, ".b");
|
||||
break;
|
||||
case 16:
|
||||
SStream_concat0(O, ".w");
|
||||
break;
|
||||
case 32:
|
||||
SStream_concat0(O, ".l");
|
||||
break;
|
||||
case 64:
|
||||
SStream_concat0(O, ".d");
|
||||
break;
|
||||
}
|
||||
SStream_concat0(O, " ");
|
||||
for (i = 0; i < info->op.op_count; i++) {
|
||||
switch(info->op.operands[i].type) {
|
||||
case SH_OP_INVALID:
|
||||
break;
|
||||
case SH_OP_REG:
|
||||
SStream_concat0(O, s_reg_names[info->op.operands[i].reg]);
|
||||
break;
|
||||
case SH_OP_IMM:
|
||||
imm = info->op.operands[i].imm;
|
||||
SStream_concat(O, "#%d", imm);
|
||||
break;
|
||||
case SH_OP_MEM:
|
||||
PrintMemop(O, &info->op.operands[i].mem);
|
||||
break;
|
||||
}
|
||||
if (i < (info->op.op_count - 1)) {
|
||||
SStream_concat0(O, ",");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const name_map group_name_maps[] = {
|
||||
{ SH_GRP_INVALID , NULL },
|
||||
{ SH_GRP_JUMP, "jump" },
|
||||
{ SH_GRP_CALL, "call" },
|
||||
{ SH_GRP_INT, "int" },
|
||||
{ SH_GRP_RET , "ret" },
|
||||
{ SH_GRP_IRET, "iret" },
|
||||
{ SH_GRP_PRIVILEGE, "privilege" },
|
||||
{ SH_GRP_BRANCH_RELATIVE, "branch_relative" },
|
||||
{ SH_GRP_SH2, "SH2" },
|
||||
{ SH_GRP_SH2E, "SH2E" },
|
||||
{ SH_GRP_SH2DSP, "SH2-DSP" },
|
||||
{ SH_GRP_SH2A, "SH2A" },
|
||||
{ SH_GRP_SH2AFPU, "SH2A-FPU" },
|
||||
{ SH_GRP_SH3, "SH3" },
|
||||
{ SH_GRP_SH3DSP, "SH3-DSP" },
|
||||
{ SH_GRP_SH4, "SH4" },
|
||||
{ SH_GRP_SH4A, "SH4A" },
|
||||
};
|
||||
#endif
|
||||
|
||||
const char *SH_group_name(csh handle, unsigned int id)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
return id2name(group_name_maps, ARR_SIZE(group_name_maps), id);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
23
arch/SH/SHInstPrinter.h
Normal file
23
arch/SH/SHInstPrinter.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Yoshinori Sato, 2022 */
|
||||
|
||||
#ifndef CS_SHINSTPRINTER_H
|
||||
#define CS_SHINSTPRINTER_H
|
||||
|
||||
|
||||
#include "capstone/capstone.h"
|
||||
#include "../../capstone/utils.h"
|
||||
#include "../../MCInst.h"
|
||||
#include "../../SStream.h"
|
||||
#include "../../cs_priv.h"
|
||||
#include "SHDisassembler.h"
|
||||
|
||||
struct SStream;
|
||||
|
||||
void SH_printInst(MCInst *MI, struct SStream *O, void *Info);
|
||||
const char* SH_reg_name(csh handle, unsigned int reg);
|
||||
void SH_get_insn_id(cs_struct* h, cs_insn* insn, unsigned int id);
|
||||
const char* SH_insn_name(csh handle, unsigned int id);
|
||||
const char *SH_group_name(csh handle, unsigned int id);
|
||||
|
||||
#endif
|
39
arch/SH/SHModule.c
Normal file
39
arch/SH/SHModule.c
Normal file
@ -0,0 +1,39 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Yoshinori Sato 2022 */
|
||||
|
||||
#ifdef CAPSTONE_HAS_SH
|
||||
|
||||
#include "../../cs_priv.h"
|
||||
#include "SHDisassembler.h"
|
||||
#include "SHInstPrinter.h"
|
||||
#include "SHModule.h"
|
||||
|
||||
cs_err SH_global_init(cs_struct *ud)
|
||||
{
|
||||
sh_info *info;
|
||||
|
||||
info = cs_mem_malloc(sizeof(sh_info));
|
||||
if (!info) {
|
||||
return CS_ERR_MEM;
|
||||
}
|
||||
|
||||
ud->printer = SH_printInst;
|
||||
ud->printer_info = info;
|
||||
ud->reg_name = SH_reg_name;
|
||||
ud->insn_id = SH_get_insn_id;
|
||||
ud->insn_name = SH_insn_name;
|
||||
ud->group_name = SH_group_name;
|
||||
ud->disasm = SH_getInstruction;
|
||||
#ifndef CAPSTONE_DIET
|
||||
ud->reg_access = SH_reg_access;
|
||||
#endif
|
||||
|
||||
return CS_ERR_OK;
|
||||
}
|
||||
|
||||
cs_err SH_option(cs_struct *handle, cs_opt_type type, size_t value)
|
||||
{
|
||||
return CS_ERR_OK;
|
||||
}
|
||||
|
||||
#endif
|
12
arch/SH/SHModule.h
Normal file
12
arch/SH/SHModule.h
Normal file
@ -0,0 +1,12 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Yoshinori Sato, 2022 */
|
||||
|
||||
#ifndef CS_SH_MODULE_H
|
||||
#define CS_SH_MODULE_H
|
||||
|
||||
#include "../../utils.h"
|
||||
|
||||
cs_err SH_global_init(cs_struct *ud);
|
||||
cs_err SH_option(cs_struct *handle, cs_opt_type type, size_t value);
|
||||
|
||||
#endif
|
390
arch/SH/mktable.rb
Normal file
390
arch/SH/mktable.rb
Normal file
@ -0,0 +1,390 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
out = Array.new(256, "NULL");
|
||||
code_list = <<EOF
|
||||
MOV_i #imm,Rn 1110nnnniiiiiiii
|
||||
MOV.W @(disp*,PC),Rn 1001nnnndddddddd
|
||||
MOV.L @(disp*,PC),Rn 1101nnnndddddddd
|
||||
MOV Rm,Rn 0110nnnnmmmm0011
|
||||
MOV.B Rm,@Rn 0010nnnnmmmm0000
|
||||
MOV.W Rm,@Rn 0010nnnnmmmm0001
|
||||
MOV.L Rm,@Rn 0010nnnnmmmm0010
|
||||
MOV.B @Rm,Rn 0110nnnnmmmm0000
|
||||
MOV.W @Rm,Rn 0110nnnnmmmm0001
|
||||
MOV.L @Rm,Rn 0110nnnnmmmm0010
|
||||
MOV.B Rm,@-Rn 0010nnnnmmmm0100
|
||||
MOV.W Rm,@-Rn 0010nnnnmmmm0101
|
||||
MOV.L Rm,@-Rn 0010nnnnmmmm0110
|
||||
MOV.B @Rm+,Rn 0110nnnnmmmm0100
|
||||
MOV.W @Rm+,Rn 0110nnnnmmmm0101
|
||||
MOV.L @Rm+,Rn 0110nnnnmmmm0110
|
||||
MOV.B R0,@(disp*,Rn) 10000000nnnndddd
|
||||
MOV.W R0,@(disp*,Rn) 10000001nnnndddd
|
||||
MOV.L Rm,@(disp*,Rn) 0001nnnnmmmmdddd
|
||||
MOV.B @(disp*,Rm),R0 10000100mmmmdddd
|
||||
MOV.W @(disp*,Rm),R0 10000101mmmmdddd
|
||||
MOV.L @(disp*,Rm),Rn 0101nnnnmmmmdddd
|
||||
MOV.B Rm,@(R0,Rn) 0000nnnnmmmm0100
|
||||
MOV.W Rm,@(R0,Rn) 0000nnnnmmmm0101
|
||||
MOV.L Rm,@(R0,Rn) 0000nnnnmmmm0110
|
||||
MOV.B @(R0,Rm),Rn 0000nnnnmmmm1100
|
||||
MOV.W @(R0,Rm),Rn 0000nnnnmmmm1101
|
||||
MOV.L @(R0,Rm),Rn 0000nnnnmmmm1110
|
||||
MOV.B R0,@(disp*,GBR) 11000000dddddddd
|
||||
MOV.W R0,@(disp*,GBR) 11000001dddddddd
|
||||
MOV.L R0,@(disp*,GBR) 11000010dddddddd
|
||||
MOV.B @(disp*,GBR),R0 11000100dddddddd
|
||||
MOV.W @(disp*,GBR),R0 11000101dddddddd
|
||||
MOV.L @(disp*,GBR),R0 11000110dddddddd
|
||||
MOVA @(disp*,PC),R0 11000111dddddddd
|
||||
MOVCO.L R0,@Rn 0000nnnn01110011
|
||||
MOVLI.L @Rm,R0 0000mmmm01100011
|
||||
MOVUA.L @Rm,R0 0100mmmm10101001
|
||||
MOVUA.L @Rm+,R0 0100mmmm11101001
|
||||
MOVT Rn 0000nnnn00101001
|
||||
SWAP.B Rm,Rn 0110nnnnmmmm1000
|
||||
SWAP.W Rm,Rn 0110nnnnmmmm1001
|
||||
XTRCT Rm,Rn 0010nnnnmmmm1101
|
||||
ADD_r Rm,Rn 0011nnnnmmmm1100
|
||||
ADD_i #imm,Rn 0111nnnniiiiiiii
|
||||
ADDC Rm,Rn 0011nnnnmmmm1110
|
||||
ADDV Rm,Rn 0011nnnnmmmm1111
|
||||
CMP/EQ #imm,R0 10001000iiiiiiii
|
||||
CMP/EQ Rm,Rn 0011nnnnmmmm0000
|
||||
CMP/HS Rm,Rn 0011nnnnmmmm0010
|
||||
CMP/GE Rm,Rn 0011nnnnmmmm0011
|
||||
CMP/HI Rm,Rn 0011nnnnmmmm0110
|
||||
CMP/GT Rm,Rn 0011nnnnmmmm0111
|
||||
CMP/PZ Rn 0100nnnn00010001
|
||||
CMP/PL Rn 0100nnnn00010101
|
||||
CMP/STR Rm,Rn 0010nnnnmmmm1100
|
||||
DIV1 Rm,Rn 0011nnnnmmmm0100
|
||||
DIV0S Rm,Rn 0010nnnnmmmm0111
|
||||
DIV0U 0000000000011001
|
||||
DMULS.L Rm,Rn 0011nnnnmmmm1101
|
||||
DMULU.L Rm,Rn 0011nnnnmmmm0101
|
||||
DT Rn 0100nnnn00010000
|
||||
EXTS.B Rm,Rn 0110nnnnmmmm1110
|
||||
EXTS.W Rm,Rn 0110nnnnmmmm1111
|
||||
EXTU.B Rm,Rn 0110nnnnmmmm1100
|
||||
EXTU.W Rm,Rn 0110nnnnmmmm1101
|
||||
MAC.L @Rm+,@Rn+ 0000nnnnmmmm1111
|
||||
MAC.W @Rm+,@Rn+ 0100nnnnmmmm1111
|
||||
MUL.L Rm,Rn 0000nnnnmmmm0111
|
||||
MULS.W Rm,Rn 0010nnnnmmmm1111
|
||||
MULU.W Rm,Rn 0010nnnnmmmm1110
|
||||
NEG Rm,Rn 0110nnnnmmmm1011
|
||||
NEGC Rm,Rn 0110nnnnmmmm1010
|
||||
SUB Rm,Rn 0011nnnnmmmm1000
|
||||
SUBC Rm,Rn 0011nnnnmmmm1010
|
||||
SUBV Rm,Rn 0011nnnnmmmm1011
|
||||
AND Rm,Rn 0010nnnnmmmm1001
|
||||
AND_i #imm,R0 11001001iiiiiiii
|
||||
AND.B #imm,@(R0,GBR) 11001101iiiiiiii
|
||||
NOT Rm,Rn 0110nnnnmmmm0111
|
||||
OR Rm,Rn 0010nnnnmmmm1011
|
||||
OR_i #imm,R0 11001011iiiiiiii
|
||||
OR.B #imm,@(R0,GBR) 11001111iiiiiiii
|
||||
TAS.B @Rn 0100nnnn00011011
|
||||
TST Rm,Rn 0010nnnnmmmm1000
|
||||
TST_i #imm,R0 11001000iiiiiiii
|
||||
TST.B #imm,@(R0,GBR) 11001100iiiiiiii
|
||||
XOR Rm,Rn 0010nnnnmmmm1010
|
||||
XOR_i #imm,R0 11001010iiiiiiii
|
||||
XOR.B #imm,@(R0,GBR) 11001110iiiiiiii
|
||||
ROTL Rn 0100nnnn00000100
|
||||
ROTR Rn 0100nnnn00000101
|
||||
ROTCL Rn 0100nnnn00100100
|
||||
ROTCR Rn 0100nnnn00100101
|
||||
SHAD Rm,Rn 0100nnnnmmmm1100
|
||||
SHAL Rn 0100nnnn00100000
|
||||
SHAR Rn 0100nnnn00100001
|
||||
SHLD Rm,Rn 0100nnnnmmmm1101
|
||||
SHLL Rn 0100nnnn00000000
|
||||
SHLR Rn 0100nnnn00000001
|
||||
SHLL2 Rn 0100nnnn00001000
|
||||
SHLR2 Rn 0100nnnn00001001
|
||||
SHLL8 Rn 0100nnnn00011000
|
||||
SHLR8 Rn 0100nnnn00011001
|
||||
SHLL16 Rn 0100nnnn00101000
|
||||
SHLR16 Rn 0100nnnn00101001
|
||||
BF label 10001011dddddddd
|
||||
BF/S label 10001111dddddddd
|
||||
BT label 10001001dddddddd
|
||||
BT/S label 10001101dddddddd
|
||||
BRA label 1010dddddddddddd
|
||||
BRAF Rn 0000nnnn00100011
|
||||
BSR label 1011dddddddddddd
|
||||
BSRF Rn 0000nnnn00000011
|
||||
JMP @Rn 0100nnnn00101011
|
||||
JSR @Rn 0100nnnn00001011
|
||||
RTS 0000000000001011
|
||||
CLRMAC 0000000000101000
|
||||
CLRS 0000000001001000
|
||||
CLRT 0000000000001000
|
||||
ICBI @Rn 0000nnnn11100011
|
||||
LDC Rm,SR 0100mmmm00001110
|
||||
LDC Rm,GBR 0100mmmm00011110
|
||||
LDC Rm,VBR 0100mmmm00101110
|
||||
LDC Rm,SGR 0100mmmm00111010
|
||||
LDC Rm,SSR 0100mmmm00111110
|
||||
LDC Rm,SPC 0100mmmm01001110
|
||||
LDC Rm,DBR 0100mmmm11111010
|
||||
LDC Rm,Rn_BANK 0100mmmm1nnn1110
|
||||
LDC.L @Rm+,SR 0100mmmm00000111
|
||||
LDC.L @Rm+,GBR 0100mmmm00010111
|
||||
LDC.L @Rm+,VBR 0100mmmm00100111
|
||||
LDC.L @Rm+,SGR 0100mmmm00110110
|
||||
LDC.L @Rm+,SSR 0100mmmm00110111
|
||||
LDC.L @Rm+,SPC 0100mmmm01000111
|
||||
LDC.L @Rm+,DBR 0100mmmm11110110
|
||||
LDC.L @Rm+,Rn_BANK 0100mmmm1nnn0111
|
||||
LDS Rm,MACH 0100mmmm00001010
|
||||
LDS Rm,MACL 0100mmmm00011010
|
||||
LDS Rm,PR 0100mmmm00101010
|
||||
LDS.L @Rm+,MACH 0100mmmm00000110
|
||||
LDS.L @Rm+,MACL 0100mmmm00010110
|
||||
LDS.L @Rm+,PR 0100mmmm00100110
|
||||
LDTLB 0000000000111000
|
||||
MOVCA.L R0,@Rn 0000nnnn11000011
|
||||
NOP 0000000000001001
|
||||
OCBI @Rn 0000nnnn10010011
|
||||
OCBP @Rn 0000nnnn10100011
|
||||
OCBWB @Rn 0000nnnn10110011
|
||||
PREF @Rn 0000nnnn10000011
|
||||
PREFI @Rn 0000nnnn11010011
|
||||
RTE 0000000000101011
|
||||
SETS 0000000001011000
|
||||
SETT 0000000000011000
|
||||
SLEEP 0000000000011011
|
||||
STC SR,Rn 0000nnnn00000010
|
||||
STC GBR,Rn 0000nnnn00010010
|
||||
STC VBR,Rn 0000nnnn00100010
|
||||
STC SSR,Rn 0000nnnn00110010
|
||||
STC SPC,Rn 0000nnnn01000010
|
||||
STC SGR,Rn 0000nnnn00111010
|
||||
STC DBR,Rn 0000nnnn11111010
|
||||
STC Rm_BANK,Rn 0000nnnn1mmm0010
|
||||
STC.L SR,@-Rn 0100nnnn00000011
|
||||
STC.L GBR,@-Rn 0100nnnn00010011
|
||||
STC.L VBR,@-Rn 0100nnnn00100011
|
||||
STC.L SSR,@-Rn 0100nnnn00110011
|
||||
STC.L SPC,@-Rn 0100nnnn01000011
|
||||
STC.L SGR,@-Rn 0100nnnn00110010
|
||||
STC.L DBR,@-Rn 0100nnnn11110010
|
||||
STC.L Rm_BANK,@-Rn 0100nnnn1mmm0011
|
||||
STS MACH,Rn 0000nnnn00001010
|
||||
STS MACL,Rn 0000nnnn00011010
|
||||
STS PR,Rn 0000nnnn00101010
|
||||
STS.L MACH,@-Rn 0100nnnn00000010
|
||||
STS.L MACL,@-Rn 0100nnnn00010010
|
||||
STS.L PR,@-Rn 0100nnnn00100010
|
||||
SYNCO 0000000010101011
|
||||
TRAPA #imm 11000011iiiiiiii
|
||||
FLDI0 FRn 1111nnnn10001101
|
||||
FLDI1 FRn 1111nnnn10011101
|
||||
FMOV FRm,FRn 1111nnnnmmmm1100
|
||||
FMOV.S @Rm,FRn 1111nnnnmmmm1000
|
||||
FMOV.S @(R0,Rm),FRn 1111nnnnmmmm0110
|
||||
FMOV.S @Rm+,FRn 1111nnnnmmmm1001
|
||||
FMOV.S FRm,@Rn 1111nnnnmmmm1010
|
||||
FMOV.S FRm,@-Rn 1111nnnnmmmm1011
|
||||
FMOV.S FRm,@(R0,Rn) 1111nnnnmmmm0111
|
||||
FMOV DRm,DRn 1111nnn0mmm01100
|
||||
FMOV @Rm,DRn 1111nnn0mmmm1000
|
||||
FMOV @(R0,Rm),DRn 1111nnn0mmmm0110
|
||||
FMOV @Rm+,DRn 1111nnn0mmmm1001
|
||||
FMOV DRm,@Rn 1111nnnnmmm01010
|
||||
FMOV DRm,@-Rn 1111nnnnmmm01011
|
||||
FMOV DRm,@(R0,Rn) 1111nnnnmmm00111
|
||||
FLDS FRm,FPUL 1111mmmm00011101
|
||||
FSTS FPUL,FRn 1111nnnn00001101
|
||||
FABS FRn 1111nnnn01011101
|
||||
FADD FRm,FRn 1111nnnnmmmm0000
|
||||
FCMP/EQ FRm,FRn 1111nnnnmmmm0100
|
||||
FCMP/GT FRm,FRn 1111nnnnmmmm0101
|
||||
FDIV FRm,FRn 1111nnnnmmmm0011
|
||||
FLOAT FPUL,FRn 1111nnnn00101101
|
||||
FMAC FR0,FRm,FRn 1111nnnnmmmm1110
|
||||
FMUL FRm,FRn 1111nnnnmmmm0010
|
||||
FNEG FRn 1111nnnn01001101
|
||||
FSQRT FRn 1111nnnn01101101
|
||||
FSUB FRm,FRn 1111nnnnmmmm0001
|
||||
FTRC FRm,FPUL 1111mmmm00111101
|
||||
FABS DRn 1111nnn001011101
|
||||
FADD DRm,DRn 1111nnn0mmm00000
|
||||
FCMP/EQ DRm,DRn 1111nnn0mmm00100
|
||||
FCMP/GT DRm,DRn 1111nnn0mmm00101
|
||||
FDIV DRm,DRn 1111nnn0mmm00011
|
||||
FCNVDS DRm,FPUL 1111mmm010111101
|
||||
FCNVSD FPUL,DRn 1111nnn010101101
|
||||
FLOAT FPUL,DRn 1111nnn000101101
|
||||
FMUL DRm,DRn 1111nnn0mmm00010
|
||||
FNEG DRn 1111nnn001001101
|
||||
FSQRT DRn 1111nnn001101101
|
||||
FSUB DRm,DRn 1111nnn0mmm00001
|
||||
FTRC DRm,FPUL 1111mmm000111101
|
||||
LDS Rm,FPSCR 0100mmmm01101010
|
||||
LDS Rm,FPUL 0100mmmm01011010
|
||||
LDS.L @Rm+,FPSCR 0100mmmm01100110
|
||||
LDS.L @Rm+,FPUL 0100mmmm01010110
|
||||
STS FPSCR,Rn 0000nnnn01101010
|
||||
STS FPUL,Rn 0000nnnn01011010
|
||||
STS.L FPSCR,@-Rn 0100nnnn01100010
|
||||
STS.L FPUL,@-Rn 0100nnnn01010010
|
||||
FMOV DRm,XDn 1111nnn1mmm01100
|
||||
FMOV XDm,DRn 1111nnn0mmm11100
|
||||
FMOV XDm,XDn 1111nnn1mmm11100
|
||||
FMOV @Rm,XDn 1111nnn1mmmm1000
|
||||
FMOV @Rm+,XDn 1111nnn1mmmm1001
|
||||
FMOV @(R0,Rm),XDn 1111nnn1mmmm0110
|
||||
FMOV XDm,@Rn 1111nnnnmmm11010
|
||||
FMOV XDm,@-Rn 1111nnnnmmm11011
|
||||
FMOV XDm,@(R0,Rn) 1111nnnnmmm10111
|
||||
FIPR FVm,FVn 1111nnmm11101101
|
||||
FTRV XMTRX,FVn 1111nn0111111101
|
||||
FRCHG 1111101111111101
|
||||
FSCHG 1111001111111101
|
||||
FPCHG 1111011111111101
|
||||
FSRRA FRn 1111nnnn01111101
|
||||
FSCA FPUL,DRn 1111nnn011111101
|
||||
MOV.B R0,@Rn+ 0100nnnn10001011
|
||||
MOV.W R0,@Rn+ 0100nnnn10011011
|
||||
MOV.L R0,@Rn+ 0100nnnn10101011
|
||||
MOV.B @-Rm,R0 0100mmmm11001011
|
||||
MOV.W @-Rm,R0 0100mmmm11011011
|
||||
MOV.L @-Rm,R0 0100mmmm11101011
|
||||
MOV.B Rm,@(disp12,Rn) 0011nnnnmmmm00010000dddddddddddd
|
||||
MOV.W Rm,@(disp12,Rn) 0011nnnnmmmm00010001dddddddddddd
|
||||
MOV.L Rm,@(disp12,Rn) 0011nnnnmmmm00010010dddddddddddd
|
||||
MOV.B @(disp12,Rm),Rn 0011nnnnmmmm00010100dddddddddddd
|
||||
MOV.W @(disp12,Rm),Rn 0011nnnnmmmm00010101dddddddddddd
|
||||
MOV.L @(disp12,Rm),Rn 0011nnnnmmmm00010110dddddddddddd
|
||||
MOVI20 #imm20,Rn 0000nnnniiii0000iiiiiiiiiiiiiiii
|
||||
MOVI20S #imm20,Rn 0000nnnniiii0001iiiiiiiiiiiiiiii
|
||||
MOVML.L Rm,@-R15 0100mmmm11110001
|
||||
MOVML.L @R15+,Rn 0100nnnn11110101
|
||||
MOVMU.L Rm,@-R15 0100mmmm11110000
|
||||
MOVMU.L @R15+,Rn 0100nnnn11110100
|
||||
MOVRT Rn 0000nnnn00111001
|
||||
MOVU.B @(disp12,Rm),Rn 0011nnnnmmmm00011000dddddddddddd
|
||||
MOVU.W @(disp12,Rm),Rn 0011nnnnmmmm00011001dddddddddddd
|
||||
NOTT 0000000001101000
|
||||
CLIPS.B Rn 0100nnnn10010001
|
||||
CLIPS.W Rn 0100nnnn10010101
|
||||
CLIPU.B Rn 0100nnnn10000001
|
||||
CLIPU.W Rn 0100nnnn10000101
|
||||
DIVS R0,Rn 0100nnnn10010100
|
||||
DIVU R0,Rn 0100nnnn10000100
|
||||
MULR R0,Rn 0100nnnn10000000
|
||||
JSR/N @Rm 0100mmmm01001011
|
||||
JSR/N @@(disp8,TBR) 10000011dddddddd
|
||||
RTS/N 0000000001101011
|
||||
RTV/N Rm 0000mmmm01111011
|
||||
LDBANK @Rm,R0 0100mmmm11100101
|
||||
LDC Rm,TBR 0100mmmm01001010
|
||||
RESBANK 0000000001011011
|
||||
STBANK R0,@Rn 0100nnnn11100001
|
||||
STC TBR,Rn 0000nnnn01001010
|
||||
FMOV.S @(disp12,Rm),FRn 0011nnnnmmmm00010111dddddddddddd
|
||||
FMOV.D @(disp12,Rm),DRn 0011nnn0mmmm00010111dddddddddddd
|
||||
FMOV.S FRm,@(disp12,Rn) 0011nnnnmmmm00010011dddddddddddd
|
||||
FMOV.D DRm,@(disp12,Rn) 0011nnnnmmm000010011dddddddddddd
|
||||
FMOV.S FRm,@(disp12,Rn) 0011nnnnmmmm00010011dddddddddddd
|
||||
FMOV.D DRm,@(disp12,Rn) 0011nnnnmmm000010011dddddddddddd
|
||||
BAND.B #imm3,@(disp12,Rn) 0011nnnn0iii10010100dddddddddddd
|
||||
BANDNOT.B #imm3,@(disp12,Rn) 0011nnnn0iii10011100dddddddddddd
|
||||
BCLR.B #imm3,@(disp12,Rn) 0011nnnn0iii10010000dddddddddddd
|
||||
BCLR #imm3,Rn 10000110nnnn0iii
|
||||
BLD.B #imm3,@(disp12,Rn) 0011nnnn0iii10010011dddddddddddd
|
||||
BLD #imm3,Rn 10000111nnnn1iii
|
||||
BLDNOT.B #imm3,@(disp12,Rn) 0011nnnn0iii10011011dddddddddddd
|
||||
BOR.B #imm3,@(disp12,Rn) 0011nnnn0iii10010101dddddddddddd
|
||||
BORNOT.B #imm3,@(disp12,Rn) 0011nnnn0iii10011101dddddddddddd
|
||||
BSET.B #imm3,@(disp12,Rn) 0011nnnn0iii10010001dddddddddddd
|
||||
BSET #imm3,Rn 10000110nnnn1iii
|
||||
BST.B #imm3,@(disp12,Rn) 0011nnnn0iii10010010dddddddddddd
|
||||
BST #imm3,Rn 10000111nnnn0iii
|
||||
BXOR.B #imm3,@(disp12,Rn) 0011nnnn0iii10010110dddddddddddd
|
||||
LDRE @(disp,PC) 10001110dddddddd
|
||||
LDRS @(disp,PC) 10001100dddddddd
|
||||
SETRC Rm 0100mmmm00010100
|
||||
SETRC #imm 10000010iiiiiiii
|
||||
LDRC #imm 10001010iiiiiiii
|
||||
EOF
|
||||
|
||||
code_list.each_line { |line|
|
||||
l = line.split
|
||||
l[2] = l[1] if (l.length < 3)
|
||||
if l[2].length > 16 then
|
||||
l[2] = l[2][0..15]
|
||||
end
|
||||
if l[2][0..3].to_i(2) < 8 || l[2][0..3].to_i(2) == 15 then
|
||||
b = l[2][0..3] + l[2][12..15]
|
||||
else
|
||||
b = l[2][0..7]
|
||||
end
|
||||
if b =~ /^\d+$/ then
|
||||
no = b.to_i(2)
|
||||
if no == 0x00 || no == 0x01 || no == 0x31 || no == 0x39 then
|
||||
# SH2A 32bit instructions prefix
|
||||
next
|
||||
end
|
||||
next if out[no] == "op" + l[0]
|
||||
if (no >= 0x20 && no <= 0x22) || (no >= 0x60 && no <= 0x62)then
|
||||
l[0] = "MOV_rind"
|
||||
end
|
||||
if no >= 0x24 && no <= 0x26 then
|
||||
l[0] = "MOV_rpd"
|
||||
end
|
||||
if no >= 0x64 && no <= 0x66 then
|
||||
l[0] = "MOV_rpi"
|
||||
end
|
||||
if no == 0x80 || no == 0x81 || no == 0x84 || no == 0x85 then
|
||||
l[0] = "MOV_BW_dsp"
|
||||
end
|
||||
if no == 0x88 then
|
||||
l[0] = "CMP_EQi"
|
||||
end
|
||||
if no == 0xc0 || no == 0xc1 || no == 0xc2 || no == 0xc4 || no == 0xc5 || no == 0xc6 then
|
||||
l[0] = "MOV_gbr"
|
||||
end
|
||||
if out[no] == "NULL" then
|
||||
out[no] = "op" + l[0]
|
||||
else
|
||||
hi = b.to_i(2) / 16
|
||||
lo = b.to_i(2) % 16
|
||||
if (hi < 0x8) || (hi >= 0x0f) then
|
||||
out[no] = "op" + hi.to_s(16) + "xx" + lo.to_s(16)
|
||||
else
|
||||
out[no] = "op" + hi.to_s(16) + lo.to_s(16) + "xx"
|
||||
end
|
||||
end
|
||||
else
|
||||
n = (l[2][0..3].to_i(2)) * 16
|
||||
if n != 0x80 && n != 0xc0 then
|
||||
if n == 0x10 || n == 0x50 then
|
||||
l[0] = "MOV_L_dsp"
|
||||
end
|
||||
if n == 0x90 || n == 0xd0 then
|
||||
l[0] = "MOV_pc"
|
||||
end
|
||||
16.times { |i|
|
||||
out[n + i] = "op" + l[0]
|
||||
}
|
||||
end
|
||||
end
|
||||
}
|
||||
code = 0
|
||||
print "bool (*decode[])(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode, sh_info *info, cs_detail *detail) = {\n"
|
||||
(256 / 8).times { |i|
|
||||
bit = "0000000" + code.to_s(2)
|
||||
print "\t/// ", bit[-8,8], "\n\t"
|
||||
8.times { |j|
|
||||
o = out[i * 8 + j].gsub(/[\.\/]/, '_')
|
||||
print o, ", "
|
||||
code = code.succ
|
||||
}
|
||||
print "\n"
|
||||
}
|
||||
print "};\n"
|
Loading…
Reference in New Issue
Block a user