x86: remove disp_size, imm_size, op_size. add size to each operand. thanks Gabriel Quadros for some nice ideas
diff --git a/MCInst.h b/MCInst.h
index a76baa5..0efb128 100644
--- a/MCInst.h
+++ b/MCInst.h
@@ -97,9 +97,9 @@
 	cs_insn *flat_insn;	// insn to be exposed to public
 	uint64_t address;	// address of this insn
 	cs_struct *csh;	// save the main csh
-	uint8_t x86_imm_size;	// save immediate size to print immediate properly
+	uint8_t x86opsize;	// opsize for [mem] operand
 
-	// (Optional) instruction prefix, which can be up to 5 bytes.
+	// (Optional) instruction prefix, which can be up to 4 bytes.
 	// A prefix byte gets value 0 when irrelevant.
 	// This is copied from cs_x86 struct
 	uint8_t x86_prefix[4];
diff --git a/arch/X86/X86ATTInstPrinter.c b/arch/X86/X86ATTInstPrinter.c
index 0e0b98b..794f024 100644
--- a/arch/X86/X86ATTInstPrinter.c
+++ b/arch/X86/X86ATTInstPrinter.c
@@ -43,6 +43,15 @@
 static void printMemReference(MCInst *MI, unsigned Op, SStream *O);
 static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
 
+
+static void set_mem_access(MCInst *MI, bool status)
+{
+	if (MI->csh->detail != CS_OPT_ON)
+		return;
+
+	MI->csh->doing_mem = status;
+}
+
 static void printopaquemem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	printMemReference(MI, OpNo, O);
@@ -50,67 +59,88 @@
 
 static void printi8mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 1;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi16mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	if (MI->Opcode == X86_BOUNDS16rm)
+		MI->x86opsize = 4;
+	else
+		MI->x86opsize = 2;
+
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi32mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	if (MI->Opcode == X86_BOUNDS32rm)
+		MI->x86opsize = 8;
+	else
+		MI->x86opsize = 4;
+
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi64mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 8;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi128mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 16;
 	printMemReference(MI, OpNo, O);
 }
 
 #ifndef CAPSTONE_X86_REDUCE
 static void printi256mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 32;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi512mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 64;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf32mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 4;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf64mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 8;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf80mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 10;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf128mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 16;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf256mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 32;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf512mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 64;
 	printMemReference(MI, OpNo, O);
 }
 
@@ -207,57 +237,74 @@
 	}
 
 	SStream_concat0(O, "(");
+	set_mem_access(MI, true);
 
 	printOperand(MI, Op, O);
 
 	SStream_concat(O, ")%s", markup(">"));
+	set_mem_access(MI, false);
 }
 
 static void printDstIdx(MCInst *MI, unsigned Op, SStream *O)
 {
-	SStream_concat(O, "%s%s", markup("<mem:"), "%es:(");
+	// DI accesses are always ES-based on non-64bit mode
+	if (MI->csh->mode != CS_MODE_64)
+		SStream_concat(O, "%s%s", markup("<mem:"), "%es:(");
+	else
+		SStream_concat(O, "%s%s", markup("<mem:"), "(");
+	set_mem_access(MI, true);
+
 	printOperand(MI, Op, O);
 
 	SStream_concat(O, ")%s", markup(">"));
+	set_mem_access(MI, false);
 }
 
 static void printSrcIdx8(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 1;
 	printSrcIdx(MI, OpNo, O);
 }
 
 static void printSrcIdx16(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 2;
 	printSrcIdx(MI, OpNo, O);
 }
 
 static void printSrcIdx32(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 4;
 	printSrcIdx(MI, OpNo, O);
 }
 
 static void printSrcIdx64(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 8;
 	printSrcIdx(MI, OpNo, O);
 }
 
 static void printDstIdx8(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 1;
 	printDstIdx(MI, OpNo, O);
 }
 
 static void printDstIdx16(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 2;
 	printDstIdx(MI, OpNo, O);
 }
 
 static void printDstIdx32(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 4;
 	printDstIdx(MI, OpNo, O);
 }
 
 static void printDstIdx64(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 8;
 	printDstIdx(MI, OpNo, O);
 }
 
@@ -276,6 +323,7 @@
 
 	if (MI->csh->detail) {
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
+		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID;
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID;
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
@@ -304,21 +352,25 @@
 
 static void printMemOffs8(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 1;
 	printMemOffset(MI, OpNo, O);
 }
 
 static void printMemOffs16(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 2;
 	printMemOffset(MI, OpNo, O);
 }
 
 static void printMemOffs32(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 4;
 	printMemOffset(MI, OpNo, O);
 }
 
 static void printMemOffs64(MCInst *MI, unsigned OpNo, SStream *O)
 {
+	MI->x86opsize = 8;
 	printMemOffset(MI, OpNo, O);
 }
 
@@ -362,9 +414,21 @@
 	if (MCOperand_isReg(Op)) {
 		printRegName(O, MCOperand_getReg(Op));
 		if (MI->csh->detail) {
-			MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
-			MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = MCOperand_getReg(Op);
-			MI->flat_insn->detail->x86.op_count++;
+			unsigned int reg = MCOperand_getReg(Op);
+			if (MI->csh->doing_mem) {
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = reg;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = 0;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
+				MI->flat_insn->detail->x86.op_count++;
+			} else {
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = reg;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->csh->regsize_map[reg];
+				MI->flat_insn->detail->x86.op_count++;
+			}
 		}
 	} else if (MCOperand_isImm(Op)) {
 		// Print X86 immediates as signed values.
@@ -381,9 +445,19 @@
 				SStream_concat(O, "%s$-%"PRIu64"%s", markup("<imm:"), -imm, markup(">"));
 		}
 		if (MI->csh->detail) {
-			MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
-			MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
-			MI->flat_insn->detail->x86.op_count++;
+			if (MI->csh->doing_mem) {
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = 0;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = 0;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
+				MI->flat_insn->detail->x86.op_count++;
+			} else {
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
+				MI->flat_insn->detail->x86.op_count++;
+			}
 		}
 	}
 }
@@ -421,6 +495,7 @@
 
 	if (MI->csh->detail) {
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
+		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = MCOperand_getReg(BaseReg);
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = MCOperand_getReg(IndexReg);
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
@@ -517,6 +592,7 @@
 				if (MI->flat_insn->detail->x86.operands[i].type == 0) {
 					MI->flat_insn->detail->x86.operands[i].type = X86_OP_REG;
 					MI->flat_insn->detail->x86.operands[i].reg = reg;
+					MI->flat_insn->detail->x86.operands[i].size = MI->csh->regsize_map[reg];
 					MI->flat_insn->detail->x86.op_count++;
 					break;
 				}
diff --git a/arch/X86/X86Disassembler.c b/arch/X86/X86Disassembler.c
index c121d81..7382754 100644
--- a/arch/X86/X86Disassembler.c
+++ b/arch/X86/X86Disassembler.c
@@ -678,10 +678,7 @@
 		pub->detail->x86.opcode[2] = inter->threeByteEscape;
 	}
 
-	pub->detail->x86.op_size = inter->operandSize;
 	pub->detail->x86.addr_size = inter->addressSize;
-	pub->detail->x86.disp_size = inter->displacementSize;
-	pub->detail->x86.imm_size = inter->immediateSize;
 
 	pub->detail->x86.modrm = inter->orgModRM;
 	pub->detail->x86.sib = inter->sib;
@@ -748,9 +745,6 @@
 				instr->x86_prefix[2] = insn.prefix2;
 				instr->x86_prefix[3] = insn.prefix3;
 			}
-
-			// save immediate size to print immediate properly
-			instr->x86_imm_size = insn.immediateSize;
 		}
 
 		return result;
diff --git a/arch/X86/X86IntelInstPrinter.c b/arch/X86/X86IntelInstPrinter.c
index 86fcbe0..5af451a 100644
--- a/arch/X86/X86IntelInstPrinter.c
+++ b/arch/X86/X86IntelInstPrinter.c
@@ -40,6 +40,15 @@
 static void printMemReference(MCInst *MI, unsigned Op, SStream *O);
 static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
 
+
+static void set_mem_access(MCInst *MI, bool status)
+{
+	if (MI->csh->detail != CS_OPT_ON)
+		return;
+
+	MI->csh->doing_mem = status;
+}
+
 static void printopaquemem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "ptr ");
@@ -49,36 +58,45 @@
 static void printi8mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "byte ptr ");
+	MI->x86opsize = 1;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi16mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	if (MI->Opcode == X86_BOUNDS16rm)
+	if (MI->Opcode == X86_BOUNDS16rm) {
 		SStream_concat0(O, "dword ptr ");
-	else
+		MI->x86opsize = 4;
+	} else {
 		SStream_concat0(O, "word ptr ");
+		MI->x86opsize = 2;
+	}
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi32mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
-	if (MI->Opcode == X86_BOUNDS32rm)
+	if (MI->Opcode == X86_BOUNDS32rm) {
 		SStream_concat0(O, "qword ptr ");
-	else
+		MI->x86opsize = 8;
+	} else {
 		SStream_concat0(O, "dword ptr ");
+		MI->x86opsize = 4;
+	}
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi64mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "qword ptr ");
+	MI->x86opsize = 8;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi128mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "xmmword ptr ");
+	MI->x86opsize = 16;
 	printMemReference(MI, OpNo, O);
 }
 
@@ -86,48 +104,56 @@
 static void printi256mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "ymmword ptr ");
+	MI->x86opsize = 32;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printi512mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "zmmword ptr ");
+	MI->x86opsize = 64;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf32mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "dword ptr ");
+	MI->x86opsize = 4;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf64mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "qword ptr ");
+	MI->x86opsize = 8;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf80mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "xword ptr ");
+	MI->x86opsize = 10;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf128mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "xmmword ptr ");
+	MI->x86opsize = 16;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf256mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "ymmword ptr ");
+	MI->x86opsize = 32;
 	printMemReference(MI, OpNo, O);
 }
 
 static void printf512mem(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "zmmword ptr ");
+	MI->x86opsize = 64;
 	printMemReference(MI, OpNo, O);
 }
 
@@ -222,8 +248,10 @@
 	}
 
 	SStream_concat0(O, "[");
+	set_mem_access(MI, true);
 	printOperand(MI, Op, O);
 	SStream_concat0(O, "]");
+	set_mem_access(MI, false);
 }
 
 static void printDstIdx(MCInst *MI, unsigned Op, SStream *O)
@@ -233,55 +261,65 @@
 		SStream_concat(O, "es:[");
 	else
 		SStream_concat(O, "[");
+	set_mem_access(MI, true);
 	printOperand(MI, Op, O);
 	SStream_concat0(O, "]");
+	set_mem_access(MI, false);
 }
 
 void printSrcIdx8(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "byte ptr ");
+	MI->x86opsize = 1;
 	printSrcIdx(MI, OpNo, O);
 }
 
 void printSrcIdx16(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "word ptr ");
+	MI->x86opsize = 2;
 	printSrcIdx(MI, OpNo, O);
 }
 
 void printSrcIdx32(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "dword ptr ");
+	MI->x86opsize = 4;
 	printSrcIdx(MI, OpNo, O);
 }
 
 void printSrcIdx64(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "qword ptr ");
+	MI->x86opsize = 8;
 	printSrcIdx(MI, OpNo, O);
 }
 
 void printDstIdx8(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "byte ptr ");
+	MI->x86opsize = 1;
 	printDstIdx(MI, OpNo, O);
 }
 
 void printDstIdx16(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "word ptr ");
+	MI->x86opsize = 2;
 	printDstIdx(MI, OpNo, O);
 }
 
 void printDstIdx32(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "dword ptr ");
+	MI->x86opsize = 4;
 	printDstIdx(MI, OpNo, O);
 }
 
 void printDstIdx64(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "qword ptr ");
+	MI->x86opsize = 8;
 	printDstIdx(MI, OpNo, O);
 }
 
@@ -292,6 +330,7 @@
 
 	if (MI->csh->detail) {
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
+		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID;
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID;
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
@@ -329,28 +368,28 @@
 static void printMemOffs8(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "byte ptr ");
-
+	MI->x86opsize = 1;
 	printMemOffset(MI, OpNo, O);
 }
 
 static void printMemOffs16(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "word ptr ");
-
+	MI->x86opsize = 2;
 	printMemOffset(MI, OpNo, O);
-
 }
 
 static void printMemOffs32(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "dword ptr ");
-
+	MI->x86opsize = 4;
 	printMemOffset(MI, OpNo, O);
 }
 
 static void printMemOffs64(MCInst *MI, unsigned OpNo, SStream *O)
 {
 	SStream_concat0(O, "qword ptr ");
+	MI->x86opsize = 8;
 	printMemOffset(MI, OpNo, O);
 }
 
@@ -378,6 +417,7 @@
 					sizeof(MI->flat_insn->detail->x86.operands[0]) * (ARR_SIZE(MI->flat_insn->detail->x86.operands) - 1));
 			MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG;
 			MI->flat_insn->detail->x86.operands[0].reg = reg;
+			MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg];
 			MI->flat_insn->detail->x86.op_count++;
 		}
 
@@ -426,9 +466,21 @@
 	if (MCOperand_isReg(Op)) {
 		printRegName(O, MCOperand_getReg(Op));
 		if (MI->csh->detail) {
-			MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
-			MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = MCOperand_getReg(Op);
-			MI->flat_insn->detail->x86.op_count++;
+			unsigned int reg = MCOperand_getReg(Op);
+			if (MI->csh->doing_mem) {
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = reg;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = 0;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
+				MI->flat_insn->detail->x86.op_count++;
+			} else {
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = reg;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->csh->regsize_map[reg];
+				MI->flat_insn->detail->x86.op_count++;
+			}
 		}
 	} else if (MCOperand_isImm(Op)) {
 		int64_t imm = MCOperand_getImm(Op);
@@ -445,9 +497,19 @@
 		}
 
 		if (MI->csh->detail) {
-			MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
-			MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
-			MI->flat_insn->detail->x86.op_count++;
+			if (MI->csh->doing_mem) {
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = 0;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = 0;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
+				MI->flat_insn->detail->x86.op_count++;
+			} else {
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
+				MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
+				MI->flat_insn->detail->x86.op_count++;
+			}
 		}
 	}
 }
@@ -486,6 +548,7 @@
 
 	if (MI->csh->detail) {
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
+		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = MCOperand_getReg(BaseReg);
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = MCOperand_getReg(IndexReg);
 		MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = (int)ScaleVal;
diff --git a/arch/X86/X86Mapping.c b/arch/X86/X86Mapping.c
index 5e8cea8..ec55cbb 100644
--- a/arch/X86/X86Mapping.c
+++ b/arch/X86/X86Mapping.c
@@ -84,7 +84,7 @@
 	{ X86_REG_BH, "bh" },
 	{ X86_REG_BL, "bl" },
 	{ X86_REG_BP, "bp" },
-	{ X86_REG_BPL, "bpL" },
+	{ X86_REG_BPL, "bpl" },
 	{ X86_REG_BX, "bx" },
 	{ X86_REG_CH, "ch" },
 	{ X86_REG_CL, "cl" },
@@ -313,6 +313,480 @@
 };
 #endif
 
+// register size in non-64bit mode
+uint8_t regsize_map_32 [] = {
+	0,	// 	{ X86_REG_INVALID, NULL },
+	1,	// { X86_REG_AH, "ah" },
+	1,	// { X86_REG_AL, "al" },
+	2,	// { X86_REG_AX, "ax" },
+	1,	// { X86_REG_BH, "bh" },
+	1,	// { X86_REG_BL, "bl" },
+	2,	// { X86_REG_BP, "bp" },
+	1,	// { X86_REG_BPL, "bpl" },
+	2,	// { X86_REG_BX, "bx" },
+	1,	// { X86_REG_CH, "ch" },
+	1,	// { X86_REG_CL, "cl" },
+	2,	// { X86_REG_CS, "cs" },
+	2,	// { X86_REG_CX, "cx" },
+	1,	// { X86_REG_DH, "dh" },
+	2,	// { X86_REG_DI, "di" },
+	1,	// { X86_REG_DIL, "dil" },
+	1,	// { X86_REG_DL, "dl" },
+	2,	// { X86_REG_DS, "ds" },
+	2,	// { X86_REG_DX, "dx" },
+	4,	// { X86_REG_EAX, "eax" },
+	4,	// { X86_REG_EBP, "ebp" },
+	4,	// { X86_REG_EBX, "ebx" },
+	4,	// { X86_REG_ECX, "ecx" },
+	4,	// { X86_REG_EDI, "edi" },
+	4,	// { X86_REG_EDX, "edx" },
+	4,	// { X86_REG_EFLAGS, "flags" },
+	4,	// { X86_REG_EIP, "eip" },
+	4,	// { X86_REG_EIZ, "eiz" },
+	2,	// { X86_REG_ES, "es" },
+	4,	// { X86_REG_ESI, "esi" },
+	4,	// { X86_REG_ESP, "esp" },
+	10,	// { X86_REG_FPSW, "fpsw" },
+	2,	// { X86_REG_FS, "fs" },
+	2,	// { X86_REG_GS, "gs" },
+	2,	// { X86_REG_IP, "ip" },
+	8,	// { X86_REG_RAX, "rax" },
+	8,	// { X86_REG_RBP, "rbp" },
+	8,	// { X86_REG_RBX, "rbx" },
+	8,	// { X86_REG_RCX, "rcx" },
+	8,	// { X86_REG_RDI, "rdi" },
+	8,	// { X86_REG_RDX, "rdx" },
+	8,	// { X86_REG_RIP, "rip" },
+	8,	// { X86_REG_RIZ, "riz" },
+	8,	// { X86_REG_RSI, "rsi" },
+	8,	// { X86_REG_RSP, "rsp" },
+	2,	// { X86_REG_SI, "si" },
+	1,	// { X86_REG_SIL, "sil" },
+	2,	// { X86_REG_SP, "sp" },
+	1,	// { X86_REG_SPL, "spl" },
+	2,	// { X86_REG_SS, "ss" },
+	4,	// { X86_REG_CR0, "cr0" },
+	4,	// { X86_REG_CR1, "cr1" },
+	4,	// { X86_REG_CR2, "cr2" },
+	4,	// { X86_REG_CR3, "cr3" },
+	4,	// { X86_REG_CR4, "cr4" },
+	8,	// { X86_REG_CR5, "cr5" },
+	8,	// { X86_REG_CR6, "cr6" },
+	8,	// { X86_REG_CR7, "cr7" },
+	8,	// { X86_REG_CR8, "cr8" },
+	8,	// { X86_REG_CR9, "cr9" },
+	8,	// { X86_REG_CR10, "cr10" },
+	8,	// { X86_REG_CR11, "cr11" },
+	8,	// { X86_REG_CR12, "cr12" },
+	8,	// { X86_REG_CR13, "cr13" },
+	8,	// { X86_REG_CR14, "cr14" },
+	8,	// { X86_REG_CR15, "cr15" },
+	4,	// { X86_REG_DR0, "dr0" },
+	4,	// { X86_REG_DR1, "dr1" },
+	4,	// { X86_REG_DR2, "dr2" },
+	4,	// { X86_REG_DR3, "dr3" },
+	4,	// { X86_REG_DR4, "dr4" },
+	4,	// { X86_REG_DR5, "dr5" },
+	4,	// { X86_REG_DR6, "dr6" },
+	4,	// { X86_REG_DR7, "dr7" },
+	10,	// { X86_REG_FP0, "fp0" },
+	10,	// { X86_REG_FP1, "fp1" },
+	10,	// { X86_REG_FP2, "fp2" },
+	10,	// { X86_REG_FP3, "fp3" },
+	10,	// { X86_REG_FP4, "fp4" },
+	10,	// { X86_REG_FP5, "fp5" },
+	10,	// { X86_REG_FP6, "fp6" },
+	2,	// { X86_REG_K0, "k0" },
+	2,	// { X86_REG_K1, "k1" },
+	2,	// { X86_REG_K2, "k2" },
+	2,	// { X86_REG_K3, "k3" },
+	2,	// { X86_REG_K4, "k4" },
+	2,	// { X86_REG_K5, "k5" },
+	2,	// { X86_REG_K6, "k6" },
+	2,	// { X86_REG_K7, "k7" },
+	8,	// { X86_REG_MM0, "mm0" },
+	8,	// { X86_REG_MM1, "mm1" },
+	8,	// { X86_REG_MM2, "mm2" },
+	8,	// { X86_REG_MM3, "mm3" },
+	8,	// { X86_REG_MM4, "mm4" },
+	8,	// { X86_REG_MM5, "mm5" },
+	8,	// { X86_REG_MM6, "mm6" },
+	8,	// { X86_REG_MM7, "mm7" },
+	8,	// { X86_REG_R8, "r8" },
+	8,	// { X86_REG_R9, "r9" },
+	8,	// { X86_REG_R10, "r10" },
+	8,	// { X86_REG_R11, "r11" },
+	8,	// { X86_REG_R12, "r12" },
+	8,	// { X86_REG_R13, "r13" },
+	8,	// { X86_REG_R14, "r14" },
+	8,	// { X86_REG_R15, "r15" },
+	10,	// { X86_REG_ST0, "st0" },
+	10,	// { X86_REG_ST1, "st1" },
+	10,	// { X86_REG_ST2, "st2" },
+	10,	// { X86_REG_ST3, "st3" },
+	10,	// { X86_REG_ST4, "st4" },
+	10,	// { X86_REG_ST5, "st5" },
+	10,	// { X86_REG_ST6, "st6" },
+	10,	// { X86_REG_ST7, "st7" },
+	16,	// { X86_REG_XMM0, "xmm0" },
+	16,	// { X86_REG_XMM1, "xmm1" },
+	16,	// { X86_REG_XMM2, "xmm2" },
+	16,	// { X86_REG_XMM3, "xmm3" },
+	16,	// { X86_REG_XMM4, "xmm4" },
+	16,	// { X86_REG_XMM5, "xmm5" },
+	16,	// { X86_REG_XMM6, "xmm6" },
+	16,	// { X86_REG_XMM7, "xmm7" },
+	16,	// { X86_REG_XMM8, "xmm8" },
+	16,	// { X86_REG_XMM9, "xmm9" },
+	16,	// { X86_REG_XMM10, "xmm10" },
+	16,	// { X86_REG_XMM11, "xmm11" },
+	16,	// { X86_REG_XMM12, "xmm12" },
+	16,	// { X86_REG_XMM13, "xmm13" },
+	16,	// { X86_REG_XMM14, "xmm14" },
+	16,	// { X86_REG_XMM15, "xmm15" },
+	16,	// { X86_REG_XMM16, "xmm16" },
+	16,	// { X86_REG_XMM17, "xmm17" },
+	16,	// { X86_REG_XMM18, "xmm18" },
+	16,	// { X86_REG_XMM19, "xmm19" },
+	16,	// { X86_REG_XMM20, "xmm20" },
+	16,	// { X86_REG_XMM21, "xmm21" },
+	16,	// { X86_REG_XMM22, "xmm22" },
+	16,	// { X86_REG_XMM23, "xmm23" },
+	16,	// { X86_REG_XMM24, "xmm24" },
+	16,	// { X86_REG_XMM25, "xmm25" },
+	16,	// { X86_REG_XMM26, "xmm26" },
+	16,	// { X86_REG_XMM27, "xmm27" },
+	16,	// { X86_REG_XMM28, "xmm28" },
+	16,	// { X86_REG_XMM29, "xmm29" },
+	16,	// { X86_REG_XMM30, "xmm30" },
+	16,	// { X86_REG_XMM31, "xmm31" },
+	32,	// { X86_REG_YMM0, "ymm0" },
+	32,	// { X86_REG_YMM1, "ymm1" },
+	32,	// { X86_REG_YMM2, "ymm2" },
+	32,	// { X86_REG_YMM3, "ymm3" },
+	32,	// { X86_REG_YMM4, "ymm4" },
+	32,	// { X86_REG_YMM5, "ymm5" },
+	32,	// { X86_REG_YMM6, "ymm6" },
+	32,	// { X86_REG_YMM7, "ymm7" },
+	32,	// { X86_REG_YMM8, "ymm8" },
+	32,	// { X86_REG_YMM9, "ymm9" },
+	32,	// { X86_REG_YMM10, "ymm10" },
+	32,	// { X86_REG_YMM11, "ymm11" },
+	32,	// { X86_REG_YMM12, "ymm12" },
+	32,	// { X86_REG_YMM13, "ymm13" },
+	32,	// { X86_REG_YMM14, "ymm14" },
+	32,	// { X86_REG_YMM15, "ymm15" },
+	32,	// { X86_REG_YMM16, "ymm16" },
+	32,	// { X86_REG_YMM17, "ymm17" },
+	32,	// { X86_REG_YMM18, "ymm18" },
+	32,	// { X86_REG_YMM19, "ymm19" },
+	32,	// { X86_REG_YMM20, "ymm20" },
+	32,	// { X86_REG_YMM21, "ymm21" },
+	32,	// { X86_REG_YMM22, "ymm22" },
+	32,	// { X86_REG_YMM23, "ymm23" },
+	32,	// { X86_REG_YMM24, "ymm24" },
+	32,	// { X86_REG_YMM25, "ymm25" },
+	32,	// { X86_REG_YMM26, "ymm26" },
+	32,	// { X86_REG_YMM27, "ymm27" },
+	32,	// { X86_REG_YMM28, "ymm28" },
+	32,	// { X86_REG_YMM29, "ymm29" },
+	32,	// { X86_REG_YMM30, "ymm30" },
+	32,	// { X86_REG_YMM31, "ymm31" },
+	64,	// { X86_REG_ZMM0, "zmm0" },
+	64,	// { X86_REG_ZMM1, "zmm1" },
+	64,	// { X86_REG_ZMM2, "zmm2" },
+	64,	// { X86_REG_ZMM3, "zmm3" },
+	64,	// { X86_REG_ZMM4, "zmm4" },
+	64,	// { X86_REG_ZMM5, "zmm5" },
+	64,	// { X86_REG_ZMM6, "zmm6" },
+	64,	// { X86_REG_ZMM7, "zmm7" },
+	64,	// { X86_REG_ZMM8, "zmm8" },
+	64,	// { X86_REG_ZMM9, "zmm9" },
+	64,	// { X86_REG_ZMM10, "zmm10" },
+	64,	// { X86_REG_ZMM11, "zmm11" },
+	64,	// { X86_REG_ZMM12, "zmm12" },
+	64,	// { X86_REG_ZMM13, "zmm13" },
+	64,	// { X86_REG_ZMM14, "zmm14" },
+	64,	// { X86_REG_ZMM15, "zmm15" },
+	64,	// { X86_REG_ZMM16, "zmm16" },
+	64,	// { X86_REG_ZMM17, "zmm17" },
+	64,	// { X86_REG_ZMM18, "zmm18" },
+	64,	// { X86_REG_ZMM19, "zmm19" },
+	64,	// { X86_REG_ZMM20, "zmm20" },
+	64,	// { X86_REG_ZMM21, "zmm21" },
+	64,	// { X86_REG_ZMM22, "zmm22" },
+	64,	// { X86_REG_ZMM23, "zmm23" },
+	64,	// { X86_REG_ZMM24, "zmm24" },
+	64,	// { X86_REG_ZMM25, "zmm25" },
+	64,	// { X86_REG_ZMM26, "zmm26" },
+	64,	// { X86_REG_ZMM27, "zmm27" },
+	64,	// { X86_REG_ZMM28, "zmm28" },
+	64,	// { X86_REG_ZMM29, "zmm29" },
+	64,	// { X86_REG_ZMM30, "zmm30" },
+	64,	// { X86_REG_ZMM31, "zmm31" },
+	1,	// { X86_REG_R8B, "r8b" },
+	1,	// { X86_REG_R9B, "r9b" },
+	1,	// { X86_REG_R10B, "r10b" },
+	1,	// { X86_REG_R11B, "r11b" },
+	1,	// { X86_REG_R12B, "r12b" },
+	1,	// { X86_REG_R13B, "r13b" },
+	1,	// { X86_REG_R14B, "r14b" },
+	1,	// { X86_REG_R15B, "r15b" },
+	4,	// { X86_REG_R8D, "r8d" },
+	4,	// { X86_REG_R9D, "r9d" },
+	4,	// { X86_REG_R10D, "r10d" },
+	4,	// { X86_REG_R11D, "r11d" },
+	4,	// { X86_REG_R12D, "r12d" },
+	4,	// { X86_REG_R13D, "r13d" },
+	4,	// { X86_REG_R14D, "r14d" },
+	4,	// { X86_REG_R15D, "r15d" },
+	2,	// { X86_REG_R8W, "r8w" },
+	2,	// { X86_REG_R9W, "r9w" },
+	2,	// { X86_REG_R10W, "r10w" },
+	2,	// { X86_REG_R11W, "r11w" },
+	2,	// { X86_REG_R12W, "r12w" },
+	2,	// { X86_REG_R13W, "r13w" },
+	2,	// { X86_REG_R14W, "r14w" },
+	2,	// { X86_REG_R15W, "r15w" },
+};
+
+// register size in 64bit mode
+uint8_t regsize_map_64 [] = {
+	0,	// 	{ X86_REG_INVALID, NULL },
+	1,	// { X86_REG_AH, "ah" },
+	1,	// { X86_REG_AL, "al" },
+	2,	// { X86_REG_AX, "ax" },
+	1,	// { X86_REG_BH, "bh" },
+	1,	// { X86_REG_BL, "bl" },
+	2,	// { X86_REG_BP, "bp" },
+	1,	// { X86_REG_BPL, "bpl" },
+	2,	// { X86_REG_BX, "bx" },
+	1,	// { X86_REG_CH, "ch" },
+	1,	// { X86_REG_CL, "cl" },
+	2,	// { X86_REG_CS, "cs" },
+	2,	// { X86_REG_CX, "cx" },
+	1,	// { X86_REG_DH, "dh" },
+	2,	// { X86_REG_DI, "di" },
+	1,	// { X86_REG_DIL, "dil" },
+	1,	// { X86_REG_DL, "dl" },
+	2,	// { X86_REG_DS, "ds" },
+	2,	// { X86_REG_DX, "dx" },
+	4,	// { X86_REG_EAX, "eax" },
+	4,	// { X86_REG_EBP, "ebp" },
+	4,	// { X86_REG_EBX, "ebx" },
+	4,	// { X86_REG_ECX, "ecx" },
+	4,	// { X86_REG_EDI, "edi" },
+	4,	// { X86_REG_EDX, "edx" },
+	8,	// { X86_REG_EFLAGS, "flags" },
+	4,	// { X86_REG_EIP, "eip" },
+	4,	// { X86_REG_EIZ, "eiz" },
+	2,	// { X86_REG_ES, "es" },
+	4,	// { X86_REG_ESI, "esi" },
+	4,	// { X86_REG_ESP, "esp" },
+	10,	// { X86_REG_FPSW, "fpsw" },
+	2,	// { X86_REG_FS, "fs" },
+	2,	// { X86_REG_GS, "gs" },
+	2,	// { X86_REG_IP, "ip" },
+	8,	// { X86_REG_RAX, "rax" },
+	8,	// { X86_REG_RBP, "rbp" },
+	8,	// { X86_REG_RBX, "rbx" },
+	8,	// { X86_REG_RCX, "rcx" },
+	8,	// { X86_REG_RDI, "rdi" },
+	8,	// { X86_REG_RDX, "rdx" },
+	8,	// { X86_REG_RIP, "rip" },
+	8,	// { X86_REG_RIZ, "riz" },
+	8,	// { X86_REG_RSI, "rsi" },
+	8,	// { X86_REG_RSP, "rsp" },
+	2,	// { X86_REG_SI, "si" },
+	1,	// { X86_REG_SIL, "sil" },
+	2,	// { X86_REG_SP, "sp" },
+	1,	// { X86_REG_SPL, "spl" },
+	2,	// { X86_REG_SS, "ss" },
+	8,	// { X86_REG_CR0, "cr0" },
+	8,	// { X86_REG_CR1, "cr1" },
+	8,	// { X86_REG_CR2, "cr2" },
+	8,	// { X86_REG_CR3, "cr3" },
+	8,	// { X86_REG_CR4, "cr4" },
+	8,	// { X86_REG_CR5, "cr5" },
+	8,	// { X86_REG_CR6, "cr6" },
+	8,	// { X86_REG_CR7, "cr7" },
+	8,	// { X86_REG_CR8, "cr8" },
+	8,	// { X86_REG_CR9, "cr9" },
+	8,	// { X86_REG_CR10, "cr10" },
+	8,	// { X86_REG_CR11, "cr11" },
+	8,	// { X86_REG_CR12, "cr12" },
+	8,	// { X86_REG_CR13, "cr13" },
+	8,	// { X86_REG_CR14, "cr14" },
+	8,	// { X86_REG_CR15, "cr15" },
+	8,	// { X86_REG_DR0, "dr0" },
+	8,	// { X86_REG_DR1, "dr1" },
+	8,	// { X86_REG_DR2, "dr2" },
+	8,	// { X86_REG_DR3, "dr3" },
+	8,	// { X86_REG_DR4, "dr4" },
+	8,	// { X86_REG_DR5, "dr5" },
+	8,	// { X86_REG_DR6, "dr6" },
+	8,	// { X86_REG_DR7, "dr7" },
+	10,	// { X86_REG_FP0, "fp0" },
+	10,	// { X86_REG_FP1, "fp1" },
+	10,	// { X86_REG_FP2, "fp2" },
+	10,	// { X86_REG_FP3, "fp3" },
+	10,	// { X86_REG_FP4, "fp4" },
+	10,	// { X86_REG_FP5, "fp5" },
+	10,	// { X86_REG_FP6, "fp6" },
+	2,	// { X86_REG_K0, "k0" },
+	2,	// { X86_REG_K1, "k1" },
+	2,	// { X86_REG_K2, "k2" },
+	2,	// { X86_REG_K3, "k3" },
+	2,	// { X86_REG_K4, "k4" },
+	2,	// { X86_REG_K5, "k5" },
+	2,	// { X86_REG_K6, "k6" },
+	2,	// { X86_REG_K7, "k7" },
+	8,	// { X86_REG_MM0, "mm0" },
+	8,	// { X86_REG_MM1, "mm1" },
+	8,	// { X86_REG_MM2, "mm2" },
+	8,	// { X86_REG_MM3, "mm3" },
+	8,	// { X86_REG_MM4, "mm4" },
+	8,	// { X86_REG_MM5, "mm5" },
+	8,	// { X86_REG_MM6, "mm6" },
+	8,	// { X86_REG_MM7, "mm7" },
+	8,	// { X86_REG_R8, "r8" },
+	8,	// { X86_REG_R9, "r9" },
+	8,	// { X86_REG_R10, "r10" },
+	8,	// { X86_REG_R11, "r11" },
+	8,	// { X86_REG_R12, "r12" },
+	8,	// { X86_REG_R13, "r13" },
+	8,	// { X86_REG_R14, "r14" },
+	8,	// { X86_REG_R15, "r15" },
+	10,	// { X86_REG_ST0, "st0" },
+	10,	// { X86_REG_ST1, "st1" },
+	10,	// { X86_REG_ST2, "st2" },
+	10,	// { X86_REG_ST3, "st3" },
+	10,	// { X86_REG_ST4, "st4" },
+	10,	// { X86_REG_ST5, "st5" },
+	10,	// { X86_REG_ST6, "st6" },
+	10,	// { X86_REG_ST7, "st7" },
+	16,	// { X86_REG_XMM0, "xmm0" },
+	16,	// { X86_REG_XMM1, "xmm1" },
+	16,	// { X86_REG_XMM2, "xmm2" },
+	16,	// { X86_REG_XMM3, "xmm3" },
+	16,	// { X86_REG_XMM4, "xmm4" },
+	16,	// { X86_REG_XMM5, "xmm5" },
+	16,	// { X86_REG_XMM6, "xmm6" },
+	16,	// { X86_REG_XMM7, "xmm7" },
+	16,	// { X86_REG_XMM8, "xmm8" },
+	16,	// { X86_REG_XMM9, "xmm9" },
+	16,	// { X86_REG_XMM10, "xmm10" },
+	16,	// { X86_REG_XMM11, "xmm11" },
+	16,	// { X86_REG_XMM12, "xmm12" },
+	16,	// { X86_REG_XMM13, "xmm13" },
+	16,	// { X86_REG_XMM14, "xmm14" },
+	16,	// { X86_REG_XMM15, "xmm15" },
+	16,	// { X86_REG_XMM16, "xmm16" },
+	16,	// { X86_REG_XMM17, "xmm17" },
+	16,	// { X86_REG_XMM18, "xmm18" },
+	16,	// { X86_REG_XMM19, "xmm19" },
+	16,	// { X86_REG_XMM20, "xmm20" },
+	16,	// { X86_REG_XMM21, "xmm21" },
+	16,	// { X86_REG_XMM22, "xmm22" },
+	16,	// { X86_REG_XMM23, "xmm23" },
+	16,	// { X86_REG_XMM24, "xmm24" },
+	16,	// { X86_REG_XMM25, "xmm25" },
+	16,	// { X86_REG_XMM26, "xmm26" },
+	16,	// { X86_REG_XMM27, "xmm27" },
+	16,	// { X86_REG_XMM28, "xmm28" },
+	16,	// { X86_REG_XMM29, "xmm29" },
+	16,	// { X86_REG_XMM30, "xmm30" },
+	16,	// { X86_REG_XMM31, "xmm31" },
+	32,	// { X86_REG_YMM0, "ymm0" },
+	32,	// { X86_REG_YMM1, "ymm1" },
+	32,	// { X86_REG_YMM2, "ymm2" },
+	32,	// { X86_REG_YMM3, "ymm3" },
+	32,	// { X86_REG_YMM4, "ymm4" },
+	32,	// { X86_REG_YMM5, "ymm5" },
+	32,	// { X86_REG_YMM6, "ymm6" },
+	32,	// { X86_REG_YMM7, "ymm7" },
+	32,	// { X86_REG_YMM8, "ymm8" },
+	32,	// { X86_REG_YMM9, "ymm9" },
+	32,	// { X86_REG_YMM10, "ymm10" },
+	32,	// { X86_REG_YMM11, "ymm11" },
+	32,	// { X86_REG_YMM12, "ymm12" },
+	32,	// { X86_REG_YMM13, "ymm13" },
+	32,	// { X86_REG_YMM14, "ymm14" },
+	32,	// { X86_REG_YMM15, "ymm15" },
+	32,	// { X86_REG_YMM16, "ymm16" },
+	32,	// { X86_REG_YMM17, "ymm17" },
+	32,	// { X86_REG_YMM18, "ymm18" },
+	32,	// { X86_REG_YMM19, "ymm19" },
+	32,	// { X86_REG_YMM20, "ymm20" },
+	32,	// { X86_REG_YMM21, "ymm21" },
+	32,	// { X86_REG_YMM22, "ymm22" },
+	32,	// { X86_REG_YMM23, "ymm23" },
+	32,	// { X86_REG_YMM24, "ymm24" },
+	32,	// { X86_REG_YMM25, "ymm25" },
+	32,	// { X86_REG_YMM26, "ymm26" },
+	32,	// { X86_REG_YMM27, "ymm27" },
+	32,	// { X86_REG_YMM28, "ymm28" },
+	32,	// { X86_REG_YMM29, "ymm29" },
+	32,	// { X86_REG_YMM30, "ymm30" },
+	32,	// { X86_REG_YMM31, "ymm31" },
+	64,	// { X86_REG_ZMM0, "zmm0" },
+	64,	// { X86_REG_ZMM1, "zmm1" },
+	64,	// { X86_REG_ZMM2, "zmm2" },
+	64,	// { X86_REG_ZMM3, "zmm3" },
+	64,	// { X86_REG_ZMM4, "zmm4" },
+	64,	// { X86_REG_ZMM5, "zmm5" },
+	64,	// { X86_REG_ZMM6, "zmm6" },
+	64,	// { X86_REG_ZMM7, "zmm7" },
+	64,	// { X86_REG_ZMM8, "zmm8" },
+	64,	// { X86_REG_ZMM9, "zmm9" },
+	64,	// { X86_REG_ZMM10, "zmm10" },
+	64,	// { X86_REG_ZMM11, "zmm11" },
+	64,	// { X86_REG_ZMM12, "zmm12" },
+	64,	// { X86_REG_ZMM13, "zmm13" },
+	64,	// { X86_REG_ZMM14, "zmm14" },
+	64,	// { X86_REG_ZMM15, "zmm15" },
+	64,	// { X86_REG_ZMM16, "zmm16" },
+	64,	// { X86_REG_ZMM17, "zmm17" },
+	64,	// { X86_REG_ZMM18, "zmm18" },
+	64,	// { X86_REG_ZMM19, "zmm19" },
+	64,	// { X86_REG_ZMM20, "zmm20" },
+	64,	// { X86_REG_ZMM21, "zmm21" },
+	64,	// { X86_REG_ZMM22, "zmm22" },
+	64,	// { X86_REG_ZMM23, "zmm23" },
+	64,	// { X86_REG_ZMM24, "zmm24" },
+	64,	// { X86_REG_ZMM25, "zmm25" },
+	64,	// { X86_REG_ZMM26, "zmm26" },
+	64,	// { X86_REG_ZMM27, "zmm27" },
+	64,	// { X86_REG_ZMM28, "zmm28" },
+	64,	// { X86_REG_ZMM29, "zmm29" },
+	64,	// { X86_REG_ZMM30, "zmm30" },
+	64,	// { X86_REG_ZMM31, "zmm31" },
+	1,	// { X86_REG_R8B, "r8b" },
+	1,	// { X86_REG_R9B, "r9b" },
+	1,	// { X86_REG_R10B, "r10b" },
+	1,	// { X86_REG_R11B, "r11b" },
+	1,	// { X86_REG_R12B, "r12b" },
+	1,	// { X86_REG_R13B, "r13b" },
+	1,	// { X86_REG_R14B, "r14b" },
+	1,	// { X86_REG_R15B, "r15b" },
+	4,	// { X86_REG_R8D, "r8d" },
+	4,	// { X86_REG_R9D, "r9d" },
+	4,	// { X86_REG_R10D, "r10d" },
+	4,	// { X86_REG_R11D, "r11d" },
+	4,	// { X86_REG_R12D, "r12d" },
+	4,	// { X86_REG_R13D, "r13d" },
+	4,	// { X86_REG_R14D, "r14d" },
+	4,	// { X86_REG_R15D, "r15d" },
+	2,	// { X86_REG_R8W, "r8w" },
+	2,	// { X86_REG_R9W, "r9w" },
+	2,	// { X86_REG_R10W, "r10w" },
+	2,	// { X86_REG_R11W, "r11w" },
+	2,	// { X86_REG_R12W, "r12w" },
+	2,	// { X86_REG_R13W, "r13w" },
+	2,	// { X86_REG_R14W, "r14w" },
+	2,	// { X86_REG_R15W, "r15w" },
+};
+
 const char *X86_reg_name(csh handle, unsigned int reg)
 {
 #ifndef CAPSTONE_DIET
diff --git a/arch/X86/X86Mapping.h b/arch/X86/X86Mapping.h
index b28868e..49f6c6b 100644
--- a/arch/X86/X86Mapping.h
+++ b/arch/X86/X86Mapping.h
@@ -39,4 +39,8 @@
 // return True if we patch mnemonic, like in MULPD case
 bool X86_lockrep(MCInst *MI, SStream *O);
 
+// map registers to sizes
+extern uint8_t regsize_map_32[];
+extern uint8_t regsize_map_64[];
+
 #endif
diff --git a/arch/X86/X86Module.c b/arch/X86/X86Module.c
index 1df1498..4d552d9 100644
--- a/arch/X86/X86Module.c
+++ b/arch/X86/X86Module.c
@@ -25,6 +25,11 @@
 	ud->insn_name = X86_insn_name;
 	ud->post_printer = X86_post_printer;
 
+	if (ud->mode == CS_MODE_64)
+		ud->regsize_map = regsize_map_64;
+	else
+		ud->regsize_map = regsize_map_32;
+
 	return CS_ERR_OK;
 }
 
diff --git a/cs_priv.h b/cs_priv.h
index d3cd3e1..d50a4b8 100644
--- a/cs_priv.h
+++ b/cs_priv.h
@@ -52,6 +52,7 @@
 	bool skipdata;	// set this to True if we skip data when disassembling
 	uint8_t skipdata_size;	// how many bytes to skip
 	cs_opt_skipdata skipdata_setup;	// user-defined skipdata setup
+	uint8_t *regsize_map;	// map to register size (x86-only for now)
 };
 
 #define MAX_ARCH 8
diff --git a/include/x86.h b/include/x86.h
index d27ddf8..3fa059e 100644
--- a/include/x86.h
+++ b/include/x86.h
@@ -94,6 +94,10 @@
 			double fp;		// floating point value for FP operand
 			x86_op_mem mem;		// base/index/scale/disp value for MEM operand
 		};
+
+		// size of this operand (in bytes).
+		// NOTE: this is irrelevant for operand type X86_OP_IMM
+		uint8_t size;
 } cs_x86_op;
 
 // Instruction structure
@@ -111,19 +115,9 @@
 	// An opcode byte gets value 0 when irrelevant.
 	uint8_t opcode[3];
 
-	// Operand size, which can be overrided with above prefix[5].
-	uint8_t op_size;
-
 	// Address size, which can be overrided with above prefix[5].
 	uint8_t addr_size;
 
-	// Size of (optional) displacement.
-	// This field get value 0 when irrelevant.
-	uint8_t disp_size;
-
-	// Size of immediate operand
-	uint8_t imm_size;
-
 	// ModR/M byte
 	uint8_t modrm;
 
diff --git a/tests/test_x86.c b/tests/test_x86.c
index ecad620..82b1b77 100644
--- a/tests/test_x86.c
+++ b/tests/test_x86.c
@@ -48,7 +48,7 @@
 		printf("\tSegment override: %s\n", cs_reg_name(handle, x86->segment));
 
 	print_string_hex("\tOpcode:", x86->opcode, 3);
-	printf("\top_size: %u, addr_size: %u, disp_size: %u, imm_size: %u\n", x86->op_size, x86->addr_size, x86->disp_size, x86->imm_size);
+	printf("\taddr_size: %u\n", x86->addr_size);
 	printf("\tmodrm: 0x%x\n", x86->modrm);
 	printf("\tdisp: 0x%x\n", x86->disp);
 
@@ -101,6 +101,10 @@
 			default:
 				break;
 		}
+
+		// the size is irrelevant for X86_OP_IMM
+		if (op->type != X86_OP_IMM)
+			printf("\t\toperands[%u].size: %u\n", i, op->size);
 	}
 
 	printf("\n");