10b57cec5SDimitry Andric//===-- X86InstrShiftRotate.td - Shift and Rotate Instrs ---*- tablegen -*-===// 20b57cec5SDimitry Andric// 30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric// 70b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric// 90b57cec5SDimitry Andric// This file describes the shift and rotate instructions. 100b57cec5SDimitry Andric// 110b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 14*7a6dacacSDimitry Andric// Shift/Rotate instructions 150b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 160b57cec5SDimitry Andric 17*7a6dacacSDimitry Andricmulticlass ShiftRotate<string m, Format RegMRM, Format MemMRM, SDPatternOperator node, 18*7a6dacacSDimitry Andric SchedReadWrite rCL, SchedReadWrite ri, SchedReadWrite mCL, 19*7a6dacacSDimitry Andric SchedReadWrite mi, list<Register> uses = []> { 200b57cec5SDimitry Andric 21*7a6dacacSDimitry Andric let Uses = uses in { 22*7a6dacacSDimitry Andric let isConvertibleToThreeAddress = !if(!eq(m, "shl"), 1, 0) in { 23*7a6dacacSDimitry Andric let Predicates = [NoNDD] in { 24*7a6dacacSDimitry Andric def 8ri : BinOpRI8U_R<m, RegMRM, Xi8, node>, Sched<[ri]>, DefEFLAGS; 25*7a6dacacSDimitry Andric def 16ri : BinOpRI8U_R<m, RegMRM, Xi16, node>, Sched<[ri]>, DefEFLAGS, OpSize16; 26*7a6dacacSDimitry Andric def 32ri : BinOpRI8U_R<m, RegMRM, Xi32, node>, Sched<[ri]>, DefEFLAGS, OpSize32; 27*7a6dacacSDimitry Andric def 64ri : BinOpRI8U_R<m, RegMRM, Xi64, node>, Sched<[ri]>, DefEFLAGS; 28*7a6dacacSDimitry Andric } 29*7a6dacacSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 30*7a6dacacSDimitry Andric def 8ri_ND : BinOpRI8U_R<m, RegMRM, Xi8, node, 1>, Sched<[ri]>, DefEFLAGS; 31*7a6dacacSDimitry Andric def 16ri_ND : BinOpRI8U_R<m, RegMRM, Xi16, node, 1>, Sched<[ri]>, DefEFLAGS, PD; 32*7a6dacacSDimitry Andric def 32ri_ND : BinOpRI8U_R<m, RegMRM, Xi32, node, 1>, Sched<[ri]>, DefEFLAGS; 33*7a6dacacSDimitry Andric def 64ri_ND : BinOpRI8U_R<m, RegMRM, Xi64, node, 1>, Sched<[ri]>, DefEFLAGS; 34*7a6dacacSDimitry Andric } 35*7a6dacacSDimitry Andric let Predicates = [In64BitMode] in { 36*7a6dacacSDimitry Andric def 8ri_EVEX : BinOpRI8U_R<m, RegMRM, Xi8>, Sched<[ri]>, DefEFLAGS, PL; 37*7a6dacacSDimitry Andric def 16ri_EVEX : BinOpRI8U_R<m, RegMRM, Xi16>, Sched<[ri]>, DefEFLAGS, PL, PD; 38*7a6dacacSDimitry Andric def 32ri_EVEX : BinOpRI8U_R<m, RegMRM, Xi32>, Sched<[ri]>, DefEFLAGS, PL; 39*7a6dacacSDimitry Andric def 64ri_EVEX : BinOpRI8U_R<m, RegMRM, Xi64>, Sched<[ri]>, DefEFLAGS, PL; 40*7a6dacacSDimitry Andric } 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 43*7a6dacacSDimitry Andric def 8mi : BinOpMI8U_M<m, MemMRM, Xi8, node>, Sched<[mi, WriteRMW]>, DefEFLAGS; 44*7a6dacacSDimitry Andric def 16mi : BinOpMI8U_M<m, MemMRM, Xi16, node>, Sched<[mi, WriteRMW]>, DefEFLAGS, OpSize16; 45*7a6dacacSDimitry Andric def 32mi : BinOpMI8U_M<m, MemMRM, Xi32, node>, Sched<[mi, WriteRMW]>, DefEFLAGS, OpSize32; 46*7a6dacacSDimitry Andric def 64mi : BinOpMI8U_M<m, MemMRM, Xi64, node>, Sched<[mi, WriteRMW]>, DefEFLAGS, Requires<[In64BitMode]>; 47*7a6dacacSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 48*7a6dacacSDimitry Andric def 8mi_ND : BinOpMI8U_R<m, MemMRM, Xi8, node>, Sched<[mi, ri]>, DefEFLAGS; 49*7a6dacacSDimitry Andric def 16mi_ND : BinOpMI8U_R<m, MemMRM, Xi16, node>, Sched<[mi, ri]>, DefEFLAGS, PD; 50*7a6dacacSDimitry Andric def 32mi_ND : BinOpMI8U_R<m, MemMRM, Xi32, node>, Sched<[mi, ri]>, DefEFLAGS; 51*7a6dacacSDimitry Andric def 64mi_ND : BinOpMI8U_R<m, MemMRM, Xi64, node>, Sched<[mi, ri]>, DefEFLAGS; 52*7a6dacacSDimitry Andric } 53*7a6dacacSDimitry Andric let Predicates = [In64BitMode] in { 54*7a6dacacSDimitry Andric def 8mi_EVEX : BinOpMI8U_M<m, MemMRM, Xi8>, Sched<[mi, WriteRMW]>, DefEFLAGS, PL; 55*7a6dacacSDimitry Andric def 16mi_EVEX : BinOpMI8U_M<m, MemMRM, Xi16>, Sched<[mi, WriteRMW]>, DefEFLAGS, PL, PD; 56*7a6dacacSDimitry Andric def 32mi_EVEX : BinOpMI8U_M<m, MemMRM, Xi32>, Sched<[mi, WriteRMW]>, DefEFLAGS, PL; 57*7a6dacacSDimitry Andric def 64mi_EVEX : BinOpMI8U_M<m, MemMRM, Xi64>, Sched<[mi, WriteRMW]>, DefEFLAGS, PL; 58*7a6dacacSDimitry Andric } 590b57cec5SDimitry Andric 60*7a6dacacSDimitry Andric let SchedRW = [ri] in { 61*7a6dacacSDimitry Andric def 8r1 : UnaryOpR_RF<0xD1, RegMRM, m, Xi8>; 62*7a6dacacSDimitry Andric def 16r1 : UnaryOpR_RF<0xD1, RegMRM, m, Xi16>, OpSize16; 63*7a6dacacSDimitry Andric def 32r1 : UnaryOpR_RF<0xD1, RegMRM, m, Xi32>, OpSize32; 64*7a6dacacSDimitry Andric def 64r1 : UnaryOpR_RF<0xD1, RegMRM, m, Xi64>; 650b57cec5SDimitry Andric 66*7a6dacacSDimitry Andric // FIXME: Assembler can't tell whether it's 8r1_ND or 8rCL when the source register is cl, e.g. 67*7a6dacacSDimitry Andric // 68*7a6dacacSDimitry Andric // shlb %cl, %al 69*7a6dacacSDimitry Andric // 70*7a6dacacSDimitry Andric // GNU binutils distinguish them by adding an explicit $1 to asm string of 8r1_ND. But we haven't support 71*7a6dacacSDimitry Andric // constant immediate in asm string for X86 in TD. So we add DisassembleOnly for 8r1_ND for the time being. 72*7a6dacacSDimitry Andric let Predicates = [In64BitMode] in { 73*7a6dacacSDimitry Andric def 8r1_ND : UnaryOpR_RF<0xD1, RegMRM, m, Xi8, null_frag, 1>, DisassembleOnly; 74*7a6dacacSDimitry Andric def 16r1_ND : UnaryOpR_RF<0xD1, RegMRM, m, Xi16, null_frag, 1>, PD; 75*7a6dacacSDimitry Andric def 32r1_ND : UnaryOpR_RF<0xD1, RegMRM, m, Xi32, null_frag, 1>; 76*7a6dacacSDimitry Andric def 64r1_ND : UnaryOpR_RF<0xD1, RegMRM, m, Xi64, null_frag, 1>; 770b57cec5SDimitry Andric 78*7a6dacacSDimitry Andric def 8r1_EVEX : UnaryOpR_RF<0xD1, RegMRM, m, Xi8>, PL; 79*7a6dacacSDimitry Andric def 16r1_EVEX : UnaryOpR_RF<0xD1, RegMRM, m, Xi16>, PL, PD; 80*7a6dacacSDimitry Andric def 32r1_EVEX : UnaryOpR_RF<0xD1, RegMRM, m, Xi32>, PL; 81*7a6dacacSDimitry Andric def 64r1_EVEX : UnaryOpR_RF<0xD1, RegMRM, m, Xi64>, PL; 82*7a6dacacSDimitry Andric } 83*7a6dacacSDimitry Andric } 840b57cec5SDimitry Andric 85*7a6dacacSDimitry Andric let SchedRW = [mi, WriteRMW] in { 86*7a6dacacSDimitry Andric def 8m1 : UnaryOpM_MF<0xD1, MemMRM, m, Xi8>; 87*7a6dacacSDimitry Andric def 16m1 : UnaryOpM_MF<0xD1, MemMRM, m, Xi16>, OpSize16; 88*7a6dacacSDimitry Andric def 32m1 : UnaryOpM_MF<0xD1, MemMRM, m, Xi32>, OpSize32; 89*7a6dacacSDimitry Andric def 64m1 : UnaryOpM_MF<0xD1, MemMRM, m, Xi64>, Requires<[In64BitMode]>; 900b57cec5SDimitry Andric 91*7a6dacacSDimitry Andric let Predicates = [In64BitMode] in { 92*7a6dacacSDimitry Andric def 8m1_EVEX : UnaryOpM_MF<0xD1, MemMRM, m, Xi8>, PL; 93*7a6dacacSDimitry Andric def 16m1_EVEX : UnaryOpM_MF<0xD1, MemMRM, m, Xi16>, PL, PD; 94*7a6dacacSDimitry Andric def 32m1_EVEX : UnaryOpM_MF<0xD1, MemMRM, m, Xi32>, PL; 95*7a6dacacSDimitry Andric def 64m1_EVEX : UnaryOpM_MF<0xD1, MemMRM, m, Xi64>, PL; 96*7a6dacacSDimitry Andric } 97*7a6dacacSDimitry Andric } 98*7a6dacacSDimitry Andric let SchedRW = [mi, ri], Predicates = [In64BitMode] in { 99*7a6dacacSDimitry Andric def 8m1_ND : UnaryOpM_RF<0xD1, MemMRM, m, Xi8>; 100*7a6dacacSDimitry Andric def 16m1_ND : UnaryOpM_RF<0xD1, MemMRM, m, Xi16>, PD; 101*7a6dacacSDimitry Andric def 32m1_ND : UnaryOpM_RF<0xD1, MemMRM, m, Xi32>; 102*7a6dacacSDimitry Andric def 64m1_ND : UnaryOpM_RF<0xD1, MemMRM, m, Xi64>; 103*7a6dacacSDimitry Andric } 104*7a6dacacSDimitry Andric } 1050b57cec5SDimitry Andric 106*7a6dacacSDimitry Andric let Uses = !listconcat([CL], uses), Defs = [EFLAGS] in { 107*7a6dacacSDimitry Andric let Predicates = [NoNDD] in { 108*7a6dacacSDimitry Andric def 8rCL : BinOpRC_R<m, RegMRM, Xi8, node>, Sched<[rCL]>; 109*7a6dacacSDimitry Andric def 16rCL : BinOpRC_R<m, RegMRM, Xi16, node>, Sched<[rCL]>, OpSize16; 110*7a6dacacSDimitry Andric def 32rCL : BinOpRC_R<m, RegMRM, Xi32, node>, Sched<[rCL]>, OpSize32; 111*7a6dacacSDimitry Andric def 64rCL : BinOpRC_R<m, RegMRM, Xi64, node>, Sched<[rCL]>; 112*7a6dacacSDimitry Andric } 113*7a6dacacSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 114*7a6dacacSDimitry Andric def 8rCL_ND : BinOpRC_R<m, RegMRM, Xi8, node, 1>, Sched<[rCL]>; 115*7a6dacacSDimitry Andric def 16rCL_ND : BinOpRC_R<m, RegMRM, Xi16, node, 1>, Sched<[rCL]>, PD; 116*7a6dacacSDimitry Andric def 32rCL_ND : BinOpRC_R<m, RegMRM, Xi32, node, 1>, Sched<[rCL]>; 117*7a6dacacSDimitry Andric def 64rCL_ND : BinOpRC_R<m, RegMRM, Xi64, node, 1>, Sched<[rCL]>; 118*7a6dacacSDimitry Andric } 119*7a6dacacSDimitry Andric let Predicates = [In64BitMode] in { 120*7a6dacacSDimitry Andric def 8rCL_EVEX : BinOpRC_R<m, RegMRM, Xi8>, Sched<[rCL]>, PL; 121*7a6dacacSDimitry Andric def 16rCL_EVEX : BinOpRC_R<m, RegMRM, Xi16>, Sched<[rCL]>, PL, PD; 122*7a6dacacSDimitry Andric def 32rCL_EVEX : BinOpRC_R<m, RegMRM, Xi32>, Sched<[rCL]>, PL; 123*7a6dacacSDimitry Andric def 64rCL_EVEX : BinOpRC_R<m, RegMRM, Xi64>, Sched<[rCL]>, PL; 124*7a6dacacSDimitry Andric } 1250b57cec5SDimitry Andric 126*7a6dacacSDimitry Andric def 8mCL : BinOpMC_M<m, MemMRM, Xi8, node>, Sched<[mCL, WriteRMW]>; 127*7a6dacacSDimitry Andric def 16mCL : BinOpMC_M<m, MemMRM, Xi16, node>, Sched<[mCL, WriteRMW]>, OpSize16; 128*7a6dacacSDimitry Andric def 32mCL : BinOpMC_M<m, MemMRM, Xi32, node>, Sched<[mCL, WriteRMW]>, OpSize32; 129*7a6dacacSDimitry Andric def 64mCL : BinOpMC_M<m, MemMRM, Xi64, node>, Sched<[mCL, WriteRMW]>, Requires<[In64BitMode]>; 1300b57cec5SDimitry Andric 131*7a6dacacSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 132*7a6dacacSDimitry Andric def 8mCL_ND : BinOpMC_R<m, MemMRM, Xi8, node>, Sched<[mCL, rCL]>; 133*7a6dacacSDimitry Andric def 16mCL_ND : BinOpMC_R<m, MemMRM, Xi16, node>, Sched<[mCL, rCL]>, PD; 134*7a6dacacSDimitry Andric def 32mCL_ND : BinOpMC_R<m, MemMRM, Xi32, node>, Sched<[mCL, rCL]>; 135*7a6dacacSDimitry Andric def 64mCL_ND : BinOpMC_R<m, MemMRM, Xi64, node>, Sched<[mCL, rCL]>; 136*7a6dacacSDimitry Andric } 1370b57cec5SDimitry Andric 138*7a6dacacSDimitry Andric let Predicates = [In64BitMode] in { 139*7a6dacacSDimitry Andric def 8mCL_EVEX : BinOpMC_M<m, MemMRM, Xi8>, Sched<[mCL, WriteRMW]>, PL; 140*7a6dacacSDimitry Andric def 16mCL_EVEX : BinOpMC_M<m, MemMRM, Xi16>, Sched<[mCL, WriteRMW]>, PL, PD; 141*7a6dacacSDimitry Andric def 32mCL_EVEX : BinOpMC_M<m, MemMRM, Xi32>, Sched<[mCL, WriteRMW]>, PL; 142*7a6dacacSDimitry Andric def 64mCL_EVEX : BinOpMC_M<m, MemMRM, Xi64>, Sched<[mCL, WriteRMW]>, PL; 143*7a6dacacSDimitry Andric } 144*7a6dacacSDimitry Andric } 145*7a6dacacSDimitry Andric} 1460b57cec5SDimitry Andric 147*7a6dacacSDimitry Andricmulticlass ShiftRotate_NF<string m, Format RegMRM, Format MemMRM, SchedReadWrite rCL, 148*7a6dacacSDimitry Andric SchedReadWrite ri, SchedReadWrite mCL, SchedReadWrite mi> { 149*7a6dacacSDimitry Andric let Predicates = [In64BitMode] in { 150*7a6dacacSDimitry Andric let isConvertibleToThreeAddress = !if(!eq(m, "shl"), 1, 0) in { 151*7a6dacacSDimitry Andric def 8ri_NF : BinOpRI8U_R<m, RegMRM, Xi8>, Sched<[ri]>, NF; 152*7a6dacacSDimitry Andric def 16ri_NF : BinOpRI8U_R<m, RegMRM, Xi16>, Sched<[ri]>, NF, PD; 153*7a6dacacSDimitry Andric def 32ri_NF : BinOpRI8U_R<m, RegMRM, Xi32>, Sched<[ri]>, NF; 154*7a6dacacSDimitry Andric def 64ri_NF : BinOpRI8U_R<m, RegMRM, Xi64>, Sched<[ri]>, NF; 1550b57cec5SDimitry Andric 156*7a6dacacSDimitry Andric def 8ri_NF_ND : BinOpRI8U_R<m, RegMRM, Xi8, null_frag, 1>, Sched<[ri]>, EVEX_NF; 157*7a6dacacSDimitry Andric def 16ri_NF_ND : BinOpRI8U_R<m, RegMRM, Xi16, null_frag, 1>, Sched<[ri]>, EVEX_NF, PD; 158*7a6dacacSDimitry Andric def 32ri_NF_ND : BinOpRI8U_R<m, RegMRM, Xi32, null_frag, 1>, Sched<[ri]>, EVEX_NF; 159*7a6dacacSDimitry Andric def 64ri_NF_ND : BinOpRI8U_R<m, RegMRM, Xi64, null_frag, 1>, Sched<[ri]>, EVEX_NF; 160*7a6dacacSDimitry Andric } 1610b57cec5SDimitry Andric 162*7a6dacacSDimitry Andric def 8mi_NF : BinOpMI8U_M<m, MemMRM, Xi8>, Sched<[mi, WriteRMW]>, NF; 163*7a6dacacSDimitry Andric def 16mi_NF : BinOpMI8U_M<m, MemMRM, Xi16>, Sched<[mi, WriteRMW]>, NF, PD; 164*7a6dacacSDimitry Andric def 32mi_NF : BinOpMI8U_M<m, MemMRM, Xi32>, Sched<[mi, WriteRMW]>, NF; 165*7a6dacacSDimitry Andric def 64mi_NF : BinOpMI8U_M<m, MemMRM, Xi64>, Sched<[mi, WriteRMW]>, NF; 1660b57cec5SDimitry Andric 167*7a6dacacSDimitry Andric def 8mi_NF_ND : BinOpMI8U_R<m, MemMRM, Xi8>, Sched<[mi, ri]>, EVEX_NF; 168*7a6dacacSDimitry Andric def 16mi_NF_ND : BinOpMI8U_R<m, MemMRM, Xi16>, Sched<[mi, ri]>, EVEX_NF, PD; 169*7a6dacacSDimitry Andric def 32mi_NF_ND : BinOpMI8U_R<m, MemMRM, Xi32>, Sched<[mi, ri]>, EVEX_NF; 170*7a6dacacSDimitry Andric def 64mi_NF_ND : BinOpMI8U_R<m, MemMRM, Xi64>, Sched<[mi, ri]>, EVEX_NF; 1710b57cec5SDimitry Andric 172*7a6dacacSDimitry Andric let SchedRW = [ri] in { 173*7a6dacacSDimitry Andric // FIXME: Assembler can't tell whether it's 8r1_NF_ND or 8rCL_NF when the source register is cl, e.g. 174*7a6dacacSDimitry Andric // 175*7a6dacacSDimitry Andric // {nf} shlb %cl, %al 176*7a6dacacSDimitry Andric // 177*7a6dacacSDimitry Andric // GNU binutils distinguish them by adding an explicit $1 to asm string of 8r1_NF_ND. But we haven't support 178*7a6dacacSDimitry Andric // constant immediate in asm string for X86 in TD. So we add DisassembleOnly for 8r1_NF_ND for the time being. 179*7a6dacacSDimitry Andric def 8r1_NF : UnaryOpR_R<0xD1, RegMRM, m, Xi8>, NF; 180*7a6dacacSDimitry Andric def 16r1_NF : UnaryOpR_R<0xD1, RegMRM, m, Xi16>, NF, PD; 181*7a6dacacSDimitry Andric def 32r1_NF : UnaryOpR_R<0xD1, RegMRM, m, Xi32>, NF; 182*7a6dacacSDimitry Andric def 64r1_NF : UnaryOpR_R<0xD1, RegMRM, m, Xi64>, NF; 1830b57cec5SDimitry Andric 184*7a6dacacSDimitry Andric def 8r1_NF_ND : UnaryOpR_R<0xD1, RegMRM, m, Xi8, null_frag, 1>, EVEX_NF, DisassembleOnly; 185*7a6dacacSDimitry Andric def 16r1_NF_ND : UnaryOpR_R<0xD1, RegMRM, m, Xi16, null_frag, 1>, EVEX_NF, PD; 186*7a6dacacSDimitry Andric def 32r1_NF_ND : UnaryOpR_R<0xD1, RegMRM, m, Xi32, null_frag, 1>, EVEX_NF; 187*7a6dacacSDimitry Andric def 64r1_NF_ND : UnaryOpR_R<0xD1, RegMRM, m, Xi64, null_frag, 1>, EVEX_NF; 188*7a6dacacSDimitry Andric } 1890b57cec5SDimitry Andric 190*7a6dacacSDimitry Andric let SchedRW = [mi, WriteRMW] in { 191*7a6dacacSDimitry Andric def 8m1_NF : UnaryOpM_M<0xD1, MemMRM, m, Xi8>, NF; 192*7a6dacacSDimitry Andric def 16m1_NF : UnaryOpM_M<0xD1, MemMRM, m, Xi16>, NF, PD; 193*7a6dacacSDimitry Andric def 32m1_NF : UnaryOpM_M<0xD1, MemMRM, m, Xi32>, NF; 194*7a6dacacSDimitry Andric def 64m1_NF : UnaryOpM_M<0xD1, MemMRM, m, Xi64>, NF; 195*7a6dacacSDimitry Andric } 196*7a6dacacSDimitry Andric let SchedRW = [mi, ri] in { 197*7a6dacacSDimitry Andric def 8m1_NF_ND : UnaryOpM_R<0xD1, MemMRM, m, Xi8>, EVEX_NF; 198*7a6dacacSDimitry Andric def 16m1_NF_ND : UnaryOpM_R<0xD1, MemMRM, m, Xi16>, EVEX_NF, PD; 199*7a6dacacSDimitry Andric def 32m1_NF_ND : UnaryOpM_R<0xD1, MemMRM, m, Xi32>, EVEX_NF; 200*7a6dacacSDimitry Andric def 64m1_NF_ND : UnaryOpM_R<0xD1, MemMRM, m, Xi64>, EVEX_NF; 201*7a6dacacSDimitry Andric } 202*7a6dacacSDimitry Andric 203*7a6dacacSDimitry Andric let Uses = [CL] in { 204*7a6dacacSDimitry Andric def 8rCL_NF : BinOpRC_R<m, RegMRM, Xi8>, Sched<[rCL]>, NF; 205*7a6dacacSDimitry Andric def 16rCL_NF : BinOpRC_R<m, RegMRM, Xi16>, Sched<[rCL]>, NF, PD; 206*7a6dacacSDimitry Andric def 32rCL_NF : BinOpRC_R<m, RegMRM, Xi32>, Sched<[rCL]>, NF; 207*7a6dacacSDimitry Andric def 64rCL_NF : BinOpRC_R<m, RegMRM, Xi64>, Sched<[rCL]>, NF; 208*7a6dacacSDimitry Andric 209*7a6dacacSDimitry Andric def 8rCL_NF_ND : BinOpRC_R<m, RegMRM, Xi8, null_frag, 1>, Sched<[rCL]>, EVEX_NF; 210*7a6dacacSDimitry Andric def 16rCL_NF_ND : BinOpRC_R<m, RegMRM, Xi16, null_frag, 1>, Sched<[rCL]>, EVEX_NF, PD; 211*7a6dacacSDimitry Andric def 32rCL_NF_ND : BinOpRC_R<m, RegMRM, Xi32, null_frag, 1>, Sched<[rCL]>, EVEX_NF; 212*7a6dacacSDimitry Andric def 64rCL_NF_ND : BinOpRC_R<m, RegMRM, Xi64, null_frag, 1>, Sched<[rCL]>, EVEX_NF; 213*7a6dacacSDimitry Andric 214*7a6dacacSDimitry Andric def 8mCL_NF : BinOpMC_M<m, MemMRM, Xi8>, Sched<[mCL, WriteRMW]>, NF; 215*7a6dacacSDimitry Andric def 16mCL_NF : BinOpMC_M<m, MemMRM, Xi16>, Sched<[mCL, WriteRMW]>, NF, PD; 216*7a6dacacSDimitry Andric def 32mCL_NF : BinOpMC_M<m, MemMRM, Xi32>, Sched<[mCL, WriteRMW]>, NF; 217*7a6dacacSDimitry Andric def 64mCL_NF : BinOpMC_M<m, MemMRM, Xi64>, Sched<[mCL, WriteRMW]>, NF; 218*7a6dacacSDimitry Andric 219*7a6dacacSDimitry Andric def 8mCL_NF_ND : BinOpMC_R<m, MemMRM, Xi8>, Sched<[mCL, rCL]>, EVEX_NF; 220*7a6dacacSDimitry Andric def 16mCL_NF_ND : BinOpMC_R<m, MemMRM, Xi16>, Sched<[mCL, rCL]>, EVEX_NF, PD; 221*7a6dacacSDimitry Andric def 32mCL_NF_ND : BinOpMC_R<m, MemMRM, Xi32>, Sched<[mCL, rCL]>, EVEX_NF; 222*7a6dacacSDimitry Andric def 64mCL_NF_ND : BinOpMC_R<m, MemMRM, Xi64>, Sched<[mCL, rCL]>, EVEX_NF; 223*7a6dacacSDimitry Andric } 224*7a6dacacSDimitry Andric } 225*7a6dacacSDimitry Andric} 226*7a6dacacSDimitry Andricdefm SHL: ShiftRotate<"shl", MRM4r, MRM4m, shl, WriteShiftCL, WriteShift, WriteShiftCLLd, WriteShiftLd>; 227*7a6dacacSDimitry Andricdefm SHR: ShiftRotate<"shr", MRM5r, MRM5m, srl, WriteShiftCL, WriteShift, WriteShiftCLLd, WriteShiftLd>; 228*7a6dacacSDimitry Andricdefm SAR: ShiftRotate<"sar", MRM7r, MRM7m, sra, WriteShiftCL, WriteShift, WriteShiftCLLd, WriteShiftLd>; 229*7a6dacacSDimitry Andric 230*7a6dacacSDimitry Andricdefm ROL: ShiftRotate<"rol", MRM0r, MRM0m, rotl, WriteRotateCL, WriteRotate, WriteRotateCLLd, WriteRotateLd>; 231*7a6dacacSDimitry Andricdefm ROR: ShiftRotate<"ror", MRM1r, MRM1m, rotr, WriteRotateCL, WriteRotate, WriteRotateCLLd, WriteRotateLd>; 232*7a6dacacSDimitry Andricdefm RCL: ShiftRotate<"rcl", MRM2r, MRM2m, null_frag, WriteRotateCL, WriteRotate, WriteRotateCLLd, WriteRotateLd, [EFLAGS]>; 233*7a6dacacSDimitry Andricdefm RCR: ShiftRotate<"rcr", MRM3r, MRM3m, null_frag, WriteRotateCL, WriteRotate, WriteRotateCLLd, WriteRotateLd, [EFLAGS]>; 234*7a6dacacSDimitry Andric 235*7a6dacacSDimitry Andricdefm SHL: ShiftRotate_NF<"shl", MRM4r, MRM4m, WriteShiftCL, WriteShift, WriteShiftCLLd, WriteShiftLd>; 236*7a6dacacSDimitry Andricdefm SHR: ShiftRotate_NF<"shr", MRM5r, MRM5m, WriteShiftCL, WriteShift, WriteShiftCLLd, WriteShiftLd>; 237*7a6dacacSDimitry Andricdefm SAR: ShiftRotate_NF<"sar", MRM7r, MRM7m, WriteShiftCL, WriteShift, WriteShiftCLLd, WriteShiftLd>; 238*7a6dacacSDimitry Andric 239*7a6dacacSDimitry Andricdefm ROL: ShiftRotate_NF<"rol", MRM0r, MRM0m, WriteRotateCL, WriteRotate, WriteRotateCLLd, WriteRotateLd>; 240*7a6dacacSDimitry Andricdefm ROR: ShiftRotate_NF<"ror", MRM1r, MRM1m, WriteRotateCL, WriteRotate, WriteRotateCLLd, WriteRotateLd>; 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric// Use the opposite rotate if allows us to use the rotate by 1 instruction. 243*7a6dacacSDimitry Andriclet Predicates = [NoNDD] in { 2440b57cec5SDimitry Andric def : Pat<(rotl GR8:$src1, (i8 7)), (ROR8r1 GR8:$src1)>; 2450b57cec5SDimitry Andric def : Pat<(rotl GR16:$src1, (i8 15)), (ROR16r1 GR16:$src1)>; 2460b57cec5SDimitry Andric def : Pat<(rotl GR32:$src1, (i8 31)), (ROR32r1 GR32:$src1)>; 2470b57cec5SDimitry Andric def : Pat<(rotl GR64:$src1, (i8 63)), (ROR64r1 GR64:$src1)>; 2480b57cec5SDimitry Andric def : Pat<(rotr GR8:$src1, (i8 7)), (ROL8r1 GR8:$src1)>; 2490b57cec5SDimitry Andric def : Pat<(rotr GR16:$src1, (i8 15)), (ROL16r1 GR16:$src1)>; 2500b57cec5SDimitry Andric def : Pat<(rotr GR32:$src1, (i8 31)), (ROL32r1 GR32:$src1)>; 2510b57cec5SDimitry Andric def : Pat<(rotr GR64:$src1, (i8 63)), (ROL64r1 GR64:$src1)>; 252*7a6dacacSDimitry Andric} 253*7a6dacacSDimitry Andriclet Predicates = [HasNDD] in { 254*7a6dacacSDimitry Andric def : Pat<(rotl GR8:$src1, (i8 7)), (ROR8r1_ND GR8:$src1)>; 255*7a6dacacSDimitry Andric def : Pat<(rotl GR16:$src1, (i8 15)), (ROR16r1_ND GR16:$src1)>; 256*7a6dacacSDimitry Andric def : Pat<(rotl GR32:$src1, (i8 31)), (ROR32r1_ND GR32:$src1)>; 257*7a6dacacSDimitry Andric def : Pat<(rotl GR64:$src1, (i8 63)), (ROR64r1_ND GR64:$src1)>; 258*7a6dacacSDimitry Andric def : Pat<(rotr GR8:$src1, (i8 7)), (ROL8r1_ND GR8:$src1)>; 259*7a6dacacSDimitry Andric def : Pat<(rotr GR16:$src1, (i8 15)), (ROL16r1_ND GR16:$src1)>; 260*7a6dacacSDimitry Andric def : Pat<(rotr GR32:$src1, (i8 31)), (ROL32r1_ND GR32:$src1)>; 261*7a6dacacSDimitry Andric def : Pat<(rotr GR64:$src1, (i8 63)), (ROL64r1_ND GR64:$src1)>; 262*7a6dacacSDimitry Andric} 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andricdef : Pat<(store (rotl (loadi8 addr:$dst), (i8 7)), addr:$dst), 2650b57cec5SDimitry Andric (ROR8m1 addr:$dst)>; 2660b57cec5SDimitry Andricdef : Pat<(store (rotl (loadi16 addr:$dst), (i8 15)), addr:$dst), 2670b57cec5SDimitry Andric (ROR16m1 addr:$dst)>; 2680b57cec5SDimitry Andricdef : Pat<(store (rotl (loadi32 addr:$dst), (i8 31)), addr:$dst), 2690b57cec5SDimitry Andric (ROR32m1 addr:$dst)>; 2700b57cec5SDimitry Andricdef : Pat<(store (rotl (loadi64 addr:$dst), (i8 63)), addr:$dst), 2710b57cec5SDimitry Andric (ROR64m1 addr:$dst)>, Requires<[In64BitMode]>; 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andricdef : Pat<(store (rotr (loadi8 addr:$dst), (i8 7)), addr:$dst), 2740b57cec5SDimitry Andric (ROL8m1 addr:$dst)>; 2750b57cec5SDimitry Andricdef : Pat<(store (rotr (loadi16 addr:$dst), (i8 15)), addr:$dst), 2760b57cec5SDimitry Andric (ROL16m1 addr:$dst)>; 2770b57cec5SDimitry Andricdef : Pat<(store (rotr (loadi32 addr:$dst), (i8 31)), addr:$dst), 2780b57cec5SDimitry Andric (ROL32m1 addr:$dst)>; 2790b57cec5SDimitry Andricdef : Pat<(store (rotr (loadi64 addr:$dst), (i8 63)), addr:$dst), 2800b57cec5SDimitry Andric (ROL64m1 addr:$dst)>, Requires<[In64BitMode]>; 2810b57cec5SDimitry Andric 282*7a6dacacSDimitry Andriclet Predicates = [HasNDD] in { 283*7a6dacacSDimitry Andricdef : Pat<(rotl (loadi8 addr:$src), (i8 7)), 284*7a6dacacSDimitry Andric (ROR8m1_ND addr:$src)>; 285*7a6dacacSDimitry Andricdef : Pat<(rotl (loadi16 addr:$src), (i8 15)), 286*7a6dacacSDimitry Andric (ROR16m1_ND addr:$src)>; 287*7a6dacacSDimitry Andricdef : Pat<(rotl (loadi32 addr:$src), (i8 31)), 288*7a6dacacSDimitry Andric (ROR32m1_ND addr:$src)>; 289*7a6dacacSDimitry Andricdef : Pat<(rotl (loadi64 addr:$src), (i8 63)), 290*7a6dacacSDimitry Andric (ROR64m1_ND addr:$src)>; 291*7a6dacacSDimitry Andric 292*7a6dacacSDimitry Andricdef : Pat<(rotr (loadi8 addr:$src), (i8 7)), 293*7a6dacacSDimitry Andric (ROL8m1_ND addr:$src)>; 294*7a6dacacSDimitry Andricdef : Pat<(rotr (loadi16 addr:$src), (i8 15)), 295*7a6dacacSDimitry Andric (ROL16m1_ND addr:$src)>; 296*7a6dacacSDimitry Andricdef : Pat<(rotr (loadi32 addr:$src), (i8 31)), 297*7a6dacacSDimitry Andric (ROL32m1_ND addr:$src)>; 298*7a6dacacSDimitry Andricdef : Pat<(rotr (loadi64 addr:$src), (i8 63)), 299*7a6dacacSDimitry Andric (ROL64m1_ND addr:$src)>; 300*7a6dacacSDimitry Andric} 301*7a6dacacSDimitry Andric 302*7a6dacacSDimitry Andric// Patterns for rotate with relocImm for the immediate field. 303*7a6dacacSDimitry Andriclet Predicates = [NoNDD] in { 304*7a6dacacSDimitry Andric def : Pat<(rotl GR8:$src1, (i8 relocImm:$src2)), 305*7a6dacacSDimitry Andric (ROL8ri GR8:$src1, relocImm:$src2)>; 306*7a6dacacSDimitry Andric def : Pat<(rotl GR16:$src1, (i8 relocImm:$src2)), 307*7a6dacacSDimitry Andric (ROL16ri GR16:$src1, relocImm:$src2)>; 308*7a6dacacSDimitry Andric def : Pat<(rotl GR32:$src1, (i8 relocImm:$src2)), 309*7a6dacacSDimitry Andric (ROL32ri GR32:$src1, relocImm:$src2)>; 310*7a6dacacSDimitry Andric def : Pat<(rotl GR64:$src1, (i8 relocImm:$src2)), 311*7a6dacacSDimitry Andric (ROL64ri GR64:$src1, relocImm:$src2)>; 312*7a6dacacSDimitry Andric 313*7a6dacacSDimitry Andric def : Pat<(rotr GR8:$src1, (i8 relocImm:$src2)), 314*7a6dacacSDimitry Andric (ROR8ri GR8:$src1, relocImm:$src2)>; 315*7a6dacacSDimitry Andric def : Pat<(rotr GR16:$src1, (i8 relocImm:$src2)), 316*7a6dacacSDimitry Andric (ROR16ri GR16:$src1, relocImm:$src2)>; 317*7a6dacacSDimitry Andric def : Pat<(rotr GR32:$src1, (i8 relocImm:$src2)), 318*7a6dacacSDimitry Andric (ROR32ri GR32:$src1, relocImm:$src2)>; 319*7a6dacacSDimitry Andric def : Pat<(rotr GR64:$src1, (i8 relocImm:$src2)), 320*7a6dacacSDimitry Andric (ROR64ri GR64:$src1, relocImm:$src2)>; 321*7a6dacacSDimitry Andric} 322*7a6dacacSDimitry Andriclet Predicates = [HasNDD] in { 323*7a6dacacSDimitry Andric def : Pat<(rotl GR8:$src1, (i8 relocImm:$src2)), 324*7a6dacacSDimitry Andric (ROL8ri_ND GR8:$src1, relocImm:$src2)>; 325*7a6dacacSDimitry Andric def : Pat<(rotl GR16:$src1, (i8 relocImm:$src2)), 326*7a6dacacSDimitry Andric (ROL16ri_ND GR16:$src1, relocImm:$src2)>; 327*7a6dacacSDimitry Andric def : Pat<(rotl GR32:$src1, (i8 relocImm:$src2)), 328*7a6dacacSDimitry Andric (ROL32ri_ND GR32:$src1, relocImm:$src2)>; 329*7a6dacacSDimitry Andric def : Pat<(rotl GR64:$src1, (i8 relocImm:$src2)), 330*7a6dacacSDimitry Andric (ROL64ri_ND GR64:$src1, relocImm:$src2)>; 331*7a6dacacSDimitry Andric 332*7a6dacacSDimitry Andric def : Pat<(rotr GR8:$src1, (i8 relocImm:$src2)), 333*7a6dacacSDimitry Andric (ROR8ri_ND GR8:$src1, relocImm:$src2)>; 334*7a6dacacSDimitry Andric def : Pat<(rotr GR16:$src1, (i8 relocImm:$src2)), 335*7a6dacacSDimitry Andric (ROR16ri_ND GR16:$src1, relocImm:$src2)>; 336*7a6dacacSDimitry Andric def : Pat<(rotr GR32:$src1, (i8 relocImm:$src2)), 337*7a6dacacSDimitry Andric (ROR32ri_ND GR32:$src1, relocImm:$src2)>; 338*7a6dacacSDimitry Andric def : Pat<(rotr GR64:$src1, (i8 relocImm:$src2)), 339*7a6dacacSDimitry Andric (ROR64ri_ND GR64:$src1, relocImm:$src2)>; 340*7a6dacacSDimitry Andric} 341*7a6dacacSDimitry Andric 342*7a6dacacSDimitry Andric//===----------------------------------------------------------------------===// 343*7a6dacacSDimitry Andric// Double precision shift instructions (generalizations of rotate) 344*7a6dacacSDimitry Andric//===----------------------------------------------------------------------===// 345*7a6dacacSDimitry Andric 346*7a6dacacSDimitry Andricclass ShlrdOpRRI8U_R<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0> 347*7a6dacacSDimitry Andric : ITy<o, MRMDestReg, t, (outs t.RegClass:$dst), 348*7a6dacacSDimitry Andric (ins t.RegClass:$src1, t.RegClass:$src2, u8imm:$src3), m, !if(!eq(ndd, 0), triop_args, triop_ndd_args), 349*7a6dacacSDimitry Andric []>, NDD<ndd> { 350*7a6dacacSDimitry Andric let isCommutable = 1; 351*7a6dacacSDimitry Andric let ImmT = Imm8; 352*7a6dacacSDimitry Andric let SchedRW = [WriteSHDrri]; 353*7a6dacacSDimitry Andric let Pattern = !if(!eq(m, "shld"), 354*7a6dacacSDimitry Andric [(set t.RegClass:$dst, (node t.RegClass:$src1, t.RegClass:$src2, (i8 imm:$src3)))], 355*7a6dacacSDimitry Andric [(set t.RegClass:$dst, (node t.RegClass:$src2, t.RegClass:$src1, (i8 imm:$src3)))]); 356*7a6dacacSDimitry Andric} 357*7a6dacacSDimitry Andric 358*7a6dacacSDimitry Andricclass ShlrdOpRRC_R<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0> 359*7a6dacacSDimitry Andric : BinOpRR<o, m, !if(!eq(ndd, 0), triop_cl_args, triop_cl_ndd_args), t, (outs t.RegClass:$dst), []>, NDD<ndd> { 360*7a6dacacSDimitry Andric let Uses = [CL]; 361*7a6dacacSDimitry Andric let SchedRW = [WriteSHDrrcl]; 362*7a6dacacSDimitry Andric let Pattern = !if(!eq(m, "shld"), 363*7a6dacacSDimitry Andric [(set t.RegClass:$dst, (node t.RegClass:$src1, t.RegClass:$src2, CL))], 364*7a6dacacSDimitry Andric [(set t.RegClass:$dst, (node t.RegClass:$src2, t.RegClass:$src1, CL))]); 365*7a6dacacSDimitry Andric} 366*7a6dacacSDimitry Andric 367*7a6dacacSDimitry Andricclass ShlrdOpMRI8U_M<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag> 368*7a6dacacSDimitry Andric : ITy<o, MRMDestMem, t, (outs), (ins t.MemOperand:$src1, t.RegClass:$src2, u8imm:$src3), 369*7a6dacacSDimitry Andric m, triop_args, []>, TB { 370*7a6dacacSDimitry Andric let ImmT = Imm8; 371*7a6dacacSDimitry Andric let SchedRW = [WriteSHDmri]; 372*7a6dacacSDimitry Andric let mayLoad = 1; 373*7a6dacacSDimitry Andric let mayStore = 1; 374*7a6dacacSDimitry Andric let Pattern = !if(!eq(m, "shld"), 375*7a6dacacSDimitry Andric [(store (node (t.LoadNode addr:$src1), t.RegClass:$src2, (i8 imm:$src3)), addr:$src1)], 376*7a6dacacSDimitry Andric [(store (node t.RegClass:$src2, (t.LoadNode addr:$src1), (i8 imm:$src3)), addr:$src1)]); 377*7a6dacacSDimitry Andric} 378*7a6dacacSDimitry Andric 379*7a6dacacSDimitry Andricclass ShlrdOpMRC_M<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag> 380*7a6dacacSDimitry Andric : BinOpMR<o, m, triop_cl_args, t, (outs), []>, TB { 381*7a6dacacSDimitry Andric let Uses = [CL]; 382*7a6dacacSDimitry Andric let SchedRW = [WriteSHDmrcl]; 383*7a6dacacSDimitry Andric let mayStore = 1; 384*7a6dacacSDimitry Andric let Pattern = !if(!eq(m, "shld"), 385*7a6dacacSDimitry Andric [(store (node (t.LoadNode addr:$src1), t.RegClass:$src2, CL), addr:$src1)], 386*7a6dacacSDimitry Andric [(store (node t.RegClass:$src2, (t.LoadNode addr:$src1), CL), addr:$src1)]); 387*7a6dacacSDimitry Andric} 388*7a6dacacSDimitry Andric 389*7a6dacacSDimitry Andricclass ShlrdOpMRI8U_R<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag> 390*7a6dacacSDimitry Andric : ITy<o, MRMDestMem, t, (outs t.RegClass:$dst), (ins t.MemOperand:$src1, t.RegClass:$src2, u8imm:$src3), 391*7a6dacacSDimitry Andric m, triop_ndd_args, []>, NDD<1> { 392*7a6dacacSDimitry Andric let ImmT = Imm8; 393*7a6dacacSDimitry Andric let SchedRW = [WriteSHDmri]; 394*7a6dacacSDimitry Andric let mayLoad = 1; 395*7a6dacacSDimitry Andric let Pattern = !if(!eq(m, "shld"), 396*7a6dacacSDimitry Andric [(set t.RegClass:$dst, (node (t.LoadNode addr:$src1), t.RegClass:$src2, (i8 imm:$src3)))], 397*7a6dacacSDimitry Andric [(set t.RegClass:$dst, (node t.RegClass:$src2, (t.LoadNode addr:$src1), (i8 imm:$src3)))]); 398*7a6dacacSDimitry Andric} 399*7a6dacacSDimitry Andric 400*7a6dacacSDimitry Andricclass ShlrdOpMRC_R<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag> 401*7a6dacacSDimitry Andric : BinOpMR<o, m, triop_cl_ndd_args, t, (outs t.RegClass:$dst), []>, NDD<1> { 402*7a6dacacSDimitry Andric let Uses = [CL]; 403*7a6dacacSDimitry Andric let SchedRW = [WriteSHDmrcl]; 404*7a6dacacSDimitry Andric let Pattern = !if(!eq(m, "shld"), 405*7a6dacacSDimitry Andric [(set t.RegClass:$dst, (node (t.LoadNode addr:$src1), t.RegClass:$src2, CL))], 406*7a6dacacSDimitry Andric [(set t.RegClass:$dst, (node t.RegClass:$src2, (t.LoadNode addr:$src1), CL))]); 407*7a6dacacSDimitry Andric} 408*7a6dacacSDimitry Andric 409*7a6dacacSDimitry Andricmulticlass Shlrd<bits<8> o1, bits<8> o2, bits<8> o3, string m, SDPatternOperator node, SDPatternOperator t_node> { 410*7a6dacacSDimitry Andric let Predicates = [NoNDD] in { 411*7a6dacacSDimitry Andric def 16rri8 : ShlrdOpRRI8U_R<o1, m, Xi16, t_node>, TB, DefEFLAGS, OpSize16; 412*7a6dacacSDimitry Andric def 32rri8 : ShlrdOpRRI8U_R<o1, m, Xi32, node>, TB, DefEFLAGS, OpSize32; 413*7a6dacacSDimitry Andric def 64rri8 : ShlrdOpRRI8U_R<o1, m, Xi64, node>, TB, DefEFLAGS; 414*7a6dacacSDimitry Andric 415*7a6dacacSDimitry Andric def 16rrCL : ShlrdOpRRC_R<o2, m, Xi16, t_node>, TB, DefEFLAGS, OpSize16; 416*7a6dacacSDimitry Andric def 32rrCL : ShlrdOpRRC_R<o2, m, Xi32, node>, TB, DefEFLAGS, OpSize32; 417*7a6dacacSDimitry Andric def 64rrCL : ShlrdOpRRC_R<o2, m, Xi64, node>, TB, DefEFLAGS; 418*7a6dacacSDimitry Andric } 419*7a6dacacSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 420*7a6dacacSDimitry Andric def 16rri8_ND : ShlrdOpRRI8U_R<o3, m, Xi16, t_node, 1>, DefEFLAGS, PD; 421*7a6dacacSDimitry Andric def 32rri8_ND : ShlrdOpRRI8U_R<o3, m, Xi32, node, 1>, DefEFLAGS; 422*7a6dacacSDimitry Andric def 64rri8_ND : ShlrdOpRRI8U_R<o3, m, Xi64, node, 1>, DefEFLAGS; 423*7a6dacacSDimitry Andric 424*7a6dacacSDimitry Andric def 16rrCL_ND : ShlrdOpRRC_R<o2, m, Xi16, t_node, 1>, DefEFLAGS, PD; 425*7a6dacacSDimitry Andric def 32rrCL_ND : ShlrdOpRRC_R<o2, m, Xi32, node, 1>, DefEFLAGS; 426*7a6dacacSDimitry Andric def 64rrCL_ND : ShlrdOpRRC_R<o2, m, Xi64, node, 1>, DefEFLAGS; 427*7a6dacacSDimitry Andric } 428*7a6dacacSDimitry Andric 429*7a6dacacSDimitry Andric let Predicates = [In64BitMode] in { 430*7a6dacacSDimitry Andric def 16rri8_NF : ShlrdOpRRI8U_R<o3, m, Xi16>, NF, PD; 431*7a6dacacSDimitry Andric def 32rri8_NF : ShlrdOpRRI8U_R<o3, m, Xi32>, NF; 432*7a6dacacSDimitry Andric def 64rri8_NF : ShlrdOpRRI8U_R<o3, m, Xi64>, NF; 433*7a6dacacSDimitry Andric 434*7a6dacacSDimitry Andric def 16rrCL_NF : ShlrdOpRRC_R<o2, m, Xi16>, NF, PD; 435*7a6dacacSDimitry Andric def 32rrCL_NF : ShlrdOpRRC_R<o2, m, Xi32>, NF; 436*7a6dacacSDimitry Andric def 64rrCL_NF : ShlrdOpRRC_R<o2, m, Xi64>, NF; 437*7a6dacacSDimitry Andric 438*7a6dacacSDimitry Andric def 16rri8_NF_ND : ShlrdOpRRI8U_R<o3, m, Xi16, null_frag, 1>, EVEX_NF, PD; 439*7a6dacacSDimitry Andric def 32rri8_NF_ND : ShlrdOpRRI8U_R<o3, m, Xi32, null_frag, 1>, EVEX_NF; 440*7a6dacacSDimitry Andric def 64rri8_NF_ND : ShlrdOpRRI8U_R<o3, m, Xi64, null_frag, 1>, EVEX_NF; 441*7a6dacacSDimitry Andric 442*7a6dacacSDimitry Andric def 16rrCL_NF_ND : ShlrdOpRRC_R<o2, m, Xi16, null_frag, 1>, EVEX_NF, PD; 443*7a6dacacSDimitry Andric def 32rrCL_NF_ND : ShlrdOpRRC_R<o2, m, Xi32, null_frag, 1>, EVEX_NF; 444*7a6dacacSDimitry Andric def 64rrCL_NF_ND : ShlrdOpRRC_R<o2, m, Xi64, null_frag, 1>, EVEX_NF; 445*7a6dacacSDimitry Andric 446*7a6dacacSDimitry Andric def 16rri8_EVEX : ShlrdOpRRI8U_R<o3, m, Xi16>, DefEFLAGS, PL, PD; 447*7a6dacacSDimitry Andric def 32rri8_EVEX : ShlrdOpRRI8U_R<o3, m, Xi32>, DefEFLAGS, PL; 448*7a6dacacSDimitry Andric def 64rri8_EVEX : ShlrdOpRRI8U_R<o3, m, Xi64>, DefEFLAGS, PL; 449*7a6dacacSDimitry Andric 450*7a6dacacSDimitry Andric def 16rrCL_EVEX : ShlrdOpRRC_R<o2, m, Xi16>, DefEFLAGS, PL, PD; 451*7a6dacacSDimitry Andric def 32rrCL_EVEX : ShlrdOpRRC_R<o2, m, Xi32>, DefEFLAGS, PL; 452*7a6dacacSDimitry Andric def 64rrCL_EVEX : ShlrdOpRRC_R<o2, m, Xi64>, DefEFLAGS, PL; 453*7a6dacacSDimitry Andric } 454*7a6dacacSDimitry Andric 455*7a6dacacSDimitry Andric def 16mri8 : ShlrdOpMRI8U_M<o1, m, Xi16, t_node>, DefEFLAGS, OpSize16; 456*7a6dacacSDimitry Andric def 32mri8 : ShlrdOpMRI8U_M<o1, m, Xi32, node>, DefEFLAGS, OpSize32; 457*7a6dacacSDimitry Andric def 64mri8 : ShlrdOpMRI8U_M<o1, m, Xi64, node>, DefEFLAGS; 458*7a6dacacSDimitry Andric 459*7a6dacacSDimitry Andric def 16mrCL : ShlrdOpMRC_M<o2, m, Xi16, t_node>, DefEFLAGS, OpSize16; 460*7a6dacacSDimitry Andric def 32mrCL : ShlrdOpMRC_M<o2, m, Xi32, node>, DefEFLAGS, OpSize32; 461*7a6dacacSDimitry Andric def 64mrCL : ShlrdOpMRC_M<o2, m, Xi64, node>, DefEFLAGS; 462*7a6dacacSDimitry Andric 463*7a6dacacSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 464*7a6dacacSDimitry Andric def 16mri8_ND : ShlrdOpMRI8U_R<o3, m, Xi16, t_node>, DefEFLAGS, PD; 465*7a6dacacSDimitry Andric def 32mri8_ND : ShlrdOpMRI8U_R<o3, m, Xi32, node>, DefEFLAGS; 466*7a6dacacSDimitry Andric def 64mri8_ND : ShlrdOpMRI8U_R<o3, m, Xi64, node>, DefEFLAGS; 467*7a6dacacSDimitry Andric 468*7a6dacacSDimitry Andric def 16mrCL_ND : ShlrdOpMRC_R<o2, m, Xi16, t_node>, DefEFLAGS, PD; 469*7a6dacacSDimitry Andric def 32mrCL_ND : ShlrdOpMRC_R<o2, m, Xi32, node>, DefEFLAGS; 470*7a6dacacSDimitry Andric def 64mrCL_ND : ShlrdOpMRC_R<o2, m, Xi64, node>, DefEFLAGS; 471*7a6dacacSDimitry Andric } 472*7a6dacacSDimitry Andric 473*7a6dacacSDimitry Andric let Predicates = [In64BitMode] in { 474*7a6dacacSDimitry Andric def 16mri8_NF : ShlrdOpMRI8U_M<o3, m, Xi16>, NF, PD; 475*7a6dacacSDimitry Andric def 32mri8_NF : ShlrdOpMRI8U_M<o3, m, Xi32>, NF; 476*7a6dacacSDimitry Andric def 64mri8_NF : ShlrdOpMRI8U_M<o3, m, Xi64>, NF; 477*7a6dacacSDimitry Andric 478*7a6dacacSDimitry Andric def 16mrCL_NF : ShlrdOpMRC_M<o2, m, Xi16>, NF, PD; 479*7a6dacacSDimitry Andric def 32mrCL_NF : ShlrdOpMRC_M<o2, m, Xi32>, NF; 480*7a6dacacSDimitry Andric def 64mrCL_NF : ShlrdOpMRC_M<o2, m, Xi64>, NF; 481*7a6dacacSDimitry Andric 482*7a6dacacSDimitry Andric def 16mri8_NF_ND : ShlrdOpMRI8U_R<o3, m, Xi16>, EVEX_NF, PD; 483*7a6dacacSDimitry Andric def 32mri8_NF_ND : ShlrdOpMRI8U_R<o3, m, Xi32>, EVEX_NF; 484*7a6dacacSDimitry Andric def 64mri8_NF_ND : ShlrdOpMRI8U_R<o3, m, Xi64>, EVEX_NF; 485*7a6dacacSDimitry Andric 486*7a6dacacSDimitry Andric def 16mrCL_NF_ND : ShlrdOpMRC_R<o2, m, Xi16>, EVEX_NF, PD; 487*7a6dacacSDimitry Andric def 32mrCL_NF_ND : ShlrdOpMRC_R<o2, m, Xi32>, EVEX_NF; 488*7a6dacacSDimitry Andric def 64mrCL_NF_ND : ShlrdOpMRC_R<o2, m, Xi64>, EVEX_NF; 489*7a6dacacSDimitry Andric 490*7a6dacacSDimitry Andric def 16mri8_EVEX : ShlrdOpMRI8U_M<o3, m, Xi16>, DefEFLAGS, PL, PD; 491*7a6dacacSDimitry Andric def 32mri8_EVEX : ShlrdOpMRI8U_M<o3, m, Xi32>, DefEFLAGS, PL; 492*7a6dacacSDimitry Andric def 64mri8_EVEX : ShlrdOpMRI8U_M<o3, m, Xi64>, DefEFLAGS, PL; 493*7a6dacacSDimitry Andric 494*7a6dacacSDimitry Andric def 16mrCL_EVEX : ShlrdOpMRC_M<o2, m, Xi16>, DefEFLAGS, PL, PD; 495*7a6dacacSDimitry Andric def 32mrCL_EVEX : ShlrdOpMRC_M<o2, m, Xi32>, DefEFLAGS, PL; 496*7a6dacacSDimitry Andric def 64mrCL_EVEX : ShlrdOpMRC_M<o2, m, Xi64>, DefEFLAGS, PL; 497*7a6dacacSDimitry Andric } 498*7a6dacacSDimitry Andric} 499*7a6dacacSDimitry Andric 500*7a6dacacSDimitry Andricdefm SHLD : Shlrd<0xA4, 0xA5, 0x24, "shld", fshl, X86fshl>; 501*7a6dacacSDimitry Andricdefm SHRD : Shlrd<0xAC, 0xAD, 0x2C, "shrd", fshr, X86fshr>; 502*7a6dacacSDimitry Andric 5030b57cec5SDimitry Andric// Sandy Bridge and newer Intel processors support faster rotates using 5040b57cec5SDimitry Andric// SHLD to avoid a partial flag update on the normal rotate instructions. 5050b57cec5SDimitry Andric// Use a pseudo so that TwoInstructionPass and register allocation will see 5060b57cec5SDimitry Andric// this as unary instruction. 5070b57cec5SDimitry Andriclet Predicates = [HasFastSHLDRotate], AddedComplexity = 5, 5080b57cec5SDimitry Andric Defs = [EFLAGS], isPseudo = 1, SchedRW = [WriteSHDrri], 5090b57cec5SDimitry Andric Constraints = "$src1 = $dst" in { 5100b57cec5SDimitry Andric def SHLDROT32ri : I<0, Pseudo, (outs GR32:$dst), 5110b57cec5SDimitry Andric (ins GR32:$src1, u8imm:$shamt), "", 5120b57cec5SDimitry Andric [(set GR32:$dst, (rotl GR32:$src1, (i8 imm:$shamt)))]>; 5130b57cec5SDimitry Andric def SHLDROT64ri : I<0, Pseudo, (outs GR64:$dst), 5140b57cec5SDimitry Andric (ins GR64:$src1, u8imm:$shamt), "", 5150b57cec5SDimitry Andric [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$shamt)))]>; 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric def SHRDROT32ri : I<0, Pseudo, (outs GR32:$dst), 5180b57cec5SDimitry Andric (ins GR32:$src1, u8imm:$shamt), "", 5190b57cec5SDimitry Andric [(set GR32:$dst, (rotr GR32:$src1, (i8 imm:$shamt)))]>; 5200b57cec5SDimitry Andric def SHRDROT64ri : I<0, Pseudo, (outs GR64:$dst), 5210b57cec5SDimitry Andric (ins GR64:$src1, u8imm:$shamt), "", 5220b57cec5SDimitry Andric [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$shamt)))]>; 5230b57cec5SDimitry Andric} 5240b57cec5SDimitry Andric 525*7a6dacacSDimitry Andric//===----------------------------------------------------------------------===// 526*7a6dacacSDimitry Andric// BMI Shift/Rotate instructions 527*7a6dacacSDimitry Andric//===----------------------------------------------------------------------===// 528*7a6dacacSDimitry Andric 5290b57cec5SDimitry Andricdef ROT32L2R_imm8 : SDNodeXForm<imm, [{ 5300b57cec5SDimitry Andric // Convert a ROTL shamt to a ROTR shamt on 32-bit integer. 5310b57cec5SDimitry Andric return getI8Imm(32 - N->getZExtValue(), SDLoc(N)); 5320b57cec5SDimitry Andric}]>; 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andricdef ROT64L2R_imm8 : SDNodeXForm<imm, [{ 5350b57cec5SDimitry Andric // Convert a ROTL shamt to a ROTR shamt on 64-bit integer. 5360b57cec5SDimitry Andric return getI8Imm(64 - N->getZExtValue(), SDLoc(N)); 5370b57cec5SDimitry Andric}]>; 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andric// NOTE: We use WriteShift for these rotates as they avoid the stalls 5400b57cec5SDimitry Andric// of many of the older x86 rotate instructions. 541*7a6dacacSDimitry Andricclass RorXri<X86TypeInfo t> 542*7a6dacacSDimitry Andric : ITy<0xF0, MRMSrcReg, t, (outs t.RegClass:$dst), (ins t.RegClass:$src1, u8imm:$src2), 543*7a6dacacSDimitry Andric "rorx", binop_ndd_args, []>, TA, XD, Sched<[WriteShift]> { 544*7a6dacacSDimitry Andric let ImmT = Imm8; 545*7a6dacacSDimitry Andric} 546*7a6dacacSDimitry Andricclass RorXmi<X86TypeInfo t> 547*7a6dacacSDimitry Andric : ITy<0xF0, MRMSrcMem, t, (outs t.RegClass:$dst), (ins t.MemOperand:$src1, u8imm:$src2), 548*7a6dacacSDimitry Andric "rorx", binop_ndd_args, []>, TA, XD, Sched<[WriteShiftLd]> { 549*7a6dacacSDimitry Andric let ImmT = Imm8; 550*7a6dacacSDimitry Andric let mayLoad = 1; 551*7a6dacacSDimitry Andric} 552*7a6dacacSDimitry Andric 553*7a6dacacSDimitry Andricmulticlass RorX<X86TypeInfo t> { 554*7a6dacacSDimitry Andric let Predicates = [HasBMI2, NoEGPR] in { 555*7a6dacacSDimitry Andric def ri : RorXri<t>, VEX; 556*7a6dacacSDimitry Andric def mi : RorXmi<t>, VEX; 557*7a6dacacSDimitry Andric } 558*7a6dacacSDimitry Andric let Predicates = [HasBMI2, HasEGPR, In64BitMode] in { 559*7a6dacacSDimitry Andric def ri_EVEX : RorXri<t>, EVEX; 560*7a6dacacSDimitry Andric def mi_EVEX : RorXmi<t>, EVEX; 5610b57cec5SDimitry Andric } 5620b57cec5SDimitry Andric} 5630b57cec5SDimitry Andric 564*7a6dacacSDimitry Andricdefm RORX32: RorX<Xi32>; 565*7a6dacacSDimitry Andricdefm RORX64: RorX<Xi64>; 566*7a6dacacSDimitry Andric 567*7a6dacacSDimitry Andricclass ShiftXrr<string m, X86TypeInfo t> 568*7a6dacacSDimitry Andric : ITy<0xF7, MRMSrcReg4VOp3, t, (outs t.RegClass:$dst), (ins t.RegClass:$src1, t.RegClass:$src2), 569*7a6dacacSDimitry Andric m, binop_ndd_args, []>, T8, Sched<[WriteShift]>; 570*7a6dacacSDimitry Andric 571*7a6dacacSDimitry Andricclass ShiftXrm<string m, X86TypeInfo t> 572*7a6dacacSDimitry Andric : ITy<0xF7, MRMSrcMem4VOp3, t, (outs t.RegClass:$dst), (ins t.MemOperand:$src1, t.RegClass:$src2), 573*7a6dacacSDimitry Andric m, binop_ndd_args, []>, T8, 574*7a6dacacSDimitry Andric Sched<[WriteShift.Folded, 5750b57cec5SDimitry Andric // x86memop:$src1 5760b57cec5SDimitry Andric ReadDefault, ReadDefault, ReadDefault, ReadDefault, 5770b57cec5SDimitry Andric ReadDefault, 5780b57cec5SDimitry Andric // RC:$src2 579*7a6dacacSDimitry Andric WriteShift.ReadAfterFold]> { 580*7a6dacacSDimitry Andric let mayLoad = 1; 5810b57cec5SDimitry Andric} 5820b57cec5SDimitry Andric 583*7a6dacacSDimitry Andric 584*7a6dacacSDimitry Andricmulticlass ShiftX<string m, X86TypeInfo t> { 5855f757f3fSDimitry Andric let Predicates = [HasBMI2, NoEGPR] in { 586*7a6dacacSDimitry Andric def rr : ShiftXrr<m, t>, VEX; 587*7a6dacacSDimitry Andric def rm : ShiftXrm<m, t>, VEX; 5885f757f3fSDimitry Andric } 5891db9f3b2SDimitry Andric let Predicates = [HasBMI2, HasEGPR, In64BitMode] in { 590*7a6dacacSDimitry Andric def rr_EVEX : ShiftXrr<m, t>, EVEX; 591*7a6dacacSDimitry Andric def rm_EVEX : ShiftXrm<m, t>, EVEX; 592*7a6dacacSDimitry Andric } 5935f757f3fSDimitry Andric} 5945f757f3fSDimitry Andric 595*7a6dacacSDimitry Andricdefm SARX32: ShiftX<"sarx", Xi32>, XS; 596*7a6dacacSDimitry Andricdefm SARX64: ShiftX<"sarx", Xi64>, XS; 597*7a6dacacSDimitry Andricdefm SHRX32: ShiftX<"shrx", Xi32>, XD; 598*7a6dacacSDimitry Andricdefm SHRX64: ShiftX<"shrx", Xi64>, XD; 599*7a6dacacSDimitry Andricdefm SHLX32: ShiftX<"shlx", Xi32>, PD; 600*7a6dacacSDimitry Andricdefm SHLX64: ShiftX<"shlx", Xi64>, PD; 601*7a6dacacSDimitry Andric 602*7a6dacacSDimitry Andricmulticlass RORX_Pats<string suffix> { 6030b57cec5SDimitry Andric // Prefer RORX which is non-destructive and doesn't update EFLAGS. 6040b57cec5SDimitry Andric let AddedComplexity = 10 in { 6050b57cec5SDimitry Andric def : Pat<(rotr GR32:$src, (i8 imm:$shamt)), 606*7a6dacacSDimitry Andric (!cast<Instruction>(RORX32ri#suffix) GR32:$src, imm:$shamt)>; 6070b57cec5SDimitry Andric def : Pat<(rotr GR64:$src, (i8 imm:$shamt)), 608*7a6dacacSDimitry Andric (!cast<Instruction>(RORX64ri#suffix) GR64:$src, imm:$shamt)>; 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric def : Pat<(rotl GR32:$src, (i8 imm:$shamt)), 611*7a6dacacSDimitry Andric (!cast<Instruction>(RORX32ri#suffix) GR32:$src, (ROT32L2R_imm8 imm:$shamt))>; 6120b57cec5SDimitry Andric def : Pat<(rotl GR64:$src, (i8 imm:$shamt)), 613*7a6dacacSDimitry Andric (!cast<Instruction>(RORX64ri#suffix) GR64:$src, (ROT64L2R_imm8 imm:$shamt))>; 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric def : Pat<(rotr (loadi32 addr:$src), (i8 imm:$shamt)), 617*7a6dacacSDimitry Andric (!cast<Instruction>(RORX32mi#suffix) addr:$src, imm:$shamt)>; 6180b57cec5SDimitry Andric def : Pat<(rotr (loadi64 addr:$src), (i8 imm:$shamt)), 619*7a6dacacSDimitry Andric (!cast<Instruction>(RORX64mi#suffix) addr:$src, imm:$shamt)>; 6200b57cec5SDimitry Andric 6210b57cec5SDimitry Andric def : Pat<(rotl (loadi32 addr:$src), (i8 imm:$shamt)), 622*7a6dacacSDimitry Andric (!cast<Instruction>(RORX32mi#suffix) addr:$src, (ROT32L2R_imm8 imm:$shamt))>; 6230b57cec5SDimitry Andric def : Pat<(rotl (loadi64 addr:$src), (i8 imm:$shamt)), 624*7a6dacacSDimitry Andric (!cast<Instruction>(RORX64mi#suffix) addr:$src, (ROT64L2R_imm8 imm:$shamt))>; 625*7a6dacacSDimitry Andric} 6260b57cec5SDimitry Andric 627*7a6dacacSDimitry Andricmulticlass ShiftX_Pats<SDNode op, string suffix = ""> { 6280b57cec5SDimitry Andric // Prefer SARX/SHRX/SHLX over SAR/SHR/SHL with variable shift BUT not 6290b57cec5SDimitry Andric // immediate shift, i.e. the following code is considered better 6300b57cec5SDimitry Andric // 6310b57cec5SDimitry Andric // mov %edi, %esi 6320b57cec5SDimitry Andric // shl $imm, %esi 6330b57cec5SDimitry Andric // ... %edi, ... 6340b57cec5SDimitry Andric // 6350b57cec5SDimitry Andric // than 6360b57cec5SDimitry Andric // 6370b57cec5SDimitry Andric // movb $imm, %sil 6380b57cec5SDimitry Andric // shlx %sil, %edi, %esi 6390b57cec5SDimitry Andric // ... %edi, ... 6400b57cec5SDimitry Andric // 6410b57cec5SDimitry Andric let AddedComplexity = 1 in { 642*7a6dacacSDimitry Andric def : Pat<(op GR32:$src1, GR8:$src2), 643*7a6dacacSDimitry Andric (!cast<Instruction>(NAME#"32rr"#suffix) GR32:$src1, 644*7a6dacacSDimitry Andric (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 645*7a6dacacSDimitry Andric def : Pat<(op GR64:$src1, GR8:$src2), 646*7a6dacacSDimitry Andric (!cast<Instruction>(NAME#"64rr"#suffix) GR64:$src1, 647*7a6dacacSDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 648*7a6dacacSDimitry Andric def : Pat<(op GR32:$src1, (shiftMask32 GR8:$src2)), 649*7a6dacacSDimitry Andric (!cast<Instruction>(NAME#"32rr"#suffix) GR32:$src1, 650*7a6dacacSDimitry Andric (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 651*7a6dacacSDimitry Andric def : Pat<(op GR64:$src1, (shiftMask64 GR8:$src2)), 652*7a6dacacSDimitry Andric (!cast<Instruction>(NAME#"64rr"#suffix) GR64:$src1, 653*7a6dacacSDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 6540b57cec5SDimitry Andric } 6550b57cec5SDimitry Andric // We prefer to use 6560b57cec5SDimitry Andric // mov (%ecx), %esi 6570b57cec5SDimitry Andric // shl $imm, $esi 6580b57cec5SDimitry Andric // 6590b57cec5SDimitry Andric // over 6600b57cec5SDimitry Andric // 6610b57cec5SDimitry Andric // movb $imm, %al 6620b57cec5SDimitry Andric // shlx %al, (%ecx), %esi 6630b57cec5SDimitry Andric // 6640b57cec5SDimitry Andric // This priority is enforced by IsProfitableToFoldLoad. 665*7a6dacacSDimitry Andric def : Pat<(op (loadi32 addr:$src1), GR8:$src2), 666*7a6dacacSDimitry Andric (!cast<Instruction>(NAME#"32rm"#suffix) addr:$src1, 667*7a6dacacSDimitry Andric (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 668*7a6dacacSDimitry Andric def : Pat<(op (loadi64 addr:$src1), GR8:$src2), 669*7a6dacacSDimitry Andric (!cast<Instruction>(NAME#"64rm"#suffix) addr:$src1, 670*7a6dacacSDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 671*7a6dacacSDimitry Andric def : Pat<(op (loadi32 addr:$src1), (shiftMask32 GR8:$src2)), 672*7a6dacacSDimitry Andric (!cast<Instruction>(NAME#"32rm"#suffix) addr:$src1, 673*7a6dacacSDimitry Andric (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 674*7a6dacacSDimitry Andric def : Pat<(op (loadi64 addr:$src1), (shiftMask64 GR8:$src2)), 675*7a6dacacSDimitry Andric (!cast<Instruction>(NAME#"64rm"#suffix) addr:$src1, 676*7a6dacacSDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 6770b57cec5SDimitry Andric} 6785ffd83dbSDimitry Andric 679*7a6dacacSDimitry Andriclet Predicates = [HasBMI2, NoEGPR] in { 680*7a6dacacSDimitry Andric defm : RORX_Pats<"">; 681*7a6dacacSDimitry Andric defm SARX : ShiftX_Pats<sra>; 682*7a6dacacSDimitry Andric defm SHRX : ShiftX_Pats<srl>; 683*7a6dacacSDimitry Andric defm SHLX : ShiftX_Pats<shl>; 684*7a6dacacSDimitry Andric} 6855ffd83dbSDimitry Andric 686*7a6dacacSDimitry Andriclet Predicates = [HasBMI2, HasEGPR] in { 687*7a6dacacSDimitry Andric defm : RORX_Pats<"_EVEX">; 688*7a6dacacSDimitry Andric defm SARX : ShiftX_Pats<sra, "_EVEX">; 689*7a6dacacSDimitry Andric defm SHRX : ShiftX_Pats<srl, "_EVEX">; 690*7a6dacacSDimitry Andric defm SHLX : ShiftX_Pats<shl, "_EVEX">; 691*7a6dacacSDimitry Andric} 692