mirror of
https://github.com/capstone-engine/capstone.git
synced 2025-01-19 04:33:01 +00:00
xcore: handle details for some special tricky instructions
This commit is contained in:
parent
8c1c36f0fc
commit
be2b788dc1
@ -434,6 +434,8 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
|
||||
default: // unreachable.
|
||||
case 0:
|
||||
// DBG_VALUE, BUNDLE, LIFETIME_START, LIFETIME_END, CLRE_0R, DCALL_0R, DE...
|
||||
// already done. this means we have to extract details out ourself.
|
||||
XCore_insn_extract(MI, AsmStrs+(Bits & 2047)-1);
|
||||
return;
|
||||
break;
|
||||
case 1:
|
||||
@ -495,35 +497,35 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
|
||||
case 7:
|
||||
// INITCP_2r
|
||||
SStream_concat(O, "%s", "]:cp, ");
|
||||
set_mem_access(MI, false, 0);
|
||||
set_mem_access(MI, false, XCORE_REG_CP);
|
||||
printOperand(MI, 0, O);
|
||||
return;
|
||||
break;
|
||||
case 8:
|
||||
// INITDP_2r
|
||||
SStream_concat(O, "%s", "]:dp, ");
|
||||
set_mem_access(MI, false, 0);
|
||||
set_mem_access(MI, false, XCORE_REG_DP);
|
||||
printOperand(MI, 0, O);
|
||||
return;
|
||||
break;
|
||||
case 9:
|
||||
// INITLR_l2r
|
||||
SStream_concat(O, "%s", "]:lr, ");
|
||||
set_mem_access(MI, false, 0);
|
||||
set_mem_access(MI, false, XCORE_REG_LR);
|
||||
printOperand(MI, 0, O);
|
||||
return;
|
||||
break;
|
||||
case 10:
|
||||
// INITPC_2r
|
||||
SStream_concat(O, "%s", "]:pc, ");
|
||||
set_mem_access(MI, false, 0);
|
||||
set_mem_access(MI, false, XCORE_REG_PC);
|
||||
printOperand(MI, 0, O);
|
||||
return;
|
||||
break;
|
||||
case 11:
|
||||
// INITSP_2r
|
||||
SStream_concat(O, "%s", "]:sp, ");
|
||||
set_mem_access(MI, false, 0);
|
||||
set_mem_access(MI, false, XCORE_REG_SP);
|
||||
printOperand(MI, 0, O);
|
||||
return;
|
||||
break;
|
||||
|
@ -39,6 +39,94 @@ void XCore_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
|
||||
*/
|
||||
}
|
||||
|
||||
// stw sed, sp[3]
|
||||
void XCore_insn_extract(MCInst *MI, char *code)
|
||||
{
|
||||
int id;
|
||||
char *p, *p2;
|
||||
char tmp[128];
|
||||
|
||||
// find the first space
|
||||
strcpy(tmp, code);
|
||||
p = strchr(tmp, ' ');
|
||||
if (p) {
|
||||
p++;
|
||||
// find the next ','
|
||||
p2 = strchr(p, ',');
|
||||
if (p2) {
|
||||
*p2 = '\0';
|
||||
id = XCore_reg_id(p);
|
||||
if (id) {
|
||||
// register
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].type = XCORE_OP_REG;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].reg = id;
|
||||
MI->flat_insn.xcore.op_count++;
|
||||
}
|
||||
// next should be register, or memory?
|
||||
// skip space
|
||||
p2++;
|
||||
while(*p2 && *p2 == ' ')
|
||||
p2++;
|
||||
if (*p2) {
|
||||
// find '['
|
||||
p = p2;
|
||||
while(*p && *p != '[')
|
||||
p++;
|
||||
if (*p) {
|
||||
// this is '['
|
||||
*p = '\0';
|
||||
id = XCore_reg_id(p2);
|
||||
if (id) {
|
||||
// base register
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].type = XCORE_OP_MEM;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.base = id;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.index = XCORE_REG_INVALID;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.disp = 0;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.direct = 1;
|
||||
|
||||
p++;
|
||||
p2 = p;
|
||||
// until ']'
|
||||
while(*p && *p != ']')
|
||||
p++;
|
||||
if (*p) {
|
||||
*p = '\0';
|
||||
// p2 is either index, or disp
|
||||
id = XCore_reg_id(p2);
|
||||
if (id) {
|
||||
// index register
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.index = id;
|
||||
} else {
|
||||
// a number means disp
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.disp = atoi(p2);
|
||||
}
|
||||
}
|
||||
|
||||
MI->flat_insn.xcore.op_count++;
|
||||
}
|
||||
} else {
|
||||
// a register?
|
||||
id = XCore_reg_id(p2);
|
||||
if (id) {
|
||||
// register
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].type = XCORE_OP_REG;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].reg = id;
|
||||
MI->flat_insn.xcore.op_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
id = XCore_reg_id(p);
|
||||
if (id) {
|
||||
// register
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].type = XCORE_OP_REG;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].reg = id;
|
||||
MI->flat_insn.xcore.op_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_mem_access(MCInst *MI, bool status, int reg)
|
||||
{
|
||||
if (MI->csh->detail != CS_OPT_ON)
|
||||
@ -69,6 +157,9 @@ static void set_mem_access(MCInst *MI, bool status, int reg)
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.direct = -1;
|
||||
}
|
||||
} else {
|
||||
if (reg) {
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.index = reg;
|
||||
}
|
||||
// done, create the next operand slot
|
||||
MI->flat_insn.xcore.op_count++;
|
||||
}
|
||||
|
@ -12,4 +12,7 @@ void XCore_printInst(MCInst *MI, SStream *O, void *Info);
|
||||
|
||||
void XCore_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci);
|
||||
|
||||
// extract details from assembly code @code
|
||||
void XCore_insn_extract(MCInst *MI, char *code);
|
||||
|
||||
#endif
|
||||
|
@ -13,7 +13,6 @@
|
||||
#define GET_INSTRINFO_ENUM
|
||||
#include "XCoreGenInstrInfo.inc"
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static name_map reg_name_maps[] = {
|
||||
{ XCORE_REG_INVALID, NULL },
|
||||
|
||||
@ -33,8 +32,19 @@ static name_map reg_name_maps[] = {
|
||||
{ XCORE_REG_R9, "r9" },
|
||||
{ XCORE_REG_R10, "r10" },
|
||||
{ XCORE_REG_R11, "r11" },
|
||||
|
||||
// pseudo registers
|
||||
{ XCORE_REG_PC, "pc" },
|
||||
|
||||
{ XCORE_REG_SCP, "scp" },
|
||||
{ XCORE_REG_SSR, "ssr" },
|
||||
{ XCORE_REG_ET, "et" },
|
||||
{ XCORE_REG_ED, "ed" },
|
||||
{ XCORE_REG_SED, "sed" },
|
||||
{ XCORE_REG_KEP, "kep" },
|
||||
{ XCORE_REG_KSP, "ksp" },
|
||||
{ XCORE_REG_ID, "id" },
|
||||
};
|
||||
#endif
|
||||
|
||||
const char *XCore_reg_name(csh handle, unsigned int reg)
|
||||
{
|
||||
@ -48,6 +58,19 @@ const char *XCore_reg_name(csh handle, unsigned int reg)
|
||||
#endif
|
||||
}
|
||||
|
||||
xcore_reg XCore_reg_id(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 1; i < ARR_SIZE(reg_name_maps); i++) {
|
||||
if (!strcmp(name, reg_name_maps[i].name))
|
||||
return reg_name_maps[i].id;
|
||||
}
|
||||
|
||||
// not found
|
||||
return 0;
|
||||
}
|
||||
|
||||
static insn_map insns[] = {
|
||||
// dummy item
|
||||
{
|
||||
|
@ -17,5 +17,8 @@ const char *XCore_insn_name(csh handle, unsigned int id);
|
||||
// map internal raw register to 'public' register
|
||||
xcore_reg XCore_map_register(unsigned int r);
|
||||
|
||||
// map register name to register ID
|
||||
xcore_reg XCore_reg_id(char *name);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -71,7 +71,21 @@ typedef enum xcore_reg {
|
||||
XCORE_REG_R10,
|
||||
XCORE_REG_R11,
|
||||
|
||||
XCORE_REG_MAX,
|
||||
//> pseudo registers
|
||||
XCORE_REG_PC, // pc
|
||||
|
||||
// internal thread registers
|
||||
// see The-XMOS-XS1-Architecture(X7879A).pdf
|
||||
XCORE_REG_SCP, // save pc
|
||||
XCORE_REG_SSR, // save status
|
||||
XCORE_REG_ET, // exception type
|
||||
XCORE_REG_ED, // exception data
|
||||
XCORE_REG_SED, // save exception data
|
||||
XCORE_REG_KEP, // kernel entry pointer
|
||||
XCORE_REG_KSP, // kernel stack pointer
|
||||
XCORE_REG_ID, // thread ID
|
||||
|
||||
XCORE_REG_MAX, // <-- mark the end of the list of registers
|
||||
} xcore_reg;
|
||||
|
||||
//> XCore instruction
|
||||
|
Loading…
x
Reference in New Issue
Block a user