arm: support cs_regs_access() API

This commit is contained in:
Nguyen Anh Quynh 2015-04-07 11:59:26 +08:00
parent 5f22deb071
commit 29f777bdd9
12 changed files with 668 additions and 2399 deletions

@ -17,6 +17,7 @@ void MCInst_Init(MCInst *inst)
inst->has_imm = false;
inst->op1_size = 0;
inst->writeback = false;
inst->ac_idx = 0;
}
void MCInst_clear(MCInst *inst)

@ -107,6 +107,8 @@ struct MCInst {
uint8_t x86_prefix[4];
uint8_t imm_size; // immediate size for X86_OP_IMM operand
bool writeback; // writeback for ARM
// operand access index for list of registers sharing the same access right (for ARM)
uint8_t ac_idx;
};
void MCInst_Init(MCInst *inst);

@ -87,6 +87,7 @@ DEP_ARM += arch/ARM/ARMGenInstrInfo.inc
DEP_ARM += arch/ARM/ARMGenRegisterInfo.inc
DEP_ARM += arch/ARM/ARMGenSubtargetInfo.inc
DEP_ARM += arch/ARM/ARMMappingInsn.inc
DEP_ARM += arch/ARM/ARMMappingInsnOp.inc
LIBOBJ_ARM =
ifneq (,$(findstring arm,$(CAPSTONE_ARCHS)))

@ -472,8 +472,10 @@ static DecodeStatus _ARM_getInstruction(cs_struct *ud, MCInst *MI, const uint8_t
if (MI->flat_insn->detail) {
memset(&MI->flat_insn->detail->arm, 0, sizeof(cs_arm));
for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++)
for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++) {
MI->flat_insn->detail->arm.operands[i].vector_index = -1;
MI->flat_insn->detail->arm.operands[i].neon_lane = -1;
}
}
if (ud->big_endian)
@ -713,8 +715,10 @@ static DecodeStatus _Thumb_getInstruction(cs_struct *ud, MCInst *MI, const uint8
if (MI->flat_insn->detail) {
memset(&MI->flat_insn->detail->arm, 0, sizeof(cs_arm));
for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++)
for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++) {
MI->flat_insn->detail->arm.operands[i].vector_index = -1;
MI->flat_insn->detail->arm.operands[i].neon_lane = -1;
}
}
if (ud->big_endian)

@ -121,6 +121,21 @@ static void printModImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
static void printInstSyncBOption(MCInst *MI, unsigned OpNum, SStream *O);
// copy & normalize access info
static uint8_t get_op_access(cs_struct *h, unsigned int id, unsigned int index)
{
#ifndef CAPSTONE_DIET
uint8_t *arr = ARM_get_op_access(h, id);
if (arr[index] == CS_AC_IGNORE)
return 0;
return arr[index];
#else
return 0;
#endif
}
static void set_mem_access(MCInst *MI, bool status)
{
if (MI->csh->detail != CS_OPT_ON)
@ -128,11 +143,21 @@ static void set_mem_access(MCInst *MI, bool status)
MI->csh->doing_mem = status;
if (status) {
#ifndef CAPSTONE_DIET
uint8_t access;
#endif
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_MEM;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = ARM_REG_INVALID;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = 0;
#ifndef CAPSTONE_DIET
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
MI->ac_idx++;
#endif
} else {
// done, create the next operand slot
MI->flat_insn->detail->arm.op_count++;
@ -391,8 +416,10 @@ void ARM_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
case ARM_MOVPCLR:
insn->detail->arm.operands[0].type = ARM_OP_REG;
insn->detail->arm.operands[0].reg = ARM_REG_PC;
insn->detail->arm.operands[0].access = CS_AC_READ;
insn->detail->arm.operands[1].type = ARM_OP_REG;
insn->detail->arm.operands[1].reg = ARM_REG_LR;
insn->detail->arm.operands[1].access = CS_AC_WRITE;
insn->detail->arm.op_count = 2;
break;
}
@ -401,9 +428,9 @@ void ARM_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
void ARM_printInst(MCInst *MI, SStream *O, void *Info)
{
MCRegisterInfo *MRI = (MCRegisterInfo *)Info;
unsigned Opcode = MCInst_getOpcode(MI), tmp, i, pubOpcode;
switch(Opcode) {
// Check for HINT instructions w/ canonical names.
case ARM_HINT:
@ -452,6 +479,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(Dst);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_WRITE;
MI->flat_insn->detail->arm.op_count++;
}
@ -461,6 +489,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.op_count++;
}
@ -469,6 +498,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO2);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.op_count++;
}
//assert(ARM_AM_getSORegOffset(MO3.getImm()) == 0);
@ -490,6 +520,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(Dst);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_WRITE;
MI->flat_insn->detail->arm.op_count++;
}
@ -498,6 +529,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.op_count++;
}
@ -546,8 +578,16 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
SStream_concat0(O, "\t{");
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, 1)));
if (MI->csh->detail) {
#ifndef CAPSTONE_DIET
uint8_t access;
#endif
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 1));
#ifndef CAPSTONE_DIET
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
MI->ac_idx++;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "}");
@ -567,6 +607,13 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
if (Opcode == ARM_t2LDMIA_UPD)
SStream_concat0(O, ".w");
SStream_concat0(O, "\t");
if (MI->csh->detail) {
MI->flat_insn->detail->regs_read[MI->flat_insn->detail->regs_read_count] = ARM_REG_SP;
MI->flat_insn->detail->regs_read_count++;
MI->flat_insn->detail->regs_write[MI->flat_insn->detail->regs_write_count] = ARM_REG_SP;
MI->flat_insn->detail->regs_write_count++;
}
printRegisterList(MI, 4, O);
return;
}
@ -586,6 +633,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 0));
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "}");
@ -638,6 +686,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = BaseReg;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.op_count++;
}
if (Writeback) {
@ -721,8 +770,17 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
else
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = Reg;
} else {
#ifndef CAPSTONE_DIET
uint8_t access;
#endif
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg;
#ifndef CAPSTONE_DIET
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
MI->ac_idx++;
#endif
MI->flat_insn->detail->arm.op_count++;
}
}
@ -829,6 +887,7 @@ static void printThumbLdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O)
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.op_count++;
}
}
@ -850,6 +909,7 @@ static void printSORegRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = (MCOperand_getImm(MO3) & 7) + ARM_SFT_ASR_REG - 1;
MI->flat_insn->detail->arm.op_count++;
@ -878,6 +938,7 @@ static void printSORegImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = MCOperand_getImm(MO2) & 7;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.value = (unsigned int)MCOperand_getImm(MO2) >> 3;
MI->flat_insn->detail->arm.op_count++;
@ -1019,6 +1080,7 @@ static void printAddrMode2OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
MI->flat_insn->detail->arm.op_count++;
}
@ -1109,6 +1171,7 @@ static void printAddrMode3OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
MI->flat_insn->detail->arm.op_count++;
}
@ -1158,6 +1221,7 @@ static void printPostIdxRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.op_count++;
}
}
@ -1194,6 +1258,7 @@ static void printAddrMode5Operand(MCInst *MI, unsigned OpNum, SStream *O,
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = 0;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
}
ImmOffs = ARM_AM_getAM5Offset((unsigned int)MCOperand_getImm(MO2));
@ -1268,6 +1333,7 @@ static void printAddrMode6OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO);
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.op_count++;
}
}
@ -1382,17 +1448,37 @@ static void printPKHASRShiftImm(MCInst *MI, unsigned OpNum, SStream *O)
static void printRegisterList(MCInst *MI, unsigned OpNum, SStream *O)
{
unsigned i, e;
#ifndef CAPSTONE_DIET
uint8_t access;
#endif
SStream_concat0(O, "{");
#ifndef CAPSTONE_DIET
if (MI->csh->detail) {
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
}
#endif
for (i = OpNum, e = MCInst_getNumOperands(MI); i != e; ++i) {
if (i != OpNum) SStream_concat0(O, ", ");
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, i)));
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, i));
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
}
SStream_concat0(O, "}");
#ifndef CAPSTONE_DIET
if (MI->csh->detail) {
MI->ac_idx++;
}
#endif
}
static void printGPRPairOperand(MCInst *MI, unsigned OpNum, SStream *O,
@ -1688,7 +1774,9 @@ static void printNoHashImmediate(MCInst *MI, unsigned OpNum, SStream *O)
SStream_concat(O, "%u", tmp);
if (MI->csh->detail) {
if (MI->csh->doing_mem) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp;
MI->flat_insn->detail->arm.op_count--;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].neon_lane = tmp;
MI->ac_idx--; // consecutive operands share the same access right
} else {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
@ -1906,6 +1994,7 @@ static void printT2SOOperand(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
MI->flat_insn->detail->arm.op_count++;
}
@ -2320,9 +2409,9 @@ static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O)
{
unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
if (tmp > HEX_THRESHOLD)
SStream_concat(O, "[0x%x]",tmp);
SStream_concat(O, "[0x%x]", tmp);
else
SStream_concat(O, "[%u]",tmp);
SStream_concat(O, "[%u]", tmp);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].vector_index = tmp;
}
@ -2333,9 +2422,22 @@ static void printVectorListOne(MCInst *MI, unsigned OpNum, SStream *O)
SStream_concat0(O, "{");
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
if (MI->csh->detail) {
#ifndef CAPSTONE_DIET
uint8_t access;
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
SStream_concat0(O, "}");
}
@ -2343,14 +2445,25 @@ static void printVectorListOne(MCInst *MI, unsigned OpNum, SStream *O)
static void printVectorListTwo(MCInst *MI, unsigned OpNum,
SStream *O, MCRegisterInfo *MRI)
{
#ifndef CAPSTONE_DIET
uint8_t access;
#endif
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_1);
#ifndef CAPSTONE_DIET
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
SStream_concat0(O, "{");
printRegName(MI->csh, O, Reg0);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, ", ");
@ -2358,22 +2471,40 @@ static void printVectorListTwo(MCInst *MI, unsigned OpNum,
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
static void printVectorListTwoSpaced(MCInst *MI, unsigned OpNum,
SStream *O, MCRegisterInfo *MRI)
{
#ifndef CAPSTONE_DIET
uint8_t access;
#endif
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_2);
#ifndef CAPSTONE_DIET
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
SStream_concat0(O, "{");
printRegName(MI->csh, O, Reg0);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, ", ");
@ -2381,13 +2512,26 @@ static void printVectorListTwoSpaced(MCInst *MI, unsigned OpNum,
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O)
{
#ifndef CAPSTONE_DIET
uint8_t access;
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
// Normally, it's not safe to use register enum values directly with
// addition to get the next register, but for VFP registers, the
// sort order is guaranteed because they're all of the form D<n>.
@ -2396,6 +2540,9 @@ static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, ", ");
@ -2403,6 +2550,9 @@ static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, ", ");
@ -2410,13 +2560,26 @@ static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
{
#ifndef CAPSTONE_DIET
uint8_t access;
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
// Normally, it's not safe to use register enum values directly with
// addition to get the next register, but for VFP registers, the
// sort order is guaranteed because they're all of the form D<n>.
@ -2425,6 +2588,9 @@ static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, ", ");
@ -2432,6 +2598,9 @@ static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, ", ");
@ -2439,6 +2608,9 @@ static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, ", ");
@ -2446,34 +2618,65 @@ static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
static void printVectorListOneAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
{
#ifndef CAPSTONE_DIET
uint8_t access;
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
SStream_concat0(O, "{");
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[]}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
static void printVectorListTwoAllLanes(MCInst *MI, unsigned OpNum,
SStream *O, MCRegisterInfo *MRI)
{
#ifndef CAPSTONE_DIET
uint8_t access;
#endif
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_1);
#ifndef CAPSTONE_DIET
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
SStream_concat0(O, "{");
printRegName(MI->csh, O, Reg0);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[], ");
@ -2481,13 +2684,26 @@ static void printVectorListTwoAllLanes(MCInst *MI, unsigned OpNum,
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[]}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
{
#ifndef CAPSTONE_DIET
uint8_t access;
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
// Normally, it's not safe to use register enum values directly with
// addition to get the next register, but for VFP registers, the
// sort order is guaranteed because they're all of the form D<n>.
@ -2496,6 +2712,9 @@ static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[], ");
@ -2503,6 +2722,9 @@ static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[], ");
@ -2510,13 +2732,26 @@ static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[]}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
{
#ifndef CAPSTONE_DIET
uint8_t access;
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
// Normally, it's not safe to use register enum values directly with
// addition to get the next register, but for VFP registers, the
// sort order is guaranteed because they're all of the form D<n>.
@ -2525,6 +2760,9 @@ static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[], ");
@ -2532,6 +2770,9 @@ static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[], ");
@ -2539,6 +2780,9 @@ static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[], ");
@ -2546,22 +2790,40 @@ static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[]}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
static void printVectorListTwoSpacedAllLanes(MCInst *MI,
unsigned OpNum, SStream *O, MCRegisterInfo *MRI)
{
#ifndef CAPSTONE_DIET
uint8_t access;
#endif
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_2);
#ifndef CAPSTONE_DIET
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
SStream_concat0(O, "{");
printRegName(MI->csh, O, Reg0);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[], ");
@ -2569,14 +2831,27 @@ static void printVectorListTwoSpacedAllLanes(MCInst *MI,
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[]}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
static void printVectorListThreeSpacedAllLanes(MCInst *MI,
unsigned OpNum, SStream *O)
{
#ifndef CAPSTONE_DIET
uint8_t access;
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
// Normally, it's not safe to use register enum values directly with
// addition to get the next register, but for VFP registers, the
// sort order is guaranteed because they're all of the form D<n>.
@ -2585,6 +2860,9 @@ static void printVectorListThreeSpacedAllLanes(MCInst *MI,
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[], ");
@ -2592,6 +2870,9 @@ static void printVectorListThreeSpacedAllLanes(MCInst *MI,
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[], ");
@ -2599,14 +2880,27 @@ static void printVectorListThreeSpacedAllLanes(MCInst *MI,
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[]}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
static void printVectorListFourSpacedAllLanes(MCInst *MI,
unsigned OpNum, SStream *O)
{
#ifndef CAPSTONE_DIET
uint8_t access;
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
// Normally, it's not safe to use register enum values directly with
// addition to get the next register, but for VFP registers, the
// sort order is guaranteed because they're all of the form D<n>.
@ -2615,6 +2909,9 @@ static void printVectorListFourSpacedAllLanes(MCInst *MI,
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[], ");
@ -2622,6 +2919,9 @@ static void printVectorListFourSpacedAllLanes(MCInst *MI,
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[], ");
@ -2629,6 +2929,9 @@ static void printVectorListFourSpacedAllLanes(MCInst *MI,
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[], ");
@ -2636,13 +2939,26 @@ static void printVectorListFourSpacedAllLanes(MCInst *MI,
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "[]}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O)
{
#ifndef CAPSTONE_DIET
uint8_t access;
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
// Normally, it's not safe to use register enum values directly with
// addition to get the next register, but for VFP registers, the
// sort order is guaranteed because they're all of the form D<n>.
@ -2651,6 +2967,9 @@ static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, ", ");
@ -2658,6 +2977,9 @@ static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, ", ");
@ -2665,13 +2987,26 @@ static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
{
#ifndef CAPSTONE_DIET
uint8_t access;
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
#endif
// Normally, it's not safe to use register enum values directly with
// addition to get the next register, but for VFP registers, the
// sort order is guaranteed because they're all of the form D<n>.
@ -2680,6 +3015,9 @@ static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, ", ");
@ -2687,6 +3025,9 @@ static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, ", ");
@ -2694,6 +3035,9 @@ static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, ", ");
@ -2701,9 +3045,16 @@ static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6;
#ifndef CAPSTONE_DIET
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
#endif
MI->flat_insn->detail->arm.op_count++;
}
SStream_concat0(O, "}");
#ifndef CAPSTONE_DIET
MI->ac_idx++;
#endif
}
void ARM_addVectorDataType(MCInst *MI, arm_vectordata_type vd)

@ -877,24 +877,83 @@ bool ARM_blx_to_arm_mode(cs_struct *h, unsigned int id) {
}
#if 0
#ifndef CAPSTONE_DIET
// map instruction to its characteristics
typedef struct insn_op {
unsigned int eflags_update; // how this instruction update status flags
cs_ac_type operands[4];
uint8_t access[7];
} insn_op;
static insn_op insn_ops[] = {
{
// NULL item
0,
{ 0 }
},
#include "ARMMappingInsnOp.inc"
};
// given internal insn id, return operand access info
uint8_t *ARM_get_op_access(cs_struct *h, unsigned int id)
{
int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
if (i != 0) {
return insn_ops[i].access;
}
return NULL;
}
void ARM_reg_access(const cs_insn *insn,
cs_regs regs_read, uint8_t *regs_read_count,
cs_regs regs_write, uint8_t *regs_write_count)
{
uint8_t i;
uint8_t read_count, write_count;
cs_arm *arm = &(insn->detail->arm);
read_count = insn->detail->regs_read_count;
write_count = insn->detail->regs_write_count;
// implicit registers
memcpy(regs_read, insn->detail->regs_read, read_count * sizeof(insn->detail->regs_read[0]));
memcpy(regs_write, insn->detail->regs_write, write_count * sizeof(insn->detail->regs_write[0]));
// explicit registers
for (i = 0; i < arm->op_count; i++) {
cs_arm_op *op = &(arm->operands[i]);
switch((int)op->type) {
case ARM_OP_REG:
if ((op->access & CS_AC_READ) && !arr_exist(regs_read, read_count, op->reg)) {
regs_read[read_count] = op->reg;
read_count++;
}
if ((op->access & CS_AC_WRITE) && !arr_exist(regs_write, write_count, op->reg)) {
regs_write[write_count] = op->reg;
write_count++;
}
break;
case ARM_OP_MEM:
// registers appeared in memory references always being read
if ((op->mem.base != ARM_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.base)) {
regs_read[read_count] = op->mem.base;
read_count++;
}
if ((op->mem.index != ARM_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.index)) {
regs_read[read_count] = op->mem.index;
read_count++;
}
if ((arm->writeback) && (op->mem.base != ARM_REG_INVALID) && !arr_exist(regs_write, write_count, op->mem.base)) {
regs_write[write_count] = op->mem.base;
write_count++;
}
default:
break;
}
}
*regs_read_count = read_count;
*regs_write_count = write_count;
}
#endif
#endif

@ -23,4 +23,10 @@ bool ARM_rel_branch(cs_struct *h, unsigned int insn_id);
bool ARM_blx_to_arm_mode(cs_struct *h, unsigned int insn_id);
uint8_t *ARM_get_op_access(cs_struct *h, unsigned int id);
void ARM_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

File diff suppressed because it is too large Load Diff

@ -30,6 +30,9 @@ static cs_err init(cs_struct *ud)
ud->insn_name = ARM_insn_name;
ud->group_name = ARM_group_name;
ud->post_printer = ARM_post_printer;
#ifndef CAPSTONE_DIET
ud->reg_access = ARM_reg_access;
#endif
if (ud->mode & CS_MODE_THUMB)
ud->disasm = Thumb_getInstruction;

@ -285,7 +285,7 @@ static void _printOperand(MCInst *MI, unsigned OpNo, SStream *O)
}
#ifndef CAPSTONE_DIET
// convert Intel access info to AT&T access info
// copy & normalize access info
static void get_op_access(cs_struct *h, unsigned int id, uint8_t *access, uint64_t *eflags)
{
#ifndef CAPSTONE_DIET

@ -262,11 +262,14 @@ typedef struct arm_op_mem {
// Instruction operand
typedef struct cs_arm_op {
int vector_index; // Vector Index for some vector operands (or -1 if irrelevant)
struct {
arm_shifter type;
unsigned int value;
} shift;
arm_op_type type; // operand type
union {
unsigned int reg; // register value for REG/SYSREG operand
int32_t imm; // immediate value for C-IMM, P-IMM or IMM operand
@ -274,9 +277,18 @@ typedef struct cs_arm_op {
arm_op_mem mem; // base/index/scale/disp value for MEM operand
arm_setend_type setend; // SETEND instruction's operand type
};
// in some instructions, an operand can be subtracted or added to
// the base register,
bool subtracted; // if TRUE, this operand is subtracted. otherwise, it is added.
// How is this operand accessed? (READ, WRITE or READ|WRITE)
// This field is combined of cs_ac_type.
// NOTE: this field is irrelevant if engine is compiled in DIET mode.
uint8_t access;
// Neon lane index for NEON instructions (or -1 if irrelevant)
int8_t neon_lane;
} cs_arm_op;
// Instruction structure

@ -30,10 +30,12 @@ static void print_string_hex(char *comment, unsigned char *str, size_t len)
printf("\n");
}
static void print_insn_detail(cs_insn *ins)
static void print_insn_detail(csh handle, cs_insn *ins)
{
cs_arm *arm;
int i;
cs_regs regs_read, regs_write;
uint8_t regs_read_count, regs_write_count;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
@ -88,6 +90,24 @@ static void print_insn_detail(cs_insn *ins)
break;
}
if (op->neon_lane != -1) {
printf("\t\toperands[%u].neon_lane = %u\n", i, op->neon_lane);
}
switch(op->access) {
default:
break;
case CS_AC_READ:
printf("\t\toperands[%u].access: READ\n", i);
break;
case CS_AC_WRITE:
printf("\t\toperands[%u].access: WRITE\n", i);
break;
case CS_AC_READ | CS_AC_WRITE:
printf("\t\toperands[%u].access: READ | WRITE\n", i);
break;
}
if (op->shift.type != ARM_SFT_INVALID && op->shift.value) {
if (op->shift.type < ARM_SFT_ASR_REG)
// shift with constant value
@ -133,6 +153,27 @@ static void print_insn_detail(cs_insn *ins)
if (arm->mem_barrier)
printf("\tMemory-barrier: %u\n", arm->mem_barrier);
// Print out all registers accessed by this instruction (either implicit or explicit)
if (!cs_regs_access(handle, ins,
regs_read, &regs_read_count,
regs_write, &regs_write_count)) {
if (regs_read_count) {
printf("\tRegisters read:");
for(i = 0; i < regs_read_count; i++) {
printf(" %s", cs_reg_name(handle, regs_read[i]));
}
printf("\n");
}
if (regs_write_count) {
printf("\tRegisters modified:");
for(i = 0; i < regs_write_count; i++) {
printf(" %s", cs_reg_name(handle, regs_write[i]));
}
printf("\n");
}
}
printf("\n");
}
@ -184,7 +225,11 @@ static void test()
//#define ARM_CODE "\x90\x04\x0E\x00" // muleq lr, r0, r4
//#define ARM_CODE "\x90\x24\x0E\x00" // muleq lr, r0, r4
//#define ARM_CODE "\xb6\x10\x5f\xe1" // ldrh r1, [pc, #-6]
#define ARM_CODE "\xED\xFF\xFF\xEB\x04\xe0\x2d\xe5\x00\x00\x00\x00\xe0\x83\x22\xe5\xf1\x02\x03\x0e\x00\x00\xa0\xe3\x02\x30\xc1\xe7\x00\x00\x53\xe3\x00\x02\x01\xf1\x05\x40\xd0\xe8\xf4\x80\x00\x00"
#define ARM_CODE "\x86\x48\x60\xf4\x4d\x0f\xe2\xf4\xED\xFF\xFF\xEB\x04\xe0\x2d\xe5\x00\x00\x00\x00\xe0\x83\x22\xe5\xf1\x02\x03\x0e\x00\x00\xa0\xe3\x02\x30\xc1\xe7\x00\x00\x53\xe3\x00\x02\x01\xf1\x05\x40\xd0\xe8\xf4\x80\x00\x00"
//#define ARM_CODE "\x86\x48\x60\xf4"
//#define ARM_CODE2 "\xf0\x24"
//#define ARM_CODE2 "\x83\xb0"
#define ARM_CODE2 "\xd1\xe8\x00\xf0\xf0\x24\x04\x07\x1f\x3c\xf2\xc0\x00\x00\x4f\xf0\x00\x01\x46\x6c"
@ -194,7 +239,10 @@ static void test()
//#define THUMB_CODE "\x01\x47" // bx r0
//#define THUMB_CODE "\x02\x47" // bx r0
//#define THUMB_CODE "\x0a\xbf" // itet eq
#define THUMB_CODE "\x70\x47\xeb\x46\x83\xb0\xc9\x68\x1f\xb1\x30\xbf\xaf\xf3\x20\x84\x52\xf8\x23\xf0"
#define THUMB_CODE "\x60\xf9\x1f\x04\xe0\xf9\x4f\x07\x70\x47\xeb\x46\x83\xb0\xc9\x68\x1f\xb1\x30\xbf\xaf\xf3\x20\x84\x52\xf8\x23\xf0"
//#define THUMB_CODE "\xe0\xf9\x4f\x07"
#define THUMB_CODE2 "\x4f\xf0\x00\x01\xbd\xe8\x00\x88\xd1\xe8\x00\xf0\x18\xbf\xad\xbf\xf3\xff\x0b\x0c\x86\xf3\x00\x89\x80\xf3\x00\x8c\x4f\xfa\x99\xf6\xd0\xff\xa2\x01"
#define THUMB_MCLASS "\xef\xf3\x02\x80"
#define ARMV8 "\xe0\x3b\xb2\xee\x42\x00\x01\xe1\x51\xf0\x7f\xf5"
@ -272,7 +320,7 @@ static void test()
for (j = 0; j < count; j++) {
printf("0x%"PRIx64":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
print_insn_detail(&insn[j]);
print_insn_detail(handle, &insn[j]);
}
printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size);