[llvm] [X86] Support encoding/decoding and lowering for APX variant SHL/SHR/SAR/SHLD/SHRD (PR #78853)

Phoebe Wang via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 21 19:54:35 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.
----------------
phoebewang wrote:

`ams` -> `asm`

https://github.com/llvm/llvm-project/pull/78853


More information about the llvm-commits mailing list