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[] = {
 		{