x86: support avx_sae & avx_rm in cs_x86 struct. this also updates Python & Java bindings following the core's change
diff --git a/arch/X86/X86ATTInstPrinter.c b/arch/X86/X86ATTInstPrinter.c
index 13c3452..e34c6cd 100644
--- a/arch/X86/X86ATTInstPrinter.c
+++ b/arch/X86/X86ATTInstPrinter.c
@@ -213,10 +213,10 @@
 {
 	int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
 	switch (Imm) {
-		case 0: SStream_concat0(O, "{rn-sae}"); break;
-		case 1: SStream_concat0(O, "{rd-sae}"); break;
-		case 2: SStream_concat0(O, "{ru-sae}"); break;
-		case 3: SStream_concat0(O, "{rz-sae}"); break;
+		case 0: SStream_concat0(O, "{rn-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RN); break;
+		case 1: SStream_concat0(O, "{rd-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RD); break;
+		case 2: SStream_concat0(O, "{ru-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RU); break;
+		case 3: SStream_concat0(O, "{rz-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RZ); break;
 		default: break;	// nev0er reach
 	}
 }
diff --git a/arch/X86/X86Disassembler.c b/arch/X86/X86Disassembler.c
index 524e5fa..ce64795 100644
--- a/arch/X86/X86Disassembler.c
+++ b/arch/X86/X86Disassembler.c
@@ -716,6 +716,9 @@
 		instr->flat_insn->detail->x86.op_count = 0;
 		instr->flat_insn->detail->x86.sse_cc = X86_SSE_CC_INVALID;
 		instr->flat_insn->detail->x86.avx_cc = X86_AVX_CC_INVALID;
+		instr->flat_insn->detail->x86.avx_sae = false;
+		instr->flat_insn->detail->x86.avx_rm = X86_AVX_RM_INVALID;
+
 		memset(instr->flat_insn->detail->x86.prefix, 0, sizeof(instr->flat_insn->detail->x86.prefix));
 		memset(instr->flat_insn->detail->x86.opcode, 0, sizeof(instr->flat_insn->detail->x86.opcode));
 		memset(instr->flat_insn->detail->x86.operands, 0, 4 * sizeof(instr->flat_insn->detail->x86.operands[0]));
diff --git a/arch/X86/X86GenAsmWriter.inc b/arch/X86/X86GenAsmWriter.inc
index 92c814c..3b23884 100644
--- a/arch/X86/X86GenAsmWriter.inc
+++ b/arch/X86/X86GenAsmWriter.inc
@@ -13193,6 +13193,7 @@
   case 45:
     // VCMPPDZrrib
     SStream_concat0(O, "pd \t{sae}, "); 
+	op_addAvxSae(MI);
     printOperand(MI, 2, O); 
     SStream_concat0(O, ", "); 
     printOperand(MI, 1, O); 
@@ -13207,6 +13208,7 @@
   case 47:
     // VCMPPSZrrib
     SStream_concat0(O, "ps \t{sae}, "); 
+	op_addAvxSae(MI);
     printOperand(MI, 2, O); 
     SStream_concat0(O, ", "); 
     printOperand(MI, 1, O); 
@@ -13570,13 +13572,13 @@
   case 5:
     // VMOVDQU32rrkz, VMOVDQU64rrkz
     SStream_concat0(O, "}  {z}"); 
-	op_addZeroOpmask(MI);
+	op_addAvxZeroOpmask(MI);
     return;
     break;
   case 6:
     // VPBROADCASTDZkrm, VPBROADCASTDZkrr, VPBROADCASTDrZkrr, VPBROADCASTQZkr...
     SStream_concat0(O, "} {z}"); 
-	op_addZeroOpmask(MI);
+	op_addAvxZeroOpmask(MI);
     return;
     break;
   case 7:
diff --git a/arch/X86/X86GenAsmWriter1.inc b/arch/X86/X86GenAsmWriter1.inc
index eccbfb9..6eab0e6 100644
--- a/arch/X86/X86GenAsmWriter1.inc
+++ b/arch/X86/X86GenAsmWriter1.inc
@@ -12823,6 +12823,7 @@
   case 5:
     // VCMPPDZrrib, VCMPPSZrrib, VRCP28PDZrb, VRCP28PSZrb, VRSQRT28PDZrb, VRS...
     SStream_concat0(O, ", {sae}"); 
+	op_addAvxSae(MI);
     return;
     break;
   case 6:
@@ -12838,7 +12839,7 @@
   case 8:
     // VMOVDQU32rrkz, VMOVDQU64rrkz, VPBROADCASTDZkrm, VPBROADCASTDZkrr, VPBR...
     SStream_concat0(O, "} {z}, "); 
-	op_addZeroOpmask(MI);
+	op_addAvxZeroOpmask(MI);
     break;
   case 9:
     // VPCONFLICTDrmb
@@ -13012,6 +13013,7 @@
   case 4:
     // VRCP28SDrrb, VRCP28SSrrb, VRSQRT28SDrrb, VRSQRT28SSrrb
     SStream_concat0(O, ", {sae}"); 
+	op_addAvxSae(MI);
     return;
     break;
   }
diff --git a/arch/X86/X86IntelInstPrinter.c b/arch/X86/X86IntelInstPrinter.c
index 85adbe4..6a0b738 100644
--- a/arch/X86/X86IntelInstPrinter.c
+++ b/arch/X86/X86IntelInstPrinter.c
@@ -229,10 +229,10 @@
 {
 	int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
 	switch (Imm) {
-		case 0: SStream_concat0(O, "{rn-sae}"); break;
-		case 1: SStream_concat0(O, "{rd-sae}"); break;
-		case 2: SStream_concat0(O, "{ru-sae}"); break;
-		case 3: SStream_concat0(O, "{rz-sae}"); break;
+		case 0: SStream_concat0(O, "{rn-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RN); break;
+		case 1: SStream_concat0(O, "{rd-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RD); break;
+		case 2: SStream_concat0(O, "{ru-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RU); break;
+		case 3: SStream_concat0(O, "{rz-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RZ); break;
 		default: break;	// never reach
 	}
 }
diff --git a/arch/X86/X86Mapping.c b/arch/X86/X86Mapping.c
index fba182e..6a8def8 100644
--- a/arch/X86/X86Mapping.c
+++ b/arch/X86/X86Mapping.c
@@ -42600,7 +42600,7 @@
 	}
 }
 
-void op_addZeroOpmask(MCInst *MI)
+void op_addAvxZeroOpmask(MCInst *MI)
 {
 	if (MI->csh->detail) {
 		// link with the previous operand
@@ -42608,4 +42608,18 @@
 	}
 }
 
+void op_addAvxSae(MCInst *MI)
+{
+	if (MI->csh->detail) {
+		MI->flat_insn->detail->x86.avx_sae = true;
+	}
+}
+
+void op_addAvxRoundingMode(MCInst *MI, int v)
+{
+	if (MI->csh->detail) {
+		MI->flat_insn->detail->x86.avx_rm = v;
+	}
+}
+
 #endif
diff --git a/arch/X86/X86Mapping.h b/arch/X86/X86Mapping.h
index 1e577bb..17ba458 100644
--- a/arch/X86/X86Mapping.h
+++ b/arch/X86/X86Mapping.h
@@ -52,6 +52,10 @@
 void op_addSseCC(MCInst *MI, int v);
 void op_addAvxCC(MCInst *MI, int v);
 
-void op_addZeroOpmask(MCInst *MI);
+void op_addAvxZeroOpmask(MCInst *MI);
+
+void op_addAvxSae(MCInst *MI);
+
+void op_addAvxRoundingMode(MCInst *MI, int v);
 
 #endif
diff --git a/bindings/java/TestX86.java b/bindings/java/TestX86.java
index 0aec400..b12cb0b 100644
--- a/bindings/java/TestX86.java
+++ b/bindings/java/TestX86.java
@@ -73,6 +73,12 @@
     if (operands.avxCC != 0)
         System.out.printf("\tavx_cc: %u\n", operands.avxCC);
 
+    if (operands.avxSae)
+        System.out.printf("\tavx_sae: TRUE\n");
+
+    if (operands.avxRm != 0)
+        System.out.printf("\tavx_rm: %u\n", operands.avxRm);
+
     int count = ins.opCount(X86_OP_IMM);
     if (count > 0) {
       System.out.printf("\timm_count: %d\n", count);
diff --git a/bindings/java/capstone/X86.java b/bindings/java/capstone/X86.java
index c43fe20..28f66a8 100644
--- a/bindings/java/capstone/X86.java
+++ b/bindings/java/capstone/X86.java
@@ -78,6 +78,8 @@
     public int sib_base;
     public int sse_cc;
     public int avx_cc;
+    public boolean avx_sae;
+    public int avx_rm;
 
     public char op_count;
 
@@ -92,7 +94,7 @@
     @Override
     public List getFieldOrder() {
       return Arrays.asList("prefix", "opcode", "addr_size",
-          "modrm", "sib", "disp", "sib_index", "sib_scale", "sib_base", "sse_cc", "avx_cc", "op_count", "op");
+          "modrm", "sib", "disp", "sib_index", "sib_scale", "sib_base", "sse_cc", "avx_cc", "avx_sae", "avx_rm", "op_count", "op");
     }
   }
 
@@ -126,6 +128,8 @@
       sibBase = e.sib_base;
       sseCC = e.sse_cc;
       avxCC = e.avx_cc;
+      avxSae = e.avx_sae;
+      avxRm = e.avx_rm;
       op = new Operand[e.op_count];
       for (int i=0; i<e.op_count; i++)
         op[i] = e.op[i];
diff --git a/bindings/java/capstone/X86_const.java b/bindings/java/capstone/X86_const.java
index aec756f..c2835be 100644
--- a/bindings/java/capstone/X86_const.java
+++ b/bindings/java/capstone/X86_const.java
@@ -310,6 +310,14 @@
 	public static final int X86_AVX_CC_GT_OQ = 31;
 	public static final int X86_AVX_CC_TRUE_US = 32;
 
+	// AVX static rounding mode type
+
+	public static final int X86_AVX_RM_INVALID = 0;
+	public static final int X86_AVX_RM_RN = 1;
+	public static final int X86_AVX_RM_RD = 2;
+	public static final int X86_AVX_RM_RU = 3;
+	public static final int X86_AVX_RM_RZ = 4;
+
 	// X86 instructions
 
 	public static final int X86_INS_INVALID = 0;
diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py
index 4e9df45..a63e8ce 100644
--- a/bindings/python/capstone/__init__.py
+++ b/bindings/python/capstone/__init__.py
@@ -473,7 +473,8 @@
         elif arch == CS_ARCH_X86:
             (self.prefix, self.opcode, self.addr_size, \
                 self.modrm, self.sib, self.disp, \
-                self.sib_index, self.sib_scale, self.sib_base, self.sse_cc, self.avx_cc, self.operands) = x86.get_arch_info(self._detail.arch.x86)
+                self.sib_index, self.sib_scale, self.sib_base, self.sse_cc, \
+                self.avx_cc, self.avx_sae, self.avx_rm, self.operands) = x86.get_arch_info(self._detail.arch.x86)
         elif arch == CS_ARCH_MIPS:
                 self.operands = mips.get_arch_info(self._detail.arch.mips)
         elif arch == CS_ARCH_PPC:
diff --git a/bindings/python/capstone/x86.py b/bindings/python/capstone/x86.py
index 4b709d7..eb913fc 100644
--- a/bindings/python/capstone/x86.py
+++ b/bindings/python/capstone/x86.py
@@ -60,6 +60,8 @@
         ('sib_base', ctypes.c_uint),
         ('sse_cc', ctypes.c_uint),
         ('avx_cc', ctypes.c_uint),
+        ('avx_sae', ctypes.c_bool),
+        ('avx_rm', ctypes.c_uint),
         ('op_count', ctypes.c_uint8),
         ('operands', X86Op * 8),
     )
@@ -67,5 +69,6 @@
 def get_arch_info(a):
     return (a.prefix[:], a.opcode[:], a.addr_size, \
             a.modrm, a.sib, a.disp, a.sib_index, a.sib_scale, \
-            a.sib_base, a.sse_cc, a.avx_cc, copy.deepcopy(a.operands[:a.op_count]))
+            a.sib_base, a.sse_cc, a.avx_cc, a.avx_sae, a.avx_rm, \
+            copy.deepcopy(a.operands[:a.op_count]))
 
diff --git a/bindings/python/capstone/x86_const.py b/bindings/python/capstone/x86_const.py
index 038ecc8..bdc8660 100644
--- a/bindings/python/capstone/x86_const.py
+++ b/bindings/python/capstone/x86_const.py
@@ -307,6 +307,14 @@
 X86_AVX_CC_GT_OQ = 31
 X86_AVX_CC_TRUE_US = 32
 
+# AVX static rounding mode type
+
+X86_AVX_RM_INVALID = 0
+X86_AVX_RM_RN = 1
+X86_AVX_RM_RD = 2
+X86_AVX_RM_RU = 3
+X86_AVX_RM_RZ = 4
+
 # X86 instructions
 
 X86_INS_INVALID = 0
diff --git a/bindings/python/test_x86.py b/bindings/python/test_x86.py
index b119075..f389fe0 100755
--- a/bindings/python/test_x86.py
+++ b/bindings/python/test_x86.py
@@ -68,6 +68,14 @@
     if insn.avx_cc != X86_AVX_CC_INVALID:
         print("\tavx_cc: %u" % (insn.avx_cc))
 
+    # AVX Suppress All Exception
+    if insn.avx_sae:
+        print("\tavx_sae: TRUE")
+
+    # AVX Rounding Mode type
+    if insn.avx_rm != X86_AVX_RM_INVALID:
+        print("\tavx_rm: %u" % (insn.avx_rm))
+
     count = insn.op_count(X86_OP_IMM)
     if count > 0:
         print("\timm_count: %u" % count)
diff --git a/include/x86.h b/include/x86.h
index 2dc0395..50e0648 100644
--- a/include/x86.h
+++ b/include/x86.h
@@ -141,6 +141,15 @@
 	X86_AVX_CC_TRUE_US,
 } x86_avx_cc;
 
+//> AVX static rounding mode type
+typedef enum x86_avx_rm {
+	X86_AVX_RM_INVALID = 0,	// Uninitialized.
+	X86_AVX_RM_RN,	// Round to nearest
+	X86_AVX_RM_RD,	// Round down
+	X86_AVX_RM_RU,	// Round up
+	X86_AVX_RM_RZ,	// Round toward zero
+} x86_avx_rm;
+
 // Instruction's operand referring to memory
 // This is associated with X86_OP_MEM operand type above
 typedef struct x86_op_mem {
@@ -208,6 +217,12 @@
 	// AVX Code Condition
 	x86_avx_cc avx_cc;
 
+	// AVX Suppress all Exception
+	bool avx_sae;
+
+	// AVX static rounding mode
+	x86_avx_rm avx_rm;
+
 	// Number of operands of this instruction,
 	// or 0 when instruction has no operand.
 	uint8_t op_count;
diff --git a/tests/test_x86.c b/tests/test_x86.c
index b1c53fe..280d5d5 100644
--- a/tests/test_x86.c
+++ b/tests/test_x86.c
@@ -60,14 +60,26 @@
 			printf("\t\tsib_scale: %d\n", x86->sib_scale);
 	}
 
+	// SSE code condition
 	if (x86->sse_cc != X86_SSE_CC_INVALID) {
 		printf("\tsse_cc: %u\n", x86->sse_cc);
 	}
 
+	// AVX code condition
 	if (x86->avx_cc != X86_AVX_CC_INVALID) {
 		printf("\tavx_cc: %u\n", x86->avx_cc);
 	}
 
+	// AVX Suppress All Exception
+	if (x86->avx_sae) {
+		printf("\tavx_sae: %u\n", x86->avx_sae);
+	}
+
+	// AVX Rounding Mode
+	if (x86->avx_rm != X86_AVX_RM_INVALID) {
+		printf("\tavx_rm: %u\n", x86->avx_rm);
+	}
+
 	count = cs_op_count(ud, ins, X86_OP_IMM);
 	if (count) {
 		printf("\timm_count: %u\n", count);
@@ -114,8 +126,8 @@
 			printf("\t\toperands[%u].avx_bcast: %u\n", i, op->avx_bcast);
 
 		// AVX zero opmask {z}
-		if (op->zero_opmask != false)
-			printf("\t\toperands[%u].zero_opmask: TRUE\n", i);
+		if (op->avx_zero_opmask != false)
+			printf("\t\toperands[%u].avx_zero_opmask: TRUE\n", i);
 
 		printf("\t\toperands[%u].size: %u\n", i, op->size);
 	}