Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 41 additions & 20 deletions arch/SH/SHDisassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "../../MCDisassembler.h"
#include "../../utils.h"
#include "SHDisassembler.h"
#include "capstone/sh.h"

#define regs_read(_detail, _reg) \
if (_detail) \
Expand Down Expand Up @@ -131,13 +132,13 @@ static int isalevel(cs_mode mode)
}

enum co_processor {none, shfpu, shdsp};
union reg_insn {
typedef union reg_insn {
sh_reg reg;
sh_insn insn;
};
} reg_insn;
struct ri_list {
int no;
union reg_insn ri;
int /* reg_insn */ri;
int level;
enum co_processor cp;
};
Expand All @@ -162,12 +163,31 @@ static const struct ri_list ldc_stc_regs[] = {
{-1, SH_REG_INVALID, ISA_ALL, none},
};

enum lookup_type {reg, insn};
static union reg_insn lookup(enum lookup_type ri, const struct ri_list *list,
static sh_insn lookup_insn(const struct ri_list *list,
int no, cs_mode mode)
{
int level = isalevel(mode);
sh_insn error = SH_INS_INVALID;
for(; list->no >= 0; list++) {
if (no != list->no)
continue;
if (((level >= 0) && (level < list->level)) ||
((level < 0) && (-(level) != list->level)))
continue;
if ((list->cp == none) ||
((list->cp == shfpu) && (mode & CS_MODE_SHFPU)) ||
((list->cp == shdsp) && (mode & CS_MODE_SHDSP))) {
return list->ri;
}
}
return error;
}

static sh_reg lookup_regs(const struct ri_list *list,
int no, cs_mode mode)
{
int level = isalevel(mode);
union reg_insn error = {SH_REG_INVALID};
sh_reg error = SH_REG_INVALID;
for(; list->no >= 0; list++) {
if (no != list->no)
continue;
Expand All @@ -183,8 +203,8 @@ static union reg_insn lookup(enum lookup_type ri, const struct ri_list *list,
return error;
}

#define lookup_regs(list, no, mode) (lookup(reg, list, no, mode).reg)
#define lookup_insn(list, no, mode) (lookup(insn, list, no, mode).insn)
// #define lookup_regs(list, no, mode) ((reg_insn)(lookup(reg, list, no, mode).reg))
// #define lookup_insn(list, no, mode) ((sh_insn)(lookup(insn, list, no, mode).insn))

static sh_reg opSTCsrc(uint16_t code, MCInst *MI, cs_mode mode,
sh_info *info, cs_detail *detail)
Expand Down Expand Up @@ -1741,15 +1761,15 @@ static void set_reg_dsp_write_z(sh_info *info, int pos, int r,
regs_write(detail, regs_dz[r]);
}

static bool dsp_op_cc_3opr(uint32_t code, sh_info *info, sh_insn insn,
sh_insn insn2, cs_detail *detail)
static bool dsp_op_cc_3opr(uint32_t code, sh_info *info, sh_dsp_insn insn,
sh_dsp_insn_type insn2, cs_detail *detail)
{
info->op.operands[2].dsp.cc = (code >> 8) & 3;
if (info->op.operands[2].dsp.cc > 0) {
info->op.operands[2].dsp.insn = insn;
} else {
if (insn2 != SH_INS_DSP_INVALID)
info->op.operands[2].dsp.insn = insn2;
info->op.operands[2].dsp.insn = (sh_dsp_insn) insn2;
else
return MCDisassembler_Fail;
}
Expand All @@ -1765,23 +1785,23 @@ static bool dsp_op_cc_3opr(uint32_t code, sh_info *info, sh_insn insn,
return MCDisassembler_Success;
}

static bool dsp_op_cc_2opr(uint32_t code, sh_info *info, sh_insn insn,
static bool dsp_op_cc_2opr(uint32_t code, sh_info *info, sh_dsp_insn insn,
int xy, int b, cs_detail *detail)
{
if (((code >> 8) & 3) == 0)
return MCDisassembler_Fail;
info->op.operands[2].dsp.insn = insn;
info->op.operands[2].dsp.insn = (sh_dsp_insn) insn;
set_reg_dsp_read(info, 0, xy, (code >> b) & 3, detail);
set_reg_dsp_write_z(info, 2, code & 0x0f, detail);
info->op.operands[2].dsp.cc = (code >> 8) & 3;
info->op.op_count = 3;
return MCDisassembler_Success;
}

static bool dsp_op_cc0_2opr(uint32_t code, sh_info *info, sh_insn insn,
static bool dsp_op_cc0_2opr(uint32_t code, sh_info *info, sh_dsp_insn insn,
int xy, int b, cs_detail *detail)
{
info->op.operands[2].dsp.insn = insn;
info->op.operands[2].dsp.insn = (sh_dsp_insn) insn;
set_reg_dsp_read(info, 0, xy, (code >> b) & 3, detail);
set_reg_dsp_write_z(info, 2, code & 0x0f, detail);
info->op.operands[2].dsp.cc = (code >> 8) & 3;
Expand Down Expand Up @@ -1894,11 +1914,11 @@ static bool decode_dsp_3op(const uint32_t code, sh_info *info,
}
case 0x08:
return dsp_op_cc_3opr(code, info,
SH_INS_DSP_PSUB, SH_INS_DSP_PSUBC,
SH_INS_DSP_PSUB, (sh_dsp_insn_type) SH_INS_DSP_PSUBC,
detail);
case 0x09:
return dsp_op_cc_3opr(code, info,
SH_INS_DSP_PXOR, SH_INS_DSP_PWSB,
SH_INS_DSP_PXOR, (sh_dsp_insn_type) SH_INS_DSP_PWSB,
detail);
case 0x0a:
switch(sx) {
Expand Down Expand Up @@ -1937,13 +1957,14 @@ static bool decode_dsp_3op(const uint32_t code, sh_info *info,
}
case 0x0d:
return dsp_op_cc_3opr(code, info,
SH_INS_DSP_POR, SH_INS_DSP_PWAD,
detail);
SH_INS_DSP_POR,
(sh_dsp_insn_type) SH_INS_DSP_PWAD,
detail);
case 0x0e:
if (cc == 0) {
if (sx != 0)
return MCDisassembler_Fail;
info->op.operands[2].dsp.insn = SH_INS_DSP_PRND;
info->op.operands[2].dsp.insn = SH_INS_DSP_PRND;
set_reg_dsp_read(info, 0, f_sy, sy, detail);
set_reg_dsp_write_z(info, 1, dz, detail);
info->op.op_count = 3;
Expand Down