[llvm] [X86] Support encoding/decoding and lowering for APX variant SHL/SHR/SAR/SHLD/SHRD (PR #78853)
Shengchen Kan via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 21 22:27:13 PST 2024
================
@@ -20,45 +20,209 @@ multiclass ShiftRotate<string m, Format RegMRM, Format MemMRM, SDPatternOperator
let Uses = uses in {
let isConvertibleToThreeAddress = !if(!eq(m, "shl"), 1, 0) in {
- def 8ri : BinOpRI8U_R<m, RegMRM, Xi8, node>, Sched<[ri]>, DefEFLAGS;
- def 16ri : BinOpRI8U_R<m, RegMRM, Xi16, node>, Sched<[ri]>, DefEFLAGS, OpSize16;
- def 32ri : BinOpRI8U_R<m, RegMRM, Xi32, node>, Sched<[ri]>, DefEFLAGS, OpSize32;
- def 64ri : BinOpRI8U_R<m, RegMRM, Xi64, node>, Sched<[ri]>, DefEFLAGS;
+ let Predicates = [NoNDD] in {
+ def 8ri : BinOpRI8U_R<m, RegMRM, Xi8, node>, Sched<[ri]>, DefEFLAGS;
+ def 16ri : BinOpRI8U_R<m, RegMRM, Xi16, node>, Sched<[ri]>, DefEFLAGS, OpSize16;
+ def 32ri : BinOpRI8U_R<m, RegMRM, Xi32, node>, Sched<[ri]>, DefEFLAGS, OpSize32;
+ def 64ri : BinOpRI8U_R<m, RegMRM, Xi64, node>, Sched<[ri]>, DefEFLAGS;
+ }
+ let Predicates = [HasNDD, In64BitMode] in {
+ def 8ri_ND : BinOpRI8U_R<m, RegMRM, Xi8, node, 1>, Sched<[ri]>, DefEFLAGS;
+ def 16ri_ND : BinOpRI8U_R<m, RegMRM, Xi16, node, 1>, Sched<[ri]>, DefEFLAGS, PD;
+ def 32ri_ND : BinOpRI8U_R<m, RegMRM, Xi32, node, 1>, Sched<[ri]>, DefEFLAGS;
+ def 64ri_ND : BinOpRI8U_R<m, RegMRM, Xi64, node, 1>, Sched<[ri]>, DefEFLAGS;
+ }
+ let Predicates = [In64BitMode] in {
+ def 8ri_EVEX : BinOpRI8U_R<m, RegMRM, Xi8, null_frag>, Sched<[ri]>, DefEFLAGS, PL;
+ def 16ri_EVEX : BinOpRI8U_R<m, RegMRM, Xi16, null_frag>, Sched<[ri]>, DefEFLAGS, PL, PD;
+ def 32ri_EVEX : BinOpRI8U_R<m, RegMRM, Xi32, null_frag>, Sched<[ri]>, DefEFLAGS, PL;
+ def 64ri_EVEX : BinOpRI8U_R<m, RegMRM, Xi64, null_frag>, Sched<[ri]>, DefEFLAGS, PL;
+ }
}
def 8mi : BinOpMI8U_M<m, MemMRM, Xi8, node>, Sched<[mi, WriteRMW]>, DefEFLAGS;
def 16mi : BinOpMI8U_M<m, MemMRM, Xi16, node>, Sched<[mi, WriteRMW]>, DefEFLAGS, OpSize16;
def 32mi : BinOpMI8U_M<m, MemMRM, Xi32, node>, Sched<[mi, WriteRMW]>, DefEFLAGS, OpSize32;
def 64mi : BinOpMI8U_M<m, MemMRM, Xi64, node>, Sched<[mi, WriteRMW]>, DefEFLAGS, Requires<[In64BitMode]>;
+ let Predicates = [HasNDD, In64BitMode] in {
+ def 8mi_ND : BinOpMI8U_R<m, MemMRM, Xi8, node>, Sched<[mi, ri]>, DefEFLAGS;
+ def 16mi_ND : BinOpMI8U_R<m, MemMRM, Xi16, node>, Sched<[mi, ri]>, DefEFLAGS, PD;
+ def 32mi_ND : BinOpMI8U_R<m, MemMRM, Xi32, node>, Sched<[mi, ri]>, DefEFLAGS;
+ def 64mi_ND : BinOpMI8U_R<m, MemMRM, Xi64, node>, Sched<[mi, ri]>, DefEFLAGS;
+ }
+ let Predicates = [In64BitMode] in {
+ def 8mi_EVEX : BinOpMI8U_M<m, MemMRM, Xi8, null_frag>, Sched<[mi, WriteRMW]>, DefEFLAGS, PL;
+ def 16mi_EVEX : BinOpMI8U_M<m, MemMRM, Xi16, null_frag>, Sched<[mi, WriteRMW]>, DefEFLAGS, PL, PD;
+ def 32mi_EVEX : BinOpMI8U_M<m, MemMRM, Xi32, null_frag>, Sched<[mi, WriteRMW]>, DefEFLAGS, PL;
+ def 64mi_EVEX : BinOpMI8U_M<m, MemMRM, Xi64, null_frag>, Sched<[mi, WriteRMW]>, DefEFLAGS, PL;
+ }
let SchedRW = [ri] in {
def 8r1 : UnaryOpR_RF<0xD1, RegMRM, m, Xi8, null_frag>;
def 16r1 : UnaryOpR_RF<0xD1, RegMRM, m, Xi16, null_frag>, OpSize16;
def 32r1 : UnaryOpR_RF<0xD1, RegMRM, m, Xi32, null_frag>, OpSize32;
def 64r1 : UnaryOpR_RF<0xD1, RegMRM, m, Xi64, null_frag>;
+
+ // FIXME: Assembler can't tell whether it's 8r1_ND or 8rCL when the source register is cl, e.g.
+ //
+ // shlb %cl, %al
+ //
+ // GNU binutils distinguish them by adding an explicit $1 to asm string of 8r1_ND. But we haven't support
+ // constant immediate in ams string for X86 in TD. So we add DisassembleOnly for 8r1_ND for the time being.
+ let Predicates = [In64BitMode] in {
+ def 8r1_ND : UnaryOpR_RF<0xD1, RegMRM, m, Xi8, null_frag, 1>, DisassembleOnly;
+ def 16r1_ND : UnaryOpR_RF<0xD1, RegMRM, m, Xi16, null_frag, 1>, PD;
+ def 32r1_ND : UnaryOpR_RF<0xD1, RegMRM, m, Xi32, null_frag, 1>;
+ def 64r1_ND : UnaryOpR_RF<0xD1, RegMRM, m, Xi64, null_frag, 1>;
+
+ def 8r1_EVEX : UnaryOpR_RF<0xD1, RegMRM, m, Xi8, null_frag>, PL;
+ def 16r1_EVEX : UnaryOpR_RF<0xD1, RegMRM, m, Xi16, null_frag>, PL, PD;
+ def 32r1_EVEX : UnaryOpR_RF<0xD1, RegMRM, m, Xi32, null_frag>, PL;
+ def 64r1_EVEX : UnaryOpR_RF<0xD1, RegMRM, m, Xi64, null_frag>, PL;
+ }
}
let SchedRW = [mi, WriteRMW] in {
def 8m1 : UnaryOpM_MF<0xD1, MemMRM, m, Xi8, null_frag>;
def 16m1 : UnaryOpM_MF<0xD1, MemMRM, m, Xi16, null_frag>, OpSize16;
def 32m1 : UnaryOpM_MF<0xD1, MemMRM, m, Xi32, null_frag>, OpSize32;
def 64m1 : UnaryOpM_MF<0xD1, MemMRM, m, Xi64, null_frag>, Requires<[In64BitMode]>;
+
+ let Predicates = [In64BitMode] in {
+ def 8m1_EVEX : UnaryOpM_MF<0xD1, MemMRM, m, Xi8, null_frag>, PL;
+ def 16m1_EVEX : UnaryOpM_MF<0xD1, MemMRM, m, Xi16, null_frag>, PL, PD;
+ def 32m1_EVEX : UnaryOpM_MF<0xD1, MemMRM, m, Xi32, null_frag>, PL;
+ def 64m1_EVEX : UnaryOpM_MF<0xD1, MemMRM, m, Xi64, null_frag>, PL;
+ }
+ }
+ let SchedRW = [mi, ri], Predicates = [In64BitMode] in {
+ def 8m1_ND : UnaryOpM_RF<0xD1, MemMRM, m, Xi8, null_frag>;
+ def 16m1_ND : UnaryOpM_RF<0xD1, MemMRM, m, Xi16, null_frag>, PD;
+ def 32m1_ND : UnaryOpM_RF<0xD1, MemMRM, m, Xi32, null_frag>;
+ def 64m1_ND : UnaryOpM_RF<0xD1, MemMRM, m, Xi64, null_frag>;
}
}
let Uses = !listconcat([CL], uses) in {
----------------
KanRobert wrote:
Done
https://github.com/llvm/llvm-project/pull/78853
More information about the llvm-commits
mailing list