-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[X86][MC] Support encoding/decoding for APX variant MUL/IMUL/DIV/IDIV instructions #76919
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-mc Author: Shengchen Kan (KanRobert) ChangesFour variants: promoted legacy, ND (new data destination), NF (no flags The syntax of NF instructions is aligned with GNU binutils. Patch is 69.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/76919.diff 14 Files Affected:
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...
[truncated]
|
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
receiving
-> holds/preserves
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. It 's copied from 3.1.2.2 New Data Destination. The verb here is used as a postpositional attributive and requires the ing form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM expect for some typos.
@phoebewang Thanks! |
Relaxed a bit the opcode checks to make the test less sensitive to changes resulting in opcode numbering.
…03f4f8f7e Local branch amd-gfx 75d03f4 Merged main:fc18b13492880ba8597333c6050a18ec6db0f831 into amd-gfx:599be57544a8 Remote branch main c49965b [mlgo] Fix post PR llvm#76919
…T/INC/DEC/IMUL (llvm#77564) We supported encoding/decoding for these instructions in llvm#76319 llvm#76721 llvm#76919
Four variants: promoted legacy, ND (new data destination), NF (no flags
update) and NF_ND (NF + ND).
The syntax of NF instructions is aligned with GNU binutils.
https://sourceware.org/pipermail/binutils/2023-September/129545.html