Merge branch 'next' into cmake2
diff --git a/CREDITS.TXT b/CREDITS.TXT
index fc8cc2f..0961dae 100644
--- a/CREDITS.TXT
+++ b/CREDITS.TXT
@@ -47,4 +47,5 @@
 Ole André Vadla Ravnås (author of the 100th Pull-Request in our Github repo, thanks!)
 Axel "0vercl0k" Souchet (@0vercl0k) & Alex Ionescu: port to MSVC.
 Daniel Pistelli: Cmake support.
+Peter Hlavaty: integrate Capstone for Windows kernel drivers.
 
diff --git a/HACK.TXT b/HACK.TXT
index 18dba98..9cb3f80 100644
--- a/HACK.TXT
+++ b/HACK.TXT
@@ -18,6 +18,7 @@
 ├── include         <- API headers in C language (*.h)
 ├── suite           <- Development test tools - for Capstone developers only
 ├── tests           <- Test code (in C language)
+├── contrib         <- Code contributed by community to help Capstone integration
 
 
 Follow instructions in COMPILE.TXT to see how to compile and run code.
diff --git a/README b/README
index 01e07dd..ceefbc0 100644
--- a/README
+++ b/README
@@ -44,8 +44,8 @@
 binary code that Capstone cannot disassemble, or does that wrongly, so we can
 fix that in the next version
 
-- This package only contains Java & Python bindings. For C#, Go, Ocaml & Ruby,
-refer to the corresponding git repositories.
+- This package only contains Java & Python bindings. For more bindings created
+and maintained by the community, see bindings/README.
 
 
 [Hack]
diff --git a/arch/ARM/ARMInstPrinter.c b/arch/ARM/ARMInstPrinter.c
index 2d18c91..d70bb1b 100644
--- a/arch/ARM/ARMInstPrinter.c
+++ b/arch/ARM/ARMInstPrinter.c
@@ -177,8 +177,12 @@
 
 	//assert (!(ShOpc == ARM_AM_ror && !ShImm) && "Cannot have ror #0");
 	SStream_concat(O, ARM_AM_getShiftOpcStr(ShOpc));
-	if (MI->csh->detail)
-		MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count - 1].shift.type = (arm_shifter)ShOpc;
+	if (MI->csh->detail) {
+			if (MI->csh->doing_mem)
+				MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].shift.type = (arm_shifter)ShOpc;
+			else
+				MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count - 1].shift.type = (arm_shifter)ShOpc;
+	}
 
 	if (ShOpc != ARM_AM_rrx) {
 		SStream_concat(O, " ");
@@ -187,8 +191,12 @@
 		SStream_concat(O, "#%u", translateShiftImm(ShImm));
 		if (_UseMarkup)
 			SStream_concat(O, ">");
-		if (MI->csh->detail)
-			MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count - 1].shift.value = translateShiftImm(ShImm);
+		if (MI->csh->detail) {
+			if (MI->csh->doing_mem)
+				MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].shift.value = translateShiftImm(ShImm);
+			else
+				MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count - 1].shift.value = translateShiftImm(ShImm);
+		}
 	}
 }
 
@@ -264,6 +272,25 @@
 			}
 		}
 	}
+
+	// instruction should not have invalid CC
+	if (insn->detail->arm.cc == ARM_CC_INVALID) {
+		insn->detail->arm.cc = ARM_CC_AL;
+	}
+
+	// manual fix for some special instructions
+	// printf(">>> id: %u, mcid: %u\n", insn->id, mci->Opcode);
+	switch(mci->Opcode) {
+		default:
+			break;
+		case ARM_MOVPCLR:
+			insn->detail->arm.operands[0].type = ARM_OP_REG;
+			insn->detail->arm.operands[0].reg = ARM_REG_PC;
+			insn->detail->arm.operands[1].type = ARM_OP_REG;
+			insn->detail->arm.operands[1].reg = ARM_REG_LR;
+			insn->detail->arm.op_count = 2;
+			break;
+	}
 }
 
 void ARM_printInst(MCInst *MI, SStream *O, void *Info)
@@ -641,6 +668,15 @@
 	}
 
 	SStream_concat(O, "]%s", markup(">"));
+
+	if (MI->csh->detail) {
+		MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].type = ARM_OP_MEM;
+		MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].mem.base = ARM_REG_PC;
+		MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].mem.index = ARM_REG_INVALID;
+		MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].mem.scale = 1;
+		MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].mem.disp = OffImm;
+		MI->flat_insn.arm.op_count++;
+	}
 }
 
 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
@@ -1055,6 +1091,14 @@
 	SStream_concat(O, "%s[", markup("<mem:"));
 	printRegName(MI->csh, O, MCOperand_getReg(MO1));
 
+	if (MI->csh->detail) {
+		MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].type = ARM_OP_MEM;
+		MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].mem.base = MCOperand_getReg(MO1);
+		MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].mem.index = ARM_REG_INVALID;
+		MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].mem.scale = 1;
+		MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].mem.disp = 0;
+	}
+
 	ImmOffs = ARM_AM_getAM5Offset((unsigned int)MCOperand_getImm(MO2));
 	Op = ARM_AM_getAM5Op((unsigned int)MCOperand_getImm(MO2));
 	if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM_sub) {
@@ -1066,8 +1110,15 @@
 			SStream_concat(O, ", %s#%s%u%s", markup("<imm:"),
 					ARM_AM_getAddrOpcStr(ARM_AM_getAM5Op((unsigned int)MCOperand_getImm(MO2))),
 					ImmOffs * 4, markup(">"));
+		if (MI->csh->detail) {
+			MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].mem.disp = ImmOffs * 4;
+		}
 	}
 	SStream_concat(O, "]%s", markup(">"));
+
+	if (MI->csh->detail) {
+		MI->flat_insn.arm.op_count++;
+	}
 }
 
 static void printAddrMode6Operand(MCInst *MI, unsigned OpNum, SStream *O)
diff --git a/arch/X86/X86ATTInstPrinter.c b/arch/X86/X86ATTInstPrinter.c
index d2fa43b..3891fad 100644
--- a/arch/X86/X86ATTInstPrinter.c
+++ b/arch/X86/X86ATTInstPrinter.c
@@ -45,50 +45,37 @@
 
 static void printopaquemem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	SStream_concat(O, "ptr ");
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi8mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	SStream_concat(O, "byte ptr ");
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi16mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	if (MI->Opcode == X86_BOUNDS16rm)
-		SStream_concat(O, "dword ptr ");
-	else
-		SStream_concat(O, "word ptr ");
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi32mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	if (MI->Opcode == X86_BOUNDS32rm)
-		SStream_concat(O, "qword ptr ");
-	else
-		SStream_concat(O, "dword ptr ");
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi64mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	SStream_concat(O, "qword ptr ");
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi128mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	SStream_concat(O, "xmmword ptr ");
 	printMemReference(MI, OpNo, O);
 }
 
 #ifndef CAPSTONE_X86_REDUCE
 static void printi256mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	SStream_concat(O, "ymmword ptr ");
 	printMemReference(MI, OpNo, O);
 }
 
@@ -99,31 +86,26 @@
 
 static void printf32mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	SStream_concat(O, "dword ptr ");
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf64mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	SStream_concat(O, "qword ptr ");
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf80mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	SStream_concat(O, "xword ptr ");
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf128mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	SStream_concat(O, "xmmword ptr ");
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf256mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	SStream_concat(O, "ymmword ptr ");
 	printMemReference(MI, OpNo, O);
 }
 
diff --git a/arch/X86/X86Mapping.c b/arch/X86/X86Mapping.c
index 2d95c48..fb5b56d 100644
--- a/arch/X86/X86Mapping.c
+++ b/arch/X86/X86Mapping.c
@@ -3372,55 +3372,55 @@
 	{
 		X86_CALL16m, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALL16r, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALL32m, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALL32r, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALL64m, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALL64pcrel32, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALL64r, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALLpcrel16, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALLpcrel32, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
@@ -3474,7 +3474,7 @@
 	{
 		X86_CLGI, X86_INS_CLGI,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
@@ -5298,31 +5298,31 @@
 	{
 		X86_FARCALL16i, X86_INS_LCALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_FARCALL16m, X86_INS_LCALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_FARCALL32i, X86_INS_LCALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_FARCALL32m, X86_INS_LCALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_FARCALL64, X86_INS_LCALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RSP, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
@@ -6216,25 +6216,25 @@
 	{
 		X86_INT, X86_INS_INT,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_INT, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_INT1, X86_INS_INT1,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { X86_REG_EFLAGS, 0 }, { 0 }, 0, 0
+		{ 0 }, { X86_REG_EFLAGS, 0 }, { X86_GRP_INT, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_INT3, X86_INS_INT3,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_INT, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_INTO, X86_INS_INTO,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_EFLAGS, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_EFLAGS, 0 }, { 0 }, { X86_GRP_INT, 0 }, 0, 0
 #endif
 	},
 	{
@@ -6264,13 +6264,13 @@
 	{
 		X86_INVLPGA32, X86_INS_INVLPGA,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_EAX, X86_REG_ECX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_EAX, X86_REG_ECX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_INVLPGA64, X86_INS_INVLPGA,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RAX, X86_REG_ECX, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RAX, X86_REG_ECX, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
@@ -6300,19 +6300,19 @@
 	{
 		X86_IRET16, X86_INS_IRET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_IRET32, X86_INS_IRETD,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_IRET64, X86_INS_IRETQ,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
@@ -8160,37 +8160,37 @@
 	{
 		X86_LRETIL, X86_INS_RETF,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_LRETIQ, X86_INS_RETFQ,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_LRETIW, X86_INS_RETF,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_LRETL, X86_INS_RETF,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_LRETQ, X86_INS_RETFQ,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_LRETW, X86_INS_RETF,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
@@ -14352,37 +14352,37 @@
 	{
 		X86_RETIL, X86_INS_RET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_RETIQ, X86_INS_RET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_RETIW, X86_INS_RET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_RETL, X86_INS_RET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_RETQ, X86_INS_RET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_RETW, X86_INS_RET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
@@ -16200,7 +16200,7 @@
 	{
 		X86_SKINIT, X86_INS_SKINIT,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_EAX, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
@@ -16362,7 +16362,7 @@
 	{
 		X86_STGI, X86_INS_STGI,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
@@ -16854,37 +16854,37 @@
 	{
 		X86_SYSCALL, X86_INS_SYSCALL,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_INT, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_SYSENTER, X86_INS_SYSENTER,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_INT, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_SYSEXIT, X86_INS_SYSEXIT,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_SYSEXIT64, X86_INS_SYSEXIT,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_SYSRET, X86_INS_SYSRET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_SYSRET64, X86_INS_SYSRET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
@@ -22674,19 +22674,19 @@
 	{
 		X86_VMCALL, X86_INS_VMCALL,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMCLEARm, X86_INS_VMCLEAR,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMFUNC, X86_INS_VMFUNC,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
@@ -22920,25 +22920,25 @@
 	{
 		X86_VMLAUNCH, X86_INS_VMLAUNCH,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMLOAD32, X86_INS_VMLOAD,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMLOAD64, X86_INS_VMLOAD,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RAX, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RAX, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMMCALL, X86_INS_VMMCALL,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
@@ -24072,67 +24072,67 @@
 	{
 		X86_VMPTRLDm, X86_INS_VMPTRLD,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMPTRSTm, X86_INS_VMPTRST,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMREAD32rm, X86_INS_VMREAD,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMREAD32rr, X86_INS_VMREAD,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMREAD64rm, X86_INS_VMREAD,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMREAD64rr, X86_INS_VMREAD,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMRESUME, X86_INS_VMRESUME,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMRUN32, X86_INS_VMRUN,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMRUN64, X86_INS_VMRUN,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RAX, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RAX, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMSAVE32, X86_INS_VMSAVE,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMSAVE64, X86_INS_VMSAVE,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RAX, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RAX, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
@@ -24294,37 +24294,37 @@
 	{
 		X86_VMWRITE32rm, X86_INS_VMWRITE,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMWRITE32rr, X86_INS_VMWRITE,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMWRITE64rm, X86_INS_VMWRITE,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMWRITE64rr, X86_INS_VMWRITE,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMXOFF, X86_INS_VMXOFF,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMXON, X86_INS_VMXON,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
@@ -31620,7 +31620,7 @@
 	{
 		X86_W64ALLOCA, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RSP, 0 }, { X86_REG_RAX, X86_REG_R10, X86_REG_R11, X86_REG_RSP, X86_REG_EFLAGS, 0 }, { 0 }, 0, 0
+		{ X86_REG_RSP, 0 }, { X86_REG_RAX, X86_REG_R10, X86_REG_R11, X86_REG_RSP, X86_REG_EFLAGS, 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
@@ -33605,55 +33605,55 @@
 	{
 		X86_CALL16m, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALL16r, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALL32m, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALL32r, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALL64m, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALL64pcrel32, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALL64r, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALLpcrel16, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_CALLpcrel32, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
@@ -33695,7 +33695,7 @@
 	{
 		X86_CLGI, X86_INS_CLGI,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
@@ -34787,31 +34787,31 @@
 	{
 		X86_FARCALL16i, X86_INS_LCALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_FARCALL16m, X86_INS_LCALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_FARCALL32i, X86_INS_LCALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_FARCALL32m, X86_INS_LCALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_ESP, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_ESP, 0 }, { 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_FARCALL64, X86_INS_LCALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RSP, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_RSP, 0 }, { 0 }, { X86_GRP_CALL, 0 }, 0, 0
 #endif
 	},
 	{
@@ -35219,25 +35219,25 @@
 	{
 		X86_INT, X86_INS_INT,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_INT, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_INT1, X86_INS_INT1,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { X86_REG_EFLAGS, 0 }, { 0 }, 0, 0
+		{ 0 }, { X86_REG_EFLAGS, 0 }, { X86_GRP_INT, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_INT3, X86_INS_INT3,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_INT, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_INTO, X86_INS_INTO,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_EFLAGS, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_EFLAGS, 0 }, { 0 }, { X86_GRP_INT, 0 }, 0, 0
 #endif
 	},
 	{
@@ -35267,13 +35267,13 @@
 	{
 		X86_INVLPGA32, X86_INS_INVLPGA,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_EAX, X86_REG_ECX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_EAX, X86_REG_ECX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_INVLPGA64, X86_INS_INVLPGA,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RAX, X86_REG_ECX, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RAX, X86_REG_ECX, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
@@ -35303,19 +35303,19 @@
 	{
 		X86_IRET16, X86_INS_IRET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_IRET32, X86_INS_IRETD,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_IRET64, X86_INS_IRETQ,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
@@ -36347,37 +36347,37 @@
 	{
 		X86_LRETIL, X86_INS_RETF,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_LRETIQ, X86_INS_RETFQ,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_LRETIW, X86_INS_RETF,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_LRETL, X86_INS_RETF,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_LRETQ, X86_INS_RETFQ,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_LRETW, X86_INS_RETF,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
@@ -38633,37 +38633,37 @@
 	{
 		X86_RETIL, X86_INS_RET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_RETIQ, X86_INS_RET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_RETIW, X86_INS_RET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_RETL, X86_INS_RET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_RETQ, X86_INS_RET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_RETW, X86_INS_RET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_RET, 0 }, 0, 0
 #endif
 	},
 	{
@@ -40253,7 +40253,7 @@
 	{
 		X86_SKINIT, X86_INS_SKINIT,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_EAX, 0 }, { 0 }, { 0 }, 0, 0
+		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
@@ -40337,7 +40337,7 @@
 	{
 		X86_STGI, X86_INS_STGI,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
@@ -40613,37 +40613,37 @@
 	{
 		X86_SYSCALL, X86_INS_SYSCALL,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_INT, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_SYSENTER, X86_INS_SYSENTER,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_INT, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_SYSEXIT, X86_INS_SYSEXIT,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_SYSEXIT64, X86_INS_SYSEXIT,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_SYSRET, X86_INS_SYSRET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_SYSRET64, X86_INS_SYSRET,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_IRET, 0 }, 0, 0
 #endif
 	},
 	{
@@ -40937,151 +40937,151 @@
 	{
 		X86_VMCALL, X86_INS_VMCALL,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMCLEARm, X86_INS_VMCLEAR,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMFUNC, X86_INS_VMFUNC,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMLAUNCH, X86_INS_VMLAUNCH,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMLOAD32, X86_INS_VMLOAD,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMLOAD64, X86_INS_VMLOAD,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RAX, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RAX, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMMCALL, X86_INS_VMMCALL,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMPTRLDm, X86_INS_VMPTRLD,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMPTRSTm, X86_INS_VMPTRST,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMREAD32rm, X86_INS_VMREAD,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMREAD32rr, X86_INS_VMREAD,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMREAD64rm, X86_INS_VMREAD,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMREAD64rr, X86_INS_VMREAD,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMRESUME, X86_INS_VMRESUME,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMRUN32, X86_INS_VMRUN,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMRUN64, X86_INS_VMRUN,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RAX, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RAX, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMSAVE32, X86_INS_VMSAVE,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ X86_REG_EAX, 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMSAVE64, X86_INS_VMSAVE,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RAX, 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ X86_REG_RAX, 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMWRITE32rm, X86_INS_VMWRITE,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMWRITE32rr, X86_INS_VMWRITE,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_NOT64BITMODE, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMWRITE64rm, X86_INS_VMWRITE,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMWRITE64rr, X86_INS_VMWRITE,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { X86_GRP_MODE64, 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_MODE64, X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMXOFF, X86_INS_VMXOFF,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_VMXON, X86_INS_VMXON,
 #ifndef CAPSTONE_DIET
-		{ 0 }, { 0 }, { 0 }, 0, 0
+		{ 0 }, { 0 }, { X86_GRP_VM, 0 }, 0, 0
 #endif
 	},
 	{
 		X86_W64ALLOCA, X86_INS_CALL,
 #ifndef CAPSTONE_DIET
-		{ X86_REG_RSP, 0 }, { X86_REG_RAX, X86_REG_R10, X86_REG_R11, X86_REG_RSP, X86_REG_EFLAGS, 0 }, { 0 }, 0, 0
+		{ X86_REG_RSP, 0 }, { X86_REG_RAX, X86_REG_R10, X86_REG_R11, X86_REG_RSP, X86_REG_EFLAGS, X86_GRP_CALL, 0 }, { 0 }, 0, 0
 #endif
 	},
 	{
@@ -41709,6 +41709,22 @@
 				insn->detail->groups[insn->detail->groups_count] = X86_GRP_JUMP;
 				insn->detail->groups_count++;
 			}
+
+			switch (insns[i].id) {
+				case X86_OUT8ir:
+				case X86_OUT16ir:
+				case X86_OUT32ir:
+					if (insn->detail->x86.operands[0].imm == -78) {
+						// Writing to port 0xb2 causes an SMI on most platforms
+						// See: http://cs.gmu.edu/~tr-admin/papers/GMU-CS-TR-2011-8.pdf
+						insn->detail->groups[insn->detail->groups_count] = X86_GRP_INT;
+						insn->detail->groups_count++;
+					}
+					break;
+
+				default:
+					break;
+			}
 #endif
 		}
 	}
diff --git a/bindings/README b/bindings/README
new file mode 100644
index 0000000..5f9ab8d
--- /dev/null
+++ b/bindings/README
@@ -0,0 +1,23 @@
+This directory contains bindings for Python, Java & OCaml.
+
+More bindings created & maintained by the community are available as followings.
+
+- Gapstone: Go binding (by Ben Nagy).
+
+	https://github.com/bnagy/gapstone
+
+- Crabstone: Ruby binding (by Ben Nagy).
+
+	https://github.com/bnagy/crabstone
+
+- Capstone-vala: Vala binding (by Pancake).
+
+	https://github.com/radare/capstone-vala
+
+- C# binding (by Matt Graeber).
+
+	https://github.com/mattifestation/capstone
+
+- NodeJS binding (by Jason Oster).
+
+	https://github.com/parasyte/node-capstone
diff --git a/bindings/java/capstone/X86_const.java b/bindings/java/capstone/X86_const.java
index 02f4e3d..b9ff3a6 100644
--- a/bindings/java/capstone/X86_const.java
+++ b/bindings/java/capstone/X86_const.java
@@ -1549,5 +1549,10 @@
 	public static final int X86_GRP_16BITMODE = 32;
 	public static final int X86_GRP_NOT64BITMODE = 33;
 	public static final int X86_GRP_JUMP = 34;
-	public static final int X86_GRP_MAX = 35;
-}
\ No newline at end of file
+	public static final int X86_GRP_VM = 35;
+	public static final int X86_GRP_INT = 36;
+	public static final int X86_GRP_IRET = 37;
+	public static final int X86_GRP_CALL = 38;
+	public static final int X86_GRP_RET = 39;
+	public static final int X86_GRP_MAX = 40;
+}
diff --git a/bindings/python/capstone/x86_const.py b/bindings/python/capstone/x86_const.py
index 1d01ccf..25dd5fb 100644
--- a/bindings/python/capstone/x86_const.py
+++ b/bindings/python/capstone/x86_const.py
@@ -1546,4 +1546,9 @@
 X86_GRP_16BITMODE = 32
 X86_GRP_NOT64BITMODE = 33
 X86_GRP_JUMP = 34
-X86_GRP_MAX = 35
+X86_GRP_VM = 35
+X86_GRP_INT = 36
+X86_GRP_IRET = 37
+X86_GRP_CALL = 38
+X86_GRP_RET = 39
+X86_GRP_MAX = 40
diff --git a/bindings/python/test_detail.py b/bindings/python/test_detail.py
index 03a4dd3..8014231 100755
--- a/bindings/python/test_detail.py
+++ b/bindings/python/test_detail.py
@@ -41,32 +41,32 @@
 )
 
 
+def print_detail(insn):
+    # "data" instruction generated by SKIPDATA option has no detail
+    if insn.id == 0:
+        return
+
+    if len(insn.regs_read) > 0:
+        print("\tImplicit registers read: ", end=''),
+        for m in insn.regs_read:
+            print("%s " % insn.reg_name(m), end=''),
+        print()
+
+    if len(insn.regs_write) > 0:
+        print("\tImplicit registers modified: ", end=''),
+        for m in insn.regs_write:
+            print("%s " % insn.reg_name(m), end=''),
+        print()
+
+    if len(insn.groups) > 0:
+        print("\tThis instruction belongs to groups:", end=''),
+        for m in insn.groups:
+            print("%u" % m, end=''),
+        print()
+
+
 # ## Test class Cs
 def test_class():
-    def print_detail(insn):
-        # "data" instruction generated by SKIPDATA option has no detail
-        if insn.id == 0:
-            return
-
-        if len(insn.regs_read) > 0:
-            print("\tImplicit registers read: ", end=''),
-            for m in insn.regs_read:
-                print("%s " % insn.reg_name(m), end=''),
-            print()
-
-        if len(insn.regs_write) > 0:
-            print("\tImplicit registers modified: ", end=''),
-            for m in insn.regs_write:
-                print("%s " % insn.reg_name(m), end=''),
-            print()
-
-        if len(insn.groups) > 0:
-            print("\tThis instruction belongs to groups:", end=''),
-            for m in insn.groups:
-                print("%u" % m, end=''),
-            print()
-
-
     for (arch, mode, code, comment, syntax) in all_tests:
         print('*' * 40)
         print("Platform: %s" % comment)
diff --git a/contrib/README b/contrib/README
new file mode 100644
index 0000000..e29823d
--- /dev/null
+++ b/contrib/README
@@ -0,0 +1,5 @@
+This directory contains contributions that do not belong to the core engine.
+Code here might be helpful for those who want to integrate Capstone into
+their own projects.
+
+The license of these code was defined by their authors.
diff --git a/contrib/windows_kernel/README b/contrib/windows_kernel/README
new file mode 100644
index 0000000..d080394
--- /dev/null
+++ b/contrib/windows_kernel/README
@@ -0,0 +1,11 @@
+For Windows kernel programming, the SDK does not offer some functions
+needed by Capstone. The missing functions are: 
+
+	- Memory allocations: malloc(), calloc(), realloc() & free().
+	- Format input variables & write out result to char buffer: vsnprintf()
+
+This directory contains some code providing above-mentioned functions, so you can
+integrate Capstone with your Windows-kernel drivers using C++.
+
+All the code here is contributed by Peter Hlavaty <zer0mem@yahoo.com>
+See the full example with Capstone integration at https://github.com/zer0mem/libc.git
diff --git a/contrib/windows_kernel/libc.cpp b/contrib/windows_kernel/libc.cpp
new file mode 100644
index 0000000..101b26a
--- /dev/null
+++ b/contrib/windows_kernel/libc.cpp
@@ -0,0 +1,134 @@
+/**
+ * @file libc.cpp
+ * @author created by: Peter Hlavaty
+ */
+
+#include "libc.h"
+#include <memory>
+
+#pragma warning(push)               
+#pragma warning (disable : 4565)
+
+#ifndef _LIBC_POOL_TAG
+#define _LIBC_POOL_TAG	'colM'
+#endif
+
+// very nice for debug forensics!
+struct MEMBLOCK
+{
+	size_t	size;
+#pragma warning(push)               
+#pragma warning (disable : 4200)
+	char data[0]; 
+#pragma warning(pop)
+};
+
+EXTERN_C
+__drv_when(return!=0, __drv_allocatesMem(pBlock))
+__checkReturn
+__drv_maxIRQL(DISPATCH_LEVEL)
+__bcount_opt(size)
+void* 
+__cdecl malloc(
+	__in size_t size
+	)
+{
+	MEMBLOCK *pBlock = static_cast<MEMBLOCK*>(
+		ExAllocatePoolWithTag(
+			NonPagedPoolNxCacheAligned, 
+			size + sizeof(MEMBLOCK), 
+			_LIBC_POOL_TAG));
+
+	if (nullptr == pBlock)
+		return nullptr;
+
+	pBlock->size = size;	
+	return pBlock->data;
+}
+
+EXTERN_C
+__drv_when(return != 0, __drv_allocatesMem(p))
+__checkReturn
+__drv_maxIRQL(DISPATCH_LEVEL)
+__bcount_opt(size * n)
+void*
+__cdecl calloc(size_t n, size_t size)
+{
+	size_t total = n * size;
+	void *p = malloc(total);
+
+	if (!p) return NULL;
+
+	return memset(p, 0, total);
+}
+
+EXTERN_C
+__drv_when(return!=0, __drv_allocatesMem(inblock))
+__checkReturn
+__drv_maxIRQL(DISPATCH_LEVEL)
+__bcount_opt(size)
+void* 
+__cdecl realloc(
+	__in_opt void* ptr, 
+	__in size_t size
+	)
+{
+	if (!ptr)
+		return malloc(size);
+
+	std::unique_ptr<unsigned char> inblock = std::unique_ptr<unsigned char>(static_cast<unsigned char*>(ptr));
+
+	// alloc new block
+	void* mem = malloc(size);
+	if (!mem)
+		return nullptr;
+
+	// copy from old one, not overflow ..
+	memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data)->size, size));
+	return mem;
+}
+
+EXTERN_C
+__drv_maxIRQL(DISPATCH_LEVEL)
+void 
+__cdecl free(
+	__inout_opt __drv_freesMem(Mem) void* ptr
+	)
+{
+	if (ptr)
+		ExFreePoolWithTag(CONTAINING_RECORD(ptr, MEMBLOCK, data), _LIBC_POOL_TAG);
+}
+
+#pragma warning(pop)
+
+__drv_when(return!=0, __drv_allocatesMem(ptr))
+__checkReturn
+__drv_maxIRQL(DISPATCH_LEVEL)
+__bcount_opt(size)
+void* 
+__cdecl operator new(
+	__in size_t size
+	)
+{
+	return malloc(size);
+}
+
+__drv_maxIRQL(DISPATCH_LEVEL)
+void 
+__cdecl operator delete(
+	__inout void* ptr
+	)
+{
+	free(ptr);
+}
+
+int 
+__cdecl vsnprintf(
+	char *buffer,
+	size_t count,
+	const char *format,
+	va_list argptr
+)
+{	
+	return vsprintf_s(buffer, count, format, argptr);
+}
diff --git a/contrib/windows_kernel/libc.h b/contrib/windows_kernel/libc.h
new file mode 100644
index 0000000..9498bac
--- /dev/null
+++ b/contrib/windows_kernel/libc.h
@@ -0,0 +1,40 @@
+/**
+ * @file libc.h
+ * @author created by: Peter Hlavaty
+ */
+
+#pragma once
+
+#include <ntifs.h>
+
+EXTERN_C
+__drv_when(return!=0, __drv_allocatesMem(pBlock))
+__checkReturn
+__drv_maxIRQL(DISPATCH_LEVEL)
+__bcount_opt(size)
+void* __cdecl malloc(__in size_t size);
+
+
+EXTERN_C
+__drv_when(return != 0, __drv_allocatesMem(p))
+__checkReturn
+__drv_maxIRQL(DISPATCH_LEVEL)
+__bcount_opt(size * n)
+void* __cdecl calloc(size_t n, size_t size);
+
+
+EXTERN_C
+__drv_when(return!=0, __drv_allocatesMem(inblock))
+__checkReturn
+__drv_maxIRQL(DISPATCH_LEVEL)
+__bcount_opt(size)
+void* __cdecl realloc(__in_opt void* ptr, __in size_t size);
+
+
+EXTERN_C
+__drv_maxIRQL(DISPATCH_LEVEL)
+void __cdecl free(__inout_opt __drv_freesMem(Mem) void* ptr);
+
+
+int __cdecl vsnprintf(char *buffer, size_t count,
+	const char *format, va_list argptr);
diff --git a/include/capstone.h b/include/capstone.h
index 2c10b6b..4f8b57e 100644
--- a/include/capstone.h
+++ b/include/capstone.h
@@ -490,7 +490,7 @@
 int cs_op_count(csh handle, cs_insn *insn, unsigned int op_type);
 
 /*
- Retrieve the position of operand of given type in arch.op_info[] array.
+ Retrieve the position of operand of given type in <arch>.operands[] array.
  Later, the operand can be accessed using the returned position.
  Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
 
@@ -502,7 +502,7 @@
  @position: position of the operand to be found. This must be in the range
 			[1, cs_op_count(handle, insn, op_type)]
 
- @return: index of operand of given type @op_type in arch.op_info[] array
+ @return: index of operand of given type @op_type in <arch>.operands[] array
  in instruction @insn, or -1 on failure.
 */
 CAPSTONE_EXPORT
diff --git a/include/x86.h b/include/x86.h
index 116d9b1..d27ddf8 100644
--- a/include/x86.h
+++ b/include/x86.h
@@ -62,7 +62,7 @@
 	X86_REG_R12B, X86_REG_R13B, X86_REG_R14B, X86_REG_R15B, X86_REG_R8D,
 	X86_REG_R9D, X86_REG_R10D, X86_REG_R11D, X86_REG_R12D, X86_REG_R13D,
 	X86_REG_R14D, X86_REG_R15D, X86_REG_R8W, X86_REG_R9W, X86_REG_R10W,
-	X86_REG_R11W, X86_REG_R12W, X86_REG_R13W, X86_REG_R14W, X86_REG_R15W, 
+	X86_REG_R11W, X86_REG_R12W, X86_REG_R13W, X86_REG_R14W, X86_REG_R15W,
 
 	X86_REG_MAX		// <-- mark the end of the list of registers
 } x86_reg;
@@ -141,7 +141,7 @@
 	// SIB base register, or X86_REG_INVALID when irrelevant.
 	x86_reg sib_base;
 
-	// Number of operands of this instruction, 
+	// Number of operands of this instruction,
 	// or 0 when instruction has no operand.
 	uint8_t op_count;
 
@@ -1454,6 +1454,11 @@
 	X86_GRP_NOT64BITMODE,
 
 	X86_GRP_JUMP,	// all jump instructions (conditional+direct+indirect jumps)
+	X86_GRP_VM,	// all virtualization instructions (VT-x + AMD-V)
+	X86_GRP_INT,	// all interrupt instructions (int+syscall)
+	X86_GRP_IRET,	// all interrupt return instructions
+	X86_GRP_CALL,	// all call instructions
+	X86_GRP_RET,	// all call return instructions
 
 	X86_GRP_MAX
 } x86_insn_group;