[llvm] [X86][MC] Support encoding/decoding for APX variant MUL/IMUL/DIV/IDIV instructions (PR #76919)

Shengchen Kan via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 5 01:04:40 PST 2024


https://github.com/KanRobert updated https://github.com/llvm/llvm-project/pull/76919

>From 2962e6b36c95086b55c619ba80cbe2b913b52beb Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Thu, 4 Jan 2024 16:29:48 +0800
Subject: [PATCH 1/7] [X86][MC] Support encoding/decoding for APX variant
 MUL/IMUL/DIV/IDIV instructions

---
 llvm/lib/Target/X86/X86InstrArithmetic.td  | 257 ++++++++++++++++----
 llvm/test/MC/Disassembler/X86/apx/div.txt  |  66 ++++++
 llvm/test/MC/Disassembler/X86/apx/idiv.txt |  66 ++++++
 llvm/test/MC/Disassembler/X86/apx/imul.txt | 258 +++++++++++++++++++++
 llvm/test/MC/Disassembler/X86/apx/mul.txt  |  66 ++++++
 llvm/test/MC/X86/apx/div-att.s             |  53 +++++
 llvm/test/MC/X86/apx/div-intel.s           |  50 ++++
 llvm/test/MC/X86/apx/idiv-att.s            |  53 +++++
 llvm/test/MC/X86/apx/idiv-intel.s          |  50 ++++
 llvm/test/MC/X86/apx/imul-att.s            | 197 ++++++++++++++++
 llvm/test/MC/X86/apx/imul-intel.s          | 194 ++++++++++++++++
 llvm/test/MC/X86/apx/mul-att.s             |  53 +++++
 llvm/test/MC/X86/apx/mul-intel.s           |  50 ++++
 llvm/test/TableGen/x86-fold-tables.inc     |  31 +++
 14 files changed, 1393 insertions(+), 51 deletions(-)
 create mode 100644 llvm/test/MC/Disassembler/X86/apx/div.txt
 create mode 100644 llvm/test/MC/Disassembler/X86/apx/idiv.txt
 create mode 100644 llvm/test/MC/Disassembler/X86/apx/imul.txt
 create mode 100644 llvm/test/MC/Disassembler/X86/apx/mul.txt
 create mode 100644 llvm/test/MC/X86/apx/div-att.s
 create mode 100644 llvm/test/MC/X86/apx/div-intel.s
 create mode 100644 llvm/test/MC/X86/apx/idiv-att.s
 create mode 100644 llvm/test/MC/X86/apx/idiv-intel.s
 create mode 100644 llvm/test/MC/X86/apx/imul-att.s
 create mode 100644 llvm/test/MC/X86/apx/imul-intel.s
 create mode 100644 llvm/test/MC/X86/apx/mul-att.s
 create mode 100644 llvm/test/MC/X86/apx/mul-intel.s

diff --git a/llvm/lib/Target/X86/X86InstrArithmetic.td b/llvm/lib/Target/X86/X86InstrArithmetic.td
index ed9f45bdd9d150..f8ef617f4eb92b 100644
--- a/llvm/lib/Target/X86/X86InstrArithmetic.td
+++ b/llvm/lib/Target/X86/X86InstrArithmetic.td
@@ -72,23 +72,59 @@ multiclass Mul<bits<8> o, string m, Format RegMRM, Format MemMRM, SDPatternOpera
   // This probably ought to be moved to a def : Pat<> if the
   // syntax can be accepted.
   let Defs = [AL,EFLAGS,AX], Uses = [AL] in
-  def 8r : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8,
-                  [(set AL, (node AL, GR8:$src1)), (implicit EFLAGS)]>;
+    def 8r : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8,
+                       [(set AL, (node AL, GR8:$src1)), (implicit EFLAGS)]>;
   let Defs = [AX,DX,EFLAGS], Uses = [AX] in
-  def 16r : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, OpSize16;
+    def 16r : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, OpSize16;
   let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
-  def 32r : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, OpSize32;
+    def 32r : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, OpSize32;
   let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
-  def 64r : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>;
+    def 64r : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>;
   let Defs = [AL,EFLAGS,AX], Uses = [AL] in
-  def 8m : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8,
-                  [(set AL, (node AL, (loadi8 addr:$src1))), (implicit EFLAGS)]>;
+    def 8m : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8,
+                       [(set AL, (node AL, (loadi8 addr:$src1))), (implicit EFLAGS)]>;
   let Defs = [AX,DX,EFLAGS], Uses = [AX] in
-  def 16m : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, OpSize16;
+    def 16m : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, OpSize16;
   let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
-  def 32m : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, OpSize32;
+    def 32m : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, OpSize32;
   let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
-  def 64m : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, Requires<[In64BitMode]>;
+    def 64m : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, Requires<[In64BitMode]>;
+
+  let Predicates = [In64BitMode] in {
+    let Defs = [AL,AX], Uses = [AL] in
+      def 8r_NF : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8, []>, NF;
+    let Defs = [AX,DX], Uses = [AX] in
+      def 16r_NF : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, NF, PD;
+    let Defs = [EAX,EDX], Uses = [EAX] in
+      def 32r_NF : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, NF;
+    let Defs = [RAX,RDX], Uses = [RAX] in
+      def 64r_NF : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>, NF;
+    let Defs = [AL,AX], Uses = [AL] in
+      def 8m_NF : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8, []>, NF;
+    let Defs = [AX,DX], Uses = [AX] in
+      def 16m_NF : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, NF, PD;
+    let Defs = [EAX,EDX], Uses = [EAX] in
+      def 32m_NF : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, NF;
+    let Defs = [RAX,RDX], Uses = [RAX] in
+      def 64m_NF : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, NF;
+
+    let Defs = [AL,EFLAGS,AX], Uses = [AL] in
+      def 8r_EVEX : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8, []>, PL;
+    let Defs = [AX,DX,EFLAGS], Uses = [AX] in
+      def 16r_EVEX : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, PL, PD;
+    let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
+      def 32r_EVEX : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, PL;
+    let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
+      def 64r_EVEX : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>, PL;
+    let Defs = [AL,EFLAGS,AX], Uses = [AL] in
+      def 8m_EVEX : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8, []>, PL;
+    let Defs = [AX,DX,EFLAGS], Uses = [AX] in
+      def 16m_EVEX : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, PL, PD;
+    let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
+      def 32m_EVEX : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, PL;
+    let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
+      def 64m_EVEX : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, PL;
+  }
 }
 
 defm MUL : Mul<0xF7, "mul", MRM4r, MRM4m, mul>;
@@ -100,66 +136,159 @@ multiclass Div<bits<8> o, string m, Format RegMRM, Format MemMRM> {
   defvar sched32 = !if(!eq(m, "div"), WriteDiv32, WriteIDiv32);
   defvar sched64 = !if(!eq(m, "div"), WriteDiv64, WriteIDiv64);
   let Defs = [AL,AH,EFLAGS], Uses = [AX] in
-  def 8r  : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>;
+    def 8r  : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>;
   let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
-  def 16r : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, OpSize16;
+    def 16r : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, OpSize16;
   let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
-  def 32r : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, OpSize32;
+    def 32r : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, OpSize32;
   let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
-  def 64r : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>;
+    def 64r : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>;
   let Defs = [AL,AH,EFLAGS], Uses = [AX] in
-  def 8m  : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>;
+    def 8m  : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>;
   let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
-  def 16m : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, OpSize16;
+    def 16m : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, OpSize16;
   let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
-  def 32m : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, OpSize32;
+    def 32m : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, OpSize32;
   let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
-  def 64m : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, Requires<[In64BitMode]>;
+    def 64m : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, Requires<[In64BitMode]>;
+
+  let Predicates = [In64BitMode] in {
+    let Defs = [AL,AH], Uses = [AX] in
+      def 8r_NF  : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>, NF;
+    let Defs = [AX,DX], Uses = [AX,DX] in
+      def 16r_NF : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, NF, PD;
+    let Defs = [EAX,EDX], Uses = [EAX,EDX] in
+      def 32r_NF : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, NF;
+    let Defs = [RAX,RDX], Uses = [RAX,RDX] in
+      def 64r_NF : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>, NF;
+    let Defs = [AL,AH], Uses = [AX] in
+      def 8m_NF  : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>, NF;
+    let Defs = [AX,DX], Uses = [AX,DX] in
+      def 16m_NF : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, NF, PD;
+    let Defs = [EAX,EDX], Uses = [EAX,EDX] in
+      def 32m_NF : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, NF;
+    let Defs = [RAX,RDX], Uses = [RAX,RDX] in
+      def 64m_NF : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, NF;
+
+    let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+      def 8r_EVEX  : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>, PL;
+    let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
+      def 16r_EVEX : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, PL, PD;
+    let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
+      def 32r_EVEX : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, PL;
+    let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
+      def 64r_EVEX : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>, PL;
+    let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+      def 8m_EVEX  : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>, PL;
+    let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
+      def 16m_EVEX : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, PL, PD;
+    let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
+      def 32m_EVEX : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, PL;
+    let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
+      def 64m_EVEX : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, PL;
+  }
 }
+
 let hasSideEffects = 1 in { // so that we don't speculatively execute
-defm DIV: Div<0xF7, "div", MRM6r, MRM6m>;
-defm IDIV: Div<0xF7, "idiv", MRM7r, MRM7m>;
+  defm DIV: Div<0xF7, "div", MRM6r, MRM6m>;
+  defm IDIV: Div<0xF7, "idiv", MRM7r, MRM7m>;
 }
 
-class IMulOpRR<X86TypeInfo t, X86FoldableSchedWrite sched>
-  : BinOpRR_RF<0xAF, "imul", t, X86smul_flag>, TB {
+class IMulOpRR_R<X86TypeInfo t, X86FoldableSchedWrite sched, bit ndd = 0>
+  : BinOpRR_R<0xAF, "imul", t, ndd> {
   let Form = MRMSrcReg;
   let SchedRW = [sched];
   // X = IMUL Y, Z --> X = IMUL Z, Y
   let isCommutable = 1;
 }
-class IMulOpRM<X86TypeInfo t, X86FoldableSchedWrite sched>
-  : BinOpRM_RF<0xAF, "imul", t, X86smul_flag>, TB {
-let Form = MRMSrcMem;
-let SchedRW = [sched.Folded, sched.ReadAfterFold];
+class IMulOpRR_RF<X86TypeInfo t, X86FoldableSchedWrite sched, bit ndd = 0>
+  : BinOpRR_RF<0xAF, "imul", t, X86smul_flag, ndd> {
+  let Form = MRMSrcReg;
+  let SchedRW = [sched];
+  // X = IMUL Y, Z --> X = IMUL Z, Y
+  let isCommutable = 1;
+}
+class IMulOpRM_R<X86TypeInfo t, X86FoldableSchedWrite sched, bit ndd = 0>
+  : BinOpRM_R<0xAF, "imul", t, ndd> {
+  let Form = MRMSrcMem;
+  let SchedRW = [sched.Folded, sched.ReadAfterFold];
+}
+class IMulOpRM_RF<X86TypeInfo t, X86FoldableSchedWrite sched, bit ndd = 0>
+  : BinOpRM_RF<0xAF, "imul", t, X86smul_flag, ndd> {
+  let Form = MRMSrcMem;
+  let SchedRW = [sched.Folded, sched.ReadAfterFold];
 }
 
-def IMUL16rr : IMulOpRR<Xi16, WriteIMul16Reg>, OpSize16;
-def IMUL32rr : IMulOpRR<Xi32, WriteIMul32Reg>, OpSize32;
-def IMUL64rr : IMulOpRR<Xi64, WriteIMul64Reg>;
-def IMUL16rm : IMulOpRM<Xi16, WriteIMul16Reg>, OpSize16;
-def IMUL32rm : IMulOpRM<Xi32, WriteIMul32Reg>, OpSize32;
-def IMUL64rm : IMulOpRM<Xi64, WriteIMul64Reg>;
+let Predicates = [NoNDD] in {
+  def IMUL16rr : IMulOpRR_RF<Xi16, WriteIMul16Reg>, TB, OpSize16;
+  def IMUL32rr : IMulOpRR_RF<Xi32, WriteIMul32Reg>, TB, OpSize32;
+  def IMUL64rr : IMulOpRR_RF<Xi64, WriteIMul64Reg>, TB;
+  def IMUL16rm : IMulOpRM_RF<Xi16, WriteIMul16Reg>, TB, OpSize16;
+  def IMUL32rm : IMulOpRM_RF<Xi32, WriteIMul32Reg>, TB, OpSize32;
+  def IMUL64rm : IMulOpRM_RF<Xi64, WriteIMul64Reg>, TB;
+}
+let Predicates = [HasNDD, In64BitMode] in {
+  def IMUL16rr_ND : IMulOpRR_RF<Xi16, WriteIMul16Reg, 1>, PD;
+  def IMUL32rr_ND : IMulOpRR_RF<Xi32, WriteIMul32Reg, 1>;
+  def IMUL64rr_ND : IMulOpRR_RF<Xi64, WriteIMul64Reg, 1>;
+  def IMUL16rm_ND : IMulOpRM_RF<Xi16, WriteIMul16Reg, 1>, PD;
+  def IMUL32rm_ND : IMulOpRM_RF<Xi32, WriteIMul32Reg, 1>;
+  def IMUL64rm_ND : IMulOpRM_RF<Xi64, WriteIMul64Reg, 1>;
+}
 
-class IMulOpRI8_R<X86TypeInfo t, X86FoldableSchedWrite sched>
+let Predicates = [In64BitMode] in {
+  def IMUL16rr_NF : IMulOpRR_R<Xi16, WriteIMul16Reg>, NF, PD;
+  def IMUL32rr_NF : IMulOpRR_R<Xi32, WriteIMul32Reg>, NF;
+  def IMUL64rr_NF : IMulOpRR_R<Xi64, WriteIMul64Reg>, NF;
+  def IMUL16rm_NF : IMulOpRM_R<Xi16, WriteIMul16Reg>, NF, PD;
+  def IMUL32rm_NF : IMulOpRM_R<Xi32, WriteIMul32Reg>, NF;
+  def IMUL64rm_NF : IMulOpRM_R<Xi64, WriteIMul64Reg>, NF;
+
+  def IMUL16rr_NF_ND : IMulOpRR_R<Xi16, WriteIMul16Reg, 1>, EVEX_NF, PD;
+  def IMUL32rr_NF_ND : IMulOpRR_R<Xi32, WriteIMul32Reg, 1>, EVEX_NF;
+  def IMUL64rr_NF_ND : IMulOpRR_R<Xi64, WriteIMul64Reg, 1>, EVEX_NF;
+  def IMUL16rm_NF_ND : IMulOpRM_R<Xi16, WriteIMul16Reg, 1>, EVEX_NF, PD;
+  def IMUL32rm_NF_ND : IMulOpRM_R<Xi32, WriteIMul32Reg, 1>, EVEX_NF;
+  def IMUL64rm_NF_ND : IMulOpRM_R<Xi64, WriteIMul64Reg, 1>, EVEX_NF;
+
+  let Pattern = [(null_frag)] in {
+    def IMUL16rr_EVEX : IMulOpRR_RF<Xi16, WriteIMul16Reg>, PL, PD;
+    def IMUL32rr_EVEX : IMulOpRR_RF<Xi32, WriteIMul32Reg>, PL;
+    def IMUL64rr_EVEX : IMulOpRR_RF<Xi64, WriteIMul64Reg>, PL;
+    def IMUL16rm_EVEX : IMulOpRM_RF<Xi16, WriteIMul16Reg>, PL, PD;
+    def IMUL32rm_EVEX : IMulOpRM_RF<Xi32, WriteIMul32Reg>, PL;
+    def IMUL64rm_EVEX : IMulOpRM_RF<Xi64, WriteIMul64Reg>, PL;
+  }
+}
+
+class IMulOpRI8<X86TypeInfo t, X86FoldableSchedWrite sched>
   : BinOpRI8<0x6B, "imul", binop_ndd_args, t, MRMSrcReg,
-             (outs t.RegClass:$dst)>, DefEFLAGS {
+             (outs t.RegClass:$dst)> {
   let SchedRW = [sched];
 }
 class IMulOpRI_R<X86TypeInfo t, X86FoldableSchedWrite sched>
+  : BinOpRI<0x69, "imul", binop_ndd_args, t, MRMSrcReg,
+            (outs t.RegClass:$dst), []> {
+  let SchedRW = [sched];
+}
+class IMulOpRI_RF<X86TypeInfo t, X86FoldableSchedWrite sched>
   : BinOpRI<0x69, "imul", binop_ndd_args, t, MRMSrcReg,
             (outs t.RegClass:$dst),
             [(set t.RegClass:$dst, EFLAGS, (X86smul_flag t.RegClass:$src1,
              t.ImmNoSuOperator:$src2))]>, DefEFLAGS {
   let SchedRW = [sched];
 }
-class IMulOpMI8_R<X86TypeInfo t, X86FoldableSchedWrite sched>
-  : BinOpMI8<"imul", binop_ndd_args, t, MRMSrcMem, (outs t.RegClass:$dst)>,
-    DefEFLAGS {
+class IMulOpMI8<X86TypeInfo t, X86FoldableSchedWrite sched>
+  : BinOpMI8<"imul", binop_ndd_args, t, MRMSrcMem, (outs t.RegClass:$dst)> {
   let Opcode = 0x6B;
   let SchedRW = [sched.Folded];
 }
 class IMulOpMI_R<X86TypeInfo t, X86FoldableSchedWrite sched>
+  : BinOpMI<0x69, "imul", binop_ndd_args, t, MRMSrcMem,
+            (outs t.RegClass:$dst), []> {
+  let SchedRW = [sched.Folded];
+}
+class IMulOpMI_RF<X86TypeInfo t, X86FoldableSchedWrite sched>
   : BinOpMI<0x69, "imul", binop_ndd_args, t, MRMSrcMem,
             (outs t.RegClass:$dst),
             [(set t.RegClass:$dst, EFLAGS, (X86smul_flag (t.LoadNode addr:$src1),
@@ -167,20 +296,46 @@ class IMulOpMI_R<X86TypeInfo t, X86FoldableSchedWrite sched>
     DefEFLAGS {
   let SchedRW = [sched.Folded];
 }
-def IMUL16rri8 : IMulOpRI8_R<Xi16, WriteIMul16Imm>, OpSize16;
-def IMUL32rri8 : IMulOpRI8_R<Xi32, WriteIMul32Imm>, OpSize32;
-def IMUL64rri8 : IMulOpRI8_R<Xi64, WriteIMul64Imm>;
-def IMUL16rri  : IMulOpRI_R<Xi16, WriteIMul16Imm>, OpSize16;
-def IMUL32rri  : IMulOpRI_R<Xi32, WriteIMul32Imm>, OpSize32;
-def IMUL64rri32 : IMulOpRI_R<Xi64, WriteIMul64Imm>;
-
-def IMUL16rmi8 : IMulOpMI8_R<Xi16, WriteIMul16Imm>, OpSize16;
-def IMUL32rmi8 : IMulOpMI8_R<Xi32, WriteIMul32Imm>, OpSize32;
-def IMUL64rmi8 : IMulOpMI8_R<Xi64, WriteIMul64Imm>;
-def IMUL16rmi  : IMulOpMI_R<Xi16, WriteIMul16Imm>, OpSize16;
-def IMUL32rmi  : IMulOpMI_R<Xi32, WriteIMul32Imm>, OpSize32;
-def IMUL64rmi32 : IMulOpMI_R<Xi64, WriteIMul64Imm>;
-
+def IMUL16rri8 : IMulOpRI8<Xi16, WriteIMul16Imm>, DefEFLAGS, OpSize16;
+def IMUL32rri8 : IMulOpRI8<Xi32, WriteIMul32Imm>, DefEFLAGS, OpSize32;
+def IMUL64rri8 : IMulOpRI8<Xi64, WriteIMul64Imm>, DefEFLAGS;
+def IMUL16rri  : IMulOpRI_RF<Xi16, WriteIMul16Imm>, OpSize16;
+def IMUL32rri  : IMulOpRI_RF<Xi32, WriteIMul32Imm>, OpSize32;
+def IMUL64rri32 : IMulOpRI_RF<Xi64, WriteIMul64Imm>;
+def IMUL16rmi8 : IMulOpMI8<Xi16, WriteIMul16Imm>, DefEFLAGS, OpSize16;
+def IMUL32rmi8 : IMulOpMI8<Xi32, WriteIMul32Imm>, DefEFLAGS, OpSize32;
+def IMUL64rmi8 : IMulOpMI8<Xi64, WriteIMul64Imm>, DefEFLAGS;
+def IMUL16rmi  : IMulOpMI_RF<Xi16, WriteIMul16Imm>, OpSize16;
+def IMUL32rmi  : IMulOpMI_RF<Xi32, WriteIMul32Imm>, OpSize32;
+def IMUL64rmi32 : IMulOpMI_RF<Xi64, WriteIMul64Imm>;
+
+let Predicates = [In64BitMode] in {
+  def IMUL16rri8_NF : IMulOpRI8<Xi16, WriteIMul16Imm>, NF, PD;
+  def IMUL32rri8_NF : IMulOpRI8<Xi32, WriteIMul32Imm>, NF;
+  def IMUL64rri8_NF : IMulOpRI8<Xi64, WriteIMul64Imm>, NF;
+  def IMUL16rri_NF  : IMulOpRI_R<Xi16, WriteIMul16Imm>, NF, PD;
+  def IMUL32rri_NF  : IMulOpRI_R<Xi32, WriteIMul32Imm>, NF;
+  def IMUL64rri32_NF : IMulOpRI_R<Xi64, WriteIMul64Imm>, NF;
+  def IMUL16rmi8_NF : IMulOpMI8<Xi16, WriteIMul16Imm>, NF, PD;
+  def IMUL32rmi8_NF : IMulOpMI8<Xi32, WriteIMul32Imm>, NF;
+  def IMUL64rmi8_NF : IMulOpMI8<Xi64, WriteIMul64Imm>, NF;
+  def IMUL16rmi_NF  : IMulOpMI_R<Xi16, WriteIMul16Imm>, NF, PD;
+  def IMUL32rmi_NF  : IMulOpMI_R<Xi32, WriteIMul32Imm>, NF;
+  def IMUL64rmi32_NF : IMulOpMI_R<Xi64, WriteIMul64Imm>, NF;
+
+  def IMUL16rri8_EVEX : IMulOpRI8<Xi16, WriteIMul16Imm>, DefEFLAGS, PL, PD;
+  def IMUL32rri8_EVEX : IMulOpRI8<Xi32, WriteIMul32Imm>, DefEFLAGS, PL;
+  def IMUL64rri8_EVEX : IMulOpRI8<Xi64, WriteIMul64Imm>, DefEFLAGS, PL;
+  def IMUL16rri_EVEX  : IMulOpRI_RF<Xi16, WriteIMul16Imm>, PL, PD;
+  def IMUL32rri_EVEX  : IMulOpRI_RF<Xi32, WriteIMul32Imm>, PL;
+  def IMUL64rri32_EVEX : IMulOpRI_RF<Xi64, WriteIMul64Imm>, PL;
+  def IMUL16rmi8_EVEX : IMulOpMI8<Xi16, WriteIMul16Imm>, DefEFLAGS, PL, PD;
+  def IMUL32rmi8_EVEX : IMulOpMI8<Xi32, WriteIMul32Imm>, DefEFLAGS, PL;
+  def IMUL64rmi8_EVEX : IMulOpMI8<Xi64, WriteIMul64Imm>, DefEFLAGS, PL;
+  def IMUL16rmi_EVEX  : IMulOpMI_RF<Xi16, WriteIMul16Imm>, PL, PD;
+  def IMUL32rmi_EVEX  : IMulOpMI_RF<Xi32, WriteIMul32Imm>, PL;
+  def IMUL64rmi32_EVEX : IMulOpMI_RF<Xi64, WriteIMul64Imm>, PL;
+}
 //===----------------------------------------------------------------------===//
 // INC and DEC Instructions
 //
diff --git a/llvm/test/MC/Disassembler/X86/apx/div.txt b/llvm/test/MC/Disassembler/X86/apx/div.txt
new file mode 100644
index 00000000000000..277e4464c57800
--- /dev/null
+++ b/llvm/test/MC/Disassembler/X86/apx/div.txt
@@ -0,0 +1,66 @@
+# RUN: llvm-mc -triple x86_64 -disassemble %s | FileCheck %s --check-prefix=ATT
+# RUN: llvm-mc -triple x86_64 -disassemble -output-asm-variant=1 %s | FileCheck %s --check-prefix=INTEL
+
+# ATT:   {evex}	divb	%bl
+# INTEL: {evex}	div	bl
+0x62,0xf4,0x7c,0x08,0xf6,0xf3
+
+# ATT:   {nf}	divb	%bl
+# INTEL: {nf}	div	bl
+0x62,0xf4,0x7c,0x0c,0xf6,0xf3
+
+# ATT:   {evex}	divw	%dx
+# INTEL: {evex}	div	dx
+0x62,0xf4,0x7d,0x08,0xf7,0xf2
+
+# ATT:   {nf}	divw	%dx
+# INTEL: {nf}	div	dx
+0x62,0xf4,0x7d,0x0c,0xf7,0xf2
+
+# ATT:   {evex}	divl	%ecx
+# INTEL: {evex}	div	ecx
+0x62,0xf4,0x7c,0x08,0xf7,0xf1
+
+# ATT:   {nf}	divl	%ecx
+# INTEL: {nf}	div	ecx
+0x62,0xf4,0x7c,0x0c,0xf7,0xf1
+
+# ATT:   {evex}	divq	%r9
+# INTEL: {evex}	div	r9
+0x62,0xd4,0xfc,0x08,0xf7,0xf1
+
+# ATT:   {nf}	divq	%r9
+# INTEL: {nf}	div	r9
+0x62,0xd4,0xfc,0x0c,0xf7,0xf1
+
+# ATT:   {evex}	divb	291(%r8,%rax,4)
+# INTEL: {evex}	div	byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xf6,0xb4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	divb	291(%r8,%rax,4)
+# INTEL: {nf}	div	byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xf6,0xb4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	divw	291(%r8,%rax,4)
+# INTEL: {evex}	div	word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x08,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	divw	291(%r8,%rax,4)
+# INTEL: {nf}	div	word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x0c,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	divl	291(%r8,%rax,4)
+# INTEL: {evex}	div	dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	divl	291(%r8,%rax,4)
+# INTEL: {nf}	div	dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	divq	291(%r8,%rax,4)
+# INTEL: {evex}	div	qword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0xfc,0x08,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	divq	291(%r8,%rax,4)
+# INTEL: {nf}	div	qword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0xfc,0x0c,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00
diff --git a/llvm/test/MC/Disassembler/X86/apx/idiv.txt b/llvm/test/MC/Disassembler/X86/apx/idiv.txt
new file mode 100644
index 00000000000000..f5daf735a0b59e
--- /dev/null
+++ b/llvm/test/MC/Disassembler/X86/apx/idiv.txt
@@ -0,0 +1,66 @@
+# RUN: llvm-mc -triple x86_64 -disassemble %s | FileCheck %s --check-prefix=ATT
+# RUN: llvm-mc -triple x86_64 -disassemble -output-asm-variant=1 %s | FileCheck %s --check-prefix=INTEL
+
+# ATT:   {evex}	idivb	%bl
+# INTEL: {evex}	idiv	bl
+0x62,0xf4,0x7c,0x08,0xf6,0xfb
+
+# ATT:   {nf}	idivb	%bl
+# INTEL: {nf}	idiv	bl
+0x62,0xf4,0x7c,0x0c,0xf6,0xfb
+
+# ATT:   {evex}	idivw	%dx
+# INTEL: {evex}	idiv	dx
+0x62,0xf4,0x7d,0x08,0xf7,0xfa
+
+# ATT:   {nf}	idivw	%dx
+# INTEL: {nf}	idiv	dx
+0x62,0xf4,0x7d,0x0c,0xf7,0xfa
+
+# ATT:   {evex}	idivl	%ecx
+# INTEL: {evex}	idiv	ecx
+0x62,0xf4,0x7c,0x08,0xf7,0xf9
+
+# ATT:   {nf}	idivl	%ecx
+# INTEL: {nf}	idiv	ecx
+0x62,0xf4,0x7c,0x0c,0xf7,0xf9
+
+# ATT:   {evex}	idivq	%r9
+# INTEL: {evex}	idiv	r9
+0x62,0xd4,0xfc,0x08,0xf7,0xf9
+
+# ATT:   {nf}	idivq	%r9
+# INTEL: {nf}	idiv	r9
+0x62,0xd4,0xfc,0x0c,0xf7,0xf9
+
+# ATT:   {evex}	idivb	291(%r8,%rax,4)
+# INTEL: {evex}	idiv	byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xf6,0xbc,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	idivb	291(%r8,%rax,4)
+# INTEL: {nf}	idiv	byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xf6,0xbc,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	idivw	291(%r8,%rax,4)
+# INTEL: {evex}	idiv	word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x08,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	idivw	291(%r8,%rax,4)
+# INTEL: {nf}	idiv	word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x0c,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	idivl	291(%r8,%rax,4)
+# INTEL: {evex}	idiv	dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	idivl	291(%r8,%rax,4)
+# INTEL: {nf}	idiv	dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	idivq	291(%r8,%rax,4)
+# INTEL: {evex}	idiv	qword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0xfc,0x08,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	idivq	291(%r8,%rax,4)
+# INTEL: {nf}	idiv	qword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0xfc,0x0c,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00
diff --git a/llvm/test/MC/Disassembler/X86/apx/imul.txt b/llvm/test/MC/Disassembler/X86/apx/imul.txt
new file mode 100644
index 00000000000000..f72a6f4aec8f92
--- /dev/null
+++ b/llvm/test/MC/Disassembler/X86/apx/imul.txt
@@ -0,0 +1,258 @@
+# RUN: llvm-mc -triple x86_64 -disassemble %s | FileCheck %s --check-prefix=ATT
+# RUN: llvm-mc -triple x86_64 -disassemble -output-asm-variant=1 %s | FileCheck %s --check-prefix=INTEL
+
+# ATT:   {evex}	imulw	$123, %dx, %dx
+# INTEL: {evex}	imul	dx, dx, 123
+0x62,0xf4,0x7d,0x08,0x6b,0xd2,0x7b
+
+# ATT:   {nf}	imulw	$123, %dx, %dx
+# INTEL: {nf}	imul	dx, dx, 123
+0x62,0xf4,0x7d,0x0c,0x6b,0xd2,0x7b
+
+# ATT:   {evex}	imull	$123, %ecx, %ecx
+# INTEL: {evex}	imul	ecx, ecx, 123
+0x62,0xf4,0x7c,0x08,0x6b,0xc9,0x7b
+
+# ATT:   {nf}	imull	$123, %ecx, %ecx
+# INTEL: {nf}	imul	ecx, ecx, 123
+0x62,0xf4,0x7c,0x0c,0x6b,0xc9,0x7b
+
+# ATT:   {evex}	imulq	$123, %r9, %r9
+# INTEL: {evex}	imul	r9, r9, 123
+0x62,0x54,0xfc,0x08,0x6b,0xc9,0x7b
+
+# ATT:   {nf}	imulq	$123, %r9, %r9
+# INTEL: {nf}	imul	r9, r9, 123
+0x62,0x54,0xfc,0x0c,0x6b,0xc9,0x7b
+
+# ATT:   {evex}	imulw	$123, 291(%r8,%rax,4), %dx
+# INTEL: {evex}	imul	dx, word ptr [r8 + 4*rax + 291], 123
+0x62,0xd4,0x7d,0x08,0x6b,0x94,0x80,0x23,0x01,0x00,0x00,0x7b
+
+# ATT:   {nf}	imulw	$123, 291(%r8,%rax,4), %dx
+# INTEL: {nf}	imul	dx, word ptr [r8 + 4*rax + 291], 123
+0x62,0xd4,0x7d,0x0c,0x6b,0x94,0x80,0x23,0x01,0x00,0x00,0x7b
+
+# ATT:   {evex}	imull	$123, 291(%r8,%rax,4), %ecx
+# INTEL: {evex}	imul	ecx, dword ptr [r8 + 4*rax + 291], 123
+0x62,0xd4,0x7c,0x08,0x6b,0x8c,0x80,0x23,0x01,0x00,0x00,0x7b
+
+# ATT:   {nf}	imull	$123, 291(%r8,%rax,4), %ecx
+# INTEL: {nf}	imul	ecx, dword ptr [r8 + 4*rax + 291], 123
+0x62,0xd4,0x7c,0x0c,0x6b,0x8c,0x80,0x23,0x01,0x00,0x00,0x7b
+
+# ATT:   {evex}	imulq	$123, 291(%r8,%rax,4), %r9
+# INTEL: {evex}	imul	r9, qword ptr [r8 + 4*rax + 291], 123
+0x62,0x54,0xfc,0x08,0x6b,0x8c,0x80,0x23,0x01,0x00,0x00,0x7b
+
+# ATT:   {nf}	imulq	$123, 291(%r8,%rax,4), %r9
+# INTEL: {nf}	imul	r9, qword ptr [r8 + 4*rax + 291], 123
+0x62,0x54,0xfc,0x0c,0x6b,0x8c,0x80,0x23,0x01,0x00,0x00,0x7b
+
+# ATT:   {evex}	imulw	$1234, %dx, %dx
+# INTEL: {evex}	imul	dx, dx, 1234
+0x62,0xf4,0x7d,0x08,0x69,0xd2,0xd2,0x04
+
+# ATT:   {nf}	imulw	$1234, %dx, %dx
+# INTEL: {nf}	imul	dx, dx, 1234
+0x62,0xf4,0x7d,0x0c,0x69,0xd2,0xd2,0x04
+
+# ATT:   {evex}	imulw	$1234, 291(%r8,%rax,4), %dx
+# INTEL: {evex}	imul	dx, word ptr [r8 + 4*rax + 291], 1234
+0x62,0xd4,0x7d,0x08,0x69,0x94,0x80,0x23,0x01,0x00,0x00,0xd2,0x04
+
+# ATT:   {nf}	imulw	$1234, 291(%r8,%rax,4), %dx
+# INTEL: {nf}	imul	dx, word ptr [r8 + 4*rax + 291], 1234
+0x62,0xd4,0x7d,0x0c,0x69,0x94,0x80,0x23,0x01,0x00,0x00,0xd2,0x04
+
+# ATT:   {evex}	imull	$123456, %ecx, %ecx
+# INTEL: {evex}	imul	ecx, ecx, 123456
+0x62,0xf4,0x7c,0x08,0x69,0xc9,0x40,0xe2,0x01,0x00
+
+# ATT:   {nf}	imull	$123456, %ecx, %ecx
+# INTEL: {nf}	imul	ecx, ecx, 123456
+0x62,0xf4,0x7c,0x0c,0x69,0xc9,0x40,0xe2,0x01,0x00
+
+# ATT:   {evex}	imulq	$123456, %r9, %r9
+# INTEL: {evex}	imul	r9, r9, 123456
+0x62,0x54,0xfc,0x08,0x69,0xc9,0x40,0xe2,0x01,0x00
+
+# ATT:   {nf}	imulq	$123456, %r9, %r9
+# INTEL: {nf}	imul	r9, r9, 123456
+0x62,0x54,0xfc,0x0c,0x69,0xc9,0x40,0xe2,0x01,0x00
+
+# ATT:   {evex}	imull	$123456, 291(%r8,%rax,4), %ecx
+# INTEL: {evex}	imul	ecx, dword ptr [r8 + 4*rax + 291], 123456
+0x62,0xd4,0x7c,0x08,0x69,0x8c,0x80,0x23,0x01,0x00,0x00,0x40,0xe2,0x01,0x00
+
+# ATT:   {nf}	imull	$123456, 291(%r8,%rax,4), %ecx
+# INTEL: {nf}	imul	ecx, dword ptr [r8 + 4*rax + 291], 123456
+0x62,0xd4,0x7c,0x0c,0x69,0x8c,0x80,0x23,0x01,0x00,0x00,0x40,0xe2,0x01,0x00
+
+# ATT:   {evex}	imulq	$123456, 291(%r8,%rax,4), %r9
+# INTEL: {evex}	imul	r9, qword ptr [r8 + 4*rax + 291], 123456
+0x62,0x54,0xfc,0x08,0x69,0x8c,0x80,0x23,0x01,0x00,0x00,0x40,0xe2,0x01,0x00
+
+# ATT:   {nf}	imulq	$123456, 291(%r8,%rax,4), %r9
+# INTEL: {nf}	imul	r9, qword ptr [r8 + 4*rax + 291], 123456
+0x62,0x54,0xfc,0x0c,0x69,0x8c,0x80,0x23,0x01,0x00,0x00,0x40,0xe2,0x01,0x00
+
+# ATT:   {evex}	imulb	%bl
+# INTEL: {evex}	imul	bl
+0x62,0xf4,0x7c,0x08,0xf6,0xeb
+
+# ATT:   {nf}	imulb	%bl
+# INTEL: {nf}	imul	bl
+0x62,0xf4,0x7c,0x0c,0xf6,0xeb
+
+# ATT:   {evex}	imulw	%dx
+# INTEL: {evex}	imul	dx
+0x62,0xf4,0x7d,0x08,0xf7,0xea
+
+# ATT:   {nf}	imulw	%dx
+# INTEL: {nf}	imul	dx
+0x62,0xf4,0x7d,0x0c,0xf7,0xea
+
+# ATT:   {evex}	imulw	%dx, %dx
+# INTEL: {evex}	imul	dx, dx
+0x62,0xf4,0x7d,0x08,0xaf,0xd2
+
+# ATT:   {nf}	imulw	%dx, %dx
+# INTEL: {nf}	imul	dx, dx
+0x62,0xf4,0x7d,0x0c,0xaf,0xd2
+
+# ATT:   imulw	%dx, %dx, %dx
+# INTEL: imul	dx, dx, dx
+0x62,0xf4,0x6d,0x18,0xaf,0xd2
+
+# ATT:   {nf}	imulw	%dx, %dx, %dx
+# INTEL: {nf}	imul	dx, dx, dx
+0x62,0xf4,0x6d,0x1c,0xaf,0xd2
+
+# ATT:   {evex}	imull	%ecx
+# INTEL: {evex}	imul	ecx
+0x62,0xf4,0x7c,0x08,0xf7,0xe9
+
+# ATT:   {nf}	imull	%ecx
+# INTEL: {nf}	imul	ecx
+0x62,0xf4,0x7c,0x0c,0xf7,0xe9
+
+# ATT:   {evex}	imull	%ecx, %ecx
+# INTEL: {evex}	imul	ecx, ecx
+0x62,0xf4,0x7c,0x08,0xaf,0xc9
+
+# ATT:   {nf}	imull	%ecx, %ecx
+# INTEL: {nf}	imul	ecx, ecx
+0x62,0xf4,0x7c,0x0c,0xaf,0xc9
+
+# ATT:   imull	%ecx, %ecx, %ecx
+# INTEL: imul	ecx, ecx, ecx
+0x62,0xf4,0x74,0x18,0xaf,0xc9
+
+# ATT:   {nf}	imull	%ecx, %ecx, %ecx
+# INTEL: {nf}	imul	ecx, ecx, ecx
+0x62,0xf4,0x74,0x1c,0xaf,0xc9
+
+# ATT:   {evex}	imulq	%r9
+# INTEL: {evex}	imul	r9
+0x62,0xd4,0xfc,0x08,0xf7,0xe9
+
+# ATT:   {nf}	imulq	%r9
+# INTEL: {nf}	imul	r9
+0x62,0xd4,0xfc,0x0c,0xf7,0xe9
+
+# ATT:   {evex}	imulq	%r9, %r9
+# INTEL: {evex}	imul	r9, r9
+0x62,0x54,0xfc,0x08,0xaf,0xc9
+
+# ATT:   {nf}	imulq	%r9, %r9
+# INTEL: {nf}	imul	r9, r9
+0x62,0x54,0xfc,0x0c,0xaf,0xc9
+
+# ATT:   imulq	%r9, %r9, %r9
+# INTEL: imul	r9, r9, r9
+0x62,0x54,0xb4,0x18,0xaf,0xc9
+
+# ATT:   {nf}	imulq	%r9, %r9, %r9
+# INTEL: {nf}	imul	r9, r9, r9
+0x62,0x54,0xb4,0x1c,0xaf,0xc9
+
+# ATT:   {evex}	imulb	291(%r8,%rax,4)
+# INTEL: {evex}	imul	byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xf6,0xac,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	imulb	291(%r8,%rax,4)
+# INTEL: {nf}	imul	byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xf6,0xac,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	imulw	291(%r8,%rax,4)
+# INTEL: {evex}	imul	word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x08,0xf7,0xac,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	imulw	291(%r8,%rax,4)
+# INTEL: {nf}	imul	word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x0c,0xf7,0xac,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	imulw	291(%r8,%rax,4), %dx
+# INTEL: {evex}	imul	dx, word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x08,0xaf,0x94,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	imulw	291(%r8,%rax,4), %dx
+# INTEL: {nf}	imul	dx, word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x0c,0xaf,0x94,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   imulw	291(%r8,%rax,4), %dx, %dx
+# INTEL: imul	dx, dx, word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x6d,0x18,0xaf,0x94,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	imulw	291(%r8,%rax,4), %dx, %dx
+# INTEL: {nf}	imul	dx, dx, word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x6d,0x1c,0xaf,0x94,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	imull	291(%r8,%rax,4)
+# INTEL: {evex}	imul	dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xf7,0xac,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	imull	291(%r8,%rax,4)
+# INTEL: {nf}	imul	dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xf7,0xac,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	imull	291(%r8,%rax,4), %ecx
+# INTEL: {evex}	imul	ecx, dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	imull	291(%r8,%rax,4), %ecx
+# INTEL: {nf}	imul	ecx, dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   imull	291(%r8,%rax,4), %ecx, %ecx
+# INTEL: imul	ecx, ecx, dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x74,0x18,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	imull	291(%r8,%rax,4), %ecx, %ecx
+# INTEL: {nf}	imul	ecx, ecx, dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x74,0x1c,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	imulq	291(%r8,%rax,4)
+# INTEL: {evex}	imul	qword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0xfc,0x08,0xf7,0xac,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	imulq	291(%r8,%rax,4)
+# INTEL: {nf}	imul	qword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0xfc,0x0c,0xf7,0xac,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	imulq	291(%r8,%rax,4), %r9
+# INTEL: {evex}	imul	r9, qword ptr [r8 + 4*rax + 291]
+0x62,0x54,0xfc,0x08,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	imulq	291(%r8,%rax,4), %r9
+# INTEL: {nf}	imul	r9, qword ptr [r8 + 4*rax + 291]
+0x62,0x54,0xfc,0x0c,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   imulq	291(%r8,%rax,4), %r9, %r9
+# INTEL: imul	r9, r9, qword ptr [r8 + 4*rax + 291]
+0x62,0x54,0xb4,0x18,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	imulq	291(%r8,%rax,4), %r9, %r9
+# INTEL: {nf}	imul	r9, r9, qword ptr [r8 + 4*rax + 291]
+0x62,0x54,0xb4,0x1c,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00
diff --git a/llvm/test/MC/Disassembler/X86/apx/mul.txt b/llvm/test/MC/Disassembler/X86/apx/mul.txt
new file mode 100644
index 00000000000000..eb5e69e3e2e567
--- /dev/null
+++ b/llvm/test/MC/Disassembler/X86/apx/mul.txt
@@ -0,0 +1,66 @@
+# RUN: llvm-mc -triple x86_64 -disassemble %s | FileCheck %s --check-prefix=ATT
+# RUN: llvm-mc -triple x86_64 -disassemble -output-asm-variant=1 %s | FileCheck %s --check-prefix=INTEL
+
+# ATT:   {evex}	mulb	%bl
+# INTEL: {evex}	mul	bl
+0x62,0xf4,0x7c,0x08,0xf6,0xe3
+
+# ATT:   {nf}	mulb	%bl
+# INTEL: {nf}	mul	bl
+0x62,0xf4,0x7c,0x0c,0xf6,0xe3
+
+# ATT:   {evex}	mulw	%dx
+# INTEL: {evex}	mul	dx
+0x62,0xf4,0x7d,0x08,0xf7,0xe2
+
+# ATT:   {nf}	mulw	%dx
+# INTEL: {nf}	mul	dx
+0x62,0xf4,0x7d,0x0c,0xf7,0xe2
+
+# ATT:   {evex}	mull	%ecx
+# INTEL: {evex}	mul	ecx
+0x62,0xf4,0x7c,0x08,0xf7,0xe1
+
+# ATT:   {nf}	mull	%ecx
+# INTEL: {nf}	mul	ecx
+0x62,0xf4,0x7c,0x0c,0xf7,0xe1
+
+# ATT:   {evex}	mulq	%r9
+# INTEL: {evex}	mul	r9
+0x62,0xd4,0xfc,0x08,0xf7,0xe1
+
+# ATT:   {nf}	mulq	%r9
+# INTEL: {nf}	mul	r9
+0x62,0xd4,0xfc,0x0c,0xf7,0xe1
+
+# ATT:   {evex}	mulb	291(%r8,%rax,4)
+# INTEL: {evex}	mul	byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xf6,0xa4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	mulb	291(%r8,%rax,4)
+# INTEL: {nf}	mul	byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xf6,0xa4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	mulw	291(%r8,%rax,4)
+# INTEL: {evex}	mul	word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x08,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	mulw	291(%r8,%rax,4)
+# INTEL: {nf}	mul	word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x0c,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	mull	291(%r8,%rax,4)
+# INTEL: {evex}	mul	dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	mull	291(%r8,%rax,4)
+# INTEL: {nf}	mul	dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {evex}	mulq	291(%r8,%rax,4)
+# INTEL: {evex}	mul	qword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0xfc,0x08,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00
+
+# ATT:   {nf}	mulq	291(%r8,%rax,4)
+# INTEL: {nf}	mul	qword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0xfc,0x0c,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00
diff --git a/llvm/test/MC/X86/apx/div-att.s b/llvm/test/MC/X86/apx/div-att.s
new file mode 100644
index 00000000000000..0b78aa5a59d1d2
--- /dev/null
+++ b/llvm/test/MC/X86/apx/div-att.s
@@ -0,0 +1,53 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
+# RUN: not llvm-mc -triple i386 -show-encoding %s 2>&1 | FileCheck %s --check-prefix=ERROR
+
+# ERROR-COUNT-16: error:
+# ERROR-NOT: error:
+# CHECK: {evex}	divb	%bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf6,0xf3]
+         {evex}	divb	%bl
+# CHECK: {nf}	divb	%bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf6,0xf3]
+         {nf}	divb	%bl
+# CHECK: {evex}	divw	%dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0xf7,0xf2]
+         {evex}	divw	%dx
+# CHECK: {nf}	divw	%dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0xf7,0xf2]
+         {nf}	divw	%dx
+# CHECK: {evex}	divl	%ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf7,0xf1]
+         {evex}	divl	%ecx
+# CHECK: {nf}	divl	%ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf7,0xf1]
+         {nf}	divl	%ecx
+# CHECK: {evex}	divq	%r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xf1]
+         {evex}	divq	%r9
+# CHECK: {nf}	divq	%r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xf1]
+         {nf}	divq	%r9
+# CHECK: {evex}	divb	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf6,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	divb	291(%r8,%rax,4)
+# CHECK: {nf}	divb	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf6,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	divb	291(%r8,%rax,4)
+# CHECK: {evex}	divw	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	divw	291(%r8,%rax,4)
+# CHECK: {nf}	divw	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	divw	291(%r8,%rax,4)
+# CHECK: {evex}	divl	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	divl	291(%r8,%rax,4)
+# CHECK: {nf}	divl	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	divl	291(%r8,%rax,4)
+# CHECK: {evex}	divq	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	divq	291(%r8,%rax,4)
+# CHECK: {nf}	divq	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	divq	291(%r8,%rax,4)
diff --git a/llvm/test/MC/X86/apx/div-intel.s b/llvm/test/MC/X86/apx/div-intel.s
new file mode 100644
index 00000000000000..3647b95d5d3499
--- /dev/null
+++ b/llvm/test/MC/X86/apx/div-intel.s
@@ -0,0 +1,50 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding -x86-asm-syntax=intel -output-asm-variant=1 %s | FileCheck %s
+
+# CHECK: {evex}	div	bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf6,0xf3]
+         {evex}	div	bl
+# CHECK: {nf}	div	bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf6,0xf3]
+         {nf}	div	bl
+# CHECK: {evex}	div	dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0xf7,0xf2]
+         {evex}	div	dx
+# CHECK: {nf}	div	dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0xf7,0xf2]
+         {nf}	div	dx
+# CHECK: {evex}	div	ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf7,0xf1]
+         {evex}	div	ecx
+# CHECK: {nf}	div	ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf7,0xf1]
+         {nf}	div	ecx
+# CHECK: {evex}	div	r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xf1]
+         {evex}	div	r9
+# CHECK: {nf}	div	r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xf1]
+         {nf}	div	r9
+# CHECK: {evex}	div	byte ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf6,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	div	byte ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	div	byte ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf6,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	div	byte ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	div	word ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	div	word ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	div	word ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	div	word ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	div	dword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	div	dword ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	div	dword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	div	dword ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	div	qword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	div	qword ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	div	qword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xb4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	div	qword ptr [r8 + 4*rax + 291]
diff --git a/llvm/test/MC/X86/apx/idiv-att.s b/llvm/test/MC/X86/apx/idiv-att.s
new file mode 100644
index 00000000000000..9b5da5808cd13d
--- /dev/null
+++ b/llvm/test/MC/X86/apx/idiv-att.s
@@ -0,0 +1,53 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
+# RUN: not llvm-mc -triple i386 -show-encoding %s 2>&1 | FileCheck %s --check-prefix=ERROR
+
+# ERROR-COUNT-16: error:
+# ERROR-NOT: error:
+# CHECK: {evex}	idivb	%bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf6,0xfb]
+         {evex}	idivb	%bl
+# CHECK: {nf}	idivb	%bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf6,0xfb]
+         {nf}	idivb	%bl
+# CHECK: {evex}	idivw	%dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0xf7,0xfa]
+         {evex}	idivw	%dx
+# CHECK: {nf}	idivw	%dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0xf7,0xfa]
+         {nf}	idivw	%dx
+# CHECK: {evex}	idivl	%ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf7,0xf9]
+         {evex}	idivl	%ecx
+# CHECK: {nf}	idivl	%ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf7,0xf9]
+         {nf}	idivl	%ecx
+# CHECK: {evex}	idivq	%r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xf9]
+         {evex}	idivq	%r9
+# CHECK: {nf}	idivq	%r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xf9]
+         {nf}	idivq	%r9
+# CHECK: {evex}	idivb	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf6,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {evex}	idivb	291(%r8,%rax,4)
+# CHECK: {nf}	idivb	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf6,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {nf}	idivb	291(%r8,%rax,4)
+# CHECK: {evex}	idivw	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {evex}	idivw	291(%r8,%rax,4)
+# CHECK: {nf}	idivw	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {nf}	idivw	291(%r8,%rax,4)
+# CHECK: {evex}	idivl	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {evex}	idivl	291(%r8,%rax,4)
+# CHECK: {nf}	idivl	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {nf}	idivl	291(%r8,%rax,4)
+# CHECK: {evex}	idivq	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {evex}	idivq	291(%r8,%rax,4)
+# CHECK: {nf}	idivq	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {nf}	idivq	291(%r8,%rax,4)
diff --git a/llvm/test/MC/X86/apx/idiv-intel.s b/llvm/test/MC/X86/apx/idiv-intel.s
new file mode 100644
index 00000000000000..1117df929a16b9
--- /dev/null
+++ b/llvm/test/MC/X86/apx/idiv-intel.s
@@ -0,0 +1,50 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding -x86-asm-syntax=intel -output-asm-variant=1 %s | FileCheck %s
+
+# CHECK: {evex}	idiv	bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf6,0xfb]
+         {evex}	idiv	bl
+# CHECK: {nf}	idiv	bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf6,0xfb]
+         {nf}	idiv	bl
+# CHECK: {evex}	idiv	dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0xf7,0xfa]
+         {evex}	idiv	dx
+# CHECK: {nf}	idiv	dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0xf7,0xfa]
+         {nf}	idiv	dx
+# CHECK: {evex}	idiv	ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf7,0xf9]
+         {evex}	idiv	ecx
+# CHECK: {nf}	idiv	ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf7,0xf9]
+         {nf}	idiv	ecx
+# CHECK: {evex}	idiv	r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xf9]
+         {evex}	idiv	r9
+# CHECK: {nf}	idiv	r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xf9]
+         {nf}	idiv	r9
+# CHECK: {evex}	idiv	byte ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf6,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {evex}	idiv	byte ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	idiv	byte ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf6,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {nf}	idiv	byte ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	idiv	word ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {evex}	idiv	word ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	idiv	word ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {nf}	idiv	word ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	idiv	dword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {evex}	idiv	dword ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	idiv	dword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {nf}	idiv	dword ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	idiv	qword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {evex}	idiv	qword ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	idiv	qword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xbc,0x80,0x23,0x01,0x00,0x00]
+         {nf}	idiv	qword ptr [r8 + 4*rax + 291]
diff --git a/llvm/test/MC/X86/apx/imul-att.s b/llvm/test/MC/X86/apx/imul-att.s
new file mode 100644
index 00000000000000..a0a19a42397521
--- /dev/null
+++ b/llvm/test/MC/X86/apx/imul-att.s
@@ -0,0 +1,197 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
+# RUN: not llvm-mc -triple i386 -show-encoding %s 2>&1 | FileCheck %s --check-prefix=ERROR
+
+# ERROR-COUNT-64: error:
+# ERROR-NOT: error:
+# CHECK: {evex}	imulw	$123, %dx, %dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0x6b,0xd2,0x7b]
+         {evex}	imulw	$123, %dx, %dx
+# CHECK: {nf}	imulw	$123, %dx, %dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0x6b,0xd2,0x7b]
+         {nf}	imulw	$123, %dx, %dx
+# CHECK: {evex}	imull	$123, %ecx, %ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0x6b,0xc9,0x7b]
+         {evex}	imull	$123, %ecx, %ecx
+# CHECK: {nf}	imull	$123, %ecx, %ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0x6b,0xc9,0x7b]
+         {nf}	imull	$123, %ecx, %ecx
+# CHECK: {evex}	imulq	$123, %r9, %r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x08,0x6b,0xc9,0x7b]
+         {evex}	imulq	$123, %r9, %r9
+# CHECK: {nf}	imulq	$123, %r9, %r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x0c,0x6b,0xc9,0x7b]
+         {nf}	imulq	$123, %r9, %r9
+# CHECK: {evex}	imulw	$123, 291(%r8,%rax,4), %dx
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0x6b,0x94,0x80,0x23,0x01,0x00,0x00,0x7b]
+         {evex}	imulw	$123, 291(%r8,%rax,4), %dx
+# CHECK: {nf}	imulw	$123, 291(%r8,%rax,4), %dx
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0x6b,0x94,0x80,0x23,0x01,0x00,0x00,0x7b]
+         {nf}	imulw	$123, 291(%r8,%rax,4), %dx
+# CHECK: {evex}	imull	$123, 291(%r8,%rax,4), %ecx
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0x6b,0x8c,0x80,0x23,0x01,0x00,0x00,0x7b]
+         {evex}	imull	$123, 291(%r8,%rax,4), %ecx
+# CHECK: {nf}	imull	$123, 291(%r8,%rax,4), %ecx
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0x6b,0x8c,0x80,0x23,0x01,0x00,0x00,0x7b]
+         {nf}	imull	$123, 291(%r8,%rax,4), %ecx
+# CHECK: {evex}	imulq	$123, 291(%r8,%rax,4), %r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x08,0x6b,0x8c,0x80,0x23,0x01,0x00,0x00,0x7b]
+         {evex}	imulq	$123, 291(%r8,%rax,4), %r9
+# CHECK: {nf}	imulq	$123, 291(%r8,%rax,4), %r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x0c,0x6b,0x8c,0x80,0x23,0x01,0x00,0x00,0x7b]
+         {nf}	imulq	$123, 291(%r8,%rax,4), %r9
+# CHECK: {evex}	imulw	$1234, %dx, %dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0x69,0xd2,0xd2,0x04]
+         {evex}	imulw	$1234, %dx, %dx
+# CHECK: {nf}	imulw	$1234, %dx, %dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0x69,0xd2,0xd2,0x04]
+         {nf}	imulw	$1234, %dx, %dx
+# CHECK: {evex}	imulw	$1234, 291(%r8,%rax,4), %dx
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0x69,0x94,0x80,0x23,0x01,0x00,0x00,0xd2,0x04]
+         {evex}	imulw	$1234, 291(%r8,%rax,4), %dx
+# CHECK: {nf}	imulw	$1234, 291(%r8,%rax,4), %dx
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0x69,0x94,0x80,0x23,0x01,0x00,0x00,0xd2,0x04]
+         {nf}	imulw	$1234, 291(%r8,%rax,4), %dx
+# CHECK: {evex}	imull	$123456, %ecx, %ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0x69,0xc9,0x40,0xe2,0x01,0x00]
+         {evex}	imull	$123456, %ecx, %ecx
+# CHECK: {nf}	imull	$123456, %ecx, %ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0x69,0xc9,0x40,0xe2,0x01,0x00]
+         {nf}	imull	$123456, %ecx, %ecx
+# CHECK: {evex}	imulq	$123456, %r9, %r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x08,0x69,0xc9,0x40,0xe2,0x01,0x00]
+         {evex}	imulq	$123456, %r9, %r9
+# CHECK: {nf}	imulq	$123456, %r9, %r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x0c,0x69,0xc9,0x40,0xe2,0x01,0x00]
+         {nf}	imulq	$123456, %r9, %r9
+# CHECK: {evex}	imull	$123456, 291(%r8,%rax,4), %ecx
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0x69,0x8c,0x80,0x23,0x01,0x00,0x00,0x40,0xe2,0x01,0x00]
+         {evex}	imull	$123456, 291(%r8,%rax,4), %ecx
+# CHECK: {nf}	imull	$123456, 291(%r8,%rax,4), %ecx
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0x69,0x8c,0x80,0x23,0x01,0x00,0x00,0x40,0xe2,0x01,0x00]
+         {nf}	imull	$123456, 291(%r8,%rax,4), %ecx
+# CHECK: {evex}	imulq	$123456, 291(%r8,%rax,4), %r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x08,0x69,0x8c,0x80,0x23,0x01,0x00,0x00,0x40,0xe2,0x01,0x00]
+         {evex}	imulq	$123456, 291(%r8,%rax,4), %r9
+# CHECK: {nf}	imulq	$123456, 291(%r8,%rax,4), %r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x0c,0x69,0x8c,0x80,0x23,0x01,0x00,0x00,0x40,0xe2,0x01,0x00]
+         {nf}	imulq	$123456, 291(%r8,%rax,4), %r9
+# CHECK: {evex}	imulb	%bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf6,0xeb]
+         {evex}	imulb	%bl
+# CHECK: {nf}	imulb	%bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf6,0xeb]
+         {nf}	imulb	%bl
+# CHECK: {evex}	imulw	%dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0xf7,0xea]
+         {evex}	imulw	%dx
+# CHECK: {nf}	imulw	%dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0xf7,0xea]
+         {nf}	imulw	%dx
+# CHECK: {evex}	imulw	%dx, %dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0xaf,0xd2]
+         {evex}	imulw	%dx, %dx
+# CHECK: {nf}	imulw	%dx, %dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0xaf,0xd2]
+         {nf}	imulw	%dx, %dx
+# CHECK: imulw	%dx, %dx, %dx
+# CHECK: encoding: [0x62,0xf4,0x6d,0x18,0xaf,0xd2]
+         imulw	%dx, %dx, %dx
+# CHECK: {nf}	imulw	%dx, %dx, %dx
+# CHECK: encoding: [0x62,0xf4,0x6d,0x1c,0xaf,0xd2]
+         {nf}	imulw	%dx, %dx, %dx
+# CHECK: {evex}	imull	%ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf7,0xe9]
+         {evex}	imull	%ecx
+# CHECK: {nf}	imull	%ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf7,0xe9]
+         {nf}	imull	%ecx
+# CHECK: {evex}	imull	%ecx, %ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xaf,0xc9]
+         {evex}	imull	%ecx, %ecx
+# CHECK: {nf}	imull	%ecx, %ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xaf,0xc9]
+         {nf}	imull	%ecx, %ecx
+# CHECK: imull	%ecx, %ecx, %ecx
+# CHECK: encoding: [0x62,0xf4,0x74,0x18,0xaf,0xc9]
+         imull	%ecx, %ecx, %ecx
+# CHECK: {nf}	imull	%ecx, %ecx, %ecx
+# CHECK: encoding: [0x62,0xf4,0x74,0x1c,0xaf,0xc9]
+         {nf}	imull	%ecx, %ecx, %ecx
+# CHECK: {evex}	imulq	%r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xe9]
+         {evex}	imulq	%r9
+# CHECK: {nf}	imulq	%r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xe9]
+         {nf}	imulq	%r9
+# CHECK: {evex}	imulq	%r9, %r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x08,0xaf,0xc9]
+         {evex}	imulq	%r9, %r9
+# CHECK: {nf}	imulq	%r9, %r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x0c,0xaf,0xc9]
+         {nf}	imulq	%r9, %r9
+# CHECK: imulq	%r9, %r9, %r9
+# CHECK: encoding: [0x62,0x54,0xb4,0x18,0xaf,0xc9]
+         imulq	%r9, %r9, %r9
+# CHECK: {nf}	imulq	%r9, %r9, %r9
+# CHECK: encoding: [0x62,0x54,0xb4,0x1c,0xaf,0xc9]
+         {nf}	imulq	%r9, %r9, %r9
+# CHECK: {evex}	imulb	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf6,0xac,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imulb	291(%r8,%rax,4)
+# CHECK: {nf}	imulb	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf6,0xac,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imulb	291(%r8,%rax,4)
+# CHECK: {evex}	imulw	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0xf7,0xac,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imulw	291(%r8,%rax,4)
+# CHECK: {nf}	imulw	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0xf7,0xac,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imulw	291(%r8,%rax,4)
+# CHECK: {evex}	imulw	291(%r8,%rax,4), %dx
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0xaf,0x94,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imulw	291(%r8,%rax,4), %dx
+# CHECK: {nf}	imulw	291(%r8,%rax,4), %dx
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0xaf,0x94,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imulw	291(%r8,%rax,4), %dx
+# CHECK: imulw	291(%r8,%rax,4), %dx, %dx
+# CHECK: encoding: [0x62,0xd4,0x6d,0x18,0xaf,0x94,0x80,0x23,0x01,0x00,0x00]
+         imulw	291(%r8,%rax,4), %dx, %dx
+# CHECK: {nf}	imulw	291(%r8,%rax,4), %dx, %dx
+# CHECK: encoding: [0x62,0xd4,0x6d,0x1c,0xaf,0x94,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imulw	291(%r8,%rax,4), %dx, %dx
+# CHECK: {evex}	imull	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf7,0xac,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imull	291(%r8,%rax,4)
+# CHECK: {nf}	imull	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf7,0xac,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imull	291(%r8,%rax,4)
+# CHECK: {evex}	imull	291(%r8,%rax,4), %ecx
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imull	291(%r8,%rax,4), %ecx
+# CHECK: {nf}	imull	291(%r8,%rax,4), %ecx
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imull	291(%r8,%rax,4), %ecx
+# CHECK: imull	291(%r8,%rax,4), %ecx, %ecx
+# CHECK: encoding: [0x62,0xd4,0x74,0x18,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         imull	291(%r8,%rax,4), %ecx, %ecx
+# CHECK: {nf}	imull	291(%r8,%rax,4), %ecx, %ecx
+# CHECK: encoding: [0x62,0xd4,0x74,0x1c,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imull	291(%r8,%rax,4), %ecx, %ecx
+# CHECK: {evex}	imulq	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xac,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imulq	291(%r8,%rax,4)
+# CHECK: {nf}	imulq	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xac,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imulq	291(%r8,%rax,4)
+# CHECK: {evex}	imulq	291(%r8,%rax,4), %r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x08,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imulq	291(%r8,%rax,4), %r9
+# CHECK: {nf}	imulq	291(%r8,%rax,4), %r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x0c,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imulq	291(%r8,%rax,4), %r9
+# CHECK: imulq	291(%r8,%rax,4), %r9, %r9
+# CHECK: encoding: [0x62,0x54,0xb4,0x18,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         imulq	291(%r8,%rax,4), %r9, %r9
+# CHECK: {nf}	imulq	291(%r8,%rax,4), %r9, %r9
+# CHECK: encoding: [0x62,0x54,0xb4,0x1c,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imulq	291(%r8,%rax,4), %r9, %r9
diff --git a/llvm/test/MC/X86/apx/imul-intel.s b/llvm/test/MC/X86/apx/imul-intel.s
new file mode 100644
index 00000000000000..b629272afa4675
--- /dev/null
+++ b/llvm/test/MC/X86/apx/imul-intel.s
@@ -0,0 +1,194 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding -x86-asm-syntax=intel -output-asm-variant=1 %s | FileCheck %s
+
+# CHECK: {evex}	imul	dx, dx, 123
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0x6b,0xd2,0x7b]
+         {evex}	imul	dx, dx, 123
+# CHECK: {nf}	imul	dx, dx, 123
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0x6b,0xd2,0x7b]
+         {nf}	imul	dx, dx, 123
+# CHECK: {evex}	imul	ecx, ecx, 123
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0x6b,0xc9,0x7b]
+         {evex}	imul	ecx, ecx, 123
+# CHECK: {nf}	imul	ecx, ecx, 123
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0x6b,0xc9,0x7b]
+         {nf}	imul	ecx, ecx, 123
+# CHECK: {evex}	imul	r9, r9, 123
+# CHECK: encoding: [0x62,0x54,0xfc,0x08,0x6b,0xc9,0x7b]
+         {evex}	imul	r9, r9, 123
+# CHECK: {nf}	imul	r9, r9, 123
+# CHECK: encoding: [0x62,0x54,0xfc,0x0c,0x6b,0xc9,0x7b]
+         {nf}	imul	r9, r9, 123
+# CHECK: {evex}	imul	dx, word ptr [r8 + 4*rax + 291], 123
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0x6b,0x94,0x80,0x23,0x01,0x00,0x00,0x7b]
+         {evex}	imul	dx, word ptr [r8 + 4*rax + 291], 123
+# CHECK: {nf}	imul	dx, word ptr [r8 + 4*rax + 291], 123
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0x6b,0x94,0x80,0x23,0x01,0x00,0x00,0x7b]
+         {nf}	imul	dx, word ptr [r8 + 4*rax + 291], 123
+# CHECK: {evex}	imul	ecx, dword ptr [r8 + 4*rax + 291], 123
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0x6b,0x8c,0x80,0x23,0x01,0x00,0x00,0x7b]
+         {evex}	imul	ecx, dword ptr [r8 + 4*rax + 291], 123
+# CHECK: {nf}	imul	ecx, dword ptr [r8 + 4*rax + 291], 123
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0x6b,0x8c,0x80,0x23,0x01,0x00,0x00,0x7b]
+         {nf}	imul	ecx, dword ptr [r8 + 4*rax + 291], 123
+# CHECK: {evex}	imul	r9, qword ptr [r8 + 4*rax + 291], 123
+# CHECK: encoding: [0x62,0x54,0xfc,0x08,0x6b,0x8c,0x80,0x23,0x01,0x00,0x00,0x7b]
+         {evex}	imul	r9, qword ptr [r8 + 4*rax + 291], 123
+# CHECK: {nf}	imul	r9, qword ptr [r8 + 4*rax + 291], 123
+# CHECK: encoding: [0x62,0x54,0xfc,0x0c,0x6b,0x8c,0x80,0x23,0x01,0x00,0x00,0x7b]
+         {nf}	imul	r9, qword ptr [r8 + 4*rax + 291], 123
+# CHECK: {evex}	imul	dx, dx, 1234
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0x69,0xd2,0xd2,0x04]
+         {evex}	imul	dx, dx, 1234
+# CHECK: {nf}	imul	dx, dx, 1234
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0x69,0xd2,0xd2,0x04]
+         {nf}	imul	dx, dx, 1234
+# CHECK: {evex}	imul	dx, word ptr [r8 + 4*rax + 291], 1234
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0x69,0x94,0x80,0x23,0x01,0x00,0x00,0xd2,0x04]
+         {evex}	imul	dx, word ptr [r8 + 4*rax + 291], 1234
+# CHECK: {nf}	imul	dx, word ptr [r8 + 4*rax + 291], 1234
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0x69,0x94,0x80,0x23,0x01,0x00,0x00,0xd2,0x04]
+         {nf}	imul	dx, word ptr [r8 + 4*rax + 291], 1234
+# CHECK: {evex}	imul	ecx, ecx, 123456
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0x69,0xc9,0x40,0xe2,0x01,0x00]
+         {evex}	imul	ecx, ecx, 123456
+# CHECK: {nf}	imul	ecx, ecx, 123456
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0x69,0xc9,0x40,0xe2,0x01,0x00]
+         {nf}	imul	ecx, ecx, 123456
+# CHECK: {evex}	imul	r9, r9, 123456
+# CHECK: encoding: [0x62,0x54,0xfc,0x08,0x69,0xc9,0x40,0xe2,0x01,0x00]
+         {evex}	imul	r9, r9, 123456
+# CHECK: {nf}	imul	r9, r9, 123456
+# CHECK: encoding: [0x62,0x54,0xfc,0x0c,0x69,0xc9,0x40,0xe2,0x01,0x00]
+         {nf}	imul	r9, r9, 123456
+# CHECK: {evex}	imul	ecx, dword ptr [r8 + 4*rax + 291], 123456
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0x69,0x8c,0x80,0x23,0x01,0x00,0x00,0x40,0xe2,0x01,0x00]
+         {evex}	imul	ecx, dword ptr [r8 + 4*rax + 291], 123456
+# CHECK: {nf}	imul	ecx, dword ptr [r8 + 4*rax + 291], 123456
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0x69,0x8c,0x80,0x23,0x01,0x00,0x00,0x40,0xe2,0x01,0x00]
+         {nf}	imul	ecx, dword ptr [r8 + 4*rax + 291], 123456
+# CHECK: {evex}	imul	r9, qword ptr [r8 + 4*rax + 291], 123456
+# CHECK: encoding: [0x62,0x54,0xfc,0x08,0x69,0x8c,0x80,0x23,0x01,0x00,0x00,0x40,0xe2,0x01,0x00]
+         {evex}	imul	r9, qword ptr [r8 + 4*rax + 291], 123456
+# CHECK: {nf}	imul	r9, qword ptr [r8 + 4*rax + 291], 123456
+# CHECK: encoding: [0x62,0x54,0xfc,0x0c,0x69,0x8c,0x80,0x23,0x01,0x00,0x00,0x40,0xe2,0x01,0x00]
+         {nf}	imul	r9, qword ptr [r8 + 4*rax + 291], 123456
+# CHECK: {evex}	imul	bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf6,0xeb]
+         {evex}	imul	bl
+# CHECK: {nf}	imul	bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf6,0xeb]
+         {nf}	imul	bl
+# CHECK: {evex}	imul	dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0xf7,0xea]
+         {evex}	imul	dx
+# CHECK: {nf}	imul	dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0xf7,0xea]
+         {nf}	imul	dx
+# CHECK: {evex}	imul	dx, dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0xaf,0xd2]
+         {evex}	imul	dx, dx
+# CHECK: {nf}	imul	dx, dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0xaf,0xd2]
+         {nf}	imul	dx, dx
+# CHECK: imul	dx, dx, dx
+# CHECK: encoding: [0x62,0xf4,0x6d,0x18,0xaf,0xd2]
+         imul	dx, dx, dx
+# CHECK: {nf}	imul	dx, dx, dx
+# CHECK: encoding: [0x62,0xf4,0x6d,0x1c,0xaf,0xd2]
+         {nf}	imul	dx, dx, dx
+# CHECK: {evex}	imul	ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf7,0xe9]
+         {evex}	imul	ecx
+# CHECK: {nf}	imul	ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf7,0xe9]
+         {nf}	imul	ecx
+# CHECK: {evex}	imul	ecx, ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xaf,0xc9]
+         {evex}	imul	ecx, ecx
+# CHECK: {nf}	imul	ecx, ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xaf,0xc9]
+         {nf}	imul	ecx, ecx
+# CHECK: imul	ecx, ecx, ecx
+# CHECK: encoding: [0x62,0xf4,0x74,0x18,0xaf,0xc9]
+         imul	ecx, ecx, ecx
+# CHECK: {nf}	imul	ecx, ecx, ecx
+# CHECK: encoding: [0x62,0xf4,0x74,0x1c,0xaf,0xc9]
+         {nf}	imul	ecx, ecx, ecx
+# CHECK: {evex}	imul	r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xe9]
+         {evex}	imul	r9
+# CHECK: {nf}	imul	r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xe9]
+         {nf}	imul	r9
+# CHECK: {evex}	imul	r9, r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x08,0xaf,0xc9]
+         {evex}	imul	r9, r9
+# CHECK: {nf}	imul	r9, r9
+# CHECK: encoding: [0x62,0x54,0xfc,0x0c,0xaf,0xc9]
+         {nf}	imul	r9, r9
+# CHECK: imul	r9, r9, r9
+# CHECK: encoding: [0x62,0x54,0xb4,0x18,0xaf,0xc9]
+         imul	r9, r9, r9
+# CHECK: {nf}	imul	r9, r9, r9
+# CHECK: encoding: [0x62,0x54,0xb4,0x1c,0xaf,0xc9]
+         {nf}	imul	r9, r9, r9
+# CHECK: {evex}	imul	byte ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf6,0xac,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imul	byte ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	imul	byte ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf6,0xac,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imul	byte ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	imul	word ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0xf7,0xac,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imul	word ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	imul	word ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0xf7,0xac,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imul	word ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	imul	dx, word ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0xaf,0x94,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imul	dx, word ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	imul	dx, word ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0xaf,0x94,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imul	dx, word ptr [r8 + 4*rax + 291]
+# CHECK: imul	dx, dx, word ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x6d,0x18,0xaf,0x94,0x80,0x23,0x01,0x00,0x00]
+         imul	dx, dx, word ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	imul	dx, dx, word ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x6d,0x1c,0xaf,0x94,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imul	dx, dx, word ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	imul	dword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf7,0xac,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imul	dword ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	imul	dword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf7,0xac,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imul	dword ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	imul	ecx, dword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imul	ecx, dword ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	imul	ecx, dword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imul	ecx, dword ptr [r8 + 4*rax + 291]
+# CHECK: imul	ecx, ecx, dword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x74,0x18,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         imul	ecx, ecx, dword ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	imul	ecx, ecx, dword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x74,0x1c,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imul	ecx, ecx, dword ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	imul	qword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xac,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imul	qword ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	imul	qword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xac,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imul	qword ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	imul	r9, qword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0x54,0xfc,0x08,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         {evex}	imul	r9, qword ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	imul	r9, qword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0x54,0xfc,0x0c,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imul	r9, qword ptr [r8 + 4*rax + 291]
+# CHECK: imul	r9, r9, qword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0x54,0xb4,0x18,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         imul	r9, r9, qword ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	imul	r9, r9, qword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0x54,0xb4,0x1c,0xaf,0x8c,0x80,0x23,0x01,0x00,0x00]
+         {nf}	imul	r9, r9, qword ptr [r8 + 4*rax + 291]
diff --git a/llvm/test/MC/X86/apx/mul-att.s b/llvm/test/MC/X86/apx/mul-att.s
new file mode 100644
index 00000000000000..d40123bae23bb8
--- /dev/null
+++ b/llvm/test/MC/X86/apx/mul-att.s
@@ -0,0 +1,53 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
+# RUN: not llvm-mc -triple i386 -show-encoding %s 2>&1 | FileCheck %s --check-prefix=ERROR
+
+# ERROR-COUNT-16: error:
+# ERROR-NOT: error:
+# CHECK: {evex}	mulb	%bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf6,0xe3]
+         {evex}	mulb	%bl
+# CHECK: {nf}	mulb	%bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf6,0xe3]
+         {nf}	mulb	%bl
+# CHECK: {evex}	mulw	%dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0xf7,0xe2]
+         {evex}	mulw	%dx
+# CHECK: {nf}	mulw	%dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0xf7,0xe2]
+         {nf}	mulw	%dx
+# CHECK: {evex}	mull	%ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf7,0xe1]
+         {evex}	mull	%ecx
+# CHECK: {nf}	mull	%ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf7,0xe1]
+         {nf}	mull	%ecx
+# CHECK: {evex}	mulq	%r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xe1]
+         {evex}	mulq	%r9
+# CHECK: {nf}	mulq	%r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xe1]
+         {nf}	mulq	%r9
+# CHECK: {evex}	mulb	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf6,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	mulb	291(%r8,%rax,4)
+# CHECK: {nf}	mulb	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf6,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	mulb	291(%r8,%rax,4)
+# CHECK: {evex}	mulw	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	mulw	291(%r8,%rax,4)
+# CHECK: {nf}	mulw	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	mulw	291(%r8,%rax,4)
+# CHECK: {evex}	mull	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	mull	291(%r8,%rax,4)
+# CHECK: {nf}	mull	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	mull	291(%r8,%rax,4)
+# CHECK: {evex}	mulq	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	mulq	291(%r8,%rax,4)
+# CHECK: {nf}	mulq	291(%r8,%rax,4)
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	mulq	291(%r8,%rax,4)
diff --git a/llvm/test/MC/X86/apx/mul-intel.s b/llvm/test/MC/X86/apx/mul-intel.s
new file mode 100644
index 00000000000000..11598addfb5123
--- /dev/null
+++ b/llvm/test/MC/X86/apx/mul-intel.s
@@ -0,0 +1,50 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding -x86-asm-syntax=intel -output-asm-variant=1 %s | FileCheck %s
+
+# CHECK: {evex}	mul	bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf6,0xe3]
+         {evex}	mul	bl
+# CHECK: {nf}	mul	bl
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf6,0xe3]
+         {nf}	mul	bl
+# CHECK: {evex}	mul	dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x08,0xf7,0xe2]
+         {evex}	mul	dx
+# CHECK: {nf}	mul	dx
+# CHECK: encoding: [0x62,0xf4,0x7d,0x0c,0xf7,0xe2]
+         {nf}	mul	dx
+# CHECK: {evex}	mul	ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x08,0xf7,0xe1]
+         {evex}	mul	ecx
+# CHECK: {nf}	mul	ecx
+# CHECK: encoding: [0x62,0xf4,0x7c,0x0c,0xf7,0xe1]
+         {nf}	mul	ecx
+# CHECK: {evex}	mul	r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xe1]
+         {evex}	mul	r9
+# CHECK: {nf}	mul	r9
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xe1]
+         {nf}	mul	r9
+# CHECK: {evex}	mul	byte ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf6,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	mul	byte ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	mul	byte ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf6,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	mul	byte ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	mul	word ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7d,0x08,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	mul	word ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	mul	word ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7d,0x0c,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	mul	word ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	mul	dword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x08,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	mul	dword ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	mul	dword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0x7c,0x0c,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	mul	dword ptr [r8 + 4*rax + 291]
+# CHECK: {evex}	mul	qword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0xfc,0x08,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {evex}	mul	qword ptr [r8 + 4*rax + 291]
+# CHECK: {nf}	mul	qword ptr [r8 + 4*rax + 291]
+# CHECK: encoding: [0x62,0xd4,0xfc,0x0c,0xf7,0xa4,0x80,0x23,0x01,0x00,0x00]
+         {nf}	mul	qword ptr [r8 + 4*rax + 291]
diff --git a/llvm/test/TableGen/x86-fold-tables.inc b/llvm/test/TableGen/x86-fold-tables.inc
index 4e37285b08ba2e..02e4ae52cc9146 100644
--- a/llvm/test/TableGen/x86-fold-tables.inc
+++ b/llvm/test/TableGen/x86-fold-tables.inc
@@ -304,18 +304,30 @@ static const X86FoldTableEntry Table0[] = {
   {X86::CMP8ri8, X86::CMP8mi8, TB_FOLDED_LOAD},
   {X86::CMP8rr, X86::CMP8mr, TB_FOLDED_LOAD},
   {X86::DIV16r, X86::DIV16m, TB_FOLDED_LOAD},
+  {X86::DIV16r_NF, X86::DIV16m_NF, TB_FOLDED_LOAD},
   {X86::DIV32r, X86::DIV32m, TB_FOLDED_LOAD},
+  {X86::DIV32r_NF, X86::DIV32m_NF, TB_FOLDED_LOAD},
   {X86::DIV64r, X86::DIV64m, TB_FOLDED_LOAD},
+  {X86::DIV64r_NF, X86::DIV64m_NF, TB_FOLDED_LOAD},
   {X86::DIV8r, X86::DIV8m, TB_FOLDED_LOAD},
+  {X86::DIV8r_NF, X86::DIV8m_NF, TB_FOLDED_LOAD},
   {X86::EXTRACTPSrr, X86::EXTRACTPSmr, TB_FOLDED_STORE},
   {X86::IDIV16r, X86::IDIV16m, TB_FOLDED_LOAD},
+  {X86::IDIV16r_NF, X86::IDIV16m_NF, TB_FOLDED_LOAD},
   {X86::IDIV32r, X86::IDIV32m, TB_FOLDED_LOAD},
+  {X86::IDIV32r_NF, X86::IDIV32m_NF, TB_FOLDED_LOAD},
   {X86::IDIV64r, X86::IDIV64m, TB_FOLDED_LOAD},
+  {X86::IDIV64r_NF, X86::IDIV64m_NF, TB_FOLDED_LOAD},
   {X86::IDIV8r, X86::IDIV8m, TB_FOLDED_LOAD},
+  {X86::IDIV8r_NF, X86::IDIV8m_NF, TB_FOLDED_LOAD},
   {X86::IMUL16r, X86::IMUL16m, TB_FOLDED_LOAD},
+  {X86::IMUL16r_NF, X86::IMUL16m_NF, TB_FOLDED_LOAD},
   {X86::IMUL32r, X86::IMUL32m, TB_FOLDED_LOAD},
+  {X86::IMUL32r_NF, X86::IMUL32m_NF, TB_FOLDED_LOAD},
   {X86::IMUL64r, X86::IMUL64m, TB_FOLDED_LOAD},
+  {X86::IMUL64r_NF, X86::IMUL64m_NF, TB_FOLDED_LOAD},
   {X86::IMUL8r, X86::IMUL8m, TB_FOLDED_LOAD},
+  {X86::IMUL8r_NF, X86::IMUL8m_NF, TB_FOLDED_LOAD},
   {X86::JMP16r, X86::JMP16m, TB_FOLDED_LOAD},
   {X86::JMP16r_NT, X86::JMP16m_NT, TB_FOLDED_LOAD},
   {X86::JMP32r, X86::JMP32m, TB_FOLDED_LOAD},
@@ -347,9 +359,13 @@ static const X86FoldTableEntry Table0[] = {
   {X86::MOVUPDrr, X86::MOVUPDmr, TB_FOLDED_STORE|TB_NO_REVERSE},
   {X86::MOVUPSrr, X86::MOVUPSmr, TB_FOLDED_STORE|TB_NO_REVERSE},
   {X86::MUL16r, X86::MUL16m, TB_FOLDED_LOAD},
+  {X86::MUL16r_NF, X86::MUL16m_NF, TB_FOLDED_LOAD},
   {X86::MUL32r, X86::MUL32m, TB_FOLDED_LOAD},
+  {X86::MUL32r_NF, X86::MUL32m_NF, TB_FOLDED_LOAD},
   {X86::MUL64r, X86::MUL64m, TB_FOLDED_LOAD},
+  {X86::MUL64r_NF, X86::MUL64m_NF, TB_FOLDED_LOAD},
   {X86::MUL8r, X86::MUL8m, TB_FOLDED_LOAD},
+  {X86::MUL8r_NF, X86::MUL8m_NF, TB_FOLDED_LOAD},
   {X86::PEXTRDrr, X86::PEXTRDmr, TB_FOLDED_STORE},
   {X86::PEXTRQrr, X86::PEXTRQmr, TB_FOLDED_STORE},
   {X86::PTWRITE64r, X86::PTWRITE64m, TB_FOLDED_LOAD},
@@ -622,10 +638,16 @@ static const X86FoldTableEntry Table1[] = {
   {X86::DEC8r_NF_ND, X86::DEC8m_NF_ND, 0},
   {X86::IMUL16rri, X86::IMUL16rmi, 0},
   {X86::IMUL16rri8, X86::IMUL16rmi8, 0},
+  {X86::IMUL16rri8_NF, X86::IMUL16rmi8_NF, 0},
+  {X86::IMUL16rri_NF, X86::IMUL16rmi_NF, 0},
   {X86::IMUL32rri, X86::IMUL32rmi, 0},
   {X86::IMUL32rri8, X86::IMUL32rmi8, 0},
+  {X86::IMUL32rri8_NF, X86::IMUL32rmi8_NF, 0},
+  {X86::IMUL32rri_NF, X86::IMUL32rmi_NF, 0},
   {X86::IMUL64rri32, X86::IMUL64rmi32, 0},
+  {X86::IMUL64rri32_NF, X86::IMUL64rmi32_NF, 0},
   {X86::IMUL64rri8, X86::IMUL64rmi8, 0},
+  {X86::IMUL64rri8_NF, X86::IMUL64rmi8_NF, 0},
   {X86::INC16r_ND, X86::INC16m_ND, 0},
   {X86::INC16r_NF_ND, X86::INC16m_NF_ND, 0},
   {X86::INC32r_ND, X86::INC32m_ND, 0},
@@ -1665,8 +1687,17 @@ static const X86FoldTableEntry Table2[] = {
   {X86::HSUBPDrr, X86::HSUBPDrm, TB_ALIGN_16},
   {X86::HSUBPSrr, X86::HSUBPSrm, TB_ALIGN_16},
   {X86::IMUL16rr, X86::IMUL16rm, 0},
+  {X86::IMUL16rr_ND, X86::IMUL16rm_ND, 0},
+  {X86::IMUL16rr_NF, X86::IMUL16rm_NF, 0},
+  {X86::IMUL16rr_NF_ND, X86::IMUL16rm_NF_ND, 0},
   {X86::IMUL32rr, X86::IMUL32rm, 0},
+  {X86::IMUL32rr_ND, X86::IMUL32rm_ND, 0},
+  {X86::IMUL32rr_NF, X86::IMUL32rm_NF, 0},
+  {X86::IMUL32rr_NF_ND, X86::IMUL32rm_NF_ND, 0},
   {X86::IMUL64rr, X86::IMUL64rm, 0},
+  {X86::IMUL64rr_ND, X86::IMUL64rm_ND, 0},
+  {X86::IMUL64rr_NF, X86::IMUL64rm_NF, 0},
+  {X86::IMUL64rr_NF_ND, X86::IMUL64rm_NF_ND, 0},
   {X86::MAXCPDrr, X86::MAXCPDrm, TB_ALIGN_16},
   {X86::MAXCPSrr, X86::MAXCPSrm, TB_ALIGN_16},
   {X86::MAXCSDrr, X86::MAXCSDrm, 0},

>From 2915fc744e0de1aaba2567f87acd59b2cac57f3e Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Thu, 4 Jan 2024 16:42:47 +0800
Subject: [PATCH 2/7] reduce let

---
 llvm/lib/Target/X86/X86InstrArithmetic.td | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/X86/X86InstrArithmetic.td b/llvm/lib/Target/X86/X86InstrArithmetic.td
index f8ef617f4eb92b..1d85f3beb45709 100644
--- a/llvm/lib/Target/X86/X86InstrArithmetic.td
+++ b/llvm/lib/Target/X86/X86InstrArithmetic.td
@@ -236,7 +236,7 @@ let Predicates = [HasNDD, In64BitMode] in {
   def IMUL64rm_ND : IMulOpRM_RF<Xi64, WriteIMul64Reg, 1>;
 }
 
-let Predicates = [In64BitMode] in {
+let Predicates = [In64BitMode], Pattern = [(null_frag)] in {
   def IMUL16rr_NF : IMulOpRR_R<Xi16, WriteIMul16Reg>, NF, PD;
   def IMUL32rr_NF : IMulOpRR_R<Xi32, WriteIMul32Reg>, NF;
   def IMUL64rr_NF : IMulOpRR_R<Xi64, WriteIMul64Reg>, NF;
@@ -251,14 +251,12 @@ let Predicates = [In64BitMode] in {
   def IMUL32rm_NF_ND : IMulOpRM_R<Xi32, WriteIMul32Reg, 1>, EVEX_NF;
   def IMUL64rm_NF_ND : IMulOpRM_R<Xi64, WriteIMul64Reg, 1>, EVEX_NF;
 
-  let Pattern = [(null_frag)] in {
-    def IMUL16rr_EVEX : IMulOpRR_RF<Xi16, WriteIMul16Reg>, PL, PD;
-    def IMUL32rr_EVEX : IMulOpRR_RF<Xi32, WriteIMul32Reg>, PL;
-    def IMUL64rr_EVEX : IMulOpRR_RF<Xi64, WriteIMul64Reg>, PL;
-    def IMUL16rm_EVEX : IMulOpRM_RF<Xi16, WriteIMul16Reg>, PL, PD;
-    def IMUL32rm_EVEX : IMulOpRM_RF<Xi32, WriteIMul32Reg>, PL;
-    def IMUL64rm_EVEX : IMulOpRM_RF<Xi64, WriteIMul64Reg>, PL;
-  }
+  def IMUL16rr_EVEX : IMulOpRR_RF<Xi16, WriteIMul16Reg>, PL, PD;
+  def IMUL32rr_EVEX : IMulOpRR_RF<Xi32, WriteIMul32Reg>, PL;
+  def IMUL64rr_EVEX : IMulOpRR_RF<Xi64, WriteIMul64Reg>, PL;
+  def IMUL16rm_EVEX : IMulOpRM_RF<Xi16, WriteIMul16Reg>, PL, PD;
+  def IMUL32rm_EVEX : IMulOpRM_RF<Xi32, WriteIMul32Reg>, PL;
+  def IMUL64rm_EVEX : IMulOpRM_RF<Xi64, WriteIMul64Reg>, PL;
 }
 
 class IMulOpRI8<X86TypeInfo t, X86FoldableSchedWrite sched>

>From d1fc7da4dc9eb2db82efc77d5311e80e4a775ba6 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Fri, 5 Jan 2024 14:53:36 +0800
Subject: [PATCH 3/7] Address review comments - add space after comma

---
 llvm/lib/Target/X86/X86InstrArithmetic.td | 96 +++++++++++------------
 1 file changed, 48 insertions(+), 48 deletions(-)

diff --git a/llvm/lib/Target/X86/X86InstrArithmetic.td b/llvm/lib/Target/X86/X86InstrArithmetic.td
index 1d85f3beb45709..26739ce8ffe2ff 100644
--- a/llvm/lib/Target/X86/X86InstrArithmetic.td
+++ b/llvm/lib/Target/X86/X86InstrArithmetic.td
@@ -71,58 +71,58 @@ multiclass Mul<bits<8> o, string m, Format RegMRM, Format MemMRM, SDPatternOpera
   // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
   // This probably ought to be moved to a def : Pat<> if the
   // syntax can be accepted.
-  let Defs = [AL,EFLAGS,AX], Uses = [AL] in
+  let Defs = [AL, EFLAGS, AX], Uses = [AL] in
     def 8r : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8,
                        [(set AL, (node AL, GR8:$src1)), (implicit EFLAGS)]>;
-  let Defs = [AX,DX,EFLAGS], Uses = [AX] in
+  let Defs = [AX, DX, EFLAGS], Uses = [AX] in
     def 16r : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, OpSize16;
-  let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
+  let Defs = [EAX, EDX, EFLAGS], Uses = [EAX] in
     def 32r : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, OpSize32;
-  let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
+  let Defs = [RAX, RDX, EFLAGS], Uses = [RAX] in
     def 64r : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>;
-  let Defs = [AL,EFLAGS,AX], Uses = [AL] in
+  let Defs = [AL, EFLAGS, AX], Uses = [AL] in
     def 8m : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8,
                        [(set AL, (node AL, (loadi8 addr:$src1))), (implicit EFLAGS)]>;
-  let Defs = [AX,DX,EFLAGS], Uses = [AX] in
+  let Defs = [AX, DX, EFLAGS], Uses = [AX] in
     def 16m : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, OpSize16;
-  let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
+  let Defs = [EAX, EDX, EFLAGS], Uses = [EAX] in
     def 32m : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, OpSize32;
-  let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
+  let Defs = [RAX, RDX, EFLAGS], Uses = [RAX] in
     def 64m : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, Requires<[In64BitMode]>;
 
   let Predicates = [In64BitMode] in {
-    let Defs = [AL,AX], Uses = [AL] in
+    let Defs = [AL, AX], Uses = [AL] in
       def 8r_NF : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8, []>, NF;
-    let Defs = [AX,DX], Uses = [AX] in
+    let Defs = [AX, DX], Uses = [AX] in
       def 16r_NF : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, NF, PD;
-    let Defs = [EAX,EDX], Uses = [EAX] in
+    let Defs = [EAX, EDX], Uses = [EAX] in
       def 32r_NF : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, NF;
-    let Defs = [RAX,RDX], Uses = [RAX] in
+    let Defs = [RAX, RDX], Uses = [RAX] in
       def 64r_NF : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>, NF;
-    let Defs = [AL,AX], Uses = [AL] in
+    let Defs = [AL, AX], Uses = [AL] in
       def 8m_NF : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8, []>, NF;
-    let Defs = [AX,DX], Uses = [AX] in
+    let Defs = [AX, DX], Uses = [AX] in
       def 16m_NF : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, NF, PD;
-    let Defs = [EAX,EDX], Uses = [EAX] in
+    let Defs = [EAX, EDX], Uses = [EAX] in
       def 32m_NF : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, NF;
-    let Defs = [RAX,RDX], Uses = [RAX] in
+    let Defs = [RAX, RDX], Uses = [RAX] in
       def 64m_NF : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, NF;
 
-    let Defs = [AL,EFLAGS,AX], Uses = [AL] in
+    let Defs = [AL, EFLAGS, AX], Uses = [AL] in
       def 8r_EVEX : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8, []>, PL;
-    let Defs = [AX,DX,EFLAGS], Uses = [AX] in
+    let Defs = [AX, DX, EFLAGS], Uses = [AX] in
       def 16r_EVEX : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, PL, PD;
-    let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
+    let Defs = [EAX, EDX, EFLAGS], Uses = [EAX] in
       def 32r_EVEX : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, PL;
-    let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
+    let Defs = [RAX, RDX, EFLAGS], Uses = [RAX] in
       def 64r_EVEX : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>, PL;
-    let Defs = [AL,EFLAGS,AX], Uses = [AL] in
+    let Defs = [AL, EFLAGS, AX], Uses = [AL] in
       def 8m_EVEX : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8, []>, PL;
-    let Defs = [AX,DX,EFLAGS], Uses = [AX] in
+    let Defs = [AX, DX, EFLAGS], Uses = [AX] in
       def 16m_EVEX : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, PL, PD;
-    let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
+    let Defs = [EAX, EDX, EFLAGS], Uses = [EAX] in
       def 32m_EVEX : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, PL;
-    let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
+    let Defs = [RAX, RDX, EFLAGS], Uses = [RAX] in
       def 64m_EVEX : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, PL;
   }
 }
@@ -135,56 +135,56 @@ multiclass Div<bits<8> o, string m, Format RegMRM, Format MemMRM> {
   defvar sched16 = !if(!eq(m, "div"), WriteDiv16, WriteIDiv16);
   defvar sched32 = !if(!eq(m, "div"), WriteDiv32, WriteIDiv32);
   defvar sched64 = !if(!eq(m, "div"), WriteDiv64, WriteIDiv64);
-  let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+  let Defs = [AL, AH, EFLAGS], Uses = [AX] in
     def 8r  : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>;
-  let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
+  let Defs = [AX, DX, EFLAGS], Uses = [AX, DX] in
     def 16r : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, OpSize16;
-  let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
+  let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EDX] in
     def 32r : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, OpSize32;
-  let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
+  let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RDX] in
     def 64r : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>;
-  let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+  let Defs = [AL, AH, EFLAGS], Uses = [AX] in
     def 8m  : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>;
-  let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
+  let Defs = [AX, DX, EFLAGS], Uses = [AX, DX] in
     def 16m : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, OpSize16;
-  let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
+  let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EDX] in
     def 32m : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, OpSize32;
-  let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
+  let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RDX] in
     def 64m : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, Requires<[In64BitMode]>;
 
   let Predicates = [In64BitMode] in {
-    let Defs = [AL,AH], Uses = [AX] in
+    let Defs = [AL, AH], Uses = [AX] in
       def 8r_NF  : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>, NF;
-    let Defs = [AX,DX], Uses = [AX,DX] in
+    let Defs = [AX, DX], Uses = [AX, DX] in
       def 16r_NF : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, NF, PD;
-    let Defs = [EAX,EDX], Uses = [EAX,EDX] in
+    let Defs = [EAX, EDX], Uses = [EAX, EDX] in
       def 32r_NF : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, NF;
-    let Defs = [RAX,RDX], Uses = [RAX,RDX] in
+    let Defs = [RAX, RDX], Uses = [RAX, RDX] in
       def 64r_NF : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>, NF;
-    let Defs = [AL,AH], Uses = [AX] in
+    let Defs = [AL, AH], Uses = [AX] in
       def 8m_NF  : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>, NF;
-    let Defs = [AX,DX], Uses = [AX,DX] in
+    let Defs = [AX, DX], Uses = [AX, DX] in
       def 16m_NF : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, NF, PD;
-    let Defs = [EAX,EDX], Uses = [EAX,EDX] in
+    let Defs = [EAX, EDX], Uses = [EAX, EDX] in
       def 32m_NF : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, NF;
-    let Defs = [RAX,RDX], Uses = [RAX,RDX] in
+    let Defs = [RAX, RDX], Uses = [RAX, RDX] in
       def 64m_NF : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, NF;
 
-    let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+    let Defs = [AL, AH, EFLAGS], Uses = [AX] in
       def 8r_EVEX  : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>, PL;
-    let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
+    let Defs = [AX, DX, EFLAGS], Uses = [AX, DX] in
       def 16r_EVEX : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, PL, PD;
-    let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
+    let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EDX] in
       def 32r_EVEX : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, PL;
-    let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
+    let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RDX] in
       def 64r_EVEX : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>, PL;
-    let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+    let Defs = [AL, AH, EFLAGS], Uses = [AX] in
       def 8m_EVEX  : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>, PL;
-    let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
+    let Defs = [AX, DX, EFLAGS], Uses = [AX, DX] in
       def 16m_EVEX : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, PL, PD;
-    let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
+    let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EDX] in
       def 32m_EVEX : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, PL;
-    let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
+    let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RDX] in
       def 64m_EVEX : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, PL;
   }
 }

>From 8e150f069700fb9dee3a17fa900dfb03c2860a46 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Fri, 5 Jan 2024 15:02:55 +0800
Subject: [PATCH 4/7] Add _R

---
 llvm/lib/Target/X86/X86InstrArithmetic.td | 40 +++++++++++------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Target/X86/X86InstrArithmetic.td b/llvm/lib/Target/X86/X86InstrArithmetic.td
index 26739ce8ffe2ff..5cfa95e085e34a 100644
--- a/llvm/lib/Target/X86/X86InstrArithmetic.td
+++ b/llvm/lib/Target/X86/X86InstrArithmetic.td
@@ -259,7 +259,7 @@ let Predicates = [In64BitMode], Pattern = [(null_frag)] in {
   def IMUL64rm_EVEX : IMulOpRM_RF<Xi64, WriteIMul64Reg>, PL;
 }
 
-class IMulOpRI8<X86TypeInfo t, X86FoldableSchedWrite sched>
+class IMulOpRI8_R<X86TypeInfo t, X86FoldableSchedWrite sched>
   : BinOpRI8<0x6B, "imul", binop_ndd_args, t, MRMSrcReg,
              (outs t.RegClass:$dst)> {
   let SchedRW = [sched];
@@ -276,7 +276,7 @@ class IMulOpRI_RF<X86TypeInfo t, X86FoldableSchedWrite sched>
              t.ImmNoSuOperator:$src2))]>, DefEFLAGS {
   let SchedRW = [sched];
 }
-class IMulOpMI8<X86TypeInfo t, X86FoldableSchedWrite sched>
+class IMulOpMI8_R<X86TypeInfo t, X86FoldableSchedWrite sched>
   : BinOpMI8<"imul", binop_ndd_args, t, MRMSrcMem, (outs t.RegClass:$dst)> {
   let Opcode = 0x6B;
   let SchedRW = [sched.Folded];
@@ -294,42 +294,42 @@ class IMulOpMI_RF<X86TypeInfo t, X86FoldableSchedWrite sched>
     DefEFLAGS {
   let SchedRW = [sched.Folded];
 }
-def IMUL16rri8 : IMulOpRI8<Xi16, WriteIMul16Imm>, DefEFLAGS, OpSize16;
-def IMUL32rri8 : IMulOpRI8<Xi32, WriteIMul32Imm>, DefEFLAGS, OpSize32;
-def IMUL64rri8 : IMulOpRI8<Xi64, WriteIMul64Imm>, DefEFLAGS;
+def IMUL16rri8 : IMulOpRI8_R<Xi16, WriteIMul16Imm>, DefEFLAGS, OpSize16;
+def IMUL32rri8 : IMulOpRI8_R<Xi32, WriteIMul32Imm>, DefEFLAGS, OpSize32;
+def IMUL64rri8 : IMulOpRI8_R<Xi64, WriteIMul64Imm>, DefEFLAGS;
 def IMUL16rri  : IMulOpRI_RF<Xi16, WriteIMul16Imm>, OpSize16;
 def IMUL32rri  : IMulOpRI_RF<Xi32, WriteIMul32Imm>, OpSize32;
 def IMUL64rri32 : IMulOpRI_RF<Xi64, WriteIMul64Imm>;
-def IMUL16rmi8 : IMulOpMI8<Xi16, WriteIMul16Imm>, DefEFLAGS, OpSize16;
-def IMUL32rmi8 : IMulOpMI8<Xi32, WriteIMul32Imm>, DefEFLAGS, OpSize32;
-def IMUL64rmi8 : IMulOpMI8<Xi64, WriteIMul64Imm>, DefEFLAGS;
+def IMUL16rmi8 : IMulOpMI8_R<Xi16, WriteIMul16Imm>, DefEFLAGS, OpSize16;
+def IMUL32rmi8 : IMulOpMI8_R<Xi32, WriteIMul32Imm>, DefEFLAGS, OpSize32;
+def IMUL64rmi8 : IMulOpMI8_R<Xi64, WriteIMul64Imm>, DefEFLAGS;
 def IMUL16rmi  : IMulOpMI_RF<Xi16, WriteIMul16Imm>, OpSize16;
 def IMUL32rmi  : IMulOpMI_RF<Xi32, WriteIMul32Imm>, OpSize32;
 def IMUL64rmi32 : IMulOpMI_RF<Xi64, WriteIMul64Imm>;
 
 let Predicates = [In64BitMode] in {
-  def IMUL16rri8_NF : IMulOpRI8<Xi16, WriteIMul16Imm>, NF, PD;
-  def IMUL32rri8_NF : IMulOpRI8<Xi32, WriteIMul32Imm>, NF;
-  def IMUL64rri8_NF : IMulOpRI8<Xi64, WriteIMul64Imm>, NF;
+  def IMUL16rri8_NF : IMulOpRI8_R<Xi16, WriteIMul16Imm>, NF, PD;
+  def IMUL32rri8_NF : IMulOpRI8_R<Xi32, WriteIMul32Imm>, NF;
+  def IMUL64rri8_NF : IMulOpRI8_R<Xi64, WriteIMul64Imm>, NF;
   def IMUL16rri_NF  : IMulOpRI_R<Xi16, WriteIMul16Imm>, NF, PD;
   def IMUL32rri_NF  : IMulOpRI_R<Xi32, WriteIMul32Imm>, NF;
   def IMUL64rri32_NF : IMulOpRI_R<Xi64, WriteIMul64Imm>, NF;
-  def IMUL16rmi8_NF : IMulOpMI8<Xi16, WriteIMul16Imm>, NF, PD;
-  def IMUL32rmi8_NF : IMulOpMI8<Xi32, WriteIMul32Imm>, NF;
-  def IMUL64rmi8_NF : IMulOpMI8<Xi64, WriteIMul64Imm>, NF;
+  def IMUL16rmi8_NF : IMulOpMI8_R<Xi16, WriteIMul16Imm>, NF, PD;
+  def IMUL32rmi8_NF : IMulOpMI8_R<Xi32, WriteIMul32Imm>, NF;
+  def IMUL64rmi8_NF : IMulOpMI8_R<Xi64, WriteIMul64Imm>, NF;
   def IMUL16rmi_NF  : IMulOpMI_R<Xi16, WriteIMul16Imm>, NF, PD;
   def IMUL32rmi_NF  : IMulOpMI_R<Xi32, WriteIMul32Imm>, NF;
   def IMUL64rmi32_NF : IMulOpMI_R<Xi64, WriteIMul64Imm>, NF;
 
-  def IMUL16rri8_EVEX : IMulOpRI8<Xi16, WriteIMul16Imm>, DefEFLAGS, PL, PD;
-  def IMUL32rri8_EVEX : IMulOpRI8<Xi32, WriteIMul32Imm>, DefEFLAGS, PL;
-  def IMUL64rri8_EVEX : IMulOpRI8<Xi64, WriteIMul64Imm>, DefEFLAGS, PL;
+  def IMUL16rri8_EVEX : IMulOpRI8_R<Xi16, WriteIMul16Imm>, DefEFLAGS, PL, PD;
+  def IMUL32rri8_EVEX : IMulOpRI8_R<Xi32, WriteIMul32Imm>, DefEFLAGS, PL;
+  def IMUL64rri8_EVEX : IMulOpRI8_R<Xi64, WriteIMul64Imm>, DefEFLAGS, PL;
   def IMUL16rri_EVEX  : IMulOpRI_RF<Xi16, WriteIMul16Imm>, PL, PD;
   def IMUL32rri_EVEX  : IMulOpRI_RF<Xi32, WriteIMul32Imm>, PL;
   def IMUL64rri32_EVEX : IMulOpRI_RF<Xi64, WriteIMul64Imm>, PL;
-  def IMUL16rmi8_EVEX : IMulOpMI8<Xi16, WriteIMul16Imm>, DefEFLAGS, PL, PD;
-  def IMUL32rmi8_EVEX : IMulOpMI8<Xi32, WriteIMul32Imm>, DefEFLAGS, PL;
-  def IMUL64rmi8_EVEX : IMulOpMI8<Xi64, WriteIMul64Imm>, DefEFLAGS, PL;
+  def IMUL16rmi8_EVEX : IMulOpMI8_R<Xi16, WriteIMul16Imm>, DefEFLAGS, PL, PD;
+  def IMUL32rmi8_EVEX : IMulOpMI8_R<Xi32, WriteIMul32Imm>, DefEFLAGS, PL;
+  def IMUL64rmi8_EVEX : IMulOpMI8_R<Xi64, WriteIMul64Imm>, DefEFLAGS, PL;
   def IMUL16rmi_EVEX  : IMulOpMI_RF<Xi16, WriteIMul16Imm>, PL, PD;
   def IMUL32rmi_EVEX  : IMulOpMI_RF<Xi32, WriteIMul32Imm>, PL;
   def IMUL64rmi32_EVEX : IMulOpMI_RF<Xi64, WriteIMul64Imm>, PL;

>From e5e370f35f866bf0c01402230ee22d083bf2da59 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Fri, 5 Jan 2024 16:11:52 +0800
Subject: [PATCH 5/7] Address review commets: add comments for predicates

---
 llvm/lib/Target/X86/X86InstrPredicates.td | 32 +++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/llvm/lib/Target/X86/X86InstrPredicates.td b/llvm/lib/Target/X86/X86InstrPredicates.td
index 94fa6e45ded9d7..d9e22adc4244a5 100644
--- a/llvm/lib/Target/X86/X86InstrPredicates.td
+++ b/llvm/lib/Target/X86/X86InstrPredicates.td
@@ -8,8 +8,40 @@
 
 def TruePredicate : Predicate<"true">;
 
+// Intel x86 instructions have three separate encoding spaces: legacy, VEX, and
+// EVEX. Not all X86 instructions are extended for EGPR. The following is an
+// overview of which instructions are extended and how we implement them.
+//
+// * Legacy space
+//   All instructions in legacy maps 0 and 1 that have explicit GPR or memory
+//   operands can use the REX2 prefix to access the EGPR, except XSAVE*/XRSTOR.
+//
+// * EVEX space
+//   All instructions in the EVEX space can access the EGPR in their
+//   register/memory operands.
+//
+// For the above intructions, the only difference in encoding is reflected in
+// the REX2/EVEX prefix when EGPR is used, i.e. the opcode and opcode name are
+// unchanged. We don’t add new entries in TD, and instead we extend GPR with
+// R16-R31 and make them allocatable only when the feature EGPR is available.
+//
+// Besides, some instructions in legacy space with map 2/3 and VEX space are
+// promoted into EVEX space. Encoding space changes and opcode, opcode map may
+// change after the promotion. For these instructions, we add new entries in TD
+// to avoid overcomplicating the assembler and disassembler.
+//
+// HasEGPR is for the new entries and NoEGPR is for the entries before promotion,
+// so that the promoted instruction can be selected first to benefit RA.
 def HasEGPR      : Predicate<"Subtarget->hasEGPR()">;
 def NoEGPR       : Predicate<"!Subtarget->hasEGPR()">;
+// APX extends some instructions with a new form that has an extra register
+// operand called a new data destination (NDD). In such forms, NDD is the new
+// destination register receiving the result of the computation and all other
+// operands (including the original destination operand) become read-only source
+// operands.
+//
+// HasNDD is for the new NDD entries and NoNDD is fo the legacy 2-address variant,
+// so that the NDD variant can be selected first to benefit RA.
 def HasNDD       : Predicate<"Subtarget->hasNDD()">;
 def NoNDD        : Predicate<"!Subtarget->hasNDD()">;
 def HasCMOV      : Predicate<"Subtarget->canUseCMOV()">;

>From 6856ddf87ecdb2d48e7a38641faa1f0bb5b91342 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Fri, 5 Jan 2024 16:24:43 +0800
Subject: [PATCH 6/7] refine words in comment

---
 llvm/lib/Target/X86/X86InstrPredicates.td | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/X86/X86InstrPredicates.td b/llvm/lib/Target/X86/X86InstrPredicates.td
index d9e22adc4244a5..dc0eeb2b3713e9 100644
--- a/llvm/lib/Target/X86/X86InstrPredicates.td
+++ b/llvm/lib/Target/X86/X86InstrPredicates.td
@@ -31,7 +31,7 @@ def TruePredicate : Predicate<"true">;
 // to avoid overcomplicating the assembler and disassembler.
 //
 // HasEGPR is for the new entries and NoEGPR is for the entries before promotion,
-// so that the promoted instruction can be selected first to benefit RA.
+// so that the promoted variant can be selected first to benefit RA.
 def HasEGPR      : Predicate<"Subtarget->hasEGPR()">;
 def NoEGPR       : Predicate<"!Subtarget->hasEGPR()">;
 // APX extends some instructions with a new form that has an extra register
@@ -40,7 +40,7 @@ def NoEGPR       : Predicate<"!Subtarget->hasEGPR()">;
 // operands (including the original destination operand) become read-only source
 // operands.
 //
-// HasNDD is for the new NDD entries and NoNDD is fo the legacy 2-address variant,
+// HasNDD is for the new NDD entries and NoNDD is fo the legacy 2-address entries,
 // so that the NDD variant can be selected first to benefit RA.
 def HasNDD       : Predicate<"Subtarget->hasNDD()">;
 def NoNDD        : Predicate<"!Subtarget->hasNDD()">;

>From 87e687fb36092538360e49cbd674fb9fd977de82 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Fri, 5 Jan 2024 17:04:16 +0800
Subject: [PATCH 7/7] Refine comments

---
 llvm/lib/Target/X86/X86InstrPredicates.td | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/X86/X86InstrPredicates.td b/llvm/lib/Target/X86/X86InstrPredicates.td
index dc0eeb2b3713e9..892f08fad85a60 100644
--- a/llvm/lib/Target/X86/X86InstrPredicates.td
+++ b/llvm/lib/Target/X86/X86InstrPredicates.td
@@ -26,22 +26,23 @@ def TruePredicate : Predicate<"true">;
 // R16-R31 and make them allocatable only when the feature EGPR is available.
 //
 // Besides, some instructions in legacy space with map 2/3 and VEX space are
-// promoted into EVEX space. Encoding space changes and opcode, opcode map may
-// change after the promotion. For these instructions, we add new entries in TD
-// to avoid overcomplicating the assembler and disassembler.
+// promoted into EVEX space. Encoding space will definitely change, opcode and
+// opcode map may change after the promotion. For these instructions, we add new
+// entries in TD to avoid overcomplicating the assembler and disassembler.
 //
-// HasEGPR is for the new entries and NoEGPR is for the entries before promotion,
-// so that the promoted variant can be selected first to benefit RA.
+// HasEGPR is for the new entries and NoEGPR is for the entries before
+// promotion, so that the promoted variant can be selected first to benefit RA.
 def HasEGPR      : Predicate<"Subtarget->hasEGPR()">;
 def NoEGPR       : Predicate<"!Subtarget->hasEGPR()">;
+
 // APX extends some instructions with a new form that has an extra register
 // operand called a new data destination (NDD). In such forms, NDD is the new
 // destination register receiving the result of the computation and all other
 // operands (including the original destination operand) become read-only source
 // operands.
 //
-// HasNDD is for the new NDD entries and NoNDD is fo the legacy 2-address entries,
-// so that the NDD variant can be selected first to benefit RA.
+// HasNDD is for the new NDD entries and NoNDD is for the legacy 2-address
+// entries, so that the NDD variant can be selected first to benefit RA.
 def HasNDD       : Predicate<"Subtarget->hasNDD()">;
 def NoNDD        : Predicate<"!Subtarget->hasNDD()">;
 def HasCMOV      : Predicate<"Subtarget->canUseCMOV()">;



More information about the llvm-commits mailing list