[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 21:47:30 PST 2024


================
@@ -163,15 +386,71 @@ class ShlrdOpMRC_M<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
                     [(store (node t.RegClass:$src2, (t.LoadNode addr:$src1), CL), addr:$src1)]);
 }
 
-multiclass Shlrd<bits<8> o1, bits<8> o2, string m, SDPatternOperator node, SDPatternOperator t_node> {
+class ShlrdOpMRI8U_R<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
+  : ITy<o, MRMDestMem, t, (outs t.RegClass:$dst), (ins t.MemOperand:$src1, t.RegClass:$src2, u8imm:$src3),
+        m, triop_ndd_args, []>, NDD<1> {
+  let ImmT = Imm8;
+  let SchedRW = [WriteSHDmri];
+  let mayLoad = 1;
+  let Pattern = !if(!eq(m, "shld"),
+                    [(set t.RegClass:$dst, (node (t.LoadNode addr:$src1), t.RegClass:$src2, (i8 imm:$src3)))],
+                    [(set t.RegClass:$dst, (node t.RegClass:$src2, (t.LoadNode addr:$src1), (i8 imm:$src3)))]);
+}
+
+class ShlrdOpMRC_R<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
+  : BinOpMR<o, m, triop_cl_ndd_args, t, (outs t.RegClass:$dst), []>, NDD<1> {
+  let Uses = [CL];
+  let SchedRW = [WriteSHDmrcl];
+  let Pattern = !if(!eq(m, "shld"),
+                    [(set t.RegClass:$dst, (node (t.LoadNode addr:$src1), t.RegClass:$src2, CL))],
+                    [(set t.RegClass:$dst, (node t.RegClass:$src2, (t.LoadNode addr:$src1), CL))]);
+}
+
+multiclass Shlrd<bits<8> o1, bits<8> o2, bits<8> o3, string m, SDPatternOperator node, SDPatternOperator t_node> {
+  let Predicates = [NoNDD] in {
+    def 16rri8 : ShlrdOpRRI8U_R<o1, m, Xi16, t_node>, TB, DefEFLAGS, OpSize16;
+    def 32rri8 : ShlrdOpRRI8U_R<o1, m, Xi32, node>, TB, DefEFLAGS, OpSize32;
+    def 64rri8 : ShlrdOpRRI8U_R<o1, m, Xi64, node>, TB, DefEFLAGS;
+
+    def 16rrCL : ShlrdOpRRC_R<o2, m, Xi16, t_node>, TB, DefEFLAGS, OpSize16;
+    def 32rrCL : ShlrdOpRRC_R<o2, m, Xi32, node>, TB, DefEFLAGS, OpSize32;
+    def 64rrCL : ShlrdOpRRC_R<o2, m, Xi64, node>, TB, DefEFLAGS;
+  }
+  let Predicates = [HasNDD, In64BitMode] in {
+    def 16rri8_ND : ShlrdOpRRI8U_R<o3, m, Xi16, t_node, 1>, DefEFLAGS, PD;
+    def 32rri8_ND : ShlrdOpRRI8U_R<o3, m, Xi32, node, 1>, DefEFLAGS;
+    def 64rri8_ND : ShlrdOpRRI8U_R<o3, m, Xi64, node, 1>, DefEFLAGS;
+
+    def 16rrCL_ND : ShlrdOpRRC_R<o2, m, Xi16, t_node, 1>, DefEFLAGS, PD;
+    def 32rrCL_ND : ShlrdOpRRC_R<o2, m, Xi32, node, 1>, DefEFLAGS;
+    def 64rrCL_ND : ShlrdOpRRC_R<o2, m, Xi64, node, 1>, DefEFLAGS;
+  }
 
-  def 16rri8 : ShlrdOpRRI8U_R<o1, m, Xi16, t_node>, DefEFLAGS, OpSize16;
-  def 32rri8 : ShlrdOpRRI8U_R<o1, m, Xi32, node>, DefEFLAGS, OpSize32;
-  def 64rri8 : ShlrdOpRRI8U_R<o1, m, Xi64, node>, DefEFLAGS;
+  let Predicates = [In64BitMode] in {
+    def 16rri8_NF : ShlrdOpRRI8U_R<o3, m, Xi16, null_frag>, NF, PD;
+    def 32rri8_NF : ShlrdOpRRI8U_R<o3, m, Xi32, null_frag>, NF;
+    def 64rri8_NF : ShlrdOpRRI8U_R<o3, m, Xi64, null_frag>, NF;
 
-  def 16rrCL : ShlrdOpRRC_R<o2, m, Xi16, t_node>, DefEFLAGS, OpSize16;
-  def 32rrCL : ShlrdOpRRC_R<o2, m, Xi32, node>, DefEFLAGS, OpSize32;
-  def 64rrCL : ShlrdOpRRC_R<o2, m, Xi64, node>, DefEFLAGS;
+    def 16rrCL_NF : ShlrdOpRRC_R<o2, m, Xi16, null_frag>, NF, PD;
+    def 32rrCL_NF : ShlrdOpRRC_R<o2, m, Xi32, null_frag>, NF;
+    def 64rrCL_NF : ShlrdOpRRC_R<o2, m, Xi64, null_frag>, NF;
+
+    def 16rri8_NF_ND : ShlrdOpRRI8U_R<o3, m, Xi16, null_frag, 1>, EVEX_NF, PD;
+    def 32rri8_NF_ND : ShlrdOpRRI8U_R<o3, m, Xi32, null_frag, 1>, EVEX_NF;
+    def 64rri8_NF_ND : ShlrdOpRRI8U_R<o3, m, Xi64, null_frag, 1>, EVEX_NF;
+
+    def 16rrCL_NF_ND : ShlrdOpRRC_R<o2, m, Xi16, null_frag, 1>, EVEX_NF, PD;
+    def 32rrCL_NF_ND : ShlrdOpRRC_R<o2, m, Xi32, null_frag, 1>, EVEX_NF;
+    def 64rrCL_NF_ND : ShlrdOpRRC_R<o2, m, Xi64, null_frag, 1>, EVEX_NF;
+
+    def 16rri8_EVEX : ShlrdOpRRI8U_R<o3, m, Xi16, null_frag>, DefEFLAGS, PL, PD;
+    def 32rri8_EVEX : ShlrdOpRRI8U_R<o3, m, Xi32, null_frag>, DefEFLAGS, PL;
+    def 64rri8_EVEX : ShlrdOpRRI8U_R<o3, m, Xi64, null_frag>, DefEFLAGS, PL;
+
+    def 16rrCL_EVEX : ShlrdOpRRC_R<o2, m, Xi16, null_frag>, DefEFLAGS, PL, PD;
+    def 32rrCL_EVEX : ShlrdOpRRC_R<o2, m, Xi32, null_frag>, DefEFLAGS, PL;
+    def 64rrCL_EVEX : ShlrdOpRRC_R<o2, m, Xi64, null_frag>, DefEFLAGS, PL;
+  }
 
   def 16mri8 : ShlrdOpMRI8U_M<o1, m, Xi16, t_node>, DefEFLAGS, OpSize16;
----------------
KanRobert wrote:

No, NDD instruction does not have `store` semantic. So we still need `16ri8` when NDD is available.

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


More information about the llvm-commits mailing list