brintos

brintos / llvm-project-archived public Read only

0
0
Text · 32.3 KiB · 2a54888 Raw
692 lines · plain
1//===-- X86InstrShiftRotate.td - Shift and Rotate Instrs ---*- tablegen -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file describes the shift and rotate instructions.10//11//===----------------------------------------------------------------------===//12 13//===----------------------------------------------------------------------===//14// Shift/Rotate instructions15//===----------------------------------------------------------------------===//16 17multiclass ShiftRotate<string m, Format RegMRM, Format MemMRM, SDPatternOperator node,18                       SchedReadWrite rCL, SchedReadWrite ri, SchedReadWrite mCL,19                       SchedReadWrite mi, list<Register> uses = []> {20 21  let Uses = uses in {22    let isConvertibleToThreeAddress = !if(!eq(m, "shl"), 1, 0) in {23      let Predicates = [NoNDD] in {24        def 8ri  : BinOpRI8U_R<m, RegMRM, Xi8, node>, Sched<[ri]>, DefEFLAGS;25        def 16ri : BinOpRI8U_R<m, RegMRM, Xi16, node>, Sched<[ri]>, DefEFLAGS, OpSize16;26        def 32ri : BinOpRI8U_R<m, RegMRM, Xi32, node>, Sched<[ri]>, DefEFLAGS, OpSize32;27        def 64ri : BinOpRI8U_R<m, RegMRM, Xi64, node>, Sched<[ri]>, DefEFLAGS;28      }29      let Predicates = [HasNDD, In64BitMode] in {30        def 8ri_ND  : BinOpRI8U_R<m, RegMRM, Xi8, node, 1>, Sched<[ri]>, DefEFLAGS;31        def 16ri_ND : BinOpRI8U_R<m, RegMRM, Xi16, node, 1>, Sched<[ri]>, DefEFLAGS, PD;32        def 32ri_ND : BinOpRI8U_R<m, RegMRM, Xi32, node, 1>, Sched<[ri]>, DefEFLAGS;33        def 64ri_ND : BinOpRI8U_R<m, RegMRM, Xi64, node, 1>, Sched<[ri]>, DefEFLAGS;34      }35      let Predicates = [In64BitMode] in {36        def 8ri_EVEX  : BinOpRI8U_R<m, RegMRM, Xi8>, Sched<[ri]>, DefEFLAGS, PL;37        def 16ri_EVEX : BinOpRI8U_R<m, RegMRM, Xi16>, Sched<[ri]>, DefEFLAGS, PL, PD;38        def 32ri_EVEX : BinOpRI8U_R<m, RegMRM, Xi32>, Sched<[ri]>, DefEFLAGS, PL;39        def 64ri_EVEX : BinOpRI8U_R<m, RegMRM, Xi64>, Sched<[ri]>, DefEFLAGS, PL;40      }41    }42 43    def 8mi  : BinOpMI8U_M<m, MemMRM, Xi8, node>, Sched<[mi, WriteRMW]>, DefEFLAGS;44    def 16mi : BinOpMI8U_M<m, MemMRM, Xi16, node>, Sched<[mi, WriteRMW]>, DefEFLAGS, OpSize16;45    def 32mi : BinOpMI8U_M<m, MemMRM, Xi32, node>, Sched<[mi, WriteRMW]>, DefEFLAGS, OpSize32;46    def 64mi : BinOpMI8U_M<m, MemMRM, Xi64, node>, Sched<[mi, WriteRMW]>, DefEFLAGS, Requires<[In64BitMode]>;47    let Predicates = [HasNDD, In64BitMode] in {48      def 8mi_ND  : BinOpMI8U_R<m, MemMRM, Xi8, node>, Sched<[mi, ri]>, DefEFLAGS;49      def 16mi_ND : BinOpMI8U_R<m, MemMRM, Xi16, node>, Sched<[mi, ri]>, DefEFLAGS, PD;50      def 32mi_ND : BinOpMI8U_R<m, MemMRM, Xi32, node>, Sched<[mi, ri]>, DefEFLAGS;51      def 64mi_ND : BinOpMI8U_R<m, MemMRM, Xi64, node>, Sched<[mi, ri]>, DefEFLAGS;52    }53    let Predicates = [In64BitMode] in {54      def 8mi_EVEX  : BinOpMI8U_M<m, MemMRM, Xi8>, Sched<[mi, WriteRMW]>, DefEFLAGS, PL;55      def 16mi_EVEX : BinOpMI8U_M<m, MemMRM, Xi16>, Sched<[mi, WriteRMW]>, DefEFLAGS, PL, PD;56      def 32mi_EVEX : BinOpMI8U_M<m, MemMRM, Xi32>, Sched<[mi, WriteRMW]>, DefEFLAGS, PL;57      def 64mi_EVEX : BinOpMI8U_M<m, MemMRM, Xi64>, Sched<[mi, WriteRMW]>, DefEFLAGS, PL;58    }59 60    let SchedRW = [ri] in {61      def 8r1  : UnaryOpR_RF<0xD1, RegMRM, m, Xi8>;62      def 16r1 : UnaryOpR_RF<0xD1, RegMRM, m, Xi16>, OpSize16;63      def 32r1 : UnaryOpR_RF<0xD1, RegMRM, m, Xi32>, OpSize32;64      def 64r1 : UnaryOpR_RF<0xD1, RegMRM, m, Xi64>;65 66      // FIXME: Assembler can't tell whether it's 8r1_ND or 8rCL when the source register is cl, e.g.67      //68      //  shlb %cl, %al69      //70      // GNU binutils distinguish them by adding an explicit $1 to asm string of 8r1_ND. But we haven't support71      // constant immediate in asm string for X86 in TD. So we add DisassembleOnly for 8r1_ND for the time being.72      let Predicates = [In64BitMode] in {73        def 8r1_ND  : UnaryOpR_RF<0xD1, RegMRM, m, Xi8, null_frag, 1>, DisassembleOnly;74        def 16r1_ND : UnaryOpR_RF<0xD1, RegMRM, m, Xi16, null_frag, 1>, PD;75        def 32r1_ND : UnaryOpR_RF<0xD1, RegMRM, m, Xi32, null_frag, 1>;76        def 64r1_ND : UnaryOpR_RF<0xD1, RegMRM, m, Xi64, null_frag, 1>;77 78        def 8r1_EVEX  : UnaryOpR_RF<0xD1, RegMRM, m, Xi8>, PL;79        def 16r1_EVEX : UnaryOpR_RF<0xD1, RegMRM, m, Xi16>, PL, PD;80        def 32r1_EVEX : UnaryOpR_RF<0xD1, RegMRM, m, Xi32>, PL;81        def 64r1_EVEX : UnaryOpR_RF<0xD1, RegMRM, m, Xi64>, PL;82      }83    }84 85    let SchedRW = [mi, WriteRMW] in {86      def 8m1  : UnaryOpM_MF<0xD1, MemMRM, m, Xi8>;87      def 16m1 : UnaryOpM_MF<0xD1, MemMRM, m, Xi16>, OpSize16;88      def 32m1 : UnaryOpM_MF<0xD1, MemMRM, m, Xi32>, OpSize32;89      def 64m1 : UnaryOpM_MF<0xD1, MemMRM, m, Xi64>, Requires<[In64BitMode]>;90 91      let Predicates = [In64BitMode] in {92        def 8m1_EVEX  : UnaryOpM_MF<0xD1, MemMRM, m, Xi8>, PL;93        def 16m1_EVEX : UnaryOpM_MF<0xD1, MemMRM, m, Xi16>, PL, PD;94        def 32m1_EVEX : UnaryOpM_MF<0xD1, MemMRM, m, Xi32>, PL;95        def 64m1_EVEX : UnaryOpM_MF<0xD1, MemMRM, m, Xi64>, PL;96      }97    }98    let SchedRW = [mi, ri], Predicates = [In64BitMode] in {99      def 8m1_ND  : UnaryOpM_RF<0xD1, MemMRM, m, Xi8>;100      def 16m1_ND : UnaryOpM_RF<0xD1, MemMRM, m, Xi16>, PD;101      def 32m1_ND : UnaryOpM_RF<0xD1, MemMRM, m, Xi32>;102      def 64m1_ND : UnaryOpM_RF<0xD1, MemMRM, m, Xi64>;103    }104  }105 106  let Uses = !listconcat([CL], uses), Defs = [EFLAGS] in {107    let Predicates = [NoNDD] in {108      def 8rCL  : BinOpRC_R<m, RegMRM, Xi8, node>, Sched<[rCL]>;109      def 16rCL : BinOpRC_R<m, RegMRM, Xi16, node>, Sched<[rCL]>, OpSize16;110      def 32rCL : BinOpRC_R<m, RegMRM, Xi32, node>, Sched<[rCL]>, OpSize32;111      def 64rCL : BinOpRC_R<m, RegMRM, Xi64, node>, Sched<[rCL]>;112    }113    let Predicates = [HasNDD, In64BitMode] in {114      def 8rCL_ND  : BinOpRC_R<m, RegMRM, Xi8, node, 1>, Sched<[rCL]>;115      def 16rCL_ND : BinOpRC_R<m, RegMRM, Xi16, node, 1>, Sched<[rCL]>, PD;116      def 32rCL_ND : BinOpRC_R<m, RegMRM, Xi32, node, 1>, Sched<[rCL]>;117      def 64rCL_ND : BinOpRC_R<m, RegMRM, Xi64, node, 1>, Sched<[rCL]>;118    }119    let Predicates = [In64BitMode] in {120      def 8rCL_EVEX  : BinOpRC_R<m, RegMRM, Xi8>, Sched<[rCL]>, PL;121      def 16rCL_EVEX : BinOpRC_R<m, RegMRM, Xi16>, Sched<[rCL]>, PL, PD;122      def 32rCL_EVEX : BinOpRC_R<m, RegMRM, Xi32>, Sched<[rCL]>, PL;123      def 64rCL_EVEX : BinOpRC_R<m, RegMRM, Xi64>, Sched<[rCL]>, PL;124    }125 126    def 8mCL  : BinOpMC_M<m, MemMRM, Xi8, node>, Sched<[mCL, WriteRMW]>;127    def 16mCL : BinOpMC_M<m, MemMRM, Xi16, node>, Sched<[mCL, WriteRMW]>, OpSize16;128    def 32mCL : BinOpMC_M<m, MemMRM, Xi32, node>, Sched<[mCL, WriteRMW]>, OpSize32;129    def 64mCL : BinOpMC_M<m, MemMRM, Xi64, node>, Sched<[mCL, WriteRMW]>, Requires<[In64BitMode]>;130 131    let Predicates = [HasNDD, In64BitMode] in {132      def 8mCL_ND  : BinOpMC_R<m, MemMRM, Xi8, node>, Sched<[mCL, rCL]>;133      def 16mCL_ND : BinOpMC_R<m, MemMRM, Xi16, node>, Sched<[mCL, rCL]>, PD;134      def 32mCL_ND : BinOpMC_R<m, MemMRM, Xi32, node>, Sched<[mCL, rCL]>;135      def 64mCL_ND : BinOpMC_R<m, MemMRM, Xi64, node>, Sched<[mCL, rCL]>;136    }137 138    let Predicates = [In64BitMode] in {139      def 8mCL_EVEX  : BinOpMC_M<m, MemMRM, Xi8>, Sched<[mCL, WriteRMW]>, PL;140      def 16mCL_EVEX : BinOpMC_M<m, MemMRM, Xi16>, Sched<[mCL, WriteRMW]>, PL, PD;141      def 32mCL_EVEX : BinOpMC_M<m, MemMRM, Xi32>, Sched<[mCL, WriteRMW]>, PL;142      def 64mCL_EVEX : BinOpMC_M<m, MemMRM, Xi64>, Sched<[mCL, WriteRMW]>, PL;143    }144  }145}146 147multiclass ShiftRotate_NF<string m, Format RegMRM, Format MemMRM, SchedReadWrite rCL,148                          SchedReadWrite ri, SchedReadWrite mCL, SchedReadWrite mi> {149  let Predicates = [In64BitMode] in {150    let isConvertibleToThreeAddress = !if(!eq(m, "shl"), 1, 0) in {151      def 8ri_NF  : BinOpRI8U_R<m, RegMRM, Xi8>, Sched<[ri]>, NF;152      def 16ri_NF : BinOpRI8U_R<m, RegMRM, Xi16>, Sched<[ri]>, NF, PD;153      def 32ri_NF : BinOpRI8U_R<m, RegMRM, Xi32>, Sched<[ri]>, NF;154      def 64ri_NF : BinOpRI8U_R<m, RegMRM, Xi64>, Sched<[ri]>, NF;155 156      def 8ri_NF_ND  : BinOpRI8U_R<m, RegMRM, Xi8, null_frag, 1>, Sched<[ri]>, EVEX_NF;157      def 16ri_NF_ND : BinOpRI8U_R<m, RegMRM, Xi16, null_frag, 1>, Sched<[ri]>, EVEX_NF, PD;158      def 32ri_NF_ND : BinOpRI8U_R<m, RegMRM, Xi32, null_frag, 1>, Sched<[ri]>, EVEX_NF;159      def 64ri_NF_ND : BinOpRI8U_R<m, RegMRM, Xi64, null_frag, 1>, Sched<[ri]>, EVEX_NF;160    }161 162    def 8mi_NF  : BinOpMI8U_M<m, MemMRM, Xi8>, Sched<[mi, WriteRMW]>, NF;163    def 16mi_NF : BinOpMI8U_M<m, MemMRM, Xi16>, Sched<[mi, WriteRMW]>, NF, PD;164    def 32mi_NF : BinOpMI8U_M<m, MemMRM, Xi32>, Sched<[mi, WriteRMW]>, NF;165    def 64mi_NF : BinOpMI8U_M<m, MemMRM, Xi64>, Sched<[mi, WriteRMW]>, NF;166 167    def 8mi_NF_ND  : BinOpMI8U_R<m, MemMRM, Xi8>, Sched<[mi, ri]>, EVEX_NF;168    def 16mi_NF_ND : BinOpMI8U_R<m, MemMRM, Xi16>, Sched<[mi, ri]>, EVEX_NF, PD;169    def 32mi_NF_ND : BinOpMI8U_R<m, MemMRM, Xi32>, Sched<[mi, ri]>, EVEX_NF;170    def 64mi_NF_ND : BinOpMI8U_R<m, MemMRM, Xi64>, Sched<[mi, ri]>, EVEX_NF;171 172    let SchedRW = [ri] in {173      // FIXME: Assembler can't tell whether it's 8r1_NF_ND or 8rCL_NF when the source register is cl, e.g.174      //175      //  {nf} shlb %cl, %al176      //177      // GNU binutils distinguish them by adding an explicit $1 to asm string of 8r1_NF_ND. But we haven't support178      // constant immediate in asm string for X86 in TD. So we add DisassembleOnly for 8r1_NF_ND for the time being.179      def 8r1_NF  : UnaryOpR_R<0xD1, RegMRM, m, Xi8>, NF;180      def 16r1_NF : UnaryOpR_R<0xD1, RegMRM, m, Xi16>, NF, PD;181      def 32r1_NF : UnaryOpR_R<0xD1, RegMRM, m, Xi32>, NF;182      def 64r1_NF : UnaryOpR_R<0xD1, RegMRM, m, Xi64>, NF;183 184      def 8r1_NF_ND  : UnaryOpR_R<0xD1, RegMRM, m, Xi8, null_frag, 1>, EVEX_NF, DisassembleOnly;185      def 16r1_NF_ND : UnaryOpR_R<0xD1, RegMRM, m, Xi16, null_frag, 1>, EVEX_NF, PD;186      def 32r1_NF_ND : UnaryOpR_R<0xD1, RegMRM, m, Xi32, null_frag, 1>, EVEX_NF;187      def 64r1_NF_ND : UnaryOpR_R<0xD1, RegMRM, m, Xi64, null_frag, 1>, EVEX_NF;188    }189 190    let SchedRW = [mi, WriteRMW] in {191      def 8m1_NF  : UnaryOpM_M<0xD1, MemMRM, m, Xi8>, NF;192      def 16m1_NF : UnaryOpM_M<0xD1, MemMRM, m, Xi16>, NF, PD;193      def 32m1_NF : UnaryOpM_M<0xD1, MemMRM, m, Xi32>, NF;194      def 64m1_NF : UnaryOpM_M<0xD1, MemMRM, m, Xi64>, NF;195    }196    let SchedRW = [mi, ri] in {197      def 8m1_NF_ND  : UnaryOpM_R<0xD1, MemMRM, m, Xi8>, EVEX_NF;198      def 16m1_NF_ND : UnaryOpM_R<0xD1, MemMRM, m, Xi16>, EVEX_NF, PD;199      def 32m1_NF_ND : UnaryOpM_R<0xD1, MemMRM, m, Xi32>, EVEX_NF;200      def 64m1_NF_ND : UnaryOpM_R<0xD1, MemMRM, m, Xi64>, EVEX_NF;201    }202 203    let Uses = [CL] in {204      def 8rCL_NF  : BinOpRC_R<m, RegMRM, Xi8>, Sched<[rCL]>, NF;205      def 16rCL_NF : BinOpRC_R<m, RegMRM, Xi16>, Sched<[rCL]>, NF, PD;206      def 32rCL_NF : BinOpRC_R<m, RegMRM, Xi32>, Sched<[rCL]>, NF;207      def 64rCL_NF : BinOpRC_R<m, RegMRM, Xi64>, Sched<[rCL]>, NF;208 209      def 8rCL_NF_ND  : BinOpRC_R<m, RegMRM, Xi8, null_frag, 1>, Sched<[rCL]>, EVEX_NF;210      def 16rCL_NF_ND : BinOpRC_R<m, RegMRM, Xi16, null_frag, 1>, Sched<[rCL]>, EVEX_NF, PD;211      def 32rCL_NF_ND : BinOpRC_R<m, RegMRM, Xi32, null_frag, 1>, Sched<[rCL]>, EVEX_NF;212      def 64rCL_NF_ND : BinOpRC_R<m, RegMRM, Xi64, null_frag, 1>, Sched<[rCL]>, EVEX_NF;213 214      def 8mCL_NF  : BinOpMC_M<m, MemMRM, Xi8>, Sched<[mCL, WriteRMW]>, NF;215      def 16mCL_NF : BinOpMC_M<m, MemMRM, Xi16>, Sched<[mCL, WriteRMW]>, NF, PD;216      def 32mCL_NF : BinOpMC_M<m, MemMRM, Xi32>, Sched<[mCL, WriteRMW]>, NF;217      def 64mCL_NF : BinOpMC_M<m, MemMRM, Xi64>, Sched<[mCL, WriteRMW]>, NF;218 219      def 8mCL_NF_ND  : BinOpMC_R<m, MemMRM, Xi8>, Sched<[mCL, rCL]>, EVEX_NF;220      def 16mCL_NF_ND : BinOpMC_R<m, MemMRM, Xi16>, Sched<[mCL, rCL]>, EVEX_NF, PD;221      def 32mCL_NF_ND : BinOpMC_R<m, MemMRM, Xi32>, Sched<[mCL, rCL]>, EVEX_NF;222      def 64mCL_NF_ND : BinOpMC_R<m, MemMRM, Xi64>, Sched<[mCL, rCL]>, EVEX_NF;223    }224  }225}226defm SHL: ShiftRotate<"shl", MRM4r, MRM4m, shl, WriteShiftCL, WriteShift, WriteShiftCLLd, WriteShiftLd>;227defm SHR: ShiftRotate<"shr", MRM5r, MRM5m, srl, WriteShiftCL, WriteShift, WriteShiftCLLd, WriteShiftLd>;228defm SAR: ShiftRotate<"sar", MRM7r, MRM7m, sra, WriteShiftCL, WriteShift, WriteShiftCLLd, WriteShiftLd>;229 230defm ROL: ShiftRotate<"rol", MRM0r, MRM0m, rotl, WriteRotateCL, WriteRotate, WriteRotateCLLd, WriteRotateLd>;231defm ROR: ShiftRotate<"ror", MRM1r, MRM1m, rotr, WriteRotateCL, WriteRotate, WriteRotateCLLd, WriteRotateLd>;232defm RCL: ShiftRotate<"rcl", MRM2r, MRM2m, null_frag, WriteRotateCL, WriteRotate, WriteRotateCLLd, WriteRotateLd, [EFLAGS]>;233defm RCR: ShiftRotate<"rcr", MRM3r, MRM3m, null_frag, WriteRotateCL, WriteRotate, WriteRotateCLLd, WriteRotateLd, [EFLAGS]>;234 235defm SHL: ShiftRotate_NF<"shl", MRM4r, MRM4m, WriteShiftCL, WriteShift, WriteShiftCLLd, WriteShiftLd>;236defm SHR: ShiftRotate_NF<"shr", MRM5r, MRM5m, WriteShiftCL, WriteShift, WriteShiftCLLd, WriteShiftLd>;237defm SAR: ShiftRotate_NF<"sar", MRM7r, MRM7m, WriteShiftCL, WriteShift, WriteShiftCLLd, WriteShiftLd>;238 239defm ROL: ShiftRotate_NF<"rol", MRM0r, MRM0m, WriteRotateCL, WriteRotate, WriteRotateCLLd, WriteRotateLd>;240defm ROR: ShiftRotate_NF<"ror", MRM1r, MRM1m, WriteRotateCL, WriteRotate, WriteRotateCLLd, WriteRotateLd>;241 242// Use the opposite rotate if allows us to use the rotate by 1 instruction.243let Predicates = [NoNDD] in {244  def : Pat<(rotl GR8:$src1,  (i8 7)),  (ROR8r1  GR8:$src1)>;245  def : Pat<(rotl GR16:$src1, (i8 15)), (ROR16r1 GR16:$src1)>;246  def : Pat<(rotl GR32:$src1, (i8 31)), (ROR32r1 GR32:$src1)>;247  def : Pat<(rotl GR64:$src1, (i8 63)), (ROR64r1 GR64:$src1)>;248  def : Pat<(rotr GR8:$src1,  (i8 7)),  (ROL8r1  GR8:$src1)>;249  def : Pat<(rotr GR16:$src1, (i8 15)), (ROL16r1 GR16:$src1)>;250  def : Pat<(rotr GR32:$src1, (i8 31)), (ROL32r1 GR32:$src1)>;251  def : Pat<(rotr GR64:$src1, (i8 63)), (ROL64r1 GR64:$src1)>;252}253let Predicates = [HasNDD] in {254  def : Pat<(rotl GR8:$src1,  (i8 7)),  (ROR8r1_ND  GR8:$src1)>;255  def : Pat<(rotl GR16:$src1, (i8 15)), (ROR16r1_ND GR16:$src1)>;256  def : Pat<(rotl GR32:$src1, (i8 31)), (ROR32r1_ND GR32:$src1)>;257  def : Pat<(rotl GR64:$src1, (i8 63)), (ROR64r1_ND GR64:$src1)>;258  def : Pat<(rotr GR8:$src1,  (i8 7)),  (ROL8r1_ND  GR8:$src1)>;259  def : Pat<(rotr GR16:$src1, (i8 15)), (ROL16r1_ND GR16:$src1)>;260  def : Pat<(rotr GR32:$src1, (i8 31)), (ROL32r1_ND GR32:$src1)>;261  def : Pat<(rotr GR64:$src1, (i8 63)), (ROL64r1_ND GR64:$src1)>;262}263 264def : Pat<(store (rotl (loadi8 addr:$dst), (i8 7)), addr:$dst),265          (ROR8m1 addr:$dst)>;266def : Pat<(store (rotl (loadi16 addr:$dst), (i8 15)), addr:$dst),267          (ROR16m1 addr:$dst)>;268def : Pat<(store (rotl (loadi32 addr:$dst), (i8 31)), addr:$dst),269          (ROR32m1 addr:$dst)>;270def : Pat<(store (rotl (loadi64 addr:$dst), (i8 63)), addr:$dst),271          (ROR64m1 addr:$dst)>, Requires<[In64BitMode]>;272 273def : Pat<(store (rotr (loadi8 addr:$dst), (i8 7)), addr:$dst),274          (ROL8m1 addr:$dst)>;275def : Pat<(store (rotr (loadi16 addr:$dst), (i8 15)), addr:$dst),276          (ROL16m1 addr:$dst)>;277def : Pat<(store (rotr (loadi32 addr:$dst), (i8 31)), addr:$dst),278          (ROL32m1 addr:$dst)>;279def : Pat<(store (rotr (loadi64 addr:$dst), (i8 63)), addr:$dst),280          (ROL64m1 addr:$dst)>, Requires<[In64BitMode]>;281 282let Predicates = [HasNDD] in {283def : Pat<(rotl (loadi8 addr:$src), (i8 7)),284          (ROR8m1_ND addr:$src)>;285def : Pat<(rotl (loadi16 addr:$src), (i8 15)),286          (ROR16m1_ND addr:$src)>;287def : Pat<(rotl (loadi32 addr:$src), (i8 31)),288          (ROR32m1_ND addr:$src)>;289def : Pat<(rotl (loadi64 addr:$src), (i8 63)),290          (ROR64m1_ND addr:$src)>;291 292def : Pat<(rotr (loadi8 addr:$src), (i8 7)),293          (ROL8m1_ND addr:$src)>;294def : Pat<(rotr (loadi16 addr:$src), (i8 15)),295          (ROL16m1_ND addr:$src)>;296def : Pat<(rotr (loadi32 addr:$src), (i8 31)),297          (ROL32m1_ND addr:$src)>;298def : Pat<(rotr (loadi64 addr:$src), (i8 63)),299          (ROL64m1_ND addr:$src)>;300}301 302// Patterns for rotate with relocImm for the immediate field.303let Predicates = [NoNDD] in {304  def : Pat<(rotl GR8:$src1, (i8 relocImm:$src2)),305            (ROL8ri GR8:$src1, relocImm:$src2)>;306  def : Pat<(rotl GR16:$src1, (i8 relocImm:$src2)),307            (ROL16ri GR16:$src1, relocImm:$src2)>;308  def : Pat<(rotl GR32:$src1, (i8 relocImm:$src2)),309            (ROL32ri GR32:$src1, relocImm:$src2)>;310  def : Pat<(rotl GR64:$src1, (i8 relocImm:$src2)),311            (ROL64ri GR64:$src1, relocImm:$src2)>;312 313  def : Pat<(rotr GR8:$src1, (i8 relocImm:$src2)),314            (ROR8ri GR8:$src1, relocImm:$src2)>;315  def : Pat<(rotr GR16:$src1, (i8 relocImm:$src2)),316            (ROR16ri GR16:$src1, relocImm:$src2)>;317  def : Pat<(rotr GR32:$src1, (i8 relocImm:$src2)),318            (ROR32ri GR32:$src1, relocImm:$src2)>;319  def : Pat<(rotr GR64:$src1, (i8 relocImm:$src2)),320            (ROR64ri GR64:$src1, relocImm:$src2)>;321}322let Predicates = [HasNDD] in {323  def : Pat<(rotl GR8:$src1, (i8 relocImm:$src2)),324            (ROL8ri_ND GR8:$src1, relocImm:$src2)>;325  def : Pat<(rotl GR16:$src1, (i8 relocImm:$src2)),326            (ROL16ri_ND GR16:$src1, relocImm:$src2)>;327  def : Pat<(rotl GR32:$src1, (i8 relocImm:$src2)),328            (ROL32ri_ND GR32:$src1, relocImm:$src2)>;329  def : Pat<(rotl GR64:$src1, (i8 relocImm:$src2)),330            (ROL64ri_ND GR64:$src1, relocImm:$src2)>;331 332  def : Pat<(rotr GR8:$src1, (i8 relocImm:$src2)),333            (ROR8ri_ND GR8:$src1, relocImm:$src2)>;334  def : Pat<(rotr GR16:$src1, (i8 relocImm:$src2)),335            (ROR16ri_ND GR16:$src1, relocImm:$src2)>;336  def : Pat<(rotr GR32:$src1, (i8 relocImm:$src2)),337            (ROR32ri_ND GR32:$src1, relocImm:$src2)>;338  def : Pat<(rotr GR64:$src1, (i8 relocImm:$src2)),339            (ROR64ri_ND GR64:$src1, relocImm:$src2)>;340}341 342//===----------------------------------------------------------------------===//343// Double precision shift instructions (generalizations of rotate)344//===----------------------------------------------------------------------===//345 346class ShlrdOpRRI8U_R<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0>347  : ITy<o, MRMDestReg, t, (outs t.RegClass:$dst),348        (ins t.RegClass:$src1, t.RegClass:$src2, u8imm:$src3), m, !if(!eq(ndd, 0), triop_args, triop_ndd_args),349        []>, NDD<ndd> {350  let isCommutable = 1;351  let ImmT = Imm8;352  let SchedRW = [WriteSHDrri];353  let Pattern = !if(!eq(m, "shld"),354                    [(set t.RegClass:$dst, (node t.RegClass:$src1, t.RegClass:$src2, (i8 imm:$src3)))],355                    [(set t.RegClass:$dst, (node t.RegClass:$src2, t.RegClass:$src1, (i8 imm:$src3)))]);356}357 358class ShlrdOpRRC_R<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0>359  : BinOpRR<o, m, !if(!eq(ndd, 0), triop_cl_args, triop_cl_ndd_args), t, (outs t.RegClass:$dst), []>, NDD<ndd> {360  let Uses = [CL];361  let SchedRW = [WriteSHDrrcl];362  let Pattern = !if(!eq(m, "shld"),363                    [(set t.RegClass:$dst, (node t.RegClass:$src1, t.RegClass:$src2, CL))],364                    [(set t.RegClass:$dst, (node t.RegClass:$src2, t.RegClass:$src1, CL))]);365}366 367class ShlrdOpMRI8U_M<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag>368  : ITy<o, MRMDestMem, t, (outs), (ins t.MemOperand:$src1, t.RegClass:$src2, u8imm:$src3),369        m, triop_args, []>, TB {370  let ImmT = Imm8;371  let SchedRW = [WriteSHDmri];372  let mayLoad = 1;373  let mayStore = 1;374  let Pattern = !if(!eq(m, "shld"),375                    [(store (node (t.LoadNode addr:$src1), t.RegClass:$src2, (i8 imm:$src3)), addr:$src1)],376                    [(store (node t.RegClass:$src2, (t.LoadNode addr:$src1), (i8 imm:$src3)), addr:$src1)]);377}378 379class ShlrdOpMRC_M<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag>380  : BinOpMR<o, m, triop_cl_args, t, (outs), []>, TB {381  let Uses = [CL];382  let SchedRW = [WriteSHDmrcl];383  let mayStore = 1;384  let Pattern = !if(!eq(m, "shld"),385                    [(store (node (t.LoadNode addr:$src1), t.RegClass:$src2, CL), addr:$src1)],386                    [(store (node t.RegClass:$src2, (t.LoadNode addr:$src1), CL), addr:$src1)]);387}388 389class ShlrdOpMRI8U_R<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag>390  : ITy<o, MRMDestMem, t, (outs t.RegClass:$dst), (ins t.MemOperand:$src1, t.RegClass:$src2, u8imm:$src3),391        m, triop_ndd_args, []>, NDD<1> {392  let ImmT = Imm8;393  let SchedRW = [WriteSHDmri];394  let mayLoad = 1;395  let Pattern = !if(!eq(m, "shld"),396                    [(set t.RegClass:$dst, (node (t.LoadNode addr:$src1), t.RegClass:$src2, (i8 imm:$src3)))],397                    [(set t.RegClass:$dst, (node t.RegClass:$src2, (t.LoadNode addr:$src1), (i8 imm:$src3)))]);398}399 400class ShlrdOpMRC_R<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag>401  : BinOpMR<o, m, triop_cl_ndd_args, t, (outs t.RegClass:$dst), []>, NDD<1> {402  let Uses = [CL];403  let SchedRW = [WriteSHDmrcl];404  let Pattern = !if(!eq(m, "shld"),405                    [(set t.RegClass:$dst, (node (t.LoadNode addr:$src1), t.RegClass:$src2, CL))],406                    [(set t.RegClass:$dst, (node t.RegClass:$src2, (t.LoadNode addr:$src1), CL))]);407}408 409multiclass Shlrd<bits<8> o1, bits<8> o2, bits<8> o3, string m, SDPatternOperator node, SDPatternOperator t_node> {410  let Predicates = [NoNDD] in {411    def 16rri8 : ShlrdOpRRI8U_R<o1, m, Xi16, t_node>, TB, DefEFLAGS, OpSize16;412    def 32rri8 : ShlrdOpRRI8U_R<o1, m, Xi32, node>, TB, DefEFLAGS, OpSize32;413    def 64rri8 : ShlrdOpRRI8U_R<o1, m, Xi64, node>, TB, DefEFLAGS;414 415    def 16rrCL : ShlrdOpRRC_R<o2, m, Xi16, t_node>, TB, DefEFLAGS, OpSize16;416    def 32rrCL : ShlrdOpRRC_R<o2, m, Xi32, node>, TB, DefEFLAGS, OpSize32;417    def 64rrCL : ShlrdOpRRC_R<o2, m, Xi64, node>, TB, DefEFLAGS;418  }419  let Predicates = [HasNDD, In64BitMode] in {420    def 16rri8_ND : ShlrdOpRRI8U_R<o3, m, Xi16, t_node, 1>, DefEFLAGS, PD;421    def 32rri8_ND : ShlrdOpRRI8U_R<o3, m, Xi32, node, 1>, DefEFLAGS;422    def 64rri8_ND : ShlrdOpRRI8U_R<o3, m, Xi64, node, 1>, DefEFLAGS;423 424    def 16rrCL_ND : ShlrdOpRRC_R<o2, m, Xi16, t_node, 1>, DefEFLAGS, PD;425    def 32rrCL_ND : ShlrdOpRRC_R<o2, m, Xi32, node, 1>, DefEFLAGS;426    def 64rrCL_ND : ShlrdOpRRC_R<o2, m, Xi64, node, 1>, DefEFLAGS;427  }428 429  let Predicates = [In64BitMode] in {430    def 16rri8_NF : ShlrdOpRRI8U_R<o3, m, Xi16>, NF, PD;431    def 32rri8_NF : ShlrdOpRRI8U_R<o3, m, Xi32>, NF;432    def 64rri8_NF : ShlrdOpRRI8U_R<o3, m, Xi64>, NF;433 434    def 16rrCL_NF : ShlrdOpRRC_R<o2, m, Xi16>, NF, PD;435    def 32rrCL_NF : ShlrdOpRRC_R<o2, m, Xi32>, NF;436    def 64rrCL_NF : ShlrdOpRRC_R<o2, m, Xi64>, NF;437 438    def 16rri8_NF_ND : ShlrdOpRRI8U_R<o3, m, Xi16, null_frag, 1>, EVEX_NF, PD;439    def 32rri8_NF_ND : ShlrdOpRRI8U_R<o3, m, Xi32, null_frag, 1>, EVEX_NF;440    def 64rri8_NF_ND : ShlrdOpRRI8U_R<o3, m, Xi64, null_frag, 1>, EVEX_NF;441 442    def 16rrCL_NF_ND : ShlrdOpRRC_R<o2, m, Xi16, null_frag, 1>, EVEX_NF, PD;443    def 32rrCL_NF_ND : ShlrdOpRRC_R<o2, m, Xi32, null_frag, 1>, EVEX_NF;444    def 64rrCL_NF_ND : ShlrdOpRRC_R<o2, m, Xi64, null_frag, 1>, EVEX_NF;445 446    def 16rri8_EVEX : ShlrdOpRRI8U_R<o3, m, Xi16>, DefEFLAGS, PL, PD;447    def 32rri8_EVEX : ShlrdOpRRI8U_R<o3, m, Xi32>, DefEFLAGS, PL;448    def 64rri8_EVEX : ShlrdOpRRI8U_R<o3, m, Xi64>, DefEFLAGS, PL;449 450    def 16rrCL_EVEX : ShlrdOpRRC_R<o2, m, Xi16>, DefEFLAGS, PL, PD;451    def 32rrCL_EVEX : ShlrdOpRRC_R<o2, m, Xi32>, DefEFLAGS, PL;452    def 64rrCL_EVEX : ShlrdOpRRC_R<o2, m, Xi64>, DefEFLAGS, PL;453  }454 455  def 16mri8 : ShlrdOpMRI8U_M<o1, m, Xi16, t_node>, DefEFLAGS, OpSize16;456  def 32mri8 : ShlrdOpMRI8U_M<o1, m, Xi32, node>, DefEFLAGS, OpSize32;457  def 64mri8 : ShlrdOpMRI8U_M<o1, m, Xi64, node>, DefEFLAGS;458 459  def 16mrCL : ShlrdOpMRC_M<o2, m, Xi16, t_node>, DefEFLAGS, OpSize16;460  def 32mrCL : ShlrdOpMRC_M<o2, m, Xi32, node>, DefEFLAGS, OpSize32;461  def 64mrCL : ShlrdOpMRC_M<o2, m, Xi64, node>, DefEFLAGS;462 463  let Predicates = [HasNDD, In64BitMode] in {464    def 16mri8_ND : ShlrdOpMRI8U_R<o3, m, Xi16, t_node>, DefEFLAGS, PD;465    def 32mri8_ND : ShlrdOpMRI8U_R<o3, m, Xi32, node>, DefEFLAGS;466    def 64mri8_ND : ShlrdOpMRI8U_R<o3, m, Xi64, node>, DefEFLAGS;467 468    def 16mrCL_ND : ShlrdOpMRC_R<o2, m, Xi16, t_node>, DefEFLAGS, PD;469    def 32mrCL_ND : ShlrdOpMRC_R<o2, m, Xi32, node>, DefEFLAGS;470    def 64mrCL_ND : ShlrdOpMRC_R<o2, m, Xi64, node>, DefEFLAGS;471  }472 473  let Predicates = [In64BitMode] in {474    def 16mri8_NF : ShlrdOpMRI8U_M<o3, m, Xi16>, NF, PD;475    def 32mri8_NF : ShlrdOpMRI8U_M<o3, m, Xi32>, NF;476    def 64mri8_NF : ShlrdOpMRI8U_M<o3, m, Xi64>, NF;477 478    def 16mrCL_NF : ShlrdOpMRC_M<o2, m, Xi16>, NF, PD;479    def 32mrCL_NF : ShlrdOpMRC_M<o2, m, Xi32>, NF;480    def 64mrCL_NF : ShlrdOpMRC_M<o2, m, Xi64>, NF;481 482    def 16mri8_NF_ND : ShlrdOpMRI8U_R<o3, m, Xi16>, EVEX_NF, PD;483    def 32mri8_NF_ND : ShlrdOpMRI8U_R<o3, m, Xi32>, EVEX_NF;484    def 64mri8_NF_ND : ShlrdOpMRI8U_R<o3, m, Xi64>, EVEX_NF;485 486    def 16mrCL_NF_ND : ShlrdOpMRC_R<o2, m, Xi16>, EVEX_NF, PD;487    def 32mrCL_NF_ND : ShlrdOpMRC_R<o2, m, Xi32>, EVEX_NF;488    def 64mrCL_NF_ND : ShlrdOpMRC_R<o2, m, Xi64>, EVEX_NF;489 490    def 16mri8_EVEX : ShlrdOpMRI8U_M<o3, m, Xi16>, DefEFLAGS, PL, PD;491    def 32mri8_EVEX : ShlrdOpMRI8U_M<o3, m, Xi32>, DefEFLAGS, PL;492    def 64mri8_EVEX : ShlrdOpMRI8U_M<o3, m, Xi64>, DefEFLAGS, PL;493 494    def 16mrCL_EVEX : ShlrdOpMRC_M<o2, m, Xi16>, DefEFLAGS, PL, PD;495    def 32mrCL_EVEX : ShlrdOpMRC_M<o2, m, Xi32>, DefEFLAGS, PL;496    def 64mrCL_EVEX : ShlrdOpMRC_M<o2, m, Xi64>, DefEFLAGS, PL;497  }498}499 500defm SHLD : Shlrd<0xA4, 0xA5, 0x24, "shld", fshl, X86fshl>;501defm SHRD : Shlrd<0xAC, 0xAD, 0x2C, "shrd", fshr, X86fshr>;502 503// Sandy Bridge and newer Intel processors support faster rotates using504// SHLD to avoid a partial flag update on the normal rotate instructions.505// Use a pseudo so that TwoInstructionPass and register allocation will see506// this as unary instruction.507let Predicates = [HasFastSHLDRotate], AddedComplexity = 5,508    Defs = [EFLAGS], isPseudo = 1, SchedRW = [WriteSHDrri],509    Constraints = "$src1 = $dst" in {510  def SHLDROT32ri  : I<0, Pseudo, (outs GR32:$dst),511                       (ins GR32:$src1, u8imm:$shamt), "",512                     [(set GR32:$dst, (rotl GR32:$src1, (i8 imm:$shamt)))]>;513  def SHLDROT64ri  : I<0, Pseudo, (outs GR64:$dst),514                       (ins GR64:$src1, u8imm:$shamt), "",515                     [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$shamt)))]>;516 517  def SHRDROT32ri  : I<0, Pseudo, (outs GR32:$dst),518                       (ins GR32:$src1, u8imm:$shamt), "",519                     [(set GR32:$dst, (rotr GR32:$src1, (i8 imm:$shamt)))]>;520  def SHRDROT64ri  : I<0, Pseudo, (outs GR64:$dst),521                       (ins GR64:$src1, u8imm:$shamt), "",522                     [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$shamt)))]>;523}524 525//===----------------------------------------------------------------------===//526// BMI Shift/Rotate instructions527//===----------------------------------------------------------------------===//528 529def ROT32L2R_imm8  : SDNodeXForm<imm, [{530  // Convert a ROTL shamt to a ROTR shamt on 32-bit integer.531  return getI8Imm(32 - N->getZExtValue(), SDLoc(N));532}]>;533 534def ROT64L2R_imm8  : SDNodeXForm<imm, [{535  // Convert a ROTL shamt to a ROTR shamt on 64-bit integer.536  return getI8Imm(64 - N->getZExtValue(), SDLoc(N));537}]>;538 539// NOTE: We use WriteShift for these rotates as they avoid the stalls540// of many of the older x86 rotate instructions.541class RorXri<X86TypeInfo t>542  : ITy<0xF0, MRMSrcReg, t, (outs t.RegClass:$dst), (ins t.RegClass:$src1, u8imm:$src2),543        "rorx", binop_ndd_args, []>, TA, XD, Sched<[WriteShift]> {544  let ImmT = Imm8;545}546class RorXmi<X86TypeInfo t>547  : ITy<0xF0, MRMSrcMem, t, (outs t.RegClass:$dst), (ins t.MemOperand:$src1, u8imm:$src2),548        "rorx", binop_ndd_args, []>, TA, XD, Sched<[WriteShiftLd]> {549  let ImmT = Imm8;550  let mayLoad = 1;551}552 553multiclass RorX<X86TypeInfo t> {554  let Predicates = [HasBMI2, NoEGPR] in {555    def ri : RorXri<t>, VEX;556    def mi : RorXmi<t>, VEX;557  }558  let Predicates = [HasBMI2, HasEGPR, In64BitMode] in {559    def ri_EVEX : RorXri<t>, EVEX;560    def mi_EVEX : RorXmi<t>, EVEX;561  }562}563 564defm RORX32: RorX<Xi32>;565defm RORX64: RorX<Xi64>;566 567class ShiftXrr<string m, X86TypeInfo t>568  : ITy<0xF7, MRMSrcReg4VOp3, t, (outs t.RegClass:$dst), (ins t.RegClass:$src1, t.RegClass:$src2),569        m, binop_ndd_args, []>, T8, Sched<[WriteShift]>;570 571class ShiftXrm<string m, X86TypeInfo t>572  : ITy<0xF7, MRMSrcMem4VOp3, t, (outs t.RegClass:$dst), (ins t.MemOperand:$src1, t.RegClass:$src2),573        m, binop_ndd_args, []>, T8,574    Sched<[WriteShift.Folded,575           // x86memop:$src1576           ReadDefault, ReadDefault, ReadDefault, ReadDefault,577           ReadDefault,578           // RC:$src2579           WriteShift.ReadAfterFold]> {580  let mayLoad = 1;581}582 583 584multiclass ShiftX<string m, X86TypeInfo t> {585  let Predicates = [HasBMI2, NoEGPR] in {586    def rr : ShiftXrr<m, t>, VEX;587    def rm : ShiftXrm<m, t>, VEX;588  }589  let Predicates = [HasBMI2, HasEGPR, In64BitMode] in {590    def rr_EVEX : ShiftXrr<m, t>, EVEX;591    def rm_EVEX : ShiftXrm<m, t>, EVEX;592  }593}594 595defm SARX32: ShiftX<"sarx", Xi32>, XS;596defm SARX64: ShiftX<"sarx", Xi64>, XS;597defm SHRX32: ShiftX<"shrx", Xi32>, XD;598defm SHRX64: ShiftX<"shrx", Xi64>, XD;599defm SHLX32: ShiftX<"shlx", Xi32>, PD;600defm SHLX64: ShiftX<"shlx", Xi64>, PD;601 602multiclass RORX_Pats<string suffix> {603  // Prefer RORX which is non-destructive and doesn't update EFLAGS.604  let AddedComplexity = 10 in {605    def : Pat<(rotr GR32:$src, (i8 imm:$shamt)),606              (!cast<Instruction>(RORX32ri#suffix) GR32:$src, imm:$shamt)>;607    def : Pat<(rotr GR64:$src, (i8 imm:$shamt)),608              (!cast<Instruction>(RORX64ri#suffix) GR64:$src, imm:$shamt)>;609 610    def : Pat<(rotl GR32:$src, (i8 imm:$shamt)),611              (!cast<Instruction>(RORX32ri#suffix) GR32:$src, (ROT32L2R_imm8 imm:$shamt))>;612    def : Pat<(rotl GR64:$src, (i8 imm:$shamt)),613              (!cast<Instruction>(RORX64ri#suffix) GR64:$src, (ROT64L2R_imm8 imm:$shamt))>;614  }615 616  def : Pat<(rotr (loadi32 addr:$src), (i8 imm:$shamt)),617            (!cast<Instruction>(RORX32mi#suffix) addr:$src, imm:$shamt)>;618  def : Pat<(rotr (loadi64 addr:$src), (i8 imm:$shamt)),619            (!cast<Instruction>(RORX64mi#suffix) addr:$src, imm:$shamt)>;620 621  def : Pat<(rotl (loadi32 addr:$src), (i8 imm:$shamt)),622            (!cast<Instruction>(RORX32mi#suffix) addr:$src, (ROT32L2R_imm8 imm:$shamt))>;623  def : Pat<(rotl (loadi64 addr:$src), (i8 imm:$shamt)),624            (!cast<Instruction>(RORX64mi#suffix) addr:$src, (ROT64L2R_imm8 imm:$shamt))>;625}626 627multiclass ShiftX_Pats<SDNode op, string suffix = ""> {628  // Prefer SARX/SHRX/SHLX over SAR/SHR/SHL with variable shift BUT not629  // immediate shift, i.e. the following code is considered better630  //631  //  mov %edi, %esi632  //  shl $imm, %esi633  //  ... %edi, ...634  //635  // than636  //637  //  movb $imm, %sil638  //  shlx %sil, %edi, %esi639  //  ... %edi, ...640  //641  let AddedComplexity = 1 in {642   def : Pat<(op GR32:$src1, GR8:$src2),643              (!cast<Instruction>(NAME#"32rr"#suffix) GR32:$src1,644               (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;645   def : Pat<(op GR64:$src1, GR8:$src2),646              (!cast<Instruction>(NAME#"64rr"#suffix) GR64:$src1,647               (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;648   def : Pat<(op GR32:$src1, (shiftMask32 GR8:$src2)),649              (!cast<Instruction>(NAME#"32rr"#suffix) GR32:$src1,650               (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;651   def : Pat<(op GR64:$src1, (shiftMask64 GR8:$src2)),652              (!cast<Instruction>(NAME#"64rr"#suffix) GR64:$src1,653               (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;654  }655  // We prefer to use656  //  mov (%ecx), %esi657  //  shl $imm, $esi658  //659  // over660  //661  //  movb $imm, %al662  //  shlx %al, (%ecx), %esi663  //664  // This priority is enforced by IsProfitableToFoldLoad.665  def : Pat<(op (loadi32 addr:$src1), GR8:$src2),666             (!cast<Instruction>(NAME#"32rm"#suffix) addr:$src1,667              (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;668  def : Pat<(op (loadi64 addr:$src1), GR8:$src2),669             (!cast<Instruction>(NAME#"64rm"#suffix) addr:$src1,670              (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;671  def : Pat<(op (loadi32 addr:$src1), (shiftMask32 GR8:$src2)),672             (!cast<Instruction>(NAME#"32rm"#suffix) addr:$src1,673              (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;674  def : Pat<(op (loadi64 addr:$src1), (shiftMask64 GR8:$src2)),675             (!cast<Instruction>(NAME#"64rm"#suffix) addr:$src1,676              (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;677}678 679let Predicates = [HasBMI2, NoEGPR] in {680  defm : RORX_Pats<"">;681  defm SARX : ShiftX_Pats<sra>;682  defm SHRX : ShiftX_Pats<srl>;683  defm SHLX : ShiftX_Pats<shl>;684}685 686let Predicates = [HasBMI2, HasEGPR] in {687  defm : RORX_Pats<"_EVEX">;688  defm SARX : ShiftX_Pats<sra, "_EVEX">;689  defm SHRX : ShiftX_Pats<srl, "_EVEX">;690  defm SHLX : ShiftX_Pats<shl, "_EVEX">;691}692