arm: update core with a lot more details provided in detail mode now. update Python & Java bindings to reflect the core's changes
diff --git a/arch/ARM/ARMBaseInfo.h b/arch/ARM/ARMBaseInfo.h
index 233a3aa..7e50396 100644
--- a/arch/ARM/ARMBaseInfo.h
+++ b/arch/ARM/ARMBaseInfo.h
@@ -20,7 +20,7 @@
#ifndef CS_ARMBASEINFO_H
#define CS_ARMBASEINFO_H
-//#include "ARMMCTargetDesc.h"
+#include "../../include/arm.h"
// Defines symbolic names for ARM registers. This defines a mapping from
// register name to register number.
@@ -92,23 +92,12 @@
}
}
-enum ARM_PROC_IMod {
- ARM_PROC_IE = 2,
- ARM_PROC_ID = 3
-};
-
-enum ARM_PROC_IFlags {
- ARM_PROC_F = 1,
- ARM_PROC_I = 2,
- ARM_PROC_A = 4
-};
-
inline static char *ARM_PROC_IFlagsToString(unsigned val)
{
switch (val) {
- case ARM_PROC_F: return "f";
- case ARM_PROC_I: return "i";
- case ARM_PROC_A: return "a";
+ case ARM_CPSFLAG_F: return "f";
+ case ARM_CPSFLAG_I: return "i";
+ case ARM_CPSFLAG_A: return "a";
default: return "";
}
}
@@ -116,10 +105,9 @@
inline static char *ARM_PROC_IModToString(unsigned val)
{
switch (val) {
- case ARM_PROC_IE: return "ie";
- case ARM_PROC_ID: return "id";
- default:
- return "";
+ case ARM_CPSMODE_IE: return "ie";
+ case ARM_CPSMODE_ID: return "id";
+ default: return "";
}
}
diff --git a/arch/ARM/ARMDisassembler.c b/arch/ARM/ARMDisassembler.c
index a62ca42..bc9fe30 100644
--- a/arch/ARM/ARMDisassembler.c
+++ b/arch/ARM/ARMDisassembler.c
@@ -441,7 +441,7 @@
static DecodeStatus _ARM_getInstruction(cs_struct *ud, MCInst *MI, const uint8_t *code, size_t code_len,
uint16_t *Size, uint64_t Address)
{
- uint32_t insn;
+ uint32_t insn, i;
uint8_t bytes[4];
DecodeStatus result;
@@ -453,6 +453,8 @@
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++)
+ MI->flat_insn->detail->arm.operands[i].vector_index = -1;
}
memcpy(bytes, code, 4);
@@ -684,6 +686,7 @@
bool InITBlock;
unsigned Firstcond, Mask;
uint32_t NEONLdStInsn, insn32, NEONDataInsn, NEONCryptoInsn, NEONv8Insn;
+ int i;
// We want to read exactly 2 bytes of data.
if (code_len < 2)
@@ -694,6 +697,8 @@
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++)
+ MI->flat_insn->detail->arm.operands[i].vector_index = -1;
}
memcpy(bytes, code, 2);
diff --git a/arch/ARM/ARMGenAsmWriter.inc b/arch/ARM/ARMGenAsmWriter.inc
index c82e88f..4a47452 100644
--- a/arch/ARM/ARMGenAsmWriter.inc
+++ b/arch/ARM/ARMGenAsmWriter.inc
@@ -6240,7 +6240,8 @@
break;
case 4:
// BX_RET
- SStream_concat0(O, "\tlr");
+ SStream_concat0(O, "\tlr");
+ ARM_addReg(MI, ARM_REG_LR);
return;
break;
case 5:
@@ -6250,17 +6251,21 @@
break;
case 6:
// FCONSTD, VABSD, VADDD, VCMPD, VCMPED, VCMPEZD, VCMPZD, VDIVD, VFMAD, V...
- SStream_concat0(O, ".f64\t");
+ SStream_concat0(O, ".f64\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F64);
printOperand(MI, 0, O);
break;
case 7:
// FCONSTS, VABDfd, VABDfq, VABSS, VABSfd, VABSfq, VACGEd, VACGEq, VACGTd...
- SStream_concat0(O, ".f32\t");
+ SStream_concat0(O, ".f32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F32);
printOperand(MI, 0, O);
break;
case 8:
// FMSTAT
SStream_concat0(O, "\tAPSR_nzcv, fpscr"); // qq
+ ARM_addReg(MI, ARM_REG_APSR_NZCV);
+ ARM_addReg(MI, ARM_REG_FPSCR);
return;
break;
case 9:
@@ -6270,7 +6275,9 @@
break;
case 10:
// MOVPCLR
- SStream_concat0(O, "\tpc, lr"); // qq
+ SStream_concat0(O, "\tpc, lr");
+ ARM_addReg(MI, ARM_REG_PC);
+ ARM_addReg(MI, ARM_REG_LR);
return;
break;
case 11:
@@ -6280,71 +6287,83 @@
break;
case 12:
// VABALsv2i64, VABAsv2i32, VABAsv4i32, VABDLsv2i64, VABDsv2i32, VABDsv4i...
- SStream_concat0(O, ".s32\t");
+ SStream_concat0(O, ".s32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_S32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
break;
case 13:
// VABALsv4i32, VABAsv4i16, VABAsv8i16, VABDLsv4i32, VABDsv4i16, VABDsv8i...
- SStream_concat0(O, ".s16\t");
+ SStream_concat0(O, ".s16\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_S16);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
break;
case 14:
// VABALsv8i16, VABAsv16i8, VABAsv8i8, VABDLsv8i16, VABDsv16i8, VABDsv8i8...
- SStream_concat0(O, ".s8\t");
+ SStream_concat0(O, ".s8\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_S8);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
break;
case 15:
// VABALuv2i64, VABAuv2i32, VABAuv4i32, VABDLuv2i64, VABDuv2i32, VABDuv4i...
- SStream_concat0(O, ".u32\t");
+ SStream_concat0(O, ".u32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_U32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
break;
case 16:
// VABALuv4i32, VABAuv4i16, VABAuv8i16, VABDLuv4i32, VABDuv4i16, VABDuv8i...
- SStream_concat0(O, ".u16\t");
+ SStream_concat0(O, ".u16\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_U16);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
break;
case 17:
// VABALuv8i16, VABAuv16i8, VABAuv8i8, VABDLuv8i16, VABDuv16i8, VABDuv8i8...
- SStream_concat0(O, ".u8\t");
+ SStream_concat0(O, ".u8\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_U8);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
break;
case 18:
// VADDHNv2i32, VADDv1i64, VADDv2i64, VMOVNv2i32, VMOVv1i64, VMOVv2i64, V...
- SStream_concat0(O, ".i64\t");
+ SStream_concat0(O, ".i64\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_I64);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
break;
case 19:
// VADDHNv4i16, VADDv2i32, VADDv4i32, VBICiv2i32, VBICiv4i32, VCEQv2i32, ...
- SStream_concat0(O, ".i32\t");
+ SStream_concat0(O, ".i32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_I32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
break;
case 20:
// VADDHNv8i8, VADDv4i16, VADDv8i16, VBICiv4i16, VBICiv8i16, VCEQv4i16, V...
- SStream_concat0(O, ".i16\t");
+ SStream_concat0(O, ".i16\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_I16);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
break;
case 21:
// VADDv16i8, VADDv8i8, VCEQv16i8, VCEQv8i8, VCEQzv16i8, VCEQzv8i8, VCLZv...
- SStream_concat0(O, ".i8\t");
+ SStream_concat0(O, ".i8\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_I8);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
break;
case 22:
// VCNTd, VCNTq, VDUP8d, VDUP8q, VDUPLN8d, VDUPLN8q, VEXTd8, VEXTq8, VLD1...
- SStream_concat0(O, ".8\t");
+ SStream_concat0(O, ".8\t");
+ ARM_addVectorDataSize(MI, 8);
break;
case 23:
// VCVTBDH, VCVTTDH
- SStream_concat0(O, ".f16.f64\t");
+ SStream_concat0(O, ".f16.f64\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F16F64);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6352,7 +6371,8 @@
break;
case 24:
// VCVTBHD, VCVTTHD
- SStream_concat0(O, ".f64.f16\t");
+ SStream_concat0(O, ".f64.f16\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F64F16);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6360,7 +6380,8 @@
break;
case 25:
// VCVTBHS, VCVTTHS, VCVTh2f
- SStream_concat0(O, ".f32.f16\t");
+ SStream_concat0(O, ".f32.f16\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F32F16);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6368,7 +6389,8 @@
break;
case 26:
// VCVTBSH, VCVTTSH, VCVTf2h
- SStream_concat0(O, ".f16.f32\t");
+ SStream_concat0(O, ".f16.f32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F16F32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6376,7 +6398,8 @@
break;
case 27:
// VCVTDS
- SStream_concat0(O, ".f64.f32\t");
+ SStream_concat0(O, ".f64.f32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F64F32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6384,7 +6407,8 @@
break;
case 28:
// VCVTSD
- SStream_concat0(O, ".f32.f64\t");
+ SStream_concat0(O, ".f32.f64\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F32F64);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6392,89 +6416,105 @@
break;
case 29:
// VCVTf2sd, VCVTf2sq, VCVTf2xsd, VCVTf2xsq, VTOSIRS, VTOSIZS, VTOSLS
- SStream_concat0(O, ".s32.f32\t");
+ SStream_concat0(O, ".s32.f32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_S32F32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
break;
case 30:
// VCVTf2ud, VCVTf2uq, VCVTf2xud, VCVTf2xuq, VTOUIRS, VTOUIZS, VTOULS
- SStream_concat0(O, ".u32.f32\t");
+ SStream_concat0(O, ".u32.f32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_U32F32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
break;
case 31:
// VCVTs2fd, VCVTs2fq, VCVTxs2fd, VCVTxs2fq, VSITOS, VSLTOS
- SStream_concat0(O, ".f32.s32\t");
+ SStream_concat0(O, ".f32.s32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F32S32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
break;
case 32:
// VCVTu2fd, VCVTu2fq, VCVTxu2fd, VCVTxu2fq, VUITOS, VULTOS
- SStream_concat0(O, ".f32.u32\t");
+ SStream_concat0(O, ".f32.u32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F32U32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
break;
case 33:
// VDUP16d, VDUP16q, VDUPLN16d, VDUPLN16q, VEXTd16, VEXTq16, VLD1DUPd16, ...
- SStream_concat0(O, ".16\t");
+ SStream_concat0(O, ".16\t");
+ ARM_addVectorDataSize(MI, 16);
break;
case 34:
// VDUP32d, VDUP32q, VDUPLN32d, VDUPLN32q, VEXTd32, VEXTq32, VGETLNi32, V...
- SStream_concat0(O, ".32\t");
+ SStream_concat0(O, ".32\t");
+ ARM_addVectorDataSize(MI, 32);
break;
case 35:
// VEXTq64, VLD1d64, VLD1d64Q, VLD1d64Qwb_fixed, VLD1d64Qwb_register, VLD...
- SStream_concat0(O, ".64\t");
+ SStream_concat0(O, ".64\t");
+ ARM_addVectorDataSize(MI, 64);
break;
case 36:
// VLD1LNd16, VLD1LNd16_UPD, VLD2LNd16, VLD2LNd16_UPD, VLD2LNq16, VLD2LNq...
- SStream_concat0(O, ".16\t{");
+ SStream_concat0(O, ".16\t{");
+ ARM_addVectorDataSize(MI, 16);
break;
case 37:
// VLD1LNd32, VLD1LNd32_UPD, VLD2LNd32, VLD2LNd32_UPD, VLD2LNq32, VLD2LNq...
- SStream_concat0(O, ".32\t{");
+ SStream_concat0(O, ".32\t{");
+ ARM_addVectorDataSize(MI, 32);
break;
case 38:
// VLD1LNd8, VLD1LNd8_UPD, VLD2LNd8, VLD2LNd8_UPD, VLD3DUPd8, VLD3DUPd8_U...
- SStream_concat0(O, ".8\t{");
+ SStream_concat0(O, ".8\t{");
+ ARM_addVectorDataSize(MI, 8);
break;
case 39:
// VMSR
- SStream_concat0(O, "\tfpscr, ");
+ SStream_concat0(O, "\tfpscr, ");
+ ARM_addReg(MI, ARM_REG_FPSCR);
printOperand(MI, 0, O);
return;
break;
case 40:
// VMSR_FPEXC
- SStream_concat0(O, "\tfpexc, ");
+ SStream_concat0(O, "\tfpexc, ");
+ ARM_addReg(MI, ARM_REG_FPEXC);
printOperand(MI, 0, O);
return;
break;
case 41:
// VMSR_FPINST
- SStream_concat0(O, "\tfpinst, ");
+ SStream_concat0(O, "\tfpinst, ");
+ ARM_addReg(MI, ARM_REG_FPINST);
printOperand(MI, 0, O);
return;
break;
case 42:
// VMSR_FPINST2
- SStream_concat0(O, "\tfpinst2, ");
+ SStream_concat0(O, "\tfpinst2, ");
+ ARM_addReg(MI, ARM_REG_FPINST2);
printOperand(MI, 0, O);
return;
break;
case 43:
// VMSR_FPSID
- SStream_concat0(O, "\tfpsid, ");
+ SStream_concat0(O, "\tfpsid, ");
+ ARM_addReg(MI, ARM_REG_FPSID);
printOperand(MI, 0, O);
return;
break;
case 44:
// VMULLp8, VMULpd, VMULpq
- SStream_concat0(O, ".p8\t");
+ SStream_concat0(O, ".p8\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_P8);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6484,19 +6524,22 @@
break;
case 45:
// VQADDsv1i64, VQADDsv2i64, VQMOVNsuv2i32, VQMOVNsv2i32, VQRSHLsv1i64, V...
- SStream_concat0(O, ".s64\t");
+ SStream_concat0(O, ".s64\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_S64);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
break;
case 46:
// VQADDuv1i64, VQADDuv2i64, VQMOVNuv2i32, VQRSHLuv1i64, VQRSHLuv2i64, VQ...
- SStream_concat0(O, ".u64\t");
+ SStream_concat0(O, ".u64\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_U64);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
break;
case 47:
// VSHTOD
- SStream_concat0(O, ".f64.s16\t");
+ SStream_concat0(O, ".f64.s16\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F64S16);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6506,7 +6549,8 @@
break;
case 48:
// VSHTOS
- SStream_concat0(O, ".f32.s16\t");
+ SStream_concat0(O, ".f32.s16\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F32S16);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6516,14 +6560,16 @@
break;
case 49:
// VSITOD, VSLTOD
- SStream_concat0(O, ".f64.s32\t");
+ SStream_concat0(O, ".f64.s32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F64S32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
break;
case 50:
// VTOSHD
- SStream_concat0(O, ".s16.f64\t");
+ SStream_concat0(O, ".s16.f64\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_S16F64);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6533,7 +6579,8 @@
break;
case 51:
// VTOSHS
- SStream_concat0(O, ".s16.f32\t");
+ SStream_concat0(O, ".s16.f32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_S16F32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6543,14 +6590,16 @@
break;
case 52:
// VTOSIRD, VTOSIZD, VTOSLD
- SStream_concat0(O, ".s32.f64\t");
+ SStream_concat0(O, ".s32.f64\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_S32F64);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
break;
case 53:
// VTOUHD
- SStream_concat0(O, ".u16.f64\t");
+ SStream_concat0(O, ".u16.f64\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_U16F64);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6560,7 +6609,8 @@
break;
case 54:
// VTOUHS
- SStream_concat0(O, ".u16.f32\t");
+ SStream_concat0(O, ".u16.f32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_U16F32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6570,14 +6620,16 @@
break;
case 55:
// VTOUIRD, VTOUIZD, VTOULD
- SStream_concat0(O, ".u32.f64\t");
+ SStream_concat0(O, ".u32.f64\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_U32F64);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
break;
case 56:
// VUHTOD
- SStream_concat0(O, ".f64.u16\t");
+ SStream_concat0(O, ".f64.u16\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F64U16);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6587,7 +6639,8 @@
break;
case 57:
// VUHTOS
- SStream_concat0(O, ".f32.u16\t");
+ SStream_concat0(O, ".f32.u16\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F32U16);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6597,7 +6650,8 @@
break;
case 58:
// VUITOD, VULTOD
- SStream_concat0(O, ".f64.u32\t");
+ SStream_concat0(O, ".f64.u32\t");
+ ARM_addVectorDataType(MI, ARM_VECTORDATA_F64U32);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
@@ -6608,19 +6662,23 @@
break;
case 60:
// t2SRSDB, t2SRSIA
- SStream_concat0(O, "\tsp, ");
+ SStream_concat0(O, "\tsp, ");
+ ARM_addReg(MI, ARM_REG_SP);
printOperand(MI, 0, O);
return;
break;
case 61:
// t2SRSDB_UPD, t2SRSIA_UPD
- SStream_concat0(O, "\tsp!, ");
+ SStream_concat0(O, "\tsp!, ");
+ ARM_addReg(MI, ARM_REG_SP);
printOperand(MI, 0, O);
return;
break;
case 62:
// t2SUBS_PC_LR
- SStream_concat0(O, "\tpc, lr, ");
+ SStream_concat0(O, "\tpc, lr, ");
+ ARM_addReg(MI, ARM_REG_PC);
+ ARM_addReg(MI, ARM_REG_LR);
printOperand(MI, 0, O);
return;
break;
@@ -7043,12 +7101,14 @@
break;
case 8:
// MRS, t2MRS_AR
- SStream_concat0(O, ", apsr");
+ SStream_concat0(O, ", apsr");
+ ARM_addReg(MI, ARM_REG_APSR);
return;
break;
case 9:
// MRSsys, t2MRSsys_AR
- SStream_concat0(O, ", spsr");
+ SStream_concat0(O, ", spsr");
+ ARM_addReg(MI, ARM_REG_SPSR);
return;
break;
case 10:
@@ -7093,42 +7153,50 @@
break;
case 18:
// VMRS
- SStream_concat0(O, ", fpscr");
+ SStream_concat0(O, ", fpscr");
+ ARM_addReg(MI, ARM_REG_FPSCR);
return;
break;
case 19:
// VMRS_FPEXC
- SStream_concat0(O, ", fpexc");
+ SStream_concat0(O, ", fpexc");
+ ARM_addReg(MI, ARM_REG_FPEXC);
return;
break;
case 20:
// VMRS_FPINST
- SStream_concat0(O, ", fpinst");
+ SStream_concat0(O, ", fpinst");
+ ARM_addReg(MI, ARM_REG_FPINST);
return;
break;
case 21:
// VMRS_FPINST2
- SStream_concat0(O, ", fpinst2");
+ SStream_concat0(O, ", fpinst2");
+ ARM_addReg(MI, ARM_REG_FPINST2);
return;
break;
case 22:
// VMRS_FPSID
- SStream_concat0(O, ", fpsid");
+ SStream_concat0(O, ", fpsid");
+ ARM_addReg(MI, ARM_REG_FPSID);
return;
break;
case 23:
// VMRS_MVFR0
- SStream_concat0(O, ", mvfr0");
+ SStream_concat0(O, ", mvfr0");
+ ARM_addReg(MI, ARM_REG_MVFR0);
return;
break;
case 24:
// VMRS_MVFR1
- SStream_concat0(O, ", mvfr1");
+ SStream_concat0(O, ", mvfr1");
+ ARM_addReg(MI, ARM_REG_MVFR1);
return;
break;
case 25:
// VMRS_MVFR2
- SStream_concat0(O, ", mvfr2");
+ SStream_concat0(O, ", mvfr2");
+ ARM_addReg(MI, ARM_REG_MVFR2);
return;
break;
case 26:
@@ -7453,7 +7521,8 @@
break;
case 46:
// sysLDMDA_UPD, sysLDMDB_UPD, sysLDMIA_UPD, sysLDMIB_UPD, sysSTMDA_UPD, ...
- SStream_concat0(O, " ^");
+ SStream_concat0(O, " ^");
+ ARM_addUserMode(MI);
return;
break;
case 47:
@@ -7666,7 +7735,8 @@
break;
case 20:
// sysLDMDA, sysLDMDB, sysLDMIA, sysLDMIB, sysSTMDA, sysSTMDB, sysSTMIA, ...
- SStream_concat0(O, " ^");
+ SStream_concat0(O, " ^");
+ ARM_addUserMode(MI);
return;
break;
case 21:
diff --git a/arch/ARM/ARMInstPrinter.c b/arch/ARM/ARMInstPrinter.c
index bd7335c..8d2a1fe 100644
--- a/arch/ARM/ARMInstPrinter.c
+++ b/arch/ARM/ARMInstPrinter.c
@@ -155,10 +155,13 @@
void ARM_getRegName(cs_struct *handle, int value)
{
- if (value == CS_OPT_SYNTAX_NOREGNAME)
+ if (value == CS_OPT_SYNTAX_NOREGNAME) {
handle->get_regname = getRegisterName2;
- else
+ handle->reg_name = ARM_reg_name2;;
+ } else {
handle->get_regname = getRegisterName;
+ handle->reg_name = ARM_reg_name;;
+ }
}
/// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
@@ -296,7 +299,7 @@
{
MCRegisterInfo *MRI = (MCRegisterInfo *)Info;
- unsigned Opcode = MCInst_getOpcode(MI), tmp, i;
+ unsigned Opcode = MCInst_getOpcode(MI), tmp, i, pubOpcode;
switch(Opcode) {
// Check for HINT instructions w/ canonical names.
@@ -304,11 +307,11 @@
case ARM_tHINT:
case ARM_t2HINT:
switch (MCOperand_getImm(MCInst_getOperand(MI, 0))) {
- case 0: SStream_concat0(O, "nop"); break;
- case 1: SStream_concat0(O, "yield"); break;
- case 2: SStream_concat0(O, "wfe"); break;
- case 3: SStream_concat0(O, "wfi"); break;
- case 4: SStream_concat0(O, "sev"); break;
+ case 0: SStream_concat0(O, "nop"); pubOpcode = ARM_INS_NOP; break;
+ case 1: SStream_concat0(O, "yield"); pubOpcode = ARM_INS_YIELD; break;
+ case 2: SStream_concat0(O, "wfe"); pubOpcode = ARM_INS_WFE; break;
+ case 3: SStream_concat0(O, "wfi"); pubOpcode = ARM_INS_WFI; break;
+ case 4: SStream_concat0(O, "sev"); pubOpcode = ARM_INS_SEV; break;
case 5:
// FIXME: HasV80Ops becomes a mode
//if ((ARM_getFeatureBits(MI->csh->mode) & ARM_HasV8Ops)) {
@@ -318,6 +321,7 @@
// Fallthrough for non-v8
SStream_concat0(O, "sevl");
+ pubOpcode = ARM_INS_SEVL;
break;
default:
// Anything else should just print normally.
@@ -326,7 +330,10 @@
}
printPredicateOperand(MI, 1, O);
if (Opcode == ARM_t2HINT)
- SStream_concat0(O, ".w"); // FIXME: expose this in register-size of insn?
+ SStream_concat0(O, ".w");
+
+ MCInst_setOpcodePub(MI, pubOpcode);
+
return;
// Check for MOVs and print canonical forms, instead.
@@ -421,6 +428,7 @@
MCInst_getNumOperands(MI) > 5) {
// Should only print PUSH if there are at least two registers in the list.
SStream_concat0(O, "push");
+ MCInst_setOpcodePub(MI, ARM_INS_PUSH);
printPredicateOperand(MI, 2, O);
if (Opcode == ARM_t2STMDB_UPD)
SStream_concat0(O, ".w");
@@ -434,6 +442,7 @@
if (MCOperand_getReg(MCInst_getOperand(MI, 2)) == ARM_SP &&
MCOperand_getImm(MCInst_getOperand(MI, 3)) == -4) {
SStream_concat0(O, "push");
+ MCInst_setOpcodePub(MI, ARM_INS_PUSH);
printPredicateOperand(MI, 4, O);
SStream_concat0(O, "\t{");
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, 1)));
@@ -454,6 +463,7 @@
MCInst_getNumOperands(MI) > 5) {
// Should only print POP if there are at least two registers in the list.
SStream_concat0(O, "pop");
+ MCInst_setOpcodePub(MI, ARM_INS_POP);
printPredicateOperand(MI, 2, O);
if (Opcode == ARM_t2LDMIA_UPD)
SStream_concat0(O, ".w");
@@ -467,6 +477,7 @@
if (MCOperand_getReg(MCInst_getOperand(MI, 2)) == ARM_SP &&
MCOperand_getImm(MCInst_getOperand(MI, 4)) == 4) {
SStream_concat0(O, "pop");
+ MCInst_setOpcodePub(MI, ARM_INS_POP);
printPredicateOperand(MI, 5, O);
SStream_concat0(O, "\t{");
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, 0)));
@@ -485,6 +496,7 @@
case ARM_VSTMDDB_UPD:
if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP) {
SStream_concat0(O, "vpush");
+ MCInst_setOpcodePub(MI, ARM_INS_VPUSH);
printPredicateOperand(MI, 2, O);
SStream_concat0(O, "\t");
printRegisterList(MI, 4, O);
@@ -497,6 +509,7 @@
case ARM_VLDMDIA_UPD:
if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP) {
SStream_concat0(O, "vpop");
+ MCInst_setOpcodePub(MI, ARM_INS_VPOP);
printPredicateOperand(MI, 2, O);
SStream_concat0(O, "\t");
printRegisterList(MI, 4, O);
@@ -514,6 +527,7 @@
}
SStream_concat0(O, "ldm");
+ MCInst_setOpcodePub(MI, ARM_INS_LDM);
printPredicateOperand(MI, 1, O);
SStream_concat0(O, "\t");
@@ -1304,16 +1318,33 @@
static void printSetendOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
MCOperand *Op = MCInst_getOperand(MI, OpNum);
- if (MCOperand_getImm(Op))
+ if (MCOperand_getImm(Op)) {
SStream_concat0(O, "be");
- else
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_SETEND;
+ MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].setend = ARM_SETEND_BE;
+ MI->flat_insn->detail->arm.op_count++;
+ }
+ } else {
SStream_concat0(O, "le");
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_SETEND;
+ MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].setend = ARM_SETEND_LE;
+ MI->flat_insn->detail->arm.op_count++;
+ }
+ }
}
static void printCPSIMod(MCInst *MI, unsigned OpNum, SStream *O)
{
MCOperand *Op = MCInst_getOperand(MI, OpNum);
- SStream_concat0(O, ARM_PROC_IModToString((unsigned int)MCOperand_getImm(Op)));
+ unsigned int mode = (unsigned int)MCOperand_getImm(Op);
+
+ SStream_concat0(O, ARM_PROC_IModToString(mode));
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->arm.cps_mode = mode;
+ }
}
static void printCPSIFlag(MCInst *MI, unsigned OpNum, SStream *O)
@@ -1321,17 +1352,19 @@
MCOperand *Op = MCInst_getOperand(MI, OpNum);
unsigned IFlags = (unsigned int)MCOperand_getImm(Op);
int i;
- for (i=2; i >= 0; --i)
- if (IFlags & (1 << i))
- SStream_concat0(O, ARM_PROC_IFlagsToString(1 << i));
- if (IFlags == 0)
+ for (i = 2; i >= 0; --i)
+ if (IFlags & (1 << i)) {
+ SStream_concat0(O, ARM_PROC_IFlagsToString(1 << i));
+ }
+
+ if (IFlags == 0) {
SStream_concat0(O, "none");
+ IFlags = ARM_CPSFLAG_NONE;
+ }
if (MI->csh->detail) {
- 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 = IFlags;
- MI->flat_insn->detail->arm.op_count++;
+ MI->flat_insn->detail->arm.cps_flag = IFlags;
}
}
@@ -1340,6 +1373,7 @@
MCOperand *Op = MCInst_getOperand(MI, OpNum);
unsigned SpecRegRBit = (unsigned)MCOperand_getImm(Op) >> 4;
unsigned Mask = MCOperand_getImm(Op) & 0xf;
+ unsigned reg;
if (ARM_getFeatureBits(MI->csh->mode) & ARM_FeatureMClass) {
unsigned SYSm = (unsigned)MCOperand_getImm(Op);
@@ -1351,41 +1385,41 @@
switch (SYSm) {
default: //llvm_unreachable("Unexpected mask value!");
case 0:
- case 0x800: SStream_concat0(O, "apsr"); return; // with _nzcvq bits is an alias for aspr
- case 0x400: SStream_concat0(O, "apsr_g"); return;
- case 0xc00: SStream_concat0(O, "apsr_nzcvqg"); return;
+ case 0x800: SStream_concat0(O, "apsr"); ARM_addSysReg(MI, ARM_SYSREG_APSR); return; // with _nzcvq bits is an alias for aspr
+ case 0x400: SStream_concat0(O, "apsr_g"); ARM_addSysReg(MI, ARM_SYSREG_APSR_G); return;
+ case 0xc00: SStream_concat0(O, "apsr_nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQG); return;
case 1:
- case 0x801: SStream_concat0(O, "iapsr"); return; // with _nzcvq bits is an alias for iapsr
- case 0x401: SStream_concat0(O, "iapsr_g"); return;
- case 0xc01: SStream_concat0(O, "iapsr_nzcvqg"); return;
+ case 0x801: SStream_concat0(O, "iapsr"); ARM_addSysReg(MI, ARM_SYSREG_IAPSR); return; // with _nzcvq bits is an alias for iapsr
+ case 0x401: SStream_concat0(O, "iapsr_g"); ARM_addSysReg(MI, ARM_SYSREG_IAPSR_G); return;
+ case 0xc01: SStream_concat0(O, "iapsr_nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_IAPSR_NZCVQG); return;
case 2:
- case 0x802: SStream_concat0(O, "eapsr"); return; // with _nzcvq bits is an alias for eapsr
- case 0x402: SStream_concat0(O, "eapsr_g"); return;
- case 0xc02: SStream_concat0(O, "eapsr_nzcvqg"); return;
+ case 0x802: SStream_concat0(O, "eapsr"); ARM_addSysReg(MI, ARM_SYSREG_EAPSR); return; // with _nzcvq bits is an alias for eapsr
+ case 0x402: SStream_concat0(O, "eapsr_g"); ARM_addSysReg(MI, ARM_SYSREG_EAPSR_G); return;
+ case 0xc02: SStream_concat0(O, "eapsr_nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_EAPSR_NZCVQG); return;
case 3:
- case 0x803: SStream_concat0(O, "xpsr"); return; // with _nzcvq bits is an alias for xpsr
- case 0x403: SStream_concat0(O, "xpsr_g"); return;
- case 0xc03: SStream_concat0(O, "xpsr_nzcvqg"); return;
+ case 0x803: SStream_concat0(O, "xpsr"); ARM_addSysReg(MI, ARM_SYSREG_XPSR); return; // with _nzcvq bits is an alias for xpsr
+ case 0x403: SStream_concat0(O, "xpsr_g"); ARM_addSysReg(MI, ARM_SYSREG_XPSR_G); return;
+ case 0xc03: SStream_concat0(O, "xpsr_nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_XPSR_NZCVQG); return;
case 5:
- case 0x805: SStream_concat0(O, "ipsr"); return;
+ case 0x805: SStream_concat0(O, "ipsr"); ARM_addSysReg(MI, ARM_SYSREG_IPSR); return;
case 6:
- case 0x806: SStream_concat0(O, "epsr"); return;
+ case 0x806: SStream_concat0(O, "epsr"); ARM_addSysReg(MI, ARM_SYSREG_EPSR); return;
case 7:
- case 0x807: SStream_concat0(O, "iepsr"); return;
+ case 0x807: SStream_concat0(O, "iepsr"); ARM_addSysReg(MI, ARM_SYSREG_IEPSR); return;
case 8:
- case 0x808: SStream_concat0(O, "msp"); return;
+ case 0x808: SStream_concat0(O, "msp"); ARM_addSysReg(MI, ARM_SYSREG_MSP); return;
case 9:
- case 0x809: SStream_concat0(O, "psp"); return;
+ case 0x809: SStream_concat0(O, "psp"); ARM_addSysReg(MI, ARM_SYSREG_PSP); return;
case 0x10:
- case 0x810: SStream_concat0(O, "primask"); return;
+ case 0x810: SStream_concat0(O, "primask"); ARM_addSysReg(MI, ARM_SYSREG_PRIMASK); return;
case 0x11:
- case 0x811: SStream_concat0(O, "basepri"); return;
+ case 0x811: SStream_concat0(O, "basepri"); ARM_addSysReg(MI, ARM_SYSREG_BASEPRI); return;
case 0x12:
- case 0x812: SStream_concat0(O, "basepri_max"); return;
+ case 0x812: SStream_concat0(O, "basepri_max"); ARM_addSysReg(MI, ARM_SYSREG_BASEPRI_MAX); return;
case 0x13:
- case 0x813: SStream_concat0(O, "faultmask"); return;
+ case 0x813: SStream_concat0(O, "faultmask"); ARM_addSysReg(MI, ARM_SYSREG_FAULTMASK); return;
case 0x14:
- case 0x814: SStream_concat0(O, "control"); return;
+ case 0x814: SStream_concat0(O, "control"); ARM_addSysReg(MI, ARM_SYSREG_CONTROL); return;
}
}
@@ -1395,23 +1429,63 @@
SStream_concat0(O, "APSR_");
switch (Mask) {
default: // llvm_unreachable("Unexpected mask value!");
- case 4: SStream_concat0(O, "g"); return;
- case 8: SStream_concat0(O, "nzcvq"); return;
- case 12: SStream_concat0(O, "nzcvqg"); return;
+ case 4: SStream_concat0(O, "g"); ARM_addSysReg(MI, ARM_SYSREG_APSR_G); return;
+ case 8: SStream_concat0(O, "nzcvq"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQ); return;
+ case 12: SStream_concat0(O, "nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQG); return;
}
}
- if (SpecRegRBit)
+ reg = 0;
+ if (SpecRegRBit) {
SStream_concat0(O, "SPSR");
- else
- SStream_concat0(O, "CPSR");
+ if (Mask) {
+ SStream_concat0(O, "_");
+ if (Mask & 8) {
+ SStream_concat0(O, "f");
+ reg += ARM_SYSREG_SPSR_F;
+ }
- if (Mask) {
- SStream_concat0(O, "_");
- if (Mask & 8) SStream_concat0(O, "f");
- if (Mask & 4) SStream_concat0(O, "s");
- if (Mask & 2) SStream_concat0(O, "x");
- if (Mask & 1) SStream_concat0(O, "c");
+ if (Mask & 4) {
+ SStream_concat0(O, "s");
+ reg += ARM_SYSREG_SPSR_S;
+ }
+
+ if (Mask & 2) {
+ SStream_concat0(O, "x");
+ reg += ARM_SYSREG_SPSR_X;
+ }
+
+ if (Mask & 1) {
+ SStream_concat0(O, "c");
+ reg += ARM_SYSREG_SPSR_C;
+ }
+ ARM_addSysReg(MI, reg);
+ }
+ } else {
+ SStream_concat0(O, "CPSR");
+ if (Mask) {
+ SStream_concat0(O, "_");
+ if (Mask & 8) {
+ SStream_concat0(O, "f");
+ reg += ARM_SYSREG_CPSR_F;
+ }
+
+ if (Mask & 4) {
+ SStream_concat0(O, "s");
+ reg += ARM_SYSREG_CPSR_S;
+ }
+
+ if (Mask & 2) {
+ SStream_concat0(O, "x");
+ reg += ARM_SYSREG_CPSR_X;
+ }
+
+ if (Mask & 1) {
+ SStream_concat0(O, "c");
+ reg += ARM_SYSREG_CPSR_C;
+ }
+ ARM_addSysReg(MI, reg);
+ }
}
}
@@ -1446,9 +1520,9 @@
if (MCOperand_getReg(MCInst_getOperand(MI, OpNum))) {
//assert(MCOperand_getReg(MCInst_getOperand(MI, OpNum)) == ARM_CPSR &&
// "Expect ARM CPSR register!");
+ SStream_concat0(O, "s");
if (MI->csh->detail)
MI->flat_insn->detail->arm.update_flags = true;
- SStream_concat0(O, "s");
}
}
@@ -1472,20 +1546,24 @@
static void printPImmediate(MCInst *MI, unsigned OpNum, SStream *O)
{
- SStream_concat(O, "p%u", MCOperand_getImm(MCInst_getOperand(MI, OpNum)));
+ unsigned imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+
+ SStream_concat(O, "p%u", imm);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_PIMM;
- MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = imm;
MI->flat_insn->detail->arm.op_count++;
}
}
static void printCImmediate(MCInst *MI, unsigned OpNum, SStream *O)
{
- SStream_concat(O, "c%u", MCOperand_getImm(MCInst_getOperand(MI, OpNum)));
+ unsigned imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+
+ SStream_concat(O, "c%u", imm);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_CIMM;
- MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = imm;
MI->flat_insn->detail->arm.op_count++;
}
}
@@ -1564,7 +1642,6 @@
}
}
-// TODO
static void printThumbITMask(MCInst *MI, unsigned OpNum, SStream *O)
{
// (3 - the number of trailing zeros) is the number of then / else.
@@ -2040,9 +2117,7 @@
else
SStream_concat(O, "[%u]",tmp);
if (MI->csh->detail) {
- 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;
- MI->flat_insn->detail->arm.op_count++;
+ MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].vector_index = tmp;
}
}
@@ -2424,4 +2499,43 @@
SStream_concat0(O, "}");
}
+void ARM_addVectorDataType(MCInst *MI, arm_vectordata_type vd)
+{
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->arm.vector_data = vd;
+ }
+}
+
+void ARM_addVectorDataSize(MCInst *MI, int size)
+{
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->arm.vector_size = size;
+ }
+}
+
+void ARM_addReg(MCInst *MI, int reg)
+{
+ 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.op_count++;
+ }
+}
+
+void ARM_addUserMode(MCInst *MI)
+{
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->arm.usermode = true;
+ }
+}
+
+void ARM_addSysReg(MCInst *MI, arm_sysreg reg)
+{
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_SYSREG;
+ MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = reg;
+ MI->flat_insn->detail->arm.op_count++;
+ }
+}
+
#endif
diff --git a/arch/ARM/ARMInstPrinter.h b/arch/ARM/ARMInstPrinter.h
index 40847ba..169d610 100644
--- a/arch/ARM/ARMInstPrinter.h
+++ b/arch/ARM/ARMInstPrinter.h
@@ -27,4 +27,17 @@
// setup handle->get_regname
void ARM_getRegName(cs_struct *handle, int value);
+// specify vector data type for vector instructions
+void ARM_addVectorDataType(MCInst *MI, arm_vectordata_type vd);
+
+void ARM_addVectorDataSize(MCInst *MI, int size);
+
+void ARM_addReg(MCInst *MI, int reg);
+
+// load usermode registers (LDM, STM)
+void ARM_addUserMode(MCInst *MI);
+
+// sysreg for MRS/MSR
+void ARM_addSysReg(MCInst *MI, arm_sysreg reg);
+
#endif
diff --git a/arch/ARM/ARMMapping.c b/arch/ARM/ARMMapping.c
index b2d24653..d42df0f 100644
--- a/arch/ARM/ARMMapping.c
+++ b/arch/ARM/ARMMapping.c
@@ -127,6 +127,119 @@
{ ARM_REG_S30, "s30"},
{ ARM_REG_S31, "s31"},
};
+static name_map reg_name_maps2[] = {
+ { ARM_REG_INVALID, NULL },
+ { ARM_REG_APSR, "apsr"},
+ { ARM_REG_APSR_NZCV, "apsr_nzcv"},
+ { ARM_REG_CPSR, "cpsr"},
+ { ARM_REG_FPEXC, "fpexc"},
+ { ARM_REG_FPINST, "fpinst"},
+ { ARM_REG_FPSCR, "fpscr"},
+ { ARM_REG_FPSCR_NZCV, "fpscr_nzcv"},
+ { ARM_REG_FPSID, "fpsid"},
+ { ARM_REG_ITSTATE, "itstate"},
+ { ARM_REG_LR, "lr"},
+ { ARM_REG_PC, "pc"},
+ { ARM_REG_SP, "sp"},
+ { ARM_REG_SPSR, "spsr"},
+ { ARM_REG_D0, "d0"},
+ { ARM_REG_D1, "d1"},
+ { ARM_REG_D2, "d2"},
+ { ARM_REG_D3, "d3"},
+ { ARM_REG_D4, "d4"},
+ { ARM_REG_D5, "d5"},
+ { ARM_REG_D6, "d6"},
+ { ARM_REG_D7, "d7"},
+ { ARM_REG_D8, "d8"},
+ { ARM_REG_D9, "d9"},
+ { ARM_REG_D10, "d10"},
+ { ARM_REG_D11, "d11"},
+ { ARM_REG_D12, "d12"},
+ { ARM_REG_D13, "d13"},
+ { ARM_REG_D14, "d14"},
+ { ARM_REG_D15, "d15"},
+ { ARM_REG_D16, "d16"},
+ { ARM_REG_D17, "d17"},
+ { ARM_REG_D18, "d18"},
+ { ARM_REG_D19, "d19"},
+ { ARM_REG_D20, "d20"},
+ { ARM_REG_D21, "d21"},
+ { ARM_REG_D22, "d22"},
+ { ARM_REG_D23, "d23"},
+ { ARM_REG_D24, "d24"},
+ { ARM_REG_D25, "d25"},
+ { ARM_REG_D26, "d26"},
+ { ARM_REG_D27, "d27"},
+ { ARM_REG_D28, "d28"},
+ { ARM_REG_D29, "d29"},
+ { ARM_REG_D30, "d30"},
+ { ARM_REG_D31, "d31"},
+ { ARM_REG_FPINST2, "fpinst2"},
+ { ARM_REG_MVFR0, "mvfr0"},
+ { ARM_REG_MVFR1, "mvfr1"},
+ { ARM_REG_MVFR2, "mvfr2"},
+ { ARM_REG_Q0, "q0"},
+ { ARM_REG_Q1, "q1"},
+ { ARM_REG_Q2, "q2"},
+ { ARM_REG_Q3, "q3"},
+ { ARM_REG_Q4, "q4"},
+ { ARM_REG_Q5, "q5"},
+ { ARM_REG_Q6, "q6"},
+ { ARM_REG_Q7, "q7"},
+ { ARM_REG_Q8, "q8"},
+ { ARM_REG_Q9, "q9"},
+ { ARM_REG_Q10, "q10"},
+ { ARM_REG_Q11, "q11"},
+ { ARM_REG_Q12, "q12"},
+ { ARM_REG_Q13, "q13"},
+ { ARM_REG_Q14, "q14"},
+ { ARM_REG_Q15, "q15"},
+ { ARM_REG_R0, "r0"},
+ { ARM_REG_R1, "r1"},
+ { ARM_REG_R2, "r2"},
+ { ARM_REG_R3, "r3"},
+ { ARM_REG_R4, "r4"},
+ { ARM_REG_R5, "r5"},
+ { ARM_REG_R6, "r6"},
+ { ARM_REG_R7, "r7"},
+ { ARM_REG_R8, "r8"},
+ { ARM_REG_R9, "r9"},
+ { ARM_REG_R10, "r10"},
+ { ARM_REG_R11, "r11"},
+ { ARM_REG_R12, "r12"},
+ { ARM_REG_S0, "s0"},
+ { ARM_REG_S1, "s1"},
+ { ARM_REG_S2, "s2"},
+ { ARM_REG_S3, "s3"},
+ { ARM_REG_S4, "s4"},
+ { ARM_REG_S5, "s5"},
+ { ARM_REG_S6, "s6"},
+ { ARM_REG_S7, "s7"},
+ { ARM_REG_S8, "s8"},
+ { ARM_REG_S9, "s9"},
+ { ARM_REG_S10, "s10"},
+ { ARM_REG_S11, "s11"},
+ { ARM_REG_S12, "s12"},
+ { ARM_REG_S13, "s13"},
+ { ARM_REG_S14, "s14"},
+ { ARM_REG_S15, "s15"},
+ { ARM_REG_S16, "s16"},
+ { ARM_REG_S17, "s17"},
+ { ARM_REG_S18, "s18"},
+ { ARM_REG_S19, "s19"},
+ { ARM_REG_S20, "s20"},
+ { ARM_REG_S21, "s21"},
+ { ARM_REG_S22, "s22"},
+ { ARM_REG_S23, "s23"},
+ { ARM_REG_S24, "s24"},
+ { ARM_REG_S25, "s25"},
+ { ARM_REG_S26, "s26"},
+ { ARM_REG_S27, "s27"},
+ { ARM_REG_S28, "s28"},
+ { ARM_REG_S29, "s29"},
+ { ARM_REG_S30, "s30"},
+ { ARM_REG_S31, "s31"},
+};
#endif
const char *ARM_reg_name(csh handle, unsigned int reg)
@@ -141,6 +254,18 @@
#endif
}
+const char *ARM_reg_name2(csh handle, unsigned int reg)
+{
+#ifndef CAPSTONE_DIET
+ if (reg >= ARM_REG_MAX)
+ return NULL;
+
+ return reg_name_maps2[reg].name;
+#else
+ return NULL;
+#endif
+}
+
static insn_map insns[] = {
// dummy item
{
@@ -13880,6 +14005,16 @@
{ ARM_INS_MOVS, "movs" },
{ ARM_INS_POP, "pop" },
{ ARM_INS_PUSH, "push" },
+
+ // special instructions
+ { ARM_INS_NOP, "nop" },
+ { ARM_INS_YIELD, "yield" },
+ { ARM_INS_WFE, "wfe" },
+ { ARM_INS_WFI, "wfi" },
+ { ARM_INS_SEV, "sev" },
+ { ARM_INS_SEVL, "sevl" },
+ { ARM_INS_VPUSH, "vpush" },
+ { ARM_INS_VPOP, "vpop" },
};
#endif
diff --git a/arch/ARM/ARMMapping.h b/arch/ARM/ARMMapping.h
index 6aad98c..f537e55 100644
--- a/arch/ARM/ARMMapping.h
+++ b/arch/ARM/ARMMapping.h
@@ -9,6 +9,7 @@
// return name of regiser in friendly string
const char *ARM_reg_name(csh handle, unsigned int reg);
+const char *ARM_reg_name2(csh handle, unsigned int reg);
// given internal insn id, return public instruction ID
void ARM_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
diff --git a/arch/Mips/MipsGenAsmWriter.inc b/arch/Mips/MipsGenAsmWriter.inc
index 5d4de76..a159676 100644
--- a/arch/Mips/MipsGenAsmWriter.inc
+++ b/arch/Mips/MipsGenAsmWriter.inc
@@ -4419,7 +4419,7 @@
// Fragment 0 encoded into 3 bits for 7 unique commands.
- //printf("Frag-0: %"PRIu64"\n", (Bits >> 14) & 7);
+ printf("Frag-0: %"PRIu64"\n", (Bits >> 14) & 7);
switch ((Bits >> 14) & 7) {
default: // unreachable.
case 0:
@@ -4461,7 +4461,7 @@
// Fragment 1 encoded into 4 bits for 15 unique commands.
- //printf("Frag-1: %"PRIu64"\n", (Bits >> 17) & 15);
+ printf("Frag-1: %"PRIu64"\n", (Bits >> 17) & 15);
switch ((Bits >> 17) & 15) {
default: // unreachable.
case 0:
@@ -4551,7 +4551,7 @@
// Fragment 2 encoded into 4 bits for 11 unique commands.
- //printf("Frag-2: %"PRIu64"\n", (Bits >> 21) & 15);
+ printf("Frag-2: %"PRIu64"\n", (Bits >> 21) & 15);
switch ((Bits >> 21) & 15) {
default: // unreachable.
case 0:
@@ -4619,7 +4619,7 @@
// Fragment 3 encoded into 4 bits for 15 unique commands.
- //printf("Frag-3: %"PRIu64"\n", (Bits >> 25) & 15);
+ printf("Frag-3: %"PRIu64"\n", (Bits >> 25) & 15);
switch ((Bits >> 25) & 15) {
default: // unreachable.
case 0:
@@ -4714,7 +4714,7 @@
// Fragment 4 encoded into 3 bits for 5 unique commands.
- //printf("Frag-4: %"PRIu64"\n", (Bits >> 29) & 7);
+ printf("Frag-4: %"PRIu64"\n", (Bits >> 29) & 7);
switch ((Bits >> 29) & 7) {
default: // unreachable.
case 0:
@@ -4741,7 +4741,7 @@
// Fragment 5 encoded into 2 bits for 3 unique commands.
- //printf("Frag-5: %"PRIu64"\n", (Bits >> 32) & 3);
+ printf("Frag-5: %"PRIu64"\n", (Bits >> 32) & 3);
switch ((Bits >> 32) & 3) {
default: // unreachable.
case 0:
@@ -4761,7 +4761,7 @@
// Fragment 6 encoded into 1 bits for 2 unique commands.
- //printf("Frag-6: %"PRIu64"\n", (Bits >> 34) & 1);
+ printf("Frag-6: %"PRIu64"\n", (Bits >> 34) & 1);
if ((Bits >> 34) & 1) {
// DEXT, DEXTM, DEXTU, DINS, DINSM, DINSU, EXT, EXT_MM, INS, INS_MM, MADD...
printOperand(MI, 3, O);
diff --git a/bindings/java/capstone/Arm_const.java b/bindings/java/capstone/Arm_const.java
index bdce806..78dda57 100644
--- a/bindings/java/capstone/Arm_const.java
+++ b/bindings/java/capstone/Arm_const.java
@@ -36,6 +36,41 @@
public static final int ARM_CC_LE = 14;
public static final int ARM_CC_AL = 15;
+ // Special registers for MSR
+
+ public static final int ARM_SYSREG_INVALID = 0;
+ public static final int ARM_SYSREG_SPSR_C = 1;
+ public static final int ARM_SYSREG_SPSR_X = 2;
+ public static final int ARM_SYSREG_SPSR_S = 4;
+ public static final int ARM_SYSREG_SPSR_F = 8;
+ public static final int ARM_SYSREG_CPSR_C = 16;
+ public static final int ARM_SYSREG_CPSR_X = 32;
+ public static final int ARM_SYSREG_CPSR_S = 64;
+ public static final int ARM_SYSREG_CPSR_F = 128;
+ public static final int ARM_SYSREG_APSR = 256;
+ public static final int ARM_SYSREG_APSR_G = 257;
+ public static final int ARM_SYSREG_APSR_NZCVQ = 258;
+ public static final int ARM_SYSREG_APSR_NZCVQG = 259;
+ public static final int ARM_SYSREG_IAPSR = 260;
+ public static final int ARM_SYSREG_IAPSR_G = 261;
+ public static final int ARM_SYSREG_IAPSR_NZCVQG = 262;
+ public static final int ARM_SYSREG_EAPSR = 263;
+ public static final int ARM_SYSREG_EAPSR_G = 264;
+ public static final int ARM_SYSREG_EAPSR_NZCVQG = 265;
+ public static final int ARM_SYSREG_XPSR = 266;
+ public static final int ARM_SYSREG_XPSR_G = 267;
+ public static final int ARM_SYSREG_XPSR_NZCVQG = 268;
+ public static final int ARM_SYSREG_IPSR = 269;
+ public static final int ARM_SYSREG_EPSR = 270;
+ public static final int ARM_SYSREG_IEPSR = 271;
+ public static final int ARM_SYSREG_MSP = 272;
+ public static final int ARM_SYSREG_PSP = 273;
+ public static final int ARM_SYSREG_PRIMASK = 274;
+ public static final int ARM_SYSREG_BASEPRI = 275;
+ public static final int ARM_SYSREG_BASEPRI_MAX = 276;
+ public static final int ARM_SYSREG_FAULTMASK = 277;
+ public static final int ARM_SYSREG_CONTROL = 278;
+
// Operand type for instruction's operands
public static final int ARM_OP_INVALID = 0;
@@ -45,6 +80,67 @@
public static final int ARM_OP_IMM = 4;
public static final int ARM_OP_FP = 5;
public static final int ARM_OP_MEM = 6;
+ public static final int ARM_OP_SETEND = 7;
+ public static final int ARM_OP_SYSREG = 8;
+
+ // Operand type for SETEND instruction
+
+ public static final int ARM_SETEND_INVALID = 0;
+ public static final int ARM_SETEND_BE = 1;
+ public static final int ARM_SETEND_LE = 2;
+
+ public static final int ARM_CPSMODE_INVALID = 0;
+ public static final int ARM_CPSMODE_IE = 2;
+ public static final int ARM_CPSMODE_ID = 3;
+
+ // Operand type for SETEND instruction
+
+ public static final int ARM_CPSFLAG_INVALID = 0;
+ public static final int ARM_CPSFLAG_F = 1;
+ public static final int ARM_CPSFLAG_I = 2;
+ public static final int ARM_CPSFLAG_A = 4;
+ public static final int ARM_CPSFLAG_NONE = 16;
+
+ // Data type for elements of vector instructions.
+
+ public static final int ARM_VECTORDATA_INVALID = 0;
+ public static final int ARM_VECTORDATA_I8 = 1;
+ public static final int ARM_VECTORDATA_I16 = 2;
+ public static final int ARM_VECTORDATA_I32 = 3;
+ public static final int ARM_VECTORDATA_I64 = 4;
+ public static final int ARM_VECTORDATA_S8 = 5;
+ public static final int ARM_VECTORDATA_S16 = 6;
+ public static final int ARM_VECTORDATA_S32 = 7;
+ public static final int ARM_VECTORDATA_S64 = 8;
+ public static final int ARM_VECTORDATA_U8 = 9;
+ public static final int ARM_VECTORDATA_U16 = 10;
+ public static final int ARM_VECTORDATA_U32 = 11;
+ public static final int ARM_VECTORDATA_U64 = 12;
+ public static final int ARM_VECTORDATA_P8 = 13;
+ public static final int ARM_VECTORDATA_F32 = 14;
+ public static final int ARM_VECTORDATA_F64 = 15;
+ public static final int ARM_VECTORDATA_F16F64 = 16;
+ public static final int ARM_VECTORDATA_F64F16 = 17;
+ public static final int ARM_VECTORDATA_F32F16 = 18;
+ public static final int ARM_VECTORDATA_F16F32 = 19;
+ public static final int ARM_VECTORDATA_F64F32 = 20;
+ public static final int ARM_VECTORDATA_F32F64 = 21;
+ public static final int ARM_VECTORDATA_S32F32 = 22;
+ public static final int ARM_VECTORDATA_U32F32 = 23;
+ public static final int ARM_VECTORDATA_F32S32 = 24;
+ public static final int ARM_VECTORDATA_F32U32 = 25;
+ public static final int ARM_VECTORDATA_F64S16 = 26;
+ public static final int ARM_VECTORDATA_F32S16 = 27;
+ public static final int ARM_VECTORDATA_F64S32 = 28;
+ public static final int ARM_VECTORDATA_S16F64 = 29;
+ public static final int ARM_VECTORDATA_S16F32 = 30;
+ public static final int ARM_VECTORDATA_S32F64 = 31;
+ public static final int ARM_VECTORDATA_U16F64 = 32;
+ public static final int ARM_VECTORDATA_U16F32 = 33;
+ public static final int ARM_VECTORDATA_U32F64 = 34;
+ public static final int ARM_VECTORDATA_F64U16 = 35;
+ public static final int ARM_VECTORDATA_F32U16 = 36;
+ public static final int ARM_VECTORDATA_F64U32 = 37;
// ARM registers
@@ -599,7 +695,15 @@
public static final int ARM_INS_MOVS = 424;
public static final int ARM_INS_POP = 425;
public static final int ARM_INS_PUSH = 426;
- public static final int ARM_INS_MAX = 427;
+ public static final int ARM_INS_NOP = 427;
+ public static final int ARM_INS_YIELD = 428;
+ public static final int ARM_INS_WFE = 429;
+ public static final int ARM_INS_WFI = 430;
+ public static final int ARM_INS_SEV = 431;
+ public static final int ARM_INS_SEVL = 432;
+ public static final int ARM_INS_VPUSH = 433;
+ public static final int ARM_INS_VPOP = 434;
+ public static final int ARM_INS_MAX = 435;
// Group of ARM instructions
diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py
index e58f9cd..63402bc 100644
--- a/bindings/python/capstone/__init__.py
+++ b/bindings/python/capstone/__init__.py
@@ -478,7 +478,7 @@
def __gen_detail(self):
arch = self._cs.arch
if arch == CS_ARCH_ARM:
- (self.cc, self.update_flags, self.writeback, self.operands) = \
+ (self.usermode, self.vector_size, self.vector_data, self.cps_mode, self.cps_flag, self.cc, self.update_flags, self.writeback, self.operands) = \
arm.get_arch_info(self._detail.arch.arm)
elif arch == CS_ARCH_ARM64:
(self.cc, self.update_flags, self.writeback, self.operands) = \
diff --git a/bindings/python/capstone/arm.py b/bindings/python/capstone/arm.py
index b1863c9..f161047 100644
--- a/bindings/python/capstone/arm.py
+++ b/bindings/python/capstone/arm.py
@@ -24,10 +24,12 @@
('imm', ctypes.c_int32),
('fp', ctypes.c_double),
('mem', ArmOpMem),
+ ('setend', ctypes.c_int),
)
class ArmOp(ctypes.Structure):
_fields_ = (
+ ('vector_index', ctypes.c_int),
('shift', ArmOpShift),
('type', ctypes.c_uint),
('value', ArmOpValue),
@@ -49,9 +51,18 @@
def mem(self):
return self.value.mem
+ @property
+ def setend(self):
+ return self.value.setend
+
class CsArm(ctypes.Structure):
_fields_ = (
+ ('usermode', ctypes.c_bool),
+ ('vector_size', ctypes.c_int),
+ ('vector_data', ctypes.c_int),
+ ('cps_mode', ctypes.c_int),
+ ('cps_flag', ctypes.c_int),
('cc', ctypes.c_uint),
('update_flags', ctypes.c_bool),
('writeback', ctypes.c_bool),
@@ -60,5 +71,5 @@
)
def get_arch_info(a):
- return (a.cc, a.update_flags, a.writeback, copy.deepcopy(a.operands[:a.op_count]))
+ return (a.usermode, a.vector_size, a.vector_data, a.cps_mode, a.cps_flag, a.cc, a.update_flags, a.writeback, copy.deepcopy(a.operands[:a.op_count]))
diff --git a/bindings/python/capstone/arm_const.py b/bindings/python/capstone/arm_const.py
index 0255f95..4edd64e 100644
--- a/bindings/python/capstone/arm_const.py
+++ b/bindings/python/capstone/arm_const.py
@@ -33,6 +33,41 @@
ARM_CC_LE = 14
ARM_CC_AL = 15
+# Special registers for MSR
+
+ARM_SYSREG_INVALID = 0
+ARM_SYSREG_SPSR_C = 1
+ARM_SYSREG_SPSR_X = 2
+ARM_SYSREG_SPSR_S = 4
+ARM_SYSREG_SPSR_F = 8
+ARM_SYSREG_CPSR_C = 16
+ARM_SYSREG_CPSR_X = 32
+ARM_SYSREG_CPSR_S = 64
+ARM_SYSREG_CPSR_F = 128
+ARM_SYSREG_APSR = 256
+ARM_SYSREG_APSR_G = 257
+ARM_SYSREG_APSR_NZCVQ = 258
+ARM_SYSREG_APSR_NZCVQG = 259
+ARM_SYSREG_IAPSR = 260
+ARM_SYSREG_IAPSR_G = 261
+ARM_SYSREG_IAPSR_NZCVQG = 262
+ARM_SYSREG_EAPSR = 263
+ARM_SYSREG_EAPSR_G = 264
+ARM_SYSREG_EAPSR_NZCVQG = 265
+ARM_SYSREG_XPSR = 266
+ARM_SYSREG_XPSR_G = 267
+ARM_SYSREG_XPSR_NZCVQG = 268
+ARM_SYSREG_IPSR = 269
+ARM_SYSREG_EPSR = 270
+ARM_SYSREG_IEPSR = 271
+ARM_SYSREG_MSP = 272
+ARM_SYSREG_PSP = 273
+ARM_SYSREG_PRIMASK = 274
+ARM_SYSREG_BASEPRI = 275
+ARM_SYSREG_BASEPRI_MAX = 276
+ARM_SYSREG_FAULTMASK = 277
+ARM_SYSREG_CONTROL = 278
+
# Operand type for instruction's operands
ARM_OP_INVALID = 0
@@ -42,6 +77,67 @@
ARM_OP_IMM = 4
ARM_OP_FP = 5
ARM_OP_MEM = 6
+ARM_OP_SETEND = 7
+ARM_OP_SYSREG = 8
+
+# Operand type for SETEND instruction
+
+ARM_SETEND_INVALID = 0
+ARM_SETEND_BE = 1
+ARM_SETEND_LE = 2
+
+ARM_CPSMODE_INVALID = 0
+ARM_CPSMODE_IE = 2
+ARM_CPSMODE_ID = 3
+
+# Operand type for SETEND instruction
+
+ARM_CPSFLAG_INVALID = 0
+ARM_CPSFLAG_F = 1
+ARM_CPSFLAG_I = 2
+ARM_CPSFLAG_A = 4
+ARM_CPSFLAG_NONE = 16
+
+# Data type for elements of vector instructions.
+
+ARM_VECTORDATA_INVALID = 0
+ARM_VECTORDATA_I8 = 1
+ARM_VECTORDATA_I16 = 2
+ARM_VECTORDATA_I32 = 3
+ARM_VECTORDATA_I64 = 4
+ARM_VECTORDATA_S8 = 5
+ARM_VECTORDATA_S16 = 6
+ARM_VECTORDATA_S32 = 7
+ARM_VECTORDATA_S64 = 8
+ARM_VECTORDATA_U8 = 9
+ARM_VECTORDATA_U16 = 10
+ARM_VECTORDATA_U32 = 11
+ARM_VECTORDATA_U64 = 12
+ARM_VECTORDATA_P8 = 13
+ARM_VECTORDATA_F32 = 14
+ARM_VECTORDATA_F64 = 15
+ARM_VECTORDATA_F16F64 = 16
+ARM_VECTORDATA_F64F16 = 17
+ARM_VECTORDATA_F32F16 = 18
+ARM_VECTORDATA_F16F32 = 19
+ARM_VECTORDATA_F64F32 = 20
+ARM_VECTORDATA_F32F64 = 21
+ARM_VECTORDATA_S32F32 = 22
+ARM_VECTORDATA_U32F32 = 23
+ARM_VECTORDATA_F32S32 = 24
+ARM_VECTORDATA_F32U32 = 25
+ARM_VECTORDATA_F64S16 = 26
+ARM_VECTORDATA_F32S16 = 27
+ARM_VECTORDATA_F64S32 = 28
+ARM_VECTORDATA_S16F64 = 29
+ARM_VECTORDATA_S16F32 = 30
+ARM_VECTORDATA_S32F64 = 31
+ARM_VECTORDATA_U16F64 = 32
+ARM_VECTORDATA_U16F32 = 33
+ARM_VECTORDATA_U32F64 = 34
+ARM_VECTORDATA_F64U16 = 35
+ARM_VECTORDATA_F32U16 = 36
+ARM_VECTORDATA_F64U32 = 37
# ARM registers
@@ -596,7 +692,15 @@
ARM_INS_MOVS = 424
ARM_INS_POP = 425
ARM_INS_PUSH = 426
-ARM_INS_MAX = 427
+ARM_INS_NOP = 427
+ARM_INS_YIELD = 428
+ARM_INS_WFE = 429
+ARM_INS_WFI = 430
+ARM_INS_SEV = 431
+ARM_INS_SEVL = 432
+ARM_INS_VPUSH = 433
+ARM_INS_VPOP = 434
+ARM_INS_MAX = 435
# Group of ARM instructions
diff --git a/bindings/python/test_arm.py b/bindings/python/test_arm.py
index 6bc482e..5e05c20 100755
--- a/bindings/python/test_arm.py
+++ b/bindings/python/test_arm.py
@@ -8,10 +8,10 @@
from xprint import to_hex, to_x, to_x_32
-ARM_CODE = b"\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"
+ARM_CODE = b"\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"
ARM_CODE2 = b"\xd1\xe8\x00\xf0\xf0\x24\x04\x07\x1f\x3c\xf2\xc0\x00\x00\x4f\xf0\x00\x01\x46\x6c"
-THUMB_CODE2 = b"\x4f\xf0\x00\x01\xbd\xe8\x00\x88\xd1\xe8\x00\xf0"
-THUMB_CODE = b"\x70\x47\xeb\x46\x83\xb0\xc9\x68\x1f\xb1"
+THUMB_CODE = b"\x70\x47\xeb\x46\x83\xb0\xc9\x68\x1f\xb1\x30\xbf\xaf\xf3\x20\x84"
+THUMB_CODE2 = b"\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"
all_tests = (
(CS_ARCH_ARM, CS_MODE_ARM, ARM_CODE, "ARM", None),
@@ -43,6 +43,11 @@
print("\t\toperands[%u].type: C-IMM = %u" % (c, i.imm))
if i.type == ARM_OP_FP:
print("\t\toperands[%u].type: FP = %f" % (c, i.fp))
+ if i.type == ARM_OP_SETEND:
+ if i.setend == ARM_SETEND_BE:
+ print("\t\toperands[%u].type: SETEND = be")
+ else:
+ print("\t\toperands[%u].type: SETEND = le")
if i.type == ARM_OP_MEM:
print("\t\toperands[%u].type: MEM" % c)
if i.mem.base != 0:
@@ -61,6 +66,9 @@
if i.shift.type != ARM_SFT_INVALID and i.shift.value:
print("\t\t\tShift: type = %u, value = %u\n" \
% (i.shift.type, i.shift.value))
+ if i.vector_index != -1:
+ print("\t\t\toperands[%u].vector_index = %u" %(c, i.vector_index))
+
c += 1
if insn.update_flags:
@@ -69,6 +77,16 @@
print("\tWrite-back: True")
if not insn.cc in [ARM_CC_AL, ARM_CC_INVALID]:
print("\tCode condition: %u" % insn.cc)
+ if insn.cps_mode:
+ print("\tCPSI-mode: %u" %(insn.cps_mode))
+ if insn.cps_flag:
+ print("\tCPSI-flag: %u" %(insn.cps_flag))
+ if insn.vector_data:
+ print("\tVector-data: %u" %(insn.vector_data))
+ if insn.vector_size:
+ print("\tVector-size: %u" %(insn.vector_size))
+ if insn.usermode:
+ print("\tUser-mode: True")
# ## Test class Cs
diff --git a/include/arm.h b/include/arm.h
index f7bc4f0..c9f3c3f 100644
--- a/include/arm.h
+++ b/include/arm.h
@@ -50,6 +50,53 @@
ARM_CC_AL // Always (unconditional) Always (unconditional)
} arm_cc;
+typedef enum arm_sysreg {
+ //> Special registers for MSR
+ ARM_SYSREG_INVALID = 0,
+
+ // SPSR* registers can be OR combined
+ ARM_SYSREG_SPSR_C = 1,
+ ARM_SYSREG_SPSR_X = 2,
+ ARM_SYSREG_SPSR_S = 4,
+ ARM_SYSREG_SPSR_F = 8,
+
+ // CPSR* registers can be OR combined
+ ARM_SYSREG_CPSR_C = 16,
+ ARM_SYSREG_CPSR_X = 32,
+ ARM_SYSREG_CPSR_S = 64,
+ ARM_SYSREG_CPSR_F = 128,
+
+ // independent registers
+ ARM_SYSREG_APSR = 256,
+ ARM_SYSREG_APSR_G,
+ ARM_SYSREG_APSR_NZCVQ,
+ ARM_SYSREG_APSR_NZCVQG,
+
+ ARM_SYSREG_IAPSR,
+ ARM_SYSREG_IAPSR_G,
+ ARM_SYSREG_IAPSR_NZCVQG,
+
+ ARM_SYSREG_EAPSR,
+ ARM_SYSREG_EAPSR_G,
+ ARM_SYSREG_EAPSR_NZCVQG,
+
+ ARM_SYSREG_XPSR,
+ ARM_SYSREG_XPSR_G,
+ ARM_SYSREG_XPSR_NZCVQG,
+
+ ARM_SYSREG_IPSR,
+ ARM_SYSREG_EPSR,
+ ARM_SYSREG_IEPSR,
+
+ ARM_SYSREG_MSP,
+ ARM_SYSREG_PSP,
+ ARM_SYSREG_PRIMASK,
+ ARM_SYSREG_BASEPRI,
+ ARM_SYSREG_BASEPRI_MAX,
+ ARM_SYSREG_FAULTMASK,
+ ARM_SYSREG_CONTROL,
+} arm_sysreg;
+
//> Operand type for instruction's operands
typedef enum arm_op_type {
ARM_OP_INVALID = 0, // Uninitialized.
@@ -59,8 +106,88 @@
ARM_OP_IMM, // Immediate operand.
ARM_OP_FP, // Floating-Point immediate operand.
ARM_OP_MEM, // Memory operand
+ ARM_OP_SETEND, // operand for SETEND instruction
+ ARM_OP_SYSREG, // MSR/MSR special register operand
} arm_op_type;
+//> Operand type for SETEND instruction
+typedef enum arm_setend_type {
+ ARM_SETEND_INVALID = 0, // Uninitialized.
+ ARM_SETEND_BE, // BE operand.
+ ARM_SETEND_LE, // LE operand
+} arm_setend_type;
+
+typedef enum arm_cpsmode_type {
+ ARM_CPSMODE_INVALID = 0,
+ ARM_CPSMODE_IE = 2,
+ ARM_CPSMODE_ID = 3
+} arm_cpsmode_type;
+
+//> Operand type for SETEND instruction
+typedef enum arm_cpsflag_type {
+ ARM_CPSFLAG_INVALID = 0,
+ ARM_CPSFLAG_F = 1,
+ ARM_CPSFLAG_I = 2,
+ ARM_CPSFLAG_A = 4,
+ ARM_CPSFLAG_NONE = 16, // no flag
+} arm_cpsflag_type;
+
+//> Data type for elements of vector instructions.
+typedef enum arm_vectordata_type {
+ ARM_VECTORDATA_INVALID = 0,
+
+ // Integer type
+ ARM_VECTORDATA_I8,
+ ARM_VECTORDATA_I16,
+ ARM_VECTORDATA_I32,
+ ARM_VECTORDATA_I64,
+
+ // Signed integer type
+ ARM_VECTORDATA_S8,
+ ARM_VECTORDATA_S16,
+ ARM_VECTORDATA_S32,
+ ARM_VECTORDATA_S64,
+
+ // Unsigned integer type
+ ARM_VECTORDATA_U8,
+ ARM_VECTORDATA_U16,
+ ARM_VECTORDATA_U32,
+ ARM_VECTORDATA_U64,
+
+ // Data type for VMUL/VMULL
+ ARM_VECTORDATA_P8,
+
+ // Floating type
+ ARM_VECTORDATA_F32,
+ ARM_VECTORDATA_F64,
+
+ // Convert float <-> float
+ ARM_VECTORDATA_F16F64, // f16.f64
+ ARM_VECTORDATA_F64F16, // f64.f16
+ ARM_VECTORDATA_F32F16, // f32.f16
+ ARM_VECTORDATA_F16F32, // f32.f16
+ ARM_VECTORDATA_F64F32, // f64.f32
+ ARM_VECTORDATA_F32F64, // f32.f64
+
+ // Convert integer <-> float
+ ARM_VECTORDATA_S32F32, // s32.f32
+ ARM_VECTORDATA_U32F32, // u32.f32
+ ARM_VECTORDATA_F32S32, // f32.s32
+ ARM_VECTORDATA_F32U32, // f32.u32
+ ARM_VECTORDATA_F64S16, // f64.s16
+ ARM_VECTORDATA_F32S16, // f32.s16
+ ARM_VECTORDATA_F64S32, // f64.s32
+ ARM_VECTORDATA_S16F64, // s16.f64
+ ARM_VECTORDATA_S16F32, // s16.f64
+ ARM_VECTORDATA_S32F64, // s32.f64
+ ARM_VECTORDATA_U16F64, // u16.f64
+ ARM_VECTORDATA_U16F32, // u16.f32
+ ARM_VECTORDATA_U32F64, // u32.f64
+ ARM_VECTORDATA_F64U16, // f64.u16
+ ARM_VECTORDATA_F32U16, // f32.u16
+ ARM_VECTORDATA_F64U32, // f64.u32
+} arm_vectordata_type;
+
// Instruction's operand referring to memory
// This is associated with ARM_OP_MEM operand type above
typedef struct arm_op_mem {
@@ -72,21 +199,28 @@
// 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 operand
+ unsigned int reg; // register value for REG/SYSREG operand
int32_t imm; // immediate value for C-IMM, P-IMM or IMM operand
double fp; // floating point value for FP operand
arm_op_mem mem; // base/index/scale/disp value for MEM operand
+ arm_setend_type setend; // SETEND instruction's operand type
};
} cs_arm_op;
// Instruction structure
typedef struct cs_arm {
+ bool usermode; // User-mode registers to be loaded (for LDM/STM instructions)
+ int vector_size; // Scalar size for vector instructions
+ arm_vectordata_type vector_data; // Data type for elements of vector instructions
+ arm_cpsmode_type cps_mode; // CPS mode for CPS instruction
+ arm_cpsflag_type cps_flag; // CPS mode for CPS instruction
arm_cc cc; // conditional code for this insn
bool update_flags; // does this insn update flags?
bool writeback; // does this insn write-back?
@@ -656,6 +790,16 @@
ARM_INS_POP,
ARM_INS_PUSH,
+ // special instructions
+ ARM_INS_NOP,
+ ARM_INS_YIELD,
+ ARM_INS_WFE,
+ ARM_INS_WFI,
+ ARM_INS_SEV,
+ ARM_INS_SEVL,
+ ARM_INS_VPUSH,
+ ARM_INS_VPOP,
+
ARM_INS_MAX, // <-- mark the end of the list of instructions
} arm_insn;
diff --git a/tests/test_arm.c b/tests/test_arm.c
index 879f360..3f1f006 100644
--- a/tests/test_arm.c
+++ b/tests/test_arm.c
@@ -78,6 +78,12 @@
case ARM_OP_CIMM:
printf("\t\toperands[%u].type: C-IMM = %u\n", i, op->imm);
break;
+ case ARM_OP_SETEND:
+ printf("\t\toperands[%u].type: SETEND = %s\n", i, op->setend == ARM_SETEND_BE? "be" : "le");
+ break;
+ case ARM_OP_SYSREG:
+ printf("\t\toperands[%u].type: SYSREG = %u\n", i, op->reg);
+ break;
}
if (op->shift.type != ARM_SFT_INVALID && op->shift.value) {
@@ -89,6 +95,10 @@
printf("\t\t\tShift: %u = %s\n", op->shift.type,
cs_reg_name(handle, op->shift.value));
}
+
+ if (op->vector_index != -1) {
+ printf("\t\toperands[%u].vector_index = %u\n", i, op->vector_index);
+ }
}
if (arm->cc != ARM_CC_AL && arm->cc != ARM_CC_INVALID)
@@ -100,6 +110,21 @@
if (arm->writeback)
printf("\tWrite-back: True\n");
+ if (arm->cps_mode)
+ printf("\tCPSI-mode: %u\n", arm->cps_mode);
+
+ if (arm->cps_flag)
+ printf("\tCPSI-flag: %u\n", arm->cps_flag);
+
+ if (arm->vector_data)
+ printf("\tVector-data: %u\n", arm->vector_data);
+
+ if (arm->vector_size)
+ printf("\tVector-size: %u\n", arm->vector_size);
+
+ if (arm->usermode)
+ printf("\tUser-mode: True\n");
+
printf("\n");
}
@@ -151,7 +176,7 @@
//#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"
+#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"
//#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"
@@ -161,8 +186,8 @@
//#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"
-#define THUMB_CODE2 "\x4f\xf0\x00\x01\xbd\xe8\x00\x88\xd1\xe8\x00\xf0"
+#define THUMB_CODE "\x70\x47\xeb\x46\x83\xb0\xc9\x68\x1f\xb1\x30\xbf\xaf\xf3\x20\x84"
+#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"
struct platform platforms[] = {
{