-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[X86][MC] Support encoding/decoding for APX variant INC/DEC/ADCX/ADOX instructions #76721
Conversation
@llvm/pr-subscribers-mc @llvm/pr-subscribers-backend-x86 Author: Shengchen Kan (KanRobert) ChangesPatch is 42.91 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/76721.diff 11 Files Affected:
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 924956295e7c60..d152c85da9393c 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -1650,6 +1650,9 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI,
if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
++SrcRegNum;
+ if (IsND)
+ ++CurOp;
+
emitRegModRMByte(MI.getOperand(SrcRegNum),
getX86RegNum(MI.getOperand(CurOp)), CB);
CurOp = SrcRegNum + 1;
diff --git a/llvm/lib/Target/X86/X86InstrArithmetic.td b/llvm/lib/Target/X86/X86InstrArithmetic.td
index 6b0c1b8c28c950..1fda4f2993211f 100644
--- a/llvm/lib/Target/X86/X86InstrArithmetic.td
+++ b/llvm/lib/Target/X86/X86InstrArithmetic.td
@@ -184,52 +184,139 @@ def IMUL64rmi32 : IMulOpMI_R<Xi64, WriteIMul64Imm>;
//===----------------------------------------------------------------------===//
// INC and DEC Instructions
//
-class IncOpR_RF<X86TypeInfo t> : UnaryOpR_RF<0xFF, MRM0r, "inc", t, null_frag> {
+class IncOpR_RF<X86TypeInfo t, bit ndd = 0> : UnaryOpR_RF<0xFF, MRM0r, "inc", t, null_frag, ndd> {
let Pattern = [(set t.RegClass:$dst, EFLAGS,
(X86add_flag_nocf t.RegClass:$src1, 1))];
}
-class DecOpR_RF<X86TypeInfo t> : UnaryOpR_RF<0xFF, MRM1r, "dec", t, null_frag> {
+class DecOpR_RF<X86TypeInfo t, bit ndd = 0> : UnaryOpR_RF<0xFF, MRM1r, "dec", t, null_frag, ndd> {
let Pattern = [(set t.RegClass:$dst, EFLAGS,
(X86sub_flag_nocf t.RegClass:$src1, 1))];
}
-class IncOpM_M<X86TypeInfo t> : UnaryOpM_MF<0xFF, MRM0m, "inc", t, null_frag> {
+class IncOpR_R<X86TypeInfo t, bit ndd = 0> : UnaryOpR_R<0xFF, MRM0r, "inc", t, null_frag, ndd>;
+class DecOpR_R<X86TypeInfo t, bit ndd = 0> : UnaryOpR_R<0xFF, MRM1r, "dec", t, null_frag, ndd>;
+class IncOpM_MF<X86TypeInfo t> : UnaryOpM_MF<0xFF, MRM0m, "inc", t, null_frag> {
let Pattern = [(store (add (t.LoadNode addr:$src1), 1), addr:$src1),
(implicit EFLAGS)];
}
-class DecOpM_M<X86TypeInfo t> : UnaryOpM_MF<0xFF, MRM1m, "dec", t, null_frag> {
+class DecOpM_MF<X86TypeInfo t> : UnaryOpM_MF<0xFF, MRM1m, "dec", t, null_frag> {
let Pattern = [(store (add (t.LoadNode addr:$src1), -1), addr:$src1),
(implicit EFLAGS)];
}
+class IncOpM_RF<X86TypeInfo t> : UnaryOpM_RF<0xFF, MRM0m, "inc", t, null_frag> {
+ let Pattern = [(set t.RegClass:$dst, EFLAGS, (add (t.LoadNode addr:$src1), 1))];
+}
+class DecOpM_RF<X86TypeInfo t> : UnaryOpM_RF<0xFF, MRM1m, "dec", t, null_frag> {
+ let Pattern = [(set t.RegClass:$dst, EFLAGS, (add (t.LoadNode addr:$src1), -1))];
+}
+class IncOpM_M<X86TypeInfo t> : UnaryOpM_M<0xFF, MRM0m, "inc", t, null_frag>;
+class DecOpM_M<X86TypeInfo t> : UnaryOpM_M<0xFF, MRM1m, "dec", t, null_frag>;
+class IncOpM_R<X86TypeInfo t> : UnaryOpM_R<0xFF, MRM0m, "inc", t, null_frag>;
+class DecOpM_R<X86TypeInfo t> : UnaryOpM_R<0xFF, MRM1m, "dec", t, null_frag>;
+
// IncDec_Alt - Instructions like "inc reg" short forms.
// Short forms only valid in 32-bit mode. Selected during MCInst lowering.
class IncDec_Alt<bits<8> o, string m, X86TypeInfo t>
: UnaryOpR_RF<o, AddRegFrm, m, t, null_frag>, Requires<[Not64BitMode]>;
let isConvertibleToThreeAddress = 1 in {
-def INC16r_alt : IncDec_Alt<0x40, "inc", Xi16>, OpSize16;
-def INC32r_alt : IncDec_Alt<0x40, "inc", Xi32>, OpSize32;
-def DEC16r_alt : IncDec_Alt<0x48, "dec", Xi16>, OpSize16;
-def DEC32r_alt : IncDec_Alt<0x48, "dec", Xi32>, OpSize32;
-def INC8r : IncOpR_RF<Xi8>;
-def INC16r : IncOpR_RF<Xi16>, OpSize16;
-def INC32r : IncOpR_RF<Xi32>, OpSize32;
-def INC64r : IncOpR_RF<Xi64>;
-def DEC8r : DecOpR_RF<Xi8>;
-def DEC16r : DecOpR_RF<Xi16>, OpSize16;
-def DEC32r : DecOpR_RF<Xi32>, OpSize32;
-def DEC64r : DecOpR_RF<Xi64>;
+ def INC16r_alt : IncDec_Alt<0x40, "inc", Xi16>, OpSize16;
+ def INC32r_alt : IncDec_Alt<0x40, "inc", Xi32>, OpSize32;
+ def DEC16r_alt : IncDec_Alt<0x48, "dec", Xi16>, OpSize16;
+ def DEC32r_alt : IncDec_Alt<0x48, "dec", Xi32>, OpSize32;
+ let Predicates = [NoNDD] in {
+ def INC8r : IncOpR_RF<Xi8>;
+ def INC16r : IncOpR_RF<Xi16>, OpSize16;
+ def INC32r : IncOpR_RF<Xi32>, OpSize32;
+ def INC64r : IncOpR_RF<Xi64>;
+ def DEC8r : DecOpR_RF<Xi8>;
+ def DEC16r : DecOpR_RF<Xi16>, OpSize16;
+ def DEC32r : DecOpR_RF<Xi32>, OpSize32;
+ def DEC64r : DecOpR_RF<Xi64>;
+ }
+ let Predicates = [HasNDD, In64BitMode] in {
+ def INC8r_ND : IncOpR_RF<Xi8, 1>;
+ def INC16r_ND : IncOpR_RF<Xi16, 1>, PD;
+ def INC32r_ND : IncOpR_RF<Xi32, 1>;
+ def INC64r_ND : IncOpR_RF<Xi64, 1>;
+ def DEC8r_ND : DecOpR_RF<Xi8, 1>;
+ def DEC16r_ND : DecOpR_RF<Xi16, 1>, PD;
+ def DEC32r_ND : DecOpR_RF<Xi32, 1>;
+ def DEC64r_ND : DecOpR_RF<Xi64, 1>;
+ }
+ let Predicates = [In64BitMode], Pattern = [(null_frag)] in {
+ def INC8r_NF : IncOpR_R<Xi8>, NF;
+ def INC16r_NF : IncOpR_R<Xi16>, NF, PD;
+ def INC32r_NF : IncOpR_R<Xi32>, NF;
+ def INC64r_NF : IncOpR_R<Xi64>, NF;
+ def DEC8r_NF : DecOpR_R<Xi8>, NF;
+ def DEC16r_NF : DecOpR_R<Xi16>, NF, PD;
+ def DEC32r_NF : DecOpR_R<Xi32>, NF;
+ def DEC64r_NF : DecOpR_R<Xi64>, NF;
+ def INC8r_NF_ND : IncOpR_R<Xi8, 1>, NF;
+ def INC16r_NF_ND : IncOpR_R<Xi16, 1>, NF, PD;
+ def INC32r_NF_ND : IncOpR_R<Xi32, 1>, NF;
+ def INC64r_NF_ND : IncOpR_R<Xi64, 1>, NF;
+ def DEC8r_NF_ND : DecOpR_R<Xi8, 1>, NF;
+ def DEC16r_NF_ND : DecOpR_R<Xi16, 1>, NF, PD;
+ def DEC32r_NF_ND : DecOpR_R<Xi32, 1>, NF;
+ def DEC64r_NF_ND : DecOpR_R<Xi64, 1>, NF;
+ def INC8r_EVEX : IncOpR_RF<Xi8>, PL;
+ def INC16r_EVEX : IncOpR_RF<Xi16>, PL, PD;
+ def INC32r_EVEX : IncOpR_RF<Xi32>, PL;
+ def INC64r_EVEX : IncOpR_RF<Xi64>, PL;
+ def DEC8r_EVEX : DecOpR_RF<Xi8>, PL;
+ def DEC16r_EVEX : DecOpR_RF<Xi16>, PL, PD;
+ def DEC32r_EVEX : DecOpR_RF<Xi32>, PL;
+ def DEC64r_EVEX : DecOpR_RF<Xi64>, PL;
+ }
}
let Predicates = [UseIncDec] in {
-def INC8m : IncOpM_M<Xi8>;
-def INC16m : IncOpM_M<Xi16>, OpSize16;
-def INC32m : IncOpM_M<Xi32>, OpSize32;
-def DEC8m : DecOpM_M<Xi8>;
-def DEC16m : DecOpM_M<Xi16>, OpSize16;
-def DEC32m : DecOpM_M<Xi32>, OpSize32;
+ def INC8m : IncOpM_MF<Xi8>;
+ def INC16m : IncOpM_MF<Xi16>, OpSize16;
+ def INC32m : IncOpM_MF<Xi32>, OpSize32;
+ def DEC8m : DecOpM_MF<Xi8>;
+ def DEC16m : DecOpM_MF<Xi16>, OpSize16;
+ def DEC32m : DecOpM_MF<Xi32>, OpSize32;
}
let Predicates = [UseIncDec, In64BitMode] in {
-def INC64m : IncOpM_M<Xi64>;
-def DEC64m : DecOpM_M<Xi64>;
+ def INC64m : IncOpM_MF<Xi64>;
+ def DEC64m : DecOpM_MF<Xi64>;
+}
+let Predicates = [HasNDD, In64BitMode, UseIncDec] in {
+ def INC8m_ND : IncOpM_RF<Xi8>;
+ def INC16m_ND : IncOpM_RF<Xi16>, PD;
+ def INC32m_ND : IncOpM_RF<Xi32>;
+ def DEC8m_ND : DecOpM_RF<Xi8>;
+ def DEC16m_ND : DecOpM_RF<Xi16>, PD;
+ def DEC32m_ND : DecOpM_RF<Xi32>;
+ def INC64m_ND : IncOpM_RF<Xi64>;
+ def DEC64m_ND : DecOpM_RF<Xi64>;
+}
+let Predicates = [In64BitMode], Pattern = [(null_frag)] in {
+ def INC8m_NF : IncOpM_M<Xi8>, NF;
+ def INC16m_NF : IncOpM_M<Xi16>, NF, PD;
+ def INC32m_NF : IncOpM_M<Xi32>, NF;
+ def INC64m_NF : IncOpM_M<Xi64>, NF;
+ def DEC8m_NF : DecOpM_M<Xi8>, NF;
+ def DEC16m_NF : DecOpM_M<Xi16>, NF, PD;
+ def DEC32m_NF : DecOpM_M<Xi32>, NF;
+ def DEC64m_NF : DecOpM_M<Xi64>, NF;
+ def INC8m_NF_ND : IncOpM_R<Xi8>, NF;
+ def INC16m_NF_ND : IncOpM_R<Xi16>, NF, PD;
+ def INC32m_NF_ND : IncOpM_R<Xi32>, NF;
+ def INC64m_NF_ND : IncOpM_R<Xi64>, NF;
+ def DEC8m_NF_ND : DecOpM_R<Xi8>, NF;
+ def DEC16m_NF_ND : DecOpM_R<Xi16>, NF, PD;
+ def DEC32m_NF_ND : DecOpM_R<Xi32>, NF;
+ def DEC64m_NF_ND : DecOpM_R<Xi64>, NF;
+ def INC8m_EVEX : IncOpM_MF<Xi8>, PL;
+ def INC16m_EVEX : IncOpM_MF<Xi16>, PL, PD;
+ def INC32m_EVEX : IncOpM_MF<Xi32>, PL;
+ def INC64m_EVEX : IncOpM_MF<Xi64>, PL;
+ def DEC8m_EVEX : DecOpM_MF<Xi8>, PL;
+ def DEC16m_EVEX : DecOpM_MF<Xi16>, PL, PD;
+ def DEC32m_EVEX : DecOpM_MF<Xi32>, PL;
+ def DEC64m_EVEX : DecOpM_MF<Xi64>, PL;
}
//===----------------------------------------------------------------------===//
@@ -1119,14 +1206,34 @@ defm MULX64 : MulX<Xi64, WriteMULX64>, REX_W;
// We don't have patterns for these as there is no advantage over ADC for
// most code.
let Form = MRMSrcReg in {
-def ADCX32rr : BinOpRRF_RF<0xF6, "adcx", Xi32, null_frag>, T8, PD;
-def ADCX64rr : BinOpRRF_RF<0xF6, "adcx", Xi64, null_frag>, T8, PD;
-def ADOX32rr : BinOpRRF_RF<0xF6, "adox", Xi32, null_frag>, T8, XS;
-def ADOX64rr : BinOpRRF_RF<0xF6, "adox", Xi64, null_frag>, T8, XS;
+ def ADCX32rr : BinOpRRF_RF<0xF6, "adcx", Xi32, null_frag>, T8, PD;
+ def ADCX64rr : BinOpRRF_RF<0xF6, "adcx", Xi64, null_frag>, T8, PD;
+ def ADOX32rr : BinOpRRF_RF<0xF6, "adox", Xi32, null_frag>, T8, XS;
+ def ADOX64rr : BinOpRRF_RF<0xF6, "adox", Xi64, null_frag>, T8, XS;
+ let Predicates =[In64BitMode] in {
+ def ADCX32rr_EVEX : BinOpRRF_RF<0x66, "adcx", Xi32, null_frag>, EVEX, T_MAP4, PD;
+ def ADCX64rr_EVEX : BinOpRRF_RF<0x66, "adcx", Xi64, null_frag>, EVEX, T_MAP4, PD;
+ def ADOX32rr_EVEX : BinOpRRF_RF<0x66, "adox", Xi32, null_frag>, EVEX, T_MAP4, XS;
+ def ADOX64rr_EVEX : BinOpRRF_RF<0x66, "adox", Xi64, null_frag>, EVEX, T_MAP4, XS;
+ def ADCX32rr_ND : BinOpRRF_RF<0x66, "adcx", Xi32, null_frag, 1>, PD;
+ def ADCX64rr_ND : BinOpRRF_RF<0x66, "adcx", Xi64, null_frag, 1>, PD;
+ def ADOX32rr_ND : BinOpRRF_RF<0x66, "adox", Xi32, null_frag, 1>, XS;
+ def ADOX64rr_ND : BinOpRRF_RF<0x66, "adox", Xi64, null_frag, 1>, XS;
+ }
}
let Form = MRMSrcMem in {
-def ADCX32rm : BinOpRMF_RF<0xF6, "adcx", Xi32, null_frag>, T8, PD;
-def ADCX64rm : BinOpRMF_RF<0xF6, "adcx", Xi64, null_frag>, T8, PD;
-def ADOX32rm : BinOpRMF_RF<0xF6, "adox", Xi32, null_frag>, T8, XS;
-def ADOX64rm : BinOpRMF_RF<0xF6, "adox", Xi64, null_frag>, T8, XS;
+ def ADCX32rm : BinOpRMF_RF<0xF6, "adcx", Xi32, null_frag>, T8, PD;
+ def ADCX64rm : BinOpRMF_RF<0xF6, "adcx", Xi64, null_frag>, T8, PD;
+ def ADOX32rm : BinOpRMF_RF<0xF6, "adox", Xi32, null_frag>, T8, XS;
+ def ADOX64rm : BinOpRMF_RF<0xF6, "adox", Xi64, null_frag>, T8, XS;
+ let Predicates =[In64BitMode] in {
+ def ADCX32rm_EVEX : BinOpRMF_RF<0x66, "adcx", Xi32, null_frag>, EVEX, T_MAP4, PD;
+ def ADCX64rm_EVEX : BinOpRMF_RF<0x66, "adcx", Xi64, null_frag>, EVEX, T_MAP4, PD;
+ def ADOX32rm_EVEX : BinOpRMF_RF<0x66, "adox", Xi32, null_frag>, EVEX, T_MAP4, XS;
+ def ADOX64rm_EVEX : BinOpRMF_RF<0x66, "adox", Xi64, null_frag>, EVEX, T_MAP4, XS;
+ def ADCX32rm_ND : BinOpRMF_RF<0x66, "adcx", Xi32, null_frag, 1>, PD;
+ def ADCX64rm_ND : BinOpRMF_RF<0x66, "adcx", Xi64, null_frag, 1>, PD;
+ def ADOX32rm_ND : BinOpRMF_RF<0x66, "adox", Xi32, null_frag, 1>, XS;
+ def ADOX64rm_ND : BinOpRMF_RF<0x66, "adox", Xi64, null_frag, 1>, XS;
+ }
}
diff --git a/llvm/test/MC/Disassembler/X86/apx/adx.txt b/llvm/test/MC/Disassembler/X86/apx/adx.txt
new file mode 100644
index 00000000000000..926cd14bef1100
--- /dev/null
+++ b/llvm/test/MC/Disassembler/X86/apx/adx.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: adcxl %r16d, %r17d
+# INTEL: adcx r17d, r16d
+0x62,0xec,0x7d,0x08,0x66,0xc8
+
+# ATT: adcxl %r16d, %r17d, %r18d
+# INTEL: adcx r18d, r17d, r16d
+0x62,0xec,0x6d,0x10,0x66,0xc8
+
+# ATT: adcxq %r16, %r17
+# INTEL: adcx r17, r16
+0x62,0xec,0xfd,0x08,0x66,0xc8
+
+# ATT: adcxq %r16, %r17, %r18
+# INTEL: adcx r18, r17, r16
+0x62,0xec,0xed,0x10,0x66,0xc8
+
+# ATT: adcxl (%r16), %r17d
+# INTEL: adcx r17d, dword ptr [r16]
+0x62,0xec,0x7d,0x08,0x66,0x08
+
+# ATT: adcxl (%r16), %r17d, %r18d
+# INTEL: adcx r18d, r17d, dword ptr [r16]
+0x62,0xec,0x6d,0x10,0x66,0x08
+
+# ATT: adcxq (%r16), %r17
+# INTEL: adcx r17, qword ptr [r16]
+0x62,0xec,0xfd,0x08,0x66,0x08
+
+# ATT: adcxq (%r16), %r17, %r18
+# INTEL: adcx r18, r17, qword ptr [r16]
+0x62,0xec,0xed,0x10,0x66,0x08
+
+# ATT: adoxl %r16d, %r17d
+# INTEL: adox r17d, r16d
+0x62,0xec,0x7e,0x08,0x66,0xc8
+
+# ATT: adoxl %r16d, %r17d, %r18d
+# INTEL: adox r18d, r17d, r16d
+0x62,0xec,0x6e,0x10,0x66,0xc8
+
+# ATT: adoxq %r16, %r17
+# INTEL: adox r17, r16
+0x62,0xec,0xfe,0x08,0x66,0xc8
+
+# ATT: adoxq %r16, %r17, %r18
+# INTEL: adox r18, r17, r16
+0x62,0xec,0xee,0x10,0x66,0xc8
+
+# ATT: adoxl (%r16), %r17d
+# INTEL: adox r17d, dword ptr [r16]
+0x62,0xec,0x7e,0x08,0x66,0x08
+
+# ATT: adoxl (%r16), %r17d, %r18d
+# INTEL: adox r18d, r17d, dword ptr [r16]
+0x62,0xec,0x6e,0x10,0x66,0x08
+
+# ATT: adoxq (%r16), %r17
+# INTEL: adox r17, qword ptr [r16]
+0x62,0xec,0xfe,0x08,0x66,0x08
+
+# ATT: adoxq (%r16), %r17, %r18
+# INTEL: adox r18, r17, qword ptr [r16]
+0x62,0xec,0xee,0x10,0x66,0x08
diff --git a/llvm/test/MC/Disassembler/X86/apx/dec.txt b/llvm/test/MC/Disassembler/X86/apx/dec.txt
new file mode 100644
index 00000000000000..029cf192558573
--- /dev/null
+++ b/llvm/test/MC/Disassembler/X86/apx/dec.txt
@@ -0,0 +1,130 @@
+# 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} decb %bl
+# INTEL: {evex} dec bl
+0x62,0xf4,0x7c,0x08,0xfe,0xcb
+
+# ATT: {nf} decb %bl
+# INTEL: {nf} dec bl
+0x62,0xf4,0x7c,0x0c,0xfe,0xcb
+
+# ATT: decb %bl, %bl
+# INTEL: dec bl, bl
+0x62,0xf4,0x64,0x18,0xfe,0xcb
+
+# ATT: {nf} decb %bl, %bl
+# INTEL: {nf} dec bl, bl
+0x62,0xf4,0x64,0x1c,0xfe,0xcb
+
+# ATT: {evex} decw %dx
+# INTEL: {evex} dec dx
+0x62,0xf4,0x7d,0x08,0xff,0xca
+
+# ATT: {nf} decw %dx
+# INTEL: {nf} dec dx
+0x62,0xf4,0x7d,0x0c,0xff,0xca
+
+# ATT: decw %dx, %dx
+# INTEL: dec dx, dx
+0x62,0xf4,0x6d,0x18,0xff,0xca
+
+# ATT: {nf} decw %dx, %dx
+# INTEL: {nf} dec dx, dx
+0x62,0xf4,0x6d,0x1c,0xff,0xca
+
+# ATT: {evex} decl %ecx
+# INTEL: {evex} dec ecx
+0x62,0xf4,0x7c,0x08,0xff,0xc9
+
+# ATT: {nf} decl %ecx
+# INTEL: {nf} dec ecx
+0x62,0xf4,0x7c,0x0c,0xff,0xc9
+
+# ATT: decl %ecx, %ecx
+# INTEL: dec ecx, ecx
+0x62,0xf4,0x74,0x18,0xff,0xc9
+
+# ATT: {nf} decl %ecx, %ecx
+# INTEL: {nf} dec ecx, ecx
+0x62,0xf4,0x74,0x1c,0xff,0xc9
+
+# ATT: {evex} decq %r9
+# INTEL: {evex} dec r9
+0x62,0xd4,0xfc,0x08,0xff,0xc9
+
+# ATT: {nf} decq %r9
+# INTEL: {nf} dec r9
+0x62,0xd4,0xfc,0x0c,0xff,0xc9
+
+# ATT: decq %r9, %r9
+# INTEL: dec r9, r9
+0x62,0xd4,0xb4,0x18,0xff,0xc9
+
+# ATT: {nf} decq %r9, %r9
+# INTEL: {nf} dec r9, r9
+0x62,0xd4,0xb4,0x1c,0xff,0xc9
+
+# ATT: {evex} decb 291(%r8,%rax,4)
+# INTEL: {evex} dec byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xfe,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} decb 291(%r8,%rax,4)
+# INTEL: {nf} dec byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xfe,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: decb 291(%r8,%rax,4), %bl
+# INTEL: dec bl, byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x64,0x18,0xfe,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} decb 291(%r8,%rax,4), %bl
+# INTEL: {nf} dec bl, byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x64,0x1c,0xfe,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {evex} decw 291(%r8,%rax,4)
+# INTEL: {evex} dec word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x08,0xff,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} decw 291(%r8,%rax,4)
+# INTEL: {nf} dec word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x0c,0xff,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: decw 291(%r8,%rax,4), %dx
+# INTEL: dec dx, word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x6d,0x18,0xff,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} decw 291(%r8,%rax,4), %dx
+# INTEL: {nf} dec dx, word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x6d,0x1c,0xff,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {evex} decl 291(%r8,%rax,4)
+# INTEL: {evex} dec dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xff,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} decl 291(%r8,%rax,4)
+# INTEL: {nf} dec dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xff,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: decl 291(%r8,%rax,4), %ecx
+# INTEL: dec ecx, dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x74,0x18,0xff,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} decl 291(%r8,%rax,4), %ecx
+# INTEL: {nf} dec ecx, dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x74,0x1c,0xff,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {evex} decq 291(%r8,%rax,4)
+# INTEL: {evex} dec qword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0xfc,0x08,0xff,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} decq 291(%r8,%rax,4)
+# INTEL: {nf} dec qword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0xfc,0x0c,0xff,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: decq 291(%r8,%rax,4), %r9
+# INTEL: dec r9, qword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0xb4,0x18,0xff,0x8c,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} decq 291(%r8,%rax,4), %r9
+# INTEL: {nf} dec r9, qword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0xb4,0x1c,0xff,0x8c,0x80,0x23,0x01,0x00,0x00
diff --git a/llvm/test/MC/Disassembler/X86/apx/inc.txt b/llvm/test/MC/Disassembler/X86/apx/inc.txt
new file mode 100644
index 00000000000000..0470319b4f6cdd
--- /dev/null
+++ b/llvm/test/MC/Disassembler/X86/apx/inc.txt
@@ -0,0 +1,130 @@
+# 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} incb %bl
+# INTEL: {evex} inc bl
+0x62,0xf4,0x7c,0x08,0xfe,0xc3
+
+# ATT: {nf} incb %bl
+# INTEL: {nf} inc bl
+0x62,0xf4,0x7c,0x0c,0xfe,0xc3
+
+# ATT: incb %bl, %bl
+# INTEL: inc bl, bl
+0x62,0xf4,0x64,0x18,0xfe,0xc3
+
+# ATT: {nf} incb %bl, %bl
+# INTEL: {nf} inc bl, bl
+0x62,0xf4,0x64,0x1c,0xfe,0xc3
+
+# ATT: {evex} incw %dx
+# INTEL: {evex} inc dx
+0x62,0xf4,0x7d,0x08,0xff,0xc2
+
+# ATT: {nf} incw %dx
+# INTEL: {nf} inc dx
+0x62,0xf4,0x7d,0x0c,0xff,0xc2
+
+# ATT: incw %dx, %dx
+# INTEL: inc dx, dx
+0x62,0xf4,0x6d,0x18,0xff,0xc2
+
+# ATT: {nf} incw %dx, %dx
+# INTEL: {nf} inc dx, dx
+0x62,0xf4,0x6d,0x1c,0xff,0xc2
+
+# ATT: {evex} incl %ecx
+# INTEL: {evex} inc ecx
+0x62,0xf4,0x7c,0x08,0xff,0xc1
+
+# ATT: {nf} incl %ecx
+# INTEL: {nf} inc ecx
+0x62,0xf4,0x7c,0x0c,0xff,0xc1
+
+# ATT: incl %ecx, %ecx
+# INTEL: inc ecx, ecx
+0x62,0xf4,0x74,0x18,0xff,0xc1
+
+# ATT: {nf} incl %ecx, %ecx
+# INTEL: {nf} inc ecx, ecx
+0x62,0xf4,0x74,0x1c,0xff,0xc1
+
+# ATT: {evex} incq %r9
+# INTEL: {evex} inc r9
+0x62,0xd4,0xfc,0x08,0xff,0xc1
+
+# ATT: {nf} incq %r9
+# INTEL: {nf} inc r9
+0x62,0xd4,0xfc,0x0c,0xff,0xc1
+
+# ATT: incq %r9, %r9
+# INTEL: inc r9, r9
+0x62,0xd4,0xb4,0x18,0xff,0xc1
+
+# ATT: {nf} incq %r9, %r9
+# INTEL: {nf} inc r9, r9
+0x62,0xd4,0xb4,0x1c,0xff,0xc1
+
+# ATT: {evex} incb 291(%r8,%rax,4)
+# INTEL: {evex} inc byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xfe,0x84,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} incb 291(%r8,%rax,4)
+# INTEL: {nf} inc byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xfe,0x84,0x80,0x23,0x01,0x00,0x00
+
+# ATT: incb 291(%r8,%rax,4), %bl
+# INTEL: inc bl, byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x64,0x18,0xfe,0x84,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} incb 291(%r8,%rax,4), %bl
+# INTEL: {nf} inc bl, byte ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x64,0x1c,0xfe,0x84,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {evex} incw 291(%r8,%rax,4)
+# INTEL: {evex} inc word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x08,0xff,0x84,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} incw 291(%r8,%rax,4)
+# INTEL: {nf} inc word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7d,0x0c,0xff,0x84,0x80,0x23,0x01,0x00,0x00
+
+# ATT: incw 291(%r8,%rax,4), %dx
+# INTEL: inc dx, word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x6d,0x18,0xff,0x84,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} incw 291(%r8,%rax,4), %dx
+# INTEL: {nf} inc dx, word ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x6d,0x1c,0xff,0x84,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {evex} incl 291(%r8,%rax,4)
+# INTEL: {evex} inc dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x08,0xff,0x84,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} incl 291(%r8,%rax,4)
+# INTEL: {nf} inc dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x7c,0x0c,0xff,0x84,0x80,0x23,0x01,0x00,0x00
+
+# ATT: incl 291(%r8,%rax,4), %ecx
+# INTEL: inc ecx, dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x74,0x18,0xff,0x84,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {nf} incl 291(%r8,%rax,4), %ecx
+# INTEL: {nf} inc ecx, dword ptr [r8 + 4*rax + 291]
+0x62,0xd4,0x74,0x1c,0xff,0x84,0x80,0x23,0x01,0x00,0x00
+
+# ATT: {evex} incq 291(%r8,%rax,4)
+# INTEL: {evex}...
[truncated]
|
def DEC32r_ND : DecOpR_RF<Xi32, 1>; | ||
def DEC64r_ND : DecOpR_RF<Xi64, 1>; | ||
} | ||
let Predicates = [In64BitMode], Pattern = [(null_frag)] in { |
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.
Why set Pattern = [(null_frag)]
here given both IncOpR_R
and IncOpR_RF
already pass null_frag
by default?
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.
We only need to set Pattern = [(null_frag)]
for INC/DEC*_EVEX
. I put the setting in a wider range just to reduce nested let
statements. Otherwise, the code would look like
let Predicates = [In64BitMode] in {
def INC8r_NF
let Pattern = [(null_frag)] in {
def INC8r_EVEX
}
}
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.
How about move INC8r_EVEX
INC8m_EVEX
together with let Predicates = [In64BitMode], Pattern = [(null_frag)]
?
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.
It does not save anything b/c we can not move INC8r_NF
, which needs isConvertibleToThreeAddress = 1
def ADCX32rr_EVEX : BinOpRRF_RF<0x66, "adcx", Xi32>, EVEX, T_MAP4, PD; | ||
def ADCX64rr_EVEX : BinOpRRF_RF<0x66, "adcx", Xi64>, EVEX, T_MAP4, PD; | ||
def ADOX32rr_EVEX : BinOpRRF_RF<0x66, "adox", Xi32>, EVEX, T_MAP4, XS; | ||
def ADOX64rr_EVEX : BinOpRRF_RF<0x66, "adox", Xi64>, EVEX, T_MAP4, XS; |
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.
Why don't set Pattern = [(null_frag)]
for these?
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.
You suggested "make null_frag a default value for BinOpRRF_RF
" and I made the change. Now the Pattern
is equivalent to [(null_frag)]
, we don't need to set it explicitly here.
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.
…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